Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debloat goal to determine needed and redundant classes and deps #481

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
01a90e7
Towards collecting interface info
henrikplate Jun 11, 2021
71e9319
Merge branch 'master' into slicing
henrikplate Jun 16, 2021
3b7967e
Discover interface methods
henrikplate Jun 16, 2021
c342bce
Completed collection of interfaces in java, class and archive files
henrikplate Jun 16, 2021
f5de5d5
added INTF to toCoreType
serenaponta Jun 22, 2021
944f07e
added INTF counting app construncts in backend
serenaponta Jun 22, 2021
9664262
added interface to app frontend
serenaponta Jun 22, 2021
b1ed42f
added interfaces to all i18n properties
serenaponta Jun 22, 2021
48125c2
additional change in i18n file
serenaponta Jun 22, 2021
4b9777e
formatted
serenaponta Jun 22, 2021
d03627c
interfaces will appear somewhere else in ui
serenaponta Jul 22, 2021
c8293f0
Merge branch 'master' into slicing
serenaponta Jul 22, 2021
553ecf1
added debloat goal
serenaponta Jul 23, 2021
53b2215
added traces and reachable constructs to debloat task
serenaponta Jul 26, 2021
2d70d1d
cherry picked 0da0d08e498ae35ee1c65d1ab771d4d92963809e
henrikplate Jul 27, 2021
cc8a4ab
filter on construct type and save missing classes
serenaponta Jul 28, 2021
98d865d
add (un)used deps
serenaponta Jul 28, 2021
ff28e07
added comments and reworked debloating logic
serenaponta Jul 29, 2021
65e0885
Fixed processing of reachable constructs; Files are written to config…
henrikplate Aug 3, 2021
c8ae37f
Code style
henrikplate Aug 4, 2021
ad12b45
removed useless code and improved handling of jdependency results
serenaponta Sep 3, 2021
139cca7
only use compile and runtime dependency in goal debloat
serenaponta Sep 3, 2021
431f28a
started adding test to entrypoints
serenaponta Oct 12, 2021
7ae7486
added debloating using test classes (set as new config value)
serenaponta Oct 13, 2021
ec69c95
do not save app after debloating
serenaponta Nov 10, 2021
e9ea3ee
merge master
serenaponta Dec 16, 2021
de190b4
merge master
serenaponta Feb 28, 2022
a255d2d
resolve conflict
serenaponta Mar 31, 2022
01d10a4
Merge branch 'master' into slicing
serenaponta Apr 1, 2022
2919e96
merge master
serenaponta Apr 2, 2022
d4314ab
Merge branch 'master' into slicing
serenaponta Apr 26, 2022
e4bb568
write file with used classes by steady static and dynamic
serenaponta Apr 26, 2022
1e09b7c
fix code style
serenaponta Apr 27, 2022
59e7d11
fix javadoc error
serenaponta Apr 27, 2022
e70cd34
always consider all steady classes
serenaponta Apr 27, 2022
61100f6
fix style
serenaponta Apr 27, 2022
1d5cb9f
minor change
serenaponta Apr 27, 2022
3c7cbdb
merge master
serenaponta Jun 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend-apps/src/main/webapp/i18n/messageBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ ratioConstructApp=Application
ratioConstructDeps=Total (app + dependencies)
ratioConstructRatio=Percentage (app/total)
# Metric names coming from the backend service
class_ratio=Classes
class_ratio=Classes, interfaces, enums
package_ratio=Packages
executable_ratio=Executable constructs (methods, constructors, static initializers)

# Test coverage table
packages=Application Package
interfaces=Interfaces (traced/total)
constructors=Constructors (traced/total)
methods=Methods (traced/total)
modules=Modules (traced/total)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ ratioConstructApp=Anwendung
ratioConstructDeps=Total (Anwendung + Abh�ngigkeiten)
ratioConstructRatio=Prozent (Anwendung/Total)
# Metric names coming from the backend service
class_ratio=Klassen
class_ratio=Klassen, Schnittstellen, Aufz�hlungstypen
package_ratio=Pakete
executable_ratio=Ausf�hrbare Konstrukte (Methoden, Konstruktoren, statische Initialisierer)

# Test coverage table
packages=Anwendungspaket
interfaces=Interfaces (traced/total)
constructors=Konstruktoren (traced/total)
methods=Methoden (traced/total)
static_inits=Statische Initialisierer (traced/total)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ ratioConstructApp=Application
ratioConstructDeps=Total (app + dependencies)
ratioConstructRatio=Percentage (app/total)
# Metric names coming from the backend service
class_ratio=Classes
class_ratio=Classes, interfaces, enums
package_ratio=Packages
executable_ratio=Executable constructs (methods, constructors, static initializers)

# Test coverage table
packages=Application Package
interfaces=Interfaces (traced/total)
constructors=Constructors (traced/total)
methods=Methods (traced/total)
static_inits=Static Initializers (traced/total)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ ratioConstructApp=Application
ratioConstructDeps=Total (app + dependencies)
ratioConstructRatio=Percentage (app/total)
# Metric names coming from the backend service
class_ratio=Classes
class_ratio=Classes, interfaces, enums
package_ratio=Packages
executable_ratio=Executable constructs (methods, constructors, static initializers)

# Test coverage table
packages=Application Package
interfaces=Interfaces (traced/total)
constructors=Constructors (traced/total)
methods=Methods (traced/total)
static_inits=Static Initializers (traced/total)
Expand Down
3 changes: 3 additions & 0 deletions frontend-apps/src/main/webapp/view/Component.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ sap.ui.controller("view.Component", {
singlePackage.modules=packageCounters[pack].MODU;
singlePackage.functions=packageCounters[pack].FUNC;
singlePackage.static_inits=packageCounters[pack].INIT;
singlePackage.interfaces=packageCounters[pack].INTF;

if(packageCountersTraced!=null&&packageCountersTraced[pack]){
//add if else to avoid traced CONSTRUCTORS > traced
Expand All @@ -611,6 +612,7 @@ sap.ui.controller("view.Component", {
singlePackage.modulesTested=packageCountersTraced[pack].MODU;
singlePackage.functionsTested=packageCountersTraced[pack].FUNC;
singlePackage.static_initsTested=packageCountersTraced[pack].INIT;
singlePackage.interfacesTested=packageCountersTraced[pack].INTF;
traced = traced + packageCountersTraced[pack].countExecutable;
}
else {
Expand All @@ -619,6 +621,7 @@ sap.ui.controller("view.Component", {
singlePackage.static_initsTested = 0;
singlePackage.modulesTested = 0;
singlePackage.functionsTested = 0;
singlePackage.interfacesTested=0;
}

//TODO ADD MODU & FUNCTION? (INITIATED
Expand Down
7 changes: 7 additions & 0 deletions lang-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Required by steady:debloat -->
<dependency>
<groupId>org.vafer</groupId>
<artifactId>jdependency</artifactId>
<version>2.7.0</version>
</dependency>

<!-- Test dependencies -->
<dependency>
Expand Down Expand Up @@ -105,6 +111,7 @@
</dependencies>

<build>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,15 @@ public Map<ConstructId, Construct> getConstructs() throws FileAnalysisException
// TODO HP, 4.4.16: This does not yet seem to work
ClassPoolUpdater.getInstance().updateClasspath(ctclass, this.file);

// Only add constructs of ctclass is either a class or enum (no interfaces)
if (ctclass.isInterface()) {
ClassFileAnalyzer.log.debug("Interface [" + ctclass.getName() + "] skipped");
} else {
// Use a class visitor to get all constructs from the class file
final ClassVisitor cv = new ClassVisitor(ctclass);
final Set<ConstructId> temp_constructs = cv.getConstructs();

// Add all constructs with a "" body
// TODO: Change Construct so that string (for source files) and binary bodies (file
// compiled classes) can be covered
for (ConstructId c : temp_constructs) this.constructs.put(c, new Construct(c, ""));
// Use a class visitor to get all constructs from the class file
final ClassVisitor cv = new ClassVisitor(ctclass);
final Set<ConstructId> temp_constructs = cv.getConstructs();

// Add all constructs with a "" body
// TODO: Change Construct so that string (for source files) and binary bodies (file
// compiled classes) can be covered
for (ConstructId c : temp_constructs) {
this.constructs.put(c, new Construct(c, ""));
}
} catch (FileNotFoundException e) {
throw new FileAnalysisException(e.getMessage(), e);
Expand Down
105 changes: 50 additions & 55 deletions lang-java/src/main/java/org/eclipse/steady/java/JarAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -526,62 +526,57 @@ else if (je.getName().endsWith("pom.xml")) {
try {
ctclass = JarAnalyzer.getClassPool().get(cn);

// Ignore interfaces (no executable code) and enums (rarely containing executable code,
// perhaps to be included later on)
if (ctclass.isInterface()) {
this.interfaceCount++;
} else {

if (ctclass.isEnum()) this.enumCount++;
else this.classCount++;

// Create ClassVisitor for the current Java class
cv = new ClassVisitor(ctclass);
this.constructs.addAll(cv.getConstructs());

// Instrument (if requested and not blacklisted)
if (this.instrument && !this.instrControl.isBlacklistedClass(cn)) {
cv.setOriginalArchiveDigest(this.getSHA1());
cv.setAppContext(JarAnalyzer.getAppContext());
if (cv.isInstrumented())
this.instrControl.updateInstrumentationStatistics(cv.getJavaId(), null);
else {
try {
cv.visitMethods(true);
cv.visitConstructors(true);
cv.finalizeInstrumentation();
this.instrumentedClasses.put(cv.getJavaId(), cv);
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(true));
} catch (IOException ioe) {
JarAnalyzer.log.error(
"I/O exception while instrumenting class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ ioe.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
} catch (CannotCompileException cce) {
JarAnalyzer.log.warn(
"Cannot compile instrumented class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ cce.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
} catch (Exception e) {
JarAnalyzer.log.error(
e.getClass().getName()
+ " occured while instrumenting class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ e.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
}
if (ctclass.isEnum()) this.enumCount++;
else if (ctclass.isInterface()) this.interfaceCount++;
else this.classCount++;

// Create ClassVisitor for the current Java class
cv = new ClassVisitor(ctclass);
this.constructs.addAll(cv.getConstructs());

// Instrument (if requested and not blacklisted)
if (this.instrument && !this.instrControl.isBlacklistedClass(cn)) {
cv.setOriginalArchiveDigest(this.getSHA1());
cv.setAppContext(JarAnalyzer.getAppContext());
if (cv.isInstrumented())
this.instrControl.updateInstrumentationStatistics(cv.getJavaId(), null);
else {
try {
cv.visitMethods(true);
cv.visitConstructors(true);
cv.finalizeInstrumentation();
this.instrumentedClasses.put(cv.getJavaId(), cv);
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(true));
} catch (IOException ioe) {
JarAnalyzer.log.error(
"I/O exception while instrumenting class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ ioe.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
} catch (CannotCompileException cce) {
JarAnalyzer.log.warn(
"Cannot compile instrumented class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ cce.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
} catch (Exception e) {
JarAnalyzer.log.error(
e.getClass().getName()
+ " occured while instrumenting class ["
+ cv.getJavaId().getQualifiedName()
+ "]: "
+ e.getMessage());
this.instrControl.updateInstrumentationStatistics(
cv.getJavaId(), Boolean.valueOf(false));
}
}
}

if (!this.instrument) {
// only detach if no static instrumentation (otherwise it will fail
// because the class was modified) in case the instrumentation is
Expand Down Expand Up @@ -627,7 +622,7 @@ else if (je.getName().endsWith("pom.xml")) {
+ constructs.size()
+ "], enums ["
+ enumCount
+ "], interfaces (ignored) ["
+ "], interfaces ["
+ interfaceCount
+ "]");
else
Expand All @@ -639,7 +634,7 @@ else if (je.getName().endsWith("pom.xml")) {
+ this.classCount
+ "], enums ["
+ enumCount
+ "], interfaces (ignored) ["
+ "], interfaces ["
+ interfaceCount
+ "]");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public void exitEnumDeclaration(@NotNull JavaParser.EnumDeclarationContext ctx)
/**
* {@inheritDoc}
*
* Interfaces are not added to {@link #constructs}.
* Interfaces are added to {@link #constructs}.
*/
@Override
public void enterInterfaceDeclaration(@NotNull JavaParser.InterfaceDeclarationContext ctx) {
Expand All @@ -191,6 +191,7 @@ public void enterInterfaceDeclaration(@NotNull JavaParser.InterfaceDeclarationCo
(cse == null ? JavaPackageId.DEFAULT_PACKAGE : (JavaId) cse.getConstructId());
final JavaId id = new JavaInterfaceId(decl_ctx, ctx.IDENTIFIER().getText());
this.contextStack.push(id);
this.saveConstruct(id, this.getConstructContent(ctx));
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -231,6 +232,24 @@ public void enterClassBody(@NotNull JavaParser.ClassBodyContext ctx) {
this.constructIdBuilder.resetCurrentDeclarationContext();
}

@Override
public void enterInterfaceMemberDeclaration(JavaParser.InterfaceMemberDeclarationContext ctx) {
if (ctx.interfaceMethodDeclaration() != null) {
// Peek JavaId and ensure it is an interface
final JavaId class_ctx = (JavaId) this.contextStack.peek().getConstructId();
this.isOfExpectedType(class_ctx, new JavaId.Type[] {JavaId.Type.INTERFACE}, true);

// Build the identifier
final JavaMethodId id =
new JavaMethodId(
(JavaId) class_ctx,
ctx.interfaceMethodDeclaration().IDENTIFIER().getText(),
this.getParameters(
ctx.interfaceMethodDeclaration().formalParameters().formalParameterList()));
this.saveConstruct(id, this.getConstructContent(ctx));
}
}

/** {@inheritDoc} */
@Override
public void exitClassBody(@NotNull JavaParser.ClassBodyContext ctx) {
Expand All @@ -244,7 +263,10 @@ public void exitClassBody(@NotNull JavaParser.ClassBodyContext ctx) {
public void enterMethodDeclaration(@NotNull JavaParser.MethodDeclarationContext ctx) {
// Peek JavaId and ensure it is a class or enum
final JavaId class_ctx = (JavaId) this.contextStack.peek().getConstructId();
this.isOfExpectedType(class_ctx, new JavaId.Type[] {JavaId.Type.CLASS, JavaId.Type.ENUM}, true);
this.isOfExpectedType(
class_ctx,
new JavaId.Type[] {JavaId.Type.CLASS, JavaId.Type.ENUM, JavaId.Type.INTERFACE},
true);

// Build the identifier
final JavaMethodId id =
Expand Down
Loading