From 01a90e7666fb5735ccd2563517ca6535bccf3922 Mon Sep 17 00:00:00 2001 From: henrikplate <17928867+henrikplate@users.noreply.github.com> Date: Fri, 11 Jun 2021 09:30:24 +0200 Subject: [PATCH 01/29] Towards collecting interface info --- .../org/eclipse/steady/java/JarAnalyzer.java | 105 +++++++++--------- .../steady/java/JavaFileAnalyzer2.java | 12 +- .../java/org/eclipse/steady/java/JavaId.java | 63 +++++++++-- .../steady/java/monitor/ClassVisitor.java | 3 +- .../steady/java/JavaFileAnalyzer2Test.java | 19 +++- .../eclipse/steady/java/JsonHelperTest.java | 9 +- .../steady/java/test/NestedDeclarations.java | 3 +- 7 files changed, 129 insertions(+), 85 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JarAnalyzer.java b/lang-java/src/main/java/org/eclipse/steady/java/JarAnalyzer.java index f55b053aa..0fd1fed17 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JarAnalyzer.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JarAnalyzer.java @@ -496,62 +496,57 @@ public synchronized Set getConstructIds() { 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) @@ -592,7 +587,7 @@ public synchronized Set getConstructIds() { + constructs.size() + "], enums [" + enumCount - + "], interfaces (ignored) [" + + "], interfaces [" + interfaceCount + "]"); else @@ -604,7 +599,7 @@ public synchronized Set getConstructIds() { + this.classCount + "], enums [" + enumCount - + "], interfaces (ignored) [" + + "], interfaces [" + interfaceCount + "]"); } diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java b/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java index 5a833bd4e..edd15da12 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java @@ -18,14 +18,14 @@ */ package org.eclipse.steady.java; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.ByteArrayOutputStream; import java.io.InputStream; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -49,14 +49,13 @@ import org.eclipse.steady.ConstructId; import org.eclipse.steady.FileAnalysisException; import org.eclipse.steady.FileAnalyzer; -import org.eclipse.steady.shared.util.FileUtil; - import org.eclipse.steady.java.antlr.JavaLexer; import org.eclipse.steady.java.antlr.JavaParser; import org.eclipse.steady.java.antlr.JavaParser.CompilationUnitContext; import org.eclipse.steady.java.antlr.JavaParser.FormalParameterContext; import org.eclipse.steady.java.antlr.JavaParser.TypeTypeContext; import org.eclipse.steady.java.antlr.JavaParserBaseListener; +import org.eclipse.steady.shared.util.FileUtil; /** * Analyzes java source files using ANTLR. @@ -179,7 +178,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) { @@ -189,6 +188,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} */ diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java index c4133f684..ad668cbfb 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java @@ -30,6 +30,9 @@ import javax.validation.constraints.NotNull; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + import org.apache.logging.log4j.Logger; import org.eclipse.steady.ConstructId; import org.eclipse.steady.java.monitor.ClassPoolUpdater; @@ -38,9 +41,6 @@ import org.eclipse.steady.shared.enums.ProgrammingLanguage; import org.eclipse.steady.shared.json.JsonBuilder; -import com.google.gson.Gson; -import com.google.gson.JsonObject; - /** *

Abstract JavaId class.

* @@ -381,7 +381,7 @@ public static JavaEnumId parseEnumQName(@NotNull String _s) { class_name = _s.substring(i + 1); } - // Create Java class id (for regular or nested class) + // Create Java enum id (for regular or nested class) int j = 0, k = 0; do { // HP, 12.09.2015: $ is also permitted in class names, i.e., it can also exist w/o a class @@ -452,6 +452,53 @@ public static JavaClassId parseClassQName(@NotNull String _s) { return cid; } + /** + *

parseInterfaceQName.

+ * + * @param _s a {@link java.lang.String} object. + * @return a {@link org.eclipse.steady.java.JavaInterfaceId} object. + */ + public static JavaInterfaceId parseInterfaceQName(@NotNull String _s) { + if (_s == null || _s.equals("")) throw new IllegalArgumentException("String null or empty"); + + final int i = _s.lastIndexOf('.'); + String class_name = null; + JavaPackageId pid = null; + JavaInterfaceId cid = null; + + // Create Java package id + if (i != -1) { + pid = new JavaPackageId(_s.substring(0, i)); + class_name = _s.substring(i + 1); + } else { + pid = JavaPackageId.DEFAULT_PACKAGE; + class_name = _s.substring(i + 1); + } + + // Create Java interface id (for regular or nested class) + int j = 0, k = 0; + do { + // HP, 12.09.2015: $ is also permitted in class names, i.e., it can also exist w/o a class + // context + j = class_name.indexOf("$", k); + if (j != -1) { + if (cid == null) cid = new JavaInterfaceId(pid, class_name.substring(k, j)); + else cid = new JavaInterfaceId(cid, class_name.substring(k, j)); + k = j + 1; + } else { + if (cid == null) cid = new JavaInterfaceId(pid, class_name.substring(k)); + else cid = new JavaInterfaceId(cid, class_name.substring(k)); + k = j + 1; + } + } while (j != -1); + // if(j!=-1) + // cid = new JavaClassId(new JavaClassId(pid, class_name.substring(0, j)), + // class_name.substring(j+1)); + // else + // cid = new JavaClassId(pid, class_name); + return cid; + } + /** * Creates a {@link JavaMethodId} from the given string, whereby the definition context is defaulted to * type {@link JavaId.Type#CLASS}. @@ -475,9 +522,9 @@ public static JavaMethodId parseMethodQName(JavaId.Type _ctx_type, String _s) { if (_s == null || _s.equals("")) throw new IllegalArgumentException("String null or empty"); if (_ctx_type == null - || (!_ctx_type.equals(JavaId.Type.CLASS) && !_ctx_type.equals(JavaId.Type.ENUM))) + || (!_ctx_type.equals(JavaId.Type.CLASS) && !_ctx_type.equals(JavaId.Type.ENUM) && !_ctx_type.equals(JavaId.Type.INTERFACE))) throw new IllegalArgumentException( - "Accepts context types CLASS or ENUM, got [" + _ctx_type + "]"); + "Accepts context types CLASS, ENUM and INTERFACE, got [" + _ctx_type + "]"); final int i = _s.indexOf('('); if (i == -1 || !_s.endsWith(")")) @@ -535,9 +582,9 @@ public static JavaConstructorId parseConstructorQName( if (_s == null || _s.equals("")) throw new IllegalArgumentException("String null or empty"); if (_ctx_type == null - || (!_ctx_type.equals(JavaId.Type.CLASS) && !_ctx_type.equals(JavaId.Type.ENUM))) + || (!_ctx_type.equals(JavaId.Type.CLASS) && !_ctx_type.equals(JavaId.Type.ENUM) && !_ctx_type.equals(JavaId.Type.INTERFACE))) throw new IllegalArgumentException( - "Accepts context types CLASS or ENUM, got [" + _ctx_type + "]"); + "Accepts context types CLASS, ENUM and INTERFACE, got [" + _ctx_type + "]"); final int i = _s.indexOf('('); if (i == -1 || !_s.endsWith(")")) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java b/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java index ea1afbec0..33f14ec00 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java @@ -108,8 +108,7 @@ private static final Logger getLog() { */ public ClassVisitor(CtClass _c) { // Build the JavaId - if (_c.isInterface()) - throw new IllegalArgumentException("[" + _c.getName() + "]: Interfaces are not supported"); + if (_c.isInterface()) this.javaId = JavaId.parseInterfaceQName(_c.getName()); else if (_c.isEnum()) this.javaId = JavaId.parseEnumQName(_c.getName()); else this.javaId = JavaId.parseClassQName(_c.getName()); diff --git a/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java b/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java index d0243bdb7..d11a899f1 100644 --- a/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java +++ b/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java @@ -91,6 +91,8 @@ public void testAnonClassInInterfaceInit() { // The parsing should produce the following 5 elements: final JavaPackageId p = new JavaPackageId("org.eclipse.steady.java.test"); + final JavaInterfaceId itf = + JavaId.parseInterfaceQName("org.eclipse.steady.java.test.ConfigurationKey"); final JavaClassId anon1 = JavaId.parseClassQName("org.eclipse.steady.java.test.ConfigurationKey$1"); final JavaMethodId anon1_m = @@ -103,8 +105,9 @@ public void testAnonClassInInterfaceInit() { "org.eclipse.steady.java.test.ConfigurationKey$2.compare(ConfigurationKey,ConfigurationKey)"); // Assertions - assertEquals(5, constructs.size()); + assertEquals(6, constructs.size()); assertTrue(constructs.containsKey(p)); + assertTrue(constructs.containsKey(itf)); assertTrue(constructs.containsKey(anon1)); assertTrue(constructs.containsKey(anon1_m)); assertTrue(constructs.containsKey(anon2)); @@ -128,8 +131,10 @@ public void testNamedClassInInterfaceAndAnonClassInConstructor() { "./src/test/java/org/eclipse/steady/java/test/HttpRequestCompletionLog.java")); final Map constructs = jfa.getConstructs(); - // The parsing should produce the following 5 elements: + // The parsing should produce the following elements: final JavaPackageId p = new JavaPackageId("org.eclipse.steady.java.test"); + final JavaInterfaceId itf = + JavaId.parseInterfaceQName("org.eclipse.steady.java.test.HttpRequestCompletionLog"); // Named inner class final JavaClassId named_class = @@ -200,8 +205,9 @@ public void testNamedClassInInterfaceAndAnonClassInConstructor() { "org.eclipse.steady.java.test.HttpRequestCompletionLog$Builder$1.getResponseContentType()"); // Assertions - assertEquals(23, constructs.size()); + assertEquals(24, constructs.size()); assertTrue(constructs.containsKey(p)); + assertTrue(constructs.containsKey(itf)); assertTrue(constructs.containsKey(named_class)); assertTrue(constructs.containsKey(named_class_cons)); @@ -373,8 +379,9 @@ public void testNestedDeclarationMess() { final FileAnalyzer fa = FileAnalyzerFactory.buildFileAnalyzer(file); final Map constructs = fa.getConstructs(); - // The parsing should produce the following 5 elements: + // The parsing should produce the following elements: final JavaPackageId p = new JavaPackageId("org.eclipse.steady.java.test"); + final JavaInterfaceId itf = JavaId.parseInterfaceQName("org.eclipse.steady.java.test.DoSomethingElse"); final JavaClassId cl1 = JavaId.parseClassQName("org.eclipse.steady.java.test.NestedDeclarations"); // line 5 @@ -457,9 +464,9 @@ public void testNestedDeclarationMess() { JavaId.parseMethodQName( "org.eclipse.steady.java.test.NestedDeclarations$Foo$1DoThis$1.doThat()"); // line 72 - // Assertions - assertEquals(25, constructs.size()); + assertEquals(26, constructs.size()); assertTrue(constructs.containsKey(p)); + assertTrue(constructs.containsKey(itf)); assertTrue(constructs.containsKey(cl1)); assertTrue(constructs.containsKey(cl1_m)); diff --git a/lang-java/src/test/java/org/eclipse/steady/java/JsonHelperTest.java b/lang-java/src/test/java/org/eclipse/steady/java/JsonHelperTest.java index 0d10c5fcf..682fca79c 100644 --- a/lang-java/src/test/java/org/eclipse/steady/java/JsonHelperTest.java +++ b/lang-java/src/test/java/org/eclipse/steady/java/JsonHelperTest.java @@ -57,12 +57,9 @@ public void jarToJsonEqualityTest() throws FileAnalysisException { } assertEquals(json1, json2); - } catch (IllegalStateException ise) { - // TODO Auto-generated catch block - ise.printStackTrace(); - } catch (IOException ioe) { - // TODO Auto-generated catch block - ioe.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + assert(false); } } diff --git a/lang-java/src/test/java/org/eclipse/steady/java/test/NestedDeclarations.java b/lang-java/src/test/java/org/eclipse/steady/java/test/NestedDeclarations.java index 135c3e5f4..20449264f 100644 --- a/lang-java/src/test/java/org/eclipse/steady/java/test/NestedDeclarations.java +++ b/lang-java/src/test/java/org/eclipse/steady/java/test/NestedDeclarations.java @@ -20,8 +20,7 @@ import java.io.Serializable; -public class NestedDeclarations { // Do not change this class, the corresponding test case - // (testNestedDeclarationMess) refers to the line numbers!!!!!!!!!!!!!!! +public class NestedDeclarations { // Member interface interface DoSomethingElse { From 3b7967ef52e1d585b0dbdf2278a1024a33de37fe Mon Sep 17 00:00:00 2001 From: henrikplate <17928867+henrikplate@users.noreply.github.com> Date: Wed, 16 Jun 2021 18:49:44 +0200 Subject: [PATCH 02/29] Discover interface methods --- lang-java/pom.xml | 1 + .../steady/java/ClassFileAnalyzer.java | 21 ++++++------- .../steady/java/JavaFileAnalyzer2.java | 18 ++++++++++- .../java/org/eclipse/steady/java/JavaId.java | 10 +++++-- .../steady/java/monitor/ClassVisitor.java | 12 ++++++-- .../steady/java/JavaFileAnalyzer2Test.java | 30 +++++++++++++++---- .../steady/java/test/ConfigurationKey.java | 2 +- pom.xml | 1 + 8 files changed, 71 insertions(+), 24 deletions(-) diff --git a/lang-java/pom.xml b/lang-java/pom.xml index 5d74bb724..797fd562d 100644 --- a/lang-java/pom.xml +++ b/lang-java/pom.xml @@ -105,6 +105,7 @@ + ${basedir}/src/test/java org.apache.maven.plugins diff --git a/lang-java/src/main/java/org/eclipse/steady/java/ClassFileAnalyzer.java b/lang-java/src/main/java/org/eclipse/steady/java/ClassFileAnalyzer.java index 7b17e118e..31350457d 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/ClassFileAnalyzer.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/ClassFileAnalyzer.java @@ -107,18 +107,15 @@ public Map 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 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 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); diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java b/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java index edd15da12..0a23f5940 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JavaFileAnalyzer2.java @@ -229,6 +229,22 @@ 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) { @@ -242,7 +258,7 @@ 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 = diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java index ad668cbfb..c8a781e18 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java @@ -539,9 +539,15 @@ public static JavaMethodId parseMethodQName(JavaId.Type _ctx_type, String _s) { JavaId def_ctx = null; JavaMethodId mid = null; try { - if (_ctx_type.equals(JavaId.Type.CLASS)) def_ctx = JavaId.parseClassQName(_s.substring(0, j)); - else if (_ctx_type.equals(JavaId.Type.ENUM)) + if (_ctx_type.equals(JavaId.Type.CLASS)) { + def_ctx = JavaId.parseClassQName(_s.substring(0, j)); + } + else if (_ctx_type.equals(JavaId.Type.ENUM)) { def_ctx = JavaId.parseEnumQName(_s.substring(0, j)); + } + else if (_ctx_type.equals(JavaId.Type.INTERFACE)) { + def_ctx = JavaId.parseInterfaceQName(_s.substring(0, j)); + } mid = new JavaMethodId( diff --git a/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java b/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java index 33f14ec00..179510058 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/monitor/ClassVisitor.java @@ -108,9 +108,15 @@ private static final Logger getLog() { */ public ClassVisitor(CtClass _c) { // Build the JavaId - if (_c.isInterface()) this.javaId = JavaId.parseInterfaceQName(_c.getName()); - else if (_c.isEnum()) this.javaId = JavaId.parseEnumQName(_c.getName()); - else this.javaId = JavaId.parseClassQName(_c.getName()); + if (_c.isInterface()) { + this.javaId = JavaId.parseInterfaceQName(_c.getName()); + } + else if (_c.isEnum()) { + this.javaId = JavaId.parseEnumQName(_c.getName()); + } + else { + this.javaId = JavaId.parseClassQName(_c.getName()); + } this.qname = this.javaId.getQualifiedName(); this.c = _c; diff --git a/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java b/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java index d11a899f1..a2835d9ad 100644 --- a/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java +++ b/lang-java/src/test/java/org/eclipse/steady/java/JavaFileAnalyzer2Test.java @@ -91,8 +91,19 @@ public void testAnonClassInInterfaceInit() { // The parsing should produce the following 5 elements: final JavaPackageId p = new JavaPackageId("org.eclipse.steady.java.test"); + final JavaInterfaceId itf = JavaId.parseInterfaceQName("org.eclipse.steady.java.test.ConfigurationKey"); + final JavaMethodId itf_m1 = + JavaId.parseMethodQName( + "org.eclipse.steady.java.test.ConfigurationKey.getType(String,int)"); + final JavaMethodId itf_m2 = + JavaId.parseMethodQName( + "org.eclipse.steady.java.test.ConfigurationKey.getKey()"); + final JavaMethodId itf_m3 = + JavaId.parseMethodQName( + "org.eclipse.steady.java.test.ConfigurationKey.getDefaultValue()"); + final JavaClassId anon1 = JavaId.parseClassQName("org.eclipse.steady.java.test.ConfigurationKey$1"); final JavaMethodId anon1_m = @@ -105,9 +116,12 @@ public void testAnonClassInInterfaceInit() { "org.eclipse.steady.java.test.ConfigurationKey$2.compare(ConfigurationKey,ConfigurationKey)"); // Assertions - assertEquals(6, constructs.size()); + assertEquals(9, constructs.size()); assertTrue(constructs.containsKey(p)); assertTrue(constructs.containsKey(itf)); + assertTrue(constructs.containsKey(itf_m1)); + assertTrue(constructs.containsKey(itf_m2)); + assertTrue(constructs.containsKey(itf_m3)); assertTrue(constructs.containsKey(anon1)); assertTrue(constructs.containsKey(anon1_m)); assertTrue(constructs.containsKey(anon2)); @@ -205,7 +219,7 @@ public void testNamedClassInInterfaceAndAnonClassInConstructor() { "org.eclipse.steady.java.test.HttpRequestCompletionLog$Builder$1.getResponseContentType()"); // Assertions - assertEquals(24, constructs.size()); + assertEquals(33, constructs.size()); assertTrue(constructs.containsKey(p)); assertTrue(constructs.containsKey(itf)); @@ -381,7 +395,9 @@ public void testNestedDeclarationMess() { // The parsing should produce the following elements: final JavaPackageId p = new JavaPackageId("org.eclipse.steady.java.test"); - final JavaInterfaceId itf = JavaId.parseInterfaceQName("org.eclipse.steady.java.test.DoSomethingElse"); + + final JavaInterfaceId itf = JavaId.parseInterfaceQName("org.eclipse.steady.java.test.NestedDeclarations$DoSomethingElse"); + final JavaMethodId itf_m = JavaId.parseMethodQName("org.eclipse.steady.java.test.NestedDeclarations$DoSomethingElse.doSomethingElse()"); final JavaClassId cl1 = JavaId.parseClassQName("org.eclipse.steady.java.test.NestedDeclarations"); // line 5 @@ -464,9 +480,12 @@ public void testNestedDeclarationMess() { JavaId.parseMethodQName( "org.eclipse.steady.java.test.NestedDeclarations$Foo$1DoThis$1.doThat()"); // line 72 - assertEquals(26, constructs.size()); + assertEquals(27, constructs.size()); assertTrue(constructs.containsKey(p)); + assertTrue(constructs.containsKey(itf)); + assertTrue(constructs.containsKey(itf_m)); + assertTrue(constructs.containsKey(cl1)); assertTrue(constructs.containsKey(cl1_m)); @@ -563,7 +582,8 @@ public void testCxfClass() { } /** - * Tests whether the constructs extracted from a Java file correspond to the ones obtained from the compiled file. + * Tests whether the constructs extracted from a Java file correspond to the + * ones obtained from the compiled file. */ @Test public void testCompareConstructCreation() { diff --git a/lang-java/src/test/java/org/eclipse/steady/java/test/ConfigurationKey.java b/lang-java/src/test/java/org/eclipse/steady/java/test/ConfigurationKey.java index efa73d658..06c3d53f4 100644 --- a/lang-java/src/test/java/org/eclipse/steady/java/test/ConfigurationKey.java +++ b/lang-java/src/test/java/org/eclipse/steady/java/test/ConfigurationKey.java @@ -41,7 +41,7 @@ public int compare(final ConfigurationKey key1, final ConfigurationKey key2) { } }; - Class getType(); + Class getType(String a, int b); String getKey(); diff --git a/pom.xml b/pom.xml index 99b93e7a2..76b7a45cd 100755 --- a/pom.xml +++ b/pom.xml @@ -397,6 +397,7 @@ + ${basedir}/src/test/java + + org.vafer + jdependency + 2.7.0 + diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java new file mode 100644 index 000000000..586412fde --- /dev/null +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -0,0 +1,197 @@ +/** + * This file is part of Eclipse Steady. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors + */ +package org.eclipse.steady.java.tasks; + +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.logging.log4j.Logger; +import org.eclipse.steady.Construct; +import org.eclipse.steady.core.util.CoreConfiguration; +import org.eclipse.steady.goals.GoalConfigurationException; +import org.eclipse.steady.goals.GoalExecutionException; +import org.eclipse.steady.java.JarAnalyzer; +import org.eclipse.steady.shared.enums.GoalClient; +import org.eclipse.steady.shared.enums.ProgrammingLanguage; +import org.eclipse.steady.shared.util.StringList; +import org.eclipse.steady.shared.util.StringUtil; +import org.eclipse.steady.shared.util.VulasConfiguration; +import org.eclipse.steady.tasks.AbstractTask; +import org.eclipse.steady.tasks.DebloatTask; +import org.vafer.jdependency.Clazz; +import org.vafer.jdependency.Clazzpath; +import org.vafer.jdependency.ClazzpathUnit; + +/** + *

JavaBomTask class.

+ */ +public class JavaDebloatTask extends AbstractTask implements DebloatTask { + + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); + + private static final String[] EXT_FILTER = new String[] {"jar", "war", "class", "java", "aar"}; + + private String[] appPrefixes = null; + + private StringList appJarNames = null; + + private static final List pluginGoalClients = + Arrays.asList(GoalClient.MAVEN_PLUGIN, GoalClient.GRADLE_PLUGIN); + + /** {@inheritDoc} */ + @Override + public Set getLanguage() { + return new HashSet( + Arrays.asList(new ProgrammingLanguage[] {ProgrammingLanguage.JAVA})); + } + + /** + * Returns true if the configuration setting {@link CoreConfiguration#APP_PREFIXES} shall be considered, false otherwise. + */ + private final boolean useAppPrefixes() { + return this.appPrefixes != null && !this.isOneOfGoalClients(pluginGoalClients); + } + + /** + * Returns true if the configuration setting {@link CoreConfiguration#APP_PREFIXES} shall be considered, false otherwise. + */ + private final boolean useAppJarNames() { + return this.appJarNames != null && !this.isOneOfGoalClients(pluginGoalClients); + } + + /** {@inheritDoc} */ + @Override + public void configure(VulasConfiguration _cfg) throws GoalConfigurationException { + super.configure(_cfg); + + // App constructs identified using package prefixes + this.appPrefixes = _cfg.getStringArray(CoreConfiguration.APP_PREFIXES, null); + + // Print warning message in case the setting is used as part of the Maven plugin + if (this.appPrefixes != null && this.isOneOfGoalClients(pluginGoalClients)) { + log.warn( + "Configuration setting [" + + CoreConfiguration.APP_PREFIXES + + "] ignored when running the goal as Maven plugin"); + this.appPrefixes = null; + } + + // App constructs identified using JAR file name patterns (regex) + final String[] app_jar_names = _cfg.getStringArray(CoreConfiguration.APP_JAR_NAMES, null); + if (app_jar_names != null) { + // Print warning message in case the setting is used as part of the Maven plugin + if (this.isOneOfGoalClients(pluginGoalClients)) { + log.warn( + "Configuration setting [" + + CoreConfiguration.APP_JAR_NAMES + + "] ignored when running the goal as Maven plugin"); + this.appJarNames = null; + } else { + this.appJarNames = new StringList(); + this.appJarNames.addAll(app_jar_names); + } + } + + // CLI: Only one of appPrefixes and appJarNames can be used + if (!this.isOneOfGoalClients(pluginGoalClients)) { + if (this.appPrefixes != null && this.appJarNames != null) { + throw new GoalConfigurationException( + "Exactly one of the configuration settings [" + + CoreConfiguration.APP_PREFIXES + + "] and [" + + CoreConfiguration.APP_JAR_NAMES + + "] must be set"); + } else if (this.appPrefixes == null && this.appJarNames == null) { + throw new GoalConfigurationException( + "Exactly one of the configuration settings [" + + CoreConfiguration.APP_PREFIXES + + "] and [" + + CoreConfiguration.APP_JAR_NAMES + + "] must be set"); + } + } + } + + /** {@inheritDoc} */ + @Override + public void execute() throws GoalExecutionException { + + final Clazzpath cp = new Clazzpath(); + + List app = new ArrayList(); + try { + //1) Add app paths + if (this.hasSearchPath()) { + for (Path p : this.getSearchPath()) { + log.info( + "Add app path [" + + p + + "] to classpath"); + app.add(cp.addClazzpathUnit(p)); + } + } + //2) Add dependencies to classpath + if (this.getKnownDependencies() != null) { + for (Path p : this.getKnownDependencies().keySet()) { + log.info( + "Add dep path [" + + p + + "] to classpath"); + cp.addClazzpathUnit(p); + } + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + final Set needed = new HashSet(); + final Set removable = cp.getClazzes(); + for(ClazzpathUnit u: app) { + removable.removeAll(u.getClazzes()); + removable.removeAll(u.getTransitiveDependencies()); + needed.addAll(u.getClazzes()); + needed.addAll(u.getTransitiveDependencies()); + } + + log.info("Needed ["+ needed.size()+"] classes"); + log.info("Removable ["+ removable.size()+"] classes"); + for(Clazz clazz : removable) { + System.out.println("class " + clazz + " is not required"); + } + try { + FileWriter writer=new FileWriter("needed.txt"); + for(Clazz c: needed) { + writer.write(c + System.lineSeparator()); + } + writer.close(); + } catch (IOException e){// TODO Auto-generated catch block + e.printStackTrace();} + } + +} diff --git a/lang-java/src/main/resources/META-INF/services/org.eclipse.steady.tasks.DebloatTask b/lang-java/src/main/resources/META-INF/services/org.eclipse.steady.tasks.DebloatTask new file mode 100644 index 000000000..c1910b842 --- /dev/null +++ b/lang-java/src/main/resources/META-INF/services/org.eclipse.steady.tasks.DebloatTask @@ -0,0 +1 @@ +org.eclipse.steady.java.tasks.JavaDebloatTask \ No newline at end of file diff --git a/lang/pom.xml b/lang/pom.xml index 5424df59b..0946054e0 100644 --- a/lang/pom.xml +++ b/lang/pom.xml @@ -78,7 +78,7 @@ com.google.code.gson gson
- + org.apache.velocity velocity-engine-core diff --git a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java new file mode 100644 index 000000000..ba353f31f --- /dev/null +++ b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java @@ -0,0 +1,144 @@ +/** + * This file is part of Eclipse Steady. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors + */ +package org.eclipse.steady.goals; + +import java.nio.file.Paths; +import java.util.ServiceLoader; +import java.util.Set; + +import org.apache.logging.log4j.Logger; +import org.eclipse.steady.backend.BackendConnector; +import org.eclipse.steady.core.util.CoreConfiguration; +import org.eclipse.steady.malice.MaliciousnessAnalysisResult; +import org.eclipse.steady.malice.MaliciousnessAnalyzerLoop; +import org.eclipse.steady.shared.enums.GoalType; +import org.eclipse.steady.shared.json.model.Application; +import org.eclipse.steady.shared.json.model.Dependency; +import org.eclipse.steady.shared.json.model.Library; +import org.eclipse.steady.tasks.BomTask; +import org.eclipse.steady.tasks.DebloatTask; + +/** + *

NeededGoal class.

+ */ +public class DebloatGoal extends AbstractAppGoal { + + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); + + /** + *

Constructor for DebloatGoal.

+ */ + public DebloatGoal() { + super(GoalType.DEBLOAT); + } + +// /** +// * {@inheritDoc} +// * +// * Evaluates the configuration setting {@link CoreConfiguration#APP_PREFIXES}. +// */ +// @Override +// protected void prepareExecution() throws GoalConfigurationException { +// super.prepareExecution(); +// } + + /** {@inheritDoc} */ + @Override + protected void executeTasks() throws Exception { + + // The application to be completed + Application a = this.getApplicationContext(); + + // Create, configure and execute tasks + final ServiceLoader loader = ServiceLoader.load(DebloatTask.class); + for (DebloatTask t : loader) { + try { + // Configure + t.setApplication(a); + t.setSearchPaths(this.getAppPaths()); + t.setGoalClient(this.getGoalClient()); + t.setKnownDependencies(this.getKnownDependencies()); + t.configure(this.getConfiguration()); + + // Execute + t.execute(); + t.cleanUp(); + // t.getNeededConstructs(); + } catch (Exception e) { + log.error("Error running task " + t + ": " + e.getMessage(), e); + } + } + + + // Upload libraries and binaries (if requested) + if (a.getDependencies() != null) { + for (Dependency dep : a.getDependencies()) { + + + + // Upload lib + final Library lib = dep.getLib(); + if (lib != null) { + if (lib.hasValidDigest()) { + BackendConnector.getInstance().uploadLibrary(this.getGoalContext(), lib); + if (CoreConfiguration.isJarUploadEnabled(this.getGoalContext().getVulasConfiguration())) + BackendConnector.getInstance() + .uploadLibraryFile(lib.getDigest(), Paths.get(dep.getPath())); + } else { + log.error("Library of dependency [" + dep + "] has no valid digest"); + } + } else { + log.error("Dependency [" + dep + "] has no library"); + } + } + } + + final boolean upload_empty = + this.getConfiguration() + .getConfiguration() + .getBoolean(CoreConfiguration.APP_UPLOAD_EMPTY, false); + final boolean app_exists_in_backend = + BackendConnector.getInstance().isAppExisting(this.getGoalContext(), a); + + // Upload if non-empty or already exists in backend or empty ones shall be uploaded + if (!a.isEmpty() || app_exists_in_backend || upload_empty) { + log.info( + "Save app " + + a + + " with [" + + a.getDependencies().size() + + "] dependencies and [" + + a.getConstructs().size() + + "] constructs (uploadEmpty=" + + upload_empty + + ")"); + BackendConnector.getInstance().uploadApp(this.getGoalContext(), a); + } else { + log.warn( + "Skip save of empty app " + + this.getApplicationContext() + + " (uploadEmpty=" + + upload_empty + + ", existsInBackend=" + + app_exists_in_backend + + ")"); + this.skipGoalUpload(); + } + } +} diff --git a/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java b/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java index d874c8d54..cd18901f4 100755 --- a/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java +++ b/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java @@ -117,7 +117,9 @@ public static AbstractGoal create(@NotNull GoalType _type) throw new IllegalStateException( "Cannot create instance of class [" + clazzname + "]: " + e.getMessage()); } - } else { + } else if (_type.equals(GoalType.DEBLOAT)) { + goal = new DebloatGoal(); + }else { throw new IllegalArgumentException("Goal [" + _type + "] is not supported"); } return goal; diff --git a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java new file mode 100644 index 000000000..d41a52ac2 --- /dev/null +++ b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java @@ -0,0 +1,40 @@ +/** + * This file is part of Eclipse Steady. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors + */ +package org.eclipse.steady.tasks; + +import java.util.Set; + +import org.eclipse.steady.Construct; + +/** + * Methods required to + */ +public interface DebloatTask extends Task { + +// /** +// * Returns the {@link Application} including (a) all its {@link Construct}s of the respective {@link ProgrammingLanguage}, +// * and (b) the {@link Dependency}s of that application. The {@link Library} of each {@link Dependency} must contain +// * all details such as its {@link Construct}s and properties. +// * +// * @return a {@link org.eclipse.steady.shared.json.model.Application} object. +// */ +// public Set getNeededConstructs(); + + +} diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java new file mode 100644 index 000000000..82c666f3c --- /dev/null +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java @@ -0,0 +1,42 @@ +/** + * This file is part of Eclipse Steady. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors + */ +package org.eclipse.steady.java.mvn; + +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.eclipse.steady.goals.DebloatGoal; + +/** + * This Mojo identifies the constructs belonging to the application itself and belonging to all its dependencies. + * Those are then uploaded to the central Vulas engine for further analysis (test coverage, vulnerability assessments, archive integrity). + */ +@Mojo( + name = "debloat", + defaultPhase = LifecyclePhase.PROCESS_CLASSES, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresOnline = true) +public class MvnPluginDebloat extends AbstractVulasMojo { + + /** {@inheritDoc} */ + @Override + protected void createGoal() { + this.goal = new DebloatGoal(); + } +} diff --git a/shared/src/main/java/org/eclipse/steady/shared/enums/GoalType.java b/shared/src/main/java/org/eclipse/steady/shared/enums/GoalType.java index a9f50c98a..b09a8f4ef 100644 --- a/shared/src/main/java/org/eclipse/steady/shared/enums/GoalType.java +++ b/shared/src/main/java/org/eclipse/steady/shared/enums/GoalType.java @@ -36,6 +36,7 @@ public enum GoalType { T2C, REPORT, UPLOAD, + DEBLOAT, // Workspace goals SPACENEW, From 53b221578da15eb8638c94ffe36bc074da7d287b Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Mon, 26 Jul 2021 13:37:57 +0200 Subject: [PATCH 12/29] added traces and reachable constructs to debloat task --- .../steady/java/tasks/JavaDebloatTask.java | 129 ++++++++---------- .../org/eclipse/steady/goals/DebloatGoal.java | 3 + .../org/eclipse/steady/tasks/DebloatTask.java | 17 ++- 3 files changed, 74 insertions(+), 75 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 586412fde..571022ffa 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -32,12 +32,16 @@ import org.apache.logging.log4j.Logger; import org.eclipse.steady.Construct; +import org.eclipse.steady.backend.BackendConnector; import org.eclipse.steady.core.util.CoreConfiguration; import org.eclipse.steady.goals.GoalConfigurationException; import org.eclipse.steady.goals.GoalExecutionException; import org.eclipse.steady.java.JarAnalyzer; import org.eclipse.steady.shared.enums.GoalClient; import org.eclipse.steady.shared.enums.ProgrammingLanguage; +import org.eclipse.steady.shared.json.model.ConstructId; +import org.eclipse.steady.shared.json.model.Dependency; +import org.eclipse.steady.shared.json.model.Trace; import org.eclipse.steady.shared.util.StringList; import org.eclipse.steady.shared.util.StringUtil; import org.eclipse.steady.shared.util.VulasConfiguration; @@ -56,10 +60,10 @@ public class JavaDebloatTask extends AbstractTask implements DebloatTask { private static final String[] EXT_FILTER = new String[] {"jar", "war", "class", "java", "aar"}; - private String[] appPrefixes = null; - - private StringList appJarNames = null; - + private Set traces = null; + + private Set reachableConstructIds = null; + private static final List pluginGoalClients = Arrays.asList(GoalClient.MAVEN_PLUGIN, GoalClient.GRADLE_PLUGIN); @@ -70,72 +74,6 @@ public Set getLanguage() { Arrays.asList(new ProgrammingLanguage[] {ProgrammingLanguage.JAVA})); } - /** - * Returns true if the configuration setting {@link CoreConfiguration#APP_PREFIXES} shall be considered, false otherwise. - */ - private final boolean useAppPrefixes() { - return this.appPrefixes != null && !this.isOneOfGoalClients(pluginGoalClients); - } - - /** - * Returns true if the configuration setting {@link CoreConfiguration#APP_PREFIXES} shall be considered, false otherwise. - */ - private final boolean useAppJarNames() { - return this.appJarNames != null && !this.isOneOfGoalClients(pluginGoalClients); - } - - /** {@inheritDoc} */ - @Override - public void configure(VulasConfiguration _cfg) throws GoalConfigurationException { - super.configure(_cfg); - - // App constructs identified using package prefixes - this.appPrefixes = _cfg.getStringArray(CoreConfiguration.APP_PREFIXES, null); - - // Print warning message in case the setting is used as part of the Maven plugin - if (this.appPrefixes != null && this.isOneOfGoalClients(pluginGoalClients)) { - log.warn( - "Configuration setting [" - + CoreConfiguration.APP_PREFIXES - + "] ignored when running the goal as Maven plugin"); - this.appPrefixes = null; - } - - // App constructs identified using JAR file name patterns (regex) - final String[] app_jar_names = _cfg.getStringArray(CoreConfiguration.APP_JAR_NAMES, null); - if (app_jar_names != null) { - // Print warning message in case the setting is used as part of the Maven plugin - if (this.isOneOfGoalClients(pluginGoalClients)) { - log.warn( - "Configuration setting [" - + CoreConfiguration.APP_JAR_NAMES - + "] ignored when running the goal as Maven plugin"); - this.appJarNames = null; - } else { - this.appJarNames = new StringList(); - this.appJarNames.addAll(app_jar_names); - } - } - - // CLI: Only one of appPrefixes and appJarNames can be used - if (!this.isOneOfGoalClients(pluginGoalClients)) { - if (this.appPrefixes != null && this.appJarNames != null) { - throw new GoalConfigurationException( - "Exactly one of the configuration settings [" - + CoreConfiguration.APP_PREFIXES - + "] and [" - + CoreConfiguration.APP_JAR_NAMES - + "] must be set"); - } else if (this.appPrefixes == null && this.appJarNames == null) { - throw new GoalConfigurationException( - "Exactly one of the configuration settings [" - + CoreConfiguration.APP_PREFIXES - + "] and [" - + CoreConfiguration.APP_JAR_NAMES - + "] must be set"); - } - } - } /** {@inheritDoc} */ @Override @@ -170,6 +108,26 @@ public void execute() throws GoalExecutionException { e.printStackTrace(); } + log.info("App classpathUnit [" + app.size() +"]"); + for (ConstructId t : traces) { + Clazz c = cp.getClazz(t.getQname().split("(")[0]); + app.addAll(c.getClazzpathUnits()); + } + log.info("App classpathUnit with traces [" + app.size() +"]"); + + for (Dependency d : reachableConstructIds) { + if(d.getReachableConstructIds()!=null) { + for (ConstructId c : d.getReachableConstructIds()) { + Clazz cl = cp.getClazz(c.getQname().split("(")[0]); + app.addAll(cl.getClazzpathUnits()); + } + } + } + log.info("App classpathUnit with reachable constructs [" + app.size() +"]"); + + log.info("Classpath classpathUnits [" + cp.getUnits().length +"]"); + + final Set needed = new HashSet(); final Set removable = cp.getClazzes(); for(ClazzpathUnit u: app) { @@ -178,12 +136,22 @@ public void execute() throws GoalExecutionException { needed.addAll(u.getClazzes()); needed.addAll(u.getTransitiveDependencies()); } + + log.info("Needed ["+ needed.size()+"] classes"); log.info("Removable ["+ removable.size()+"] classes"); - for(Clazz clazz : removable) { - System.out.println("class " + clazz + " is not required"); - } + + try { + FileWriter writer=new FileWriter("removable.txt"); + for(Clazz clazz : removable) { + writer.write(clazz + System.lineSeparator()); + } + writer.close(); + } catch (IOException e){// TODO Auto-generated catch block + e.printStackTrace(); + } + try { FileWriter writer=new FileWriter("needed.txt"); for(Clazz c: needed) { @@ -191,7 +159,20 @@ public void execute() throws GoalExecutionException { } writer.close(); } catch (IOException e){// TODO Auto-generated catch block - e.printStackTrace();} + e.printStackTrace(); + } + } + + /** {@inheritDoc} */ + @Override + public void setTraces(Set _traces){ + this.traces = _traces; + } + + /** {@inheritDoc} */ + @Override + public void setReachableConstructIds(Set _deps){ + this.reachableConstructIds = _deps; } } diff --git a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java index ba353f31f..c8d28c8ec 100644 --- a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java +++ b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java @@ -69,8 +69,11 @@ protected void executeTasks() throws Exception { final ServiceLoader loader = ServiceLoader.load(DebloatTask.class); for (DebloatTask t : loader) { try { + // Configure t.setApplication(a); + t.setTraces(BackendConnector.getInstance().getAppTraces(this.getGoalContext(), a)); + t.setReachableConstructIds(BackendConnector.getInstance().getAppDependencies(this.getGoalContext(), a)); t.setSearchPaths(this.getAppPaths()); t.setGoalClient(this.getGoalClient()); t.setKnownDependencies(this.getKnownDependencies()); diff --git a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java index d41a52ac2..e797c5fc5 100644 --- a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java +++ b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java @@ -20,7 +20,8 @@ import java.util.Set; -import org.eclipse.steady.Construct; +import org.eclipse.steady.shared.json.model.ConstructId; +import org.eclipse.steady.shared.json.model.Dependency; /** * Methods required to @@ -35,6 +36,20 @@ public interface DebloatTask extends Task { // * @return a {@link org.eclipse.steady.shared.json.model.Application} object. // */ // public Set getNeededConstructs(); + + /** + * Sets the traced constructs to be used as starting point for debloating the {@link Application} + * (traces resulting from the dynamic analysis) + * + */ + public void setTraces(Set _traces); + + /** + * Sets the reachable constructs to be used as starting point for debloating the {@link Application} + * (resulting from the static analysis) + * + */ + public void setReachableConstructIds(Set _deps); } From 2d70d1d415eaa20a84a4e3dda5e611d4659b9013 Mon Sep 17 00:00:00 2001 From: henrikplate <17928867+henrikplate@users.noreply.github.com> Date: Tue, 27 Jul 2021 19:52:58 +0200 Subject: [PATCH 13/29] cherry picked 0da0d08e498ae35ee1c65d1ab771d4d92963809e --- .../main/webapp/i18n/messageBundle.properties | 2 +- .../webapp/i18n/messageBundle_de.properties | 2 +- .../webapp/i18n/messageBundle_en.properties | 2 +- .../i18n/messageBundle_en_US.properties | 2 +- .../backend/rest/ApplicationController.java | 28 +++++++++++-------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/frontend-apps/src/main/webapp/i18n/messageBundle.properties b/frontend-apps/src/main/webapp/i18n/messageBundle.properties index b001cdef4..786c52960 100755 --- a/frontend-apps/src/main/webapp/i18n/messageBundle.properties +++ b/frontend-apps/src/main/webapp/i18n/messageBundle.properties @@ -60,7 +60,7 @@ 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) diff --git a/frontend-apps/src/main/webapp/i18n/messageBundle_de.properties b/frontend-apps/src/main/webapp/i18n/messageBundle_de.properties index 25a13b301..7bcb3a6c6 100755 --- a/frontend-apps/src/main/webapp/i18n/messageBundle_de.properties +++ b/frontend-apps/src/main/webapp/i18n/messageBundle_de.properties @@ -48,7 +48,7 @@ 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) diff --git a/frontend-apps/src/main/webapp/i18n/messageBundle_en.properties b/frontend-apps/src/main/webapp/i18n/messageBundle_en.properties index 64f09f671..e98e22a59 100755 --- a/frontend-apps/src/main/webapp/i18n/messageBundle_en.properties +++ b/frontend-apps/src/main/webapp/i18n/messageBundle_en.properties @@ -54,7 +54,7 @@ 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) diff --git a/frontend-apps/src/main/webapp/i18n/messageBundle_en_US.properties b/frontend-apps/src/main/webapp/i18n/messageBundle_en_US.properties index 64f09f671..e98e22a59 100644 --- a/frontend-apps/src/main/webapp/i18n/messageBundle_en_US.properties +++ b/frontend-apps/src/main/webapp/i18n/messageBundle_en_US.properties @@ -54,7 +54,7 @@ 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) diff --git a/rest-backend/src/main/java/org/eclipse/steady/backend/rest/ApplicationController.java b/rest-backend/src/main/java/org/eclipse/steady/backend/rest/ApplicationController.java index dd1fd86e8..f487ad8a7 100644 --- a/rest-backend/src/main/java/org/eclipse/steady/backend/rest/ApplicationController.java +++ b/rest-backend/src/main/java/org/eclipse/steady/backend/rest/ApplicationController.java @@ -1601,14 +1601,17 @@ public ResponseEntity getDependency( } /** - * Provides application-specific metrics regarding application size and the size of all application dependencies. - * Requires that the given dependency has a valid library Id. + * Provides application-specific metrics regarding application size and the + * size of all application dependencies. Requires that the given dependency + * has a valid library Id. * - * @return 404 {@link HttpStatus#NOT_FOUND} if application with given GAV does not exist, 200 {@link HttpStatus#OK} if the application is found + * @return 404 {@link HttpStatus#NOT_FOUND} if application with given GAV does + * not exist, 200 {@link HttpStatus#OK} if the application is found * @param mvnGroup a {@link java.lang.String} object. * @param artifact a {@link java.lang.String} object. * @param version a {@link java.lang.String} object. - * @param excludedScopes an array of {@link org.eclipse.steady.shared.enums.Scope} objects. + * @param excludedScopes an array of + * {@link org.eclipse.steady.shared.enums.Scope} objects. * @param space a {@link java.lang.String} object. */ @RequestMapping( @@ -1664,27 +1667,28 @@ public ResponseEntity getApplicationMetrics( packages.incrementTotal(count_packages); metrics.addRatio(packages); - // Classes - final Ratio classes = new Ratio("class_ratio", af.countClass(), af.countClass()); - int count_classes; + // Classes, enums and interfaces + final int _count = af.countClass() + af.countEnum() + af.countIntf(); + final Ratio classes = new Ratio("class_ratio", _count, _count); + int count_classes_interfaces_enums; if (excludedScopes == null || excludedScopes.length == 0) - count_classes = + count_classes_interfaces_enums = this.appRepository.countDepConstructTypes( a.getMvnGroup(), a.getArtifact(), a.getVersion(), a.getSpace(), - new ConstructType[] {ConstructType.CLAS}); + new ConstructType[] {ConstructType.CLAS, ConstructType.ENUM, ConstructType.INTF}); else - count_classes = + count_classes_interfaces_enums = this.appRepository.countDepConstructTypes( a.getMvnGroup(), a.getArtifact(), a.getVersion(), a.getSpace(), - new ConstructType[] {ConstructType.CLAS}, + new ConstructType[] {ConstructType.CLAS, ConstructType.ENUM, ConstructType.INTF}, excludedScopes); - classes.incrementTotal(count_classes); + classes.incrementTotal(count_classes_interfaces_enums); metrics.addRatio(classes); // Executable constructs (METH, CONS, INIT) From cc8a4abee0e790a452db5670c1b8a1d6d76e74ad Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 28 Jul 2021 18:09:09 +0200 Subject: [PATCH 14/29] filter on construct type and save missing classes --- .../steady/java/tasks/JavaDebloatTask.java | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 571022ffa..31b76290e 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -21,30 +21,21 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.List; -import java.util.Map; import java.util.Set; import org.apache.logging.log4j.Logger; -import org.eclipse.steady.Construct; -import org.eclipse.steady.backend.BackendConnector; -import org.eclipse.steady.core.util.CoreConfiguration; -import org.eclipse.steady.goals.GoalConfigurationException; import org.eclipse.steady.goals.GoalExecutionException; -import org.eclipse.steady.java.JarAnalyzer; +import org.eclipse.steady.shared.enums.ConstructType; import org.eclipse.steady.shared.enums.GoalClient; import org.eclipse.steady.shared.enums.ProgrammingLanguage; import org.eclipse.steady.shared.json.model.ConstructId; import org.eclipse.steady.shared.json.model.Dependency; -import org.eclipse.steady.shared.json.model.Trace; -import org.eclipse.steady.shared.util.StringList; -import org.eclipse.steady.shared.util.StringUtil; -import org.eclipse.steady.shared.util.VulasConfiguration; import org.eclipse.steady.tasks.AbstractTask; import org.eclipse.steady.tasks.DebloatTask; import org.vafer.jdependency.Clazz; @@ -110,16 +101,36 @@ public void execute() throws GoalExecutionException { log.info("App classpathUnit [" + app.size() +"]"); for (ConstructId t : traces) { - Clazz c = cp.getClazz(t.getQname().split("(")[0]); - app.addAll(c.getClazzpathUnits()); + if(t.getType().equals(ConstructType.CLAS) || t.getType().equals(ConstructType.INTF) || t.getType().equals(ConstructType.ENUM)) { + Clazz c = cp.getClazz(t.getQname()); + Set units = c.getClazzpathUnits(); + if(units.size()>1) { + log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + c + "] : ["); + for(ClazzpathUnit u: units) { + log.warn(u + ","); + log.warn("]"); + } + } + app.addAll(units); + } } log.info("App classpathUnit with traces [" + app.size() +"]"); for (Dependency d : reachableConstructIds) { if(d.getReachableConstructIds()!=null) { for (ConstructId c : d.getReachableConstructIds()) { - Clazz cl = cp.getClazz(c.getQname().split("(")[0]); - app.addAll(cl.getClazzpathUnits()); + if(c.getType().equals(ConstructType.CLAS) || c.getType().equals(ConstructType.INTF) || c.getType().equals(ConstructType.ENUM)) { + Clazz cl = cp.getClazz(c.getQname()); + Set units = cl.getClazzpathUnits(); + if(units.size()>1) { + log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + cl + "] : ["); + for(ClazzpathUnit u: units) { + log.warn(u + ","); + log.warn("]"); + } + } + app.addAll(units); + } } } } @@ -127,17 +138,21 @@ public void execute() throws GoalExecutionException { log.info("Classpath classpathUnits [" + cp.getUnits().length +"]"); + + SortedSet missing = new TreeSet(); + for (Clazz c : cp.getMissingClazzes()) { + missing.add(c); + } - final Set needed = new HashSet(); - final Set removable = cp.getClazzes(); + final SortedSet needed = new TreeSet(); + final Set cp_set = cp.getClazzes(); for(ClazzpathUnit u: app) { - removable.removeAll(u.getClazzes()); - removable.removeAll(u.getTransitiveDependencies()); + cp_set.removeAll(u.getClazzes()); + cp_set.removeAll(u.getTransitiveDependencies()); needed.addAll(u.getClazzes()); needed.addAll(u.getTransitiveDependencies()); } - - + final SortedSet removable = new TreeSet(cp_set); log.info("Needed ["+ needed.size()+"] classes"); log.info("Removable ["+ removable.size()+"] classes"); @@ -161,6 +176,15 @@ public void execute() throws GoalExecutionException { } catch (IOException e){// TODO Auto-generated catch block e.printStackTrace(); } + try { + FileWriter writer=new FileWriter("missing.txt"); + for(Clazz c: missing) { + writer.write(c + System.lineSeparator()); + } + writer.close(); + } catch (IOException e){// TODO Auto-generated catch block + e.printStackTrace(); + } } /** {@inheritDoc} */ From 98d865d393fbc594908361eaf15ca58895a1f603 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 28 Jul 2021 19:04:42 +0200 Subject: [PATCH 15/29] add (un)used deps --- .../steady/java/tasks/JavaDebloatTask.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 31b76290e..bf787193d 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -73,6 +73,9 @@ public void execute() throws GoalExecutionException { final Clazzpath cp = new Clazzpath(); List app = new ArrayList(); + Set deps = new HashSet(); + Set deps_used = new HashSet(); + try { //1) Add app paths if (this.hasSearchPath()) { @@ -91,7 +94,8 @@ public void execute() throws GoalExecutionException { "Add dep path [" + p + "] to classpath"); - cp.addClazzpathUnit(p); + deps.add(cp.addClazzpathUnit(p)); + } } } catch (IOException e) { @@ -150,12 +154,22 @@ public void execute() throws GoalExecutionException { cp_set.removeAll(u.getClazzes()); cp_set.removeAll(u.getTransitiveDependencies()); needed.addAll(u.getClazzes()); + needed.addAll(u.getDependencies()); needed.addAll(u.getTransitiveDependencies()); + if(deps.contains(u)) + deps_used.add(u); + for (Clazz c : u.getDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); + } + for (Clazz c : u.getTransitiveDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); + } } final SortedSet removable = new TreeSet(cp_set); - log.info("Needed ["+ needed.size()+"] classes"); - log.info("Removable ["+ removable.size()+"] classes"); + log.info("Needed classes ["+ needed.size()+"] classes"); + log.info("Removable classes ["+ removable.size()+"] classes"); + log.info("Used dependencies ["+ deps_used.size()+"] out of [" + deps.size() + "]"); try { FileWriter writer=new FileWriter("removable.txt"); @@ -163,25 +177,25 @@ public void execute() throws GoalExecutionException { writer.write(clazz + System.lineSeparator()); } writer.close(); - } catch (IOException e){// TODO Auto-generated catch block - e.printStackTrace(); - } - - try { - FileWriter writer=new FileWriter("needed.txt"); + + writer=new FileWriter("needed.txt"); for(Clazz c: needed) { writer.write(c + System.lineSeparator()); } writer.close(); - } catch (IOException e){// TODO Auto-generated catch block - e.printStackTrace(); - } - try { - FileWriter writer=new FileWriter("missing.txt"); + + writer=new FileWriter("missing.txt"); for(Clazz c: missing) { writer.write(c + System.lineSeparator()); } writer.close(); + + writer=new FileWriter("removable_deps.txt"); + deps.removeAll(deps_used); + for(ClazzpathUnit c: deps) { + writer.write(c + System.lineSeparator()); + } + writer.close(); } catch (IOException e){// TODO Auto-generated catch block e.printStackTrace(); } From ff28e077fcb9ba9201c59fcd3a5e5a8cd25809a2 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Thu, 29 Jul 2021 17:36:16 +0200 Subject: [PATCH 16/29] added comments and reworked debloating logic --- .../steady/java/tasks/JavaDebloatTask.java | 77 ++++++++++++++----- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index bf787193d..bcf33fe64 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -72,12 +72,17 @@ public void execute() throws GoalExecutionException { final Clazzpath cp = new Clazzpath(); + // list of classpathunits to be used as entrypoints List app = new ArrayList(); - Set deps = new HashSet(); + // list of classes to be used as entrypoints (from traces and reachable constructs) + List used_classes = new ArrayList(); + // classpathunits for the application dependencies (as identified by maven) + Set maven_deps = new HashSet(); + // classpathunits considered used according to traces, reachable constructs and jdependency analysis Set deps_used = new HashSet(); try { - //1) Add app paths + //1) Add application paths (to be then used as entrypoints) if (this.hasSearchPath()) { for (Path p : this.getSearchPath()) { log.info( @@ -87,14 +92,14 @@ public void execute() throws GoalExecutionException { app.add(cp.addClazzpathUnit(p)); } } - //2) Add dependencies to classpath + //2) Add dependencies to jdependency classpath object and populate set of dependencies if (this.getKnownDependencies() != null) { for (Path p : this.getKnownDependencies().keySet()) { log.info( "Add dep path [" + p + "] to classpath"); - deps.add(cp.addClazzpathUnit(p)); + maven_deps.add(cp.addClazzpathUnit(p)); } } @@ -103,10 +108,13 @@ public void execute() throws GoalExecutionException { e.printStackTrace(); } - log.info("App classpathUnit [" + app.size() +"]"); + log.info("[" + app.size() +"] ClasspathUnit for the application to be used as entrypoints "); + + // retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) for (ConstructId t : traces) { if(t.getType().equals(ConstructType.CLAS) || t.getType().equals(ConstructType.INTF) || t.getType().equals(ConstructType.ENUM)) { Clazz c = cp.getClazz(t.getQname()); + used_classes.add(c); Set units = c.getClazzpathUnits(); if(units.size()>1) { log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + c + "] : ["); @@ -115,16 +123,19 @@ public void execute() throws GoalExecutionException { log.warn("]"); } } - app.addAll(units); + deps_used.addAll(units); } } - log.info("App classpathUnit with traces [" + app.size() +"]"); + log.info("[" + used_classes.size() +"] Clazz as entrypoints from traces"); + // retrieve reachable constructs to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) + //TODO: deserialization not working (method getAppDependencies in BackendConnector:707) for (Dependency d : reachableConstructIds) { if(d.getReachableConstructIds()!=null) { for (ConstructId c : d.getReachableConstructIds()) { if(c.getType().equals(ConstructType.CLAS) || c.getType().equals(ConstructType.INTF) || c.getType().equals(ConstructType.ENUM)) { Clazz cl = cp.getClazz(c.getQname()); + used_classes.add(cl); Set units = cl.getClazzpathUnits(); if(units.size()>1) { log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + cl + "] : ["); @@ -133,31 +144,37 @@ public void execute() throws GoalExecutionException { log.warn("]"); } } - app.addAll(units); + deps_used.addAll(units); } } } } - log.info("App classpathUnit with reachable constructs [" + app.size() +"]"); + log.info("[" + used_classes.size() +"] Clazz as entrypoints from traces and reachable constructs"); - log.info("Classpath classpathUnits [" + cp.getUnits().length +"]"); + log.info("[" + cp.getUnits().length +"] classpathUnits in jdependency classpath object"); + // also collect "missing" classes to be able to check their relation with jre objects considered used + // to be removed from final version SortedSet missing = new TreeSet(); for (Clazz c : cp.getMissingClazzes()) { missing.add(c); } - + + // classes considered used final SortedSet needed = new TreeSet(); - final Set cp_set = cp.getClazzes(); + final Set classes = cp.getClazzes(); + //loop over classpathunits (representing the application) marked as entrypoints to find needed classes for(ClazzpathUnit u: app) { - cp_set.removeAll(u.getClazzes()); - cp_set.removeAll(u.getTransitiveDependencies()); + classes.removeAll(u.getClazzes()); + //TODO: check if getDependencies is also needed or getTransitiveDependencies sufficies + classes.removeAll(u.getDependencies()); + classes.removeAll(u.getTransitiveDependencies()); needed.addAll(u.getClazzes()); needed.addAll(u.getDependencies()); needed.addAll(u.getTransitiveDependencies()); - if(deps.contains(u)) - deps_used.add(u); + + //loop over dependent classes to add their units among the used dependencies for (Clazz c : u.getDependencies()) { deps_used.addAll(c.getClazzpathUnits()); } @@ -165,12 +182,32 @@ public void execute() throws GoalExecutionException { deps_used.addAll(c.getClazzpathUnits()); } } - final SortedSet removable = new TreeSet(cp_set); + + + // loop over class (representing traces and reachable constructs) marked as entrypoints to find needed classes + for(Clazz c: used_classes) { + classes.remove(c); + classes.removeAll(c.getDependencies()); + classes.removeAll(c.getTransitiveDependencies()); + needed.add(c); + needed.addAll(c.getDependencies()); + needed.addAll(c.getTransitiveDependencies()); + + //loop over dependent classes to add their units among the used dependencies + for (Clazz cc : c.getDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + for (Clazz cc : c.getTransitiveDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + } + final SortedSet removable = new TreeSet(classes); log.info("Needed classes ["+ needed.size()+"] classes"); log.info("Removable classes ["+ removable.size()+"] classes"); - log.info("Used dependencies ["+ deps_used.size()+"] out of [" + deps.size() + "]"); + log.info("Used dependencies ["+ deps_used.size()+"] out of [" + maven_deps.size() + "]"); + //TODO: write to target/vulas/... try { FileWriter writer=new FileWriter("removable.txt"); for(Clazz clazz : removable) { @@ -191,8 +228,8 @@ public void execute() throws GoalExecutionException { writer.close(); writer=new FileWriter("removable_deps.txt"); - deps.removeAll(deps_used); - for(ClazzpathUnit c: deps) { + maven_deps.removeAll(deps_used); + for(ClazzpathUnit c: maven_deps) { writer.write(c + System.lineSeparator()); } writer.close(); From 65e0885cd417a50e60de66f87de47aec180ae635 Mon Sep 17 00:00:00 2001 From: henrikplate <17928867+henrikplate@users.noreply.github.com> Date: Tue, 3 Aug 2021 16:37:34 +0200 Subject: [PATCH 17/29] Fixed processing of reachable constructs; Files are written to configurable directory --- .../java/org/eclipse/steady/java/JavaId.java | 8 +- .../steady/java/tasks/JavaDebloatTask.java | 120 +++++++++--------- .../steady/backend/BackendConnector.java | 3 + .../steady/core/util/CoreConfiguration.java | 3 + lang/src/main/resources/vulas-core.properties | 14 +- .../steady/java/mvn/AbstractVulasMojo.java | 3 + .../steady/shared/json/model/Dependency.java | 8 +- .../steady/shared/model/ApplicationTest.java | 19 +++ 8 files changed, 109 insertions(+), 69 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java index 941a76c07..ef67d3a24 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/JavaId.java @@ -558,7 +558,7 @@ public static JavaMethodId parseMethodQName(JavaId.Type _ctx_type, String _s) { _s.substring(j + 1, i), JavaId.parseParameterTypes(_s.substring(i + 1, _s.length() - 1))); } catch (StringIndexOutOfBoundsException e) { - JavaId.log.error("Exception while parsing the string '" + _s + "'"); + JavaId.log.error("Exception while parsing the string [" + _s + "]"); } return mid; } @@ -627,7 +627,7 @@ else if (_ctx_type.equals(JavaId.Type.ENUM)) } coid = new JavaConstructorId(def_ctx, params); } catch (StringIndexOutOfBoundsException e) { - JavaId.log.error("Exception while parsing the string '" + _s + "'"); + JavaId.log.error("Exception while parsing the string [" + _s + "]"); } return coid; } @@ -644,7 +644,7 @@ public static JavaClassInit parseClassInitQName(String _s) { final int i = _s.indexOf(JavaClassInit.NAME); if (i == -1) throw new IllegalArgumentException( - "String does not contain brackets " + "String does not contain " + JavaClassInit.NAME + ", as required for qualified names for Java class initializers"); @@ -653,7 +653,7 @@ public static JavaClassInit parseClassInitQName(String _s) { final JavaClassId cid = JavaId.parseClassQName(_s.substring(0, i - 1)); clinit = cid.getClassInit(); } catch (StringIndexOutOfBoundsException e) { - JavaId.log.error("Exception while parsing the string '" + _s + "'"); + JavaId.log.error("Exception while parsing the string [" + _s + "]"); } return clinit; } diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index bcf33fe64..a2ae7e6a8 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -18,24 +18,29 @@ */ package org.eclipse.steady.java.tasks; -import java.io.FileWriter; +import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import java.util.SortedSet; -import java.util.TreeSet; import java.util.List; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import org.apache.logging.log4j.Logger; +import org.eclipse.steady.core.util.CoreConfiguration; import org.eclipse.steady.goals.GoalExecutionException; +import org.eclipse.steady.java.JavaId; import org.eclipse.steady.shared.enums.ConstructType; import org.eclipse.steady.shared.enums.GoalClient; import org.eclipse.steady.shared.enums.ProgrammingLanguage; import org.eclipse.steady.shared.json.model.ConstructId; import org.eclipse.steady.shared.json.model.Dependency; +import org.eclipse.steady.shared.util.FileUtil; +import org.eclipse.steady.shared.util.StringUtil; import org.eclipse.steady.tasks.AbstractTask; import org.eclipse.steady.tasks.DebloatTask; import org.vafer.jdependency.Clazz; @@ -53,7 +58,7 @@ public class JavaDebloatTask extends AbstractTask implements DebloatTask { private Set traces = null; - private Set reachableConstructIds = null; + private Set dependencies = null; private static final List pluginGoalClients = Arrays.asList(GoalClient.MAVEN_PLUGIN, GoalClient.GRADLE_PLUGIN); @@ -104,56 +109,59 @@ public void execute() throws GoalExecutionException { } } } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } log.info("[" + app.size() +"] ClasspathUnit for the application to be used as entrypoints "); - // retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) + // Retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) for (ConstructId t : traces) { if(t.getType().equals(ConstructType.CLAS) || t.getType().equals(ConstructType.INTF) || t.getType().equals(ConstructType.ENUM)) { Clazz c = cp.getClazz(t.getQname()); - used_classes.add(c); - Set units = c.getClazzpathUnits(); - if(units.size()>1) { - log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + c + "] : ["); - for(ClazzpathUnit u: units) { - log.warn(u + ","); - log.warn("]"); + if(c==null) { + log.warn("Could not obtain jdependency clazz for traced class [" + t.getQname() + "]"); + } + else { + used_classes.add(c); + Set units = c.getClazzpathUnits(); + if(units.size()>1) { + log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + c + "] : [" + StringUtil.join(units, ",") + "]"); } + deps_used.addAll(units); } - deps_used.addAll(units); } } - log.info("[" + used_classes.size() +"] Clazz as entrypoints from traces"); + log.info("Using [" + used_classes.size() +"] jdependency clazzes as entrypoints from traces"); - // retrieve reachable constructs to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) - //TODO: deserialization not working (method getAppDependencies in BackendConnector:707) - for (Dependency d : reachableConstructIds) { - if(d.getReachableConstructIds()!=null) { + // Loop reachable constructs (METH, CONS, INIT), find their definition + // context (CLASS, ENUM, INTF) and use those as jdependency clazz + // entrypoints (1 class may be part of multiple classpathUnits). + for (Dependency d : dependencies) { + log.info("Processing [" + d.getReachableConstructIds().size() + "] reachable constructs of " + d.getLib().getLibraryId()); + if(d.getReachableConstructIds()!=null) { for (ConstructId c : d.getReachableConstructIds()) { - if(c.getType().equals(ConstructType.CLAS) || c.getType().equals(ConstructType.INTF) || c.getType().equals(ConstructType.ENUM)) { - Clazz cl = cp.getClazz(c.getQname()); + JavaId core_construct = (JavaId)JavaId.toCoreType(c); + JavaId def_context = (JavaId)core_construct.getDefinitionContext(); + Clazz cl = cp.getClazz(def_context.getQualifiedName()); + if(cl==null) { + log.warn("Could not obtain jdependency clazz for [" + def_context + "]"); + } + else { used_classes.add(cl); Set units = cl.getClazzpathUnits(); if(units.size()>1) { - log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + cl + "] : ["); - for(ClazzpathUnit u: units) { - log.warn(u + ","); - log.warn("]"); - } + log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + cl + "] : [" + StringUtil.join(units, ",") + "]"); } deps_used.addAll(units); } } } } - log.info("[" + used_classes.size() +"] Clazz as entrypoints from traces and reachable constructs"); + + log.info("Using [" + used_classes.size() + "] jdependency clazzes as entrypoints from traces and reachable constructs"); log.info("[" + cp.getUnits().length +"] classpathUnits in jdependency classpath object"); - // also collect "missing" classes to be able to check their relation with jre objects considered used // to be removed from final version SortedSet missing = new TreeSet(); @@ -161,7 +169,7 @@ public void execute() throws GoalExecutionException { missing.add(c); } - // classes considered used + // Classes considered used final SortedSet needed = new TreeSet(); final Set classes = cp.getClazzes(); //loop over classpathunits (representing the application) marked as entrypoints to find needed classes @@ -203,37 +211,30 @@ public void execute() throws GoalExecutionException { } final SortedSet removable = new TreeSet(classes); - log.info("Needed classes ["+ needed.size()+"] classes"); - log.info("Removable classes ["+ removable.size()+"] classes"); - log.info("Used dependencies ["+ deps_used.size()+"] out of [" + maven_deps.size() + "]"); + log.info("Needed classes: ["+ needed.size()+"]"); + log.info("Removable classes: ["+ removable.size()+"]"); + log.info("Used dependencies: ["+ deps_used.size()+"] out of [" + maven_deps.size() + "]"); + + maven_deps.removeAll(deps_used); - //TODO: write to target/vulas/... + // Write names of needed/removable classes and dependencies to disk try { - FileWriter writer=new FileWriter("removable.txt"); - for(Clazz clazz : removable) { - writer.write(clazz + System.lineSeparator()); - } - writer.close(); - - writer=new FileWriter("needed.txt"); - for(Clazz c: needed) { - writer.write(c + System.lineSeparator()); - } - writer.close(); - - writer=new FileWriter("missing.txt"); - for(Clazz c: missing) { - writer.write(c + System.lineSeparator()); - } - writer.close(); - - writer=new FileWriter("removable_deps.txt"); - maven_deps.removeAll(deps_used); - for(ClazzpathUnit c: maven_deps) { - writer.write(c + System.lineSeparator()); - } - writer.close(); - } catch (IOException e){// TODO Auto-generated catch block + File f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "removable-classes.txt").toFile(); + FileUtil.writeToFile(f, StringUtil.join(removable, System.lineSeparator())); + log.info("List of removable classes written to [" + f.toPath() + "]"); + + f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "needed-classes.txt").toFile(); + FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); + log.info("List of needed classes written to [" + f.toPath() + "]"); + + f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "missing-classes.txt").toFile(); + FileUtil.writeToFile(f, StringUtil.join(missing, System.lineSeparator())); + log.info("List of missing classes written to [" + f.toPath() + "]"); + + f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "removable-deps.txt").toFile(); + FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); + log.info("List of removable dependencies written to [" + f.toPath() + "]"); + } catch (IOException e){ e.printStackTrace(); } } @@ -247,7 +248,6 @@ public void setTraces(Set _traces){ /** {@inheritDoc} */ @Override public void setReachableConstructIds(Set _deps){ - this.reachableConstructIds = _deps; + this.dependencies = _deps; } - } diff --git a/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java b/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java index 5af3e8d5e..c05d06cbb 100755 --- a/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java +++ b/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java @@ -720,6 +720,9 @@ public Set getAppDependencies(GoalContext _ctx, @NotNull Application (org.eclipse.steady.shared.json.model.Dependency[]) JacksonUtil.asObject(json, org.eclipse.steady.shared.json.model.Dependency[].class); else backend_deps = new org.eclipse.steady.shared.json.model.Dependency[] {}; + for(org.eclipse.steady.shared.json.model.Dependency d: backend_deps) { + d.setApp(_app); + } deps.addAll(Arrays.asList(backend_deps)); BackendConnector.log.info("[" + deps.size() + "] dependencies received from backend"); } diff --git a/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java b/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java index e1517d69b..4c0f45436 100755 --- a/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java +++ b/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java @@ -124,6 +124,9 @@ public enum ConnectType { /** Constant REP_LIB_ASSESS="vulas.report.createLibraryAssessments" */ public static final String REP_CREATE_AFF_LIB = "vulas.report.createLibraryAssessments"; + /** Constant SLICING_DIR="vulas.slicing.slicingDir" */ + public static final String SLICING_DIR = "vulas.slicing.slicingDir"; + /** Constant SEQ_DEFAULT="vulas.core.sequence.defaultGoals" */ public static final String SEQ_DEFAULT = "vulas.core.sequence.defaultGoals"; diff --git a/lang/src/main/resources/vulas-core.properties b/lang/src/main/resources/vulas-core.properties index 4baee6953..5cc19275f 100644 --- a/lang/src/main/resources/vulas-core.properties +++ b/lang/src/main/resources/vulas-core.properties @@ -195,7 +195,7 @@ vulas.report.exceptionExcludeUnassessed = all # Note: The scope of this assessment is beyond a specific application, hence, the CURL command requires a security token. #vulas.report.createLibraryAssessments = -# Directory to where the reports (JSON, XML, HTML) will be written to +# Directory to which the reports (JSON, XML, HTML) will be written to # Default: # CLI: - # MVN: ${project.build.directory}/vulas/report @@ -208,6 +208,18 @@ vulas.report.reportDir = # Note: This setting is only relevant in the context of Maven #vulas.report.overridePomVersion = false + + +########## vulas:slicing + +# Directory to which files with needed/redundant classes and dependencies will be written to +# Default: +# CLI: - +# MVN: ${project.build.directory}/vulas/slicing +vulas.slicing.slicingDir = + + + ########## vulas:sequence # Sequence of goals executed by the sequence goal diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java index a9d379a44..68943e2fa 100644 --- a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java @@ -146,6 +146,9 @@ public final void prepareConfiguration() throws Exception { this.vulasConfiguration.setPropertyIfEmpty( CoreConfiguration.REP_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "report").toString()); + this.vulasConfiguration.setPropertyIfEmpty( + CoreConfiguration.SLICING_DIR, + Paths.get(this.project.getBuild().getDirectory(), "vulas", "slicing").toString()); // Read app constructs from src/main/java and target/classes final String p = diff --git a/shared/src/main/java/org/eclipse/steady/shared/json/model/Dependency.java b/shared/src/main/java/org/eclipse/steady/shared/json/model/Dependency.java index 13d09f0ed..baafacff7 100644 --- a/shared/src/main/java/org/eclipse/steady/shared/json/model/Dependency.java +++ b/shared/src/main/java/org/eclipse/steady/shared/json/model/Dependency.java @@ -22,21 +22,21 @@ import java.util.Collection; import java.util.List; -import org.eclipse.steady.shared.enums.DependencyOrigin; -import org.eclipse.steady.shared.enums.Scope; - import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; +import org.eclipse.steady.shared.enums.DependencyOrigin; +import org.eclipse.steady.shared.enums.Scope; + /** *

Dependency class.

*/ @JsonInclude(JsonInclude.Include.ALWAYS) @JsonIgnoreProperties( ignoreUnknown = true, - value = {"reachableConstructIds", "touchPoints"}, + value = {"touchPoints"}, allowGetters = true) public class Dependency implements Serializable, Comparable { diff --git a/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java b/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java index 0829df41c..ec0174e06 100644 --- a/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java +++ b/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java @@ -18,8 +18,14 @@ */ package org.eclipse.steady.shared.model; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; + +import org.eclipse.steady.shared.json.JacksonUtil; import org.eclipse.steady.shared.json.model.Application; import org.eclipse.steady.shared.util.Constants; +import org.eclipse.steady.shared.util.FileUtil; import org.junit.Test; public class ApplicationTest { @@ -35,4 +41,17 @@ public void testArgumentTooLong() { for (int i = 0; i <= Constants.MAX_LENGTH_GROUP + 10; i++) g.append("a"); new Application(g.toString(), "foo", "bar"); } + + @Test + public void testAppReachDeserialization() { + try { + String json = FileUtil.readFile("./src/test/resources/appReachConstructIds.json"); + org.eclipse.steady.shared.json.model.Dependency[] backend_deps = (org.eclipse.steady.shared.json.model.Dependency[]) JacksonUtil + .asObject(json, org.eclipse.steady.shared.json.model.Dependency[].class); + assertNotNull(backend_deps[0].getReachableConstructIds()); + } catch (IOException e) { + assert(false); + } + + } } From c8ae37ff0f5170abe9551f30a01a0344266ae4ef Mon Sep 17 00:00:00 2001 From: henrikplate <17928867+henrikplate@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:53:20 +0200 Subject: [PATCH 18/29] Code style --- .../steady/java/tasks/JavaDebloatTask.java | 371 +-- .../steady/backend/BackendConnector.java | 2 +- .../org/eclipse/steady/goals/DebloatGoal.java | 32 +- .../org/eclipse/steady/goals/GoalFactory.java | 4 +- .../org/eclipse/steady/tasks/DebloatTask.java | 42 +- .../steady/java/mvn/AbstractVulasMojo.java | 4 +- .../steady/shared/model/ApplicationTest.java | 8 +- .../test/resources/appReachConstructIds.json | 2621 +++++++++++++++++ 8 files changed, 2864 insertions(+), 220 deletions(-) create mode 100644 shared/src/test/resources/appReachConstructIds.json diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index a2ae7e6a8..a2b10a2a9 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -57,9 +57,9 @@ public class JavaDebloatTask extends AbstractTask implements DebloatTask { private static final String[] EXT_FILTER = new String[] {"jar", "war", "class", "java", "aar"}; private Set traces = null; - + private Set dependencies = null; - + private static final List pluginGoalClients = Arrays.asList(GoalClient.MAVEN_PLUGIN, GoalClient.GRADLE_PLUGIN); @@ -70,184 +70,213 @@ public Set getLanguage() { Arrays.asList(new ProgrammingLanguage[] {ProgrammingLanguage.JAVA})); } - /** {@inheritDoc} */ @Override public void execute() throws GoalExecutionException { - final Clazzpath cp = new Clazzpath(); - - // list of classpathunits to be used as entrypoints - List app = new ArrayList(); - // list of classes to be used as entrypoints (from traces and reachable constructs) - List used_classes = new ArrayList(); - // classpathunits for the application dependencies (as identified by maven) - Set maven_deps = new HashSet(); - // classpathunits considered used according to traces, reachable constructs and jdependency analysis - Set deps_used = new HashSet(); - - try { - //1) Add application paths (to be then used as entrypoints) - if (this.hasSearchPath()) { - for (Path p : this.getSearchPath()) { - log.info( - "Add app path [" - + p - + "] to classpath"); - app.add(cp.addClazzpathUnit(p)); - } - } - //2) Add dependencies to jdependency classpath object and populate set of dependencies - if (this.getKnownDependencies() != null) { - for (Path p : this.getKnownDependencies().keySet()) { - log.info( - "Add dep path [" - + p - + "] to classpath"); - maven_deps.add(cp.addClazzpathUnit(p)); - - } - } - } catch (IOException e) { - e.printStackTrace(); - } - - log.info("[" + app.size() +"] ClasspathUnit for the application to be used as entrypoints "); - - // Retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple classpathUnits) - for (ConstructId t : traces) { - if(t.getType().equals(ConstructType.CLAS) || t.getType().equals(ConstructType.INTF) || t.getType().equals(ConstructType.ENUM)) { - Clazz c = cp.getClazz(t.getQname()); - if(c==null) { - log.warn("Could not obtain jdependency clazz for traced class [" + t.getQname() + "]"); - } - else { - used_classes.add(c); - Set units = c.getClazzpathUnits(); - if(units.size()>1) { - log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + c + "] : [" + StringUtil.join(units, ",") + "]"); - } - deps_used.addAll(units); - } - } - } - log.info("Using [" + used_classes.size() +"] jdependency clazzes as entrypoints from traces"); - - // Loop reachable constructs (METH, CONS, INIT), find their definition - // context (CLASS, ENUM, INTF) and use those as jdependency clazz - // entrypoints (1 class may be part of multiple classpathUnits). - for (Dependency d : dependencies) { - log.info("Processing [" + d.getReachableConstructIds().size() + "] reachable constructs of " + d.getLib().getLibraryId()); - if(d.getReachableConstructIds()!=null) { - for (ConstructId c : d.getReachableConstructIds()) { - JavaId core_construct = (JavaId)JavaId.toCoreType(c); - JavaId def_context = (JavaId)core_construct.getDefinitionContext(); - Clazz cl = cp.getClazz(def_context.getQualifiedName()); - if(cl==null) { - log.warn("Could not obtain jdependency clazz for [" + def_context + "]"); - } - else { - used_classes.add(cl); - Set units = cl.getClazzpathUnits(); - if(units.size()>1) { - log.warn("Added as entrypoints multiple ClasspathUnits from single class [" + cl + "] : [" + StringUtil.join(units, ",") + "]"); - } - deps_used.addAll(units); - } - } - } - } - - log.info("Using [" + used_classes.size() + "] jdependency clazzes as entrypoints from traces and reachable constructs"); - - log.info("[" + cp.getUnits().length +"] classpathUnits in jdependency classpath object"); - - // also collect "missing" classes to be able to check their relation with jre objects considered used - // to be removed from final version - SortedSet missing = new TreeSet(); - for (Clazz c : cp.getMissingClazzes()) { - missing.add(c); - } - - // Classes considered used - final SortedSet needed = new TreeSet(); - final Set classes = cp.getClazzes(); - //loop over classpathunits (representing the application) marked as entrypoints to find needed classes - for(ClazzpathUnit u: app) { - classes.removeAll(u.getClazzes()); - //TODO: check if getDependencies is also needed or getTransitiveDependencies sufficies - classes.removeAll(u.getDependencies()); - classes.removeAll(u.getTransitiveDependencies()); - needed.addAll(u.getClazzes()); - needed.addAll(u.getDependencies()); - needed.addAll(u.getTransitiveDependencies()); - - //loop over dependent classes to add their units among the used dependencies - for (Clazz c : u.getDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); - } - for (Clazz c : u.getTransitiveDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); - } - } - - - // loop over class (representing traces and reachable constructs) marked as entrypoints to find needed classes - for(Clazz c: used_classes) { - classes.remove(c); - classes.removeAll(c.getDependencies()); - classes.removeAll(c.getTransitiveDependencies()); - needed.add(c); - needed.addAll(c.getDependencies()); - needed.addAll(c.getTransitiveDependencies()); - - //loop over dependent classes to add their units among the used dependencies - for (Clazz cc : c.getDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } - for (Clazz cc : c.getTransitiveDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } - } - final SortedSet removable = new TreeSet(classes); - - log.info("Needed classes: ["+ needed.size()+"]"); - log.info("Removable classes: ["+ removable.size()+"]"); - log.info("Used dependencies: ["+ deps_used.size()+"] out of [" + maven_deps.size() + "]"); - - maven_deps.removeAll(deps_used); - - // Write names of needed/removable classes and dependencies to disk - try { - File f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "removable-classes.txt").toFile(); - FileUtil.writeToFile(f, StringUtil.join(removable, System.lineSeparator())); - log.info("List of removable classes written to [" + f.toPath() + "]"); - - f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "needed-classes.txt").toFile(); - FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); - log.info("List of needed classes written to [" + f.toPath() + "]"); - - f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "missing-classes.txt").toFile(); - FileUtil.writeToFile(f, StringUtil.join(missing, System.lineSeparator())); - log.info("List of missing classes written to [" + f.toPath() + "]"); - - f = Paths.get(this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "removable-deps.txt").toFile(); - FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); - log.info("List of removable dependencies written to [" + f.toPath() + "]"); - } catch (IOException e){ - e.printStackTrace(); - } + final Clazzpath cp = new Clazzpath(); + + // list of classpathunits to be used as entrypoints + List app = new ArrayList(); + // list of classes to be used as entrypoints (from traces and reachable constructs) + List used_classes = new ArrayList(); + // classpathunits for the application dependencies (as identified by maven) + Set maven_deps = new HashSet(); + // classpathunits considered used according to traces, reachable constructs and jdependency + // analysis + Set deps_used = new HashSet(); + + try { + // 1) Add application paths (to be then used as entrypoints) + if (this.hasSearchPath()) { + for (Path p : this.getSearchPath()) { + log.info("Add app path [" + p + "] to classpath"); + app.add(cp.addClazzpathUnit(p)); + } + } + // 2) Add dependencies to jdependency classpath object and populate set of dependencies + if (this.getKnownDependencies() != null) { + for (Path p : this.getKnownDependencies().keySet()) { + log.info("Add dep path [" + p + "] to classpath"); + maven_deps.add(cp.addClazzpathUnit(p)); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + log.info("[" + app.size() + "] ClasspathUnit for the application to be used as entrypoints "); + + // Retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple + // classpathUnits) + for (ConstructId t : traces) { + if (t.getType().equals(ConstructType.CLAS) + || t.getType().equals(ConstructType.INTF) + || t.getType().equals(ConstructType.ENUM)) { + Clazz c = cp.getClazz(t.getQname()); + if (c == null) { + log.warn("Could not obtain jdependency clazz for traced class [" + t.getQname() + "]"); + } else { + used_classes.add(c); + Set units = c.getClazzpathUnits(); + if (units.size() > 1) { + log.warn( + "Added as entrypoints multiple ClasspathUnits from single class [" + + c + + "] : [" + + StringUtil.join(units, ",") + + "]"); + } + deps_used.addAll(units); + } + } + } + log.info("Using [" + used_classes.size() + "] jdependency clazzes as entrypoints from traces"); + + // Loop reachable constructs (METH, CONS, INIT), find their definition + // context (CLASS, ENUM, INTF) and use those as jdependency clazz + // entrypoints (1 class may be part of multiple classpathUnits). + for (Dependency d : dependencies) { + log.info( + "Processing [" + + d.getReachableConstructIds().size() + + "] reachable constructs of " + + d.getLib().getLibraryId()); + if (d.getReachableConstructIds() != null) { + for (ConstructId c : d.getReachableConstructIds()) { + JavaId core_construct = (JavaId) JavaId.toCoreType(c); + JavaId def_context = (JavaId) core_construct.getDefinitionContext(); + Clazz cl = cp.getClazz(def_context.getQualifiedName()); + if (cl == null) { + log.warn("Could not obtain jdependency clazz for [" + def_context + "]"); + } else { + used_classes.add(cl); + Set units = cl.getClazzpathUnits(); + if (units.size() > 1) { + log.warn( + "Added as entrypoints multiple ClasspathUnits from single class [" + + cl + + "] : [" + + StringUtil.join(units, ",") + + "]"); + } + deps_used.addAll(units); + } + } + } + } + + log.info( + "Using [" + + used_classes.size() + + "] jdependency clazzes as entrypoints from traces and reachable constructs"); + + log.info("[" + cp.getUnits().length + "] classpathUnits in jdependency classpath object"); + + // also collect "missing" classes to be able to check their relation with jre objects considered + // used + // to be removed from final version + SortedSet missing = new TreeSet(); + for (Clazz c : cp.getMissingClazzes()) { + missing.add(c); + } + + // Classes considered used + final SortedSet needed = new TreeSet(); + final Set classes = cp.getClazzes(); + // loop over classpathunits (representing the application) marked as entrypoints to find needed + // classes + for (ClazzpathUnit u : app) { + classes.removeAll(u.getClazzes()); + // TODO: check if getDependencies is also needed or getTransitiveDependencies sufficies + classes.removeAll(u.getDependencies()); + classes.removeAll(u.getTransitiveDependencies()); + needed.addAll(u.getClazzes()); + needed.addAll(u.getDependencies()); + needed.addAll(u.getTransitiveDependencies()); + + // loop over dependent classes to add their units among the used dependencies + for (Clazz c : u.getDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); + } + for (Clazz c : u.getTransitiveDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); + } + } + + // loop over class (representing traces and reachable constructs) marked as entrypoints to find + // needed classes + for (Clazz c : used_classes) { + classes.remove(c); + classes.removeAll(c.getDependencies()); + classes.removeAll(c.getTransitiveDependencies()); + needed.add(c); + needed.addAll(c.getDependencies()); + needed.addAll(c.getTransitiveDependencies()); + + // loop over dependent classes to add their units among the used dependencies + for (Clazz cc : c.getDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + for (Clazz cc : c.getTransitiveDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + } + final SortedSet removable = new TreeSet(classes); + + log.info("Needed classes: [" + needed.size() + "]"); + log.info("Removable classes: [" + removable.size() + "]"); + log.info("Used dependencies: [" + deps_used.size() + "] out of [" + maven_deps.size() + "]"); + + maven_deps.removeAll(deps_used); + + // Write names of needed/removable classes and dependencies to disk + try { + File f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "removable-classes.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(removable, System.lineSeparator())); + log.info("List of removable classes written to [" + f.toPath() + "]"); + + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "needed-classes.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); + log.info("List of needed classes written to [" + f.toPath() + "]"); + + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "missing-classes.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(missing, System.lineSeparator())); + log.info("List of missing classes written to [" + f.toPath() + "]"); + + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "removable-deps.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); + log.info("List of removable dependencies written to [" + f.toPath() + "]"); + } catch (IOException e) { + e.printStackTrace(); + } } /** {@inheritDoc} */ - @Override - public void setTraces(Set _traces){ - this.traces = _traces; + @Override + public void setTraces(Set _traces) { + this.traces = _traces; } /** {@inheritDoc} */ - @Override - public void setReachableConstructIds(Set _deps){ - this.dependencies = _deps; + @Override + public void setReachableConstructIds(Set _deps) { + this.dependencies = _deps; } } diff --git a/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java b/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java index c05d06cbb..25b8aa7d4 100755 --- a/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java +++ b/lang/src/main/java/org/eclipse/steady/backend/BackendConnector.java @@ -720,7 +720,7 @@ public Set getAppDependencies(GoalContext _ctx, @NotNull Application (org.eclipse.steady.shared.json.model.Dependency[]) JacksonUtil.asObject(json, org.eclipse.steady.shared.json.model.Dependency[].class); else backend_deps = new org.eclipse.steady.shared.json.model.Dependency[] {}; - for(org.eclipse.steady.shared.json.model.Dependency d: backend_deps) { + for (org.eclipse.steady.shared.json.model.Dependency d : backend_deps) { d.setApp(_app); } deps.addAll(Arrays.asList(backend_deps)); diff --git a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java index c8d28c8ec..4ff13ac44 100644 --- a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java +++ b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java @@ -20,18 +20,14 @@ import java.nio.file.Paths; import java.util.ServiceLoader; -import java.util.Set; import org.apache.logging.log4j.Logger; import org.eclipse.steady.backend.BackendConnector; import org.eclipse.steady.core.util.CoreConfiguration; -import org.eclipse.steady.malice.MaliciousnessAnalysisResult; -import org.eclipse.steady.malice.MaliciousnessAnalyzerLoop; import org.eclipse.steady.shared.enums.GoalType; import org.eclipse.steady.shared.json.model.Application; import org.eclipse.steady.shared.json.model.Dependency; import org.eclipse.steady.shared.json.model.Library; -import org.eclipse.steady.tasks.BomTask; import org.eclipse.steady.tasks.DebloatTask; /** @@ -48,15 +44,15 @@ public DebloatGoal() { super(GoalType.DEBLOAT); } -// /** -// * {@inheritDoc} -// * -// * Evaluates the configuration setting {@link CoreConfiguration#APP_PREFIXES}. -// */ -// @Override -// protected void prepareExecution() throws GoalConfigurationException { -// super.prepareExecution(); -// } + // /** + // * {@inheritDoc} + // * + // * Evaluates the configuration setting {@link CoreConfiguration#APP_PREFIXES}. + // */ + // @Override + // protected void prepareExecution() throws GoalConfigurationException { + // super.prepareExecution(); + // } /** {@inheritDoc} */ @Override @@ -69,11 +65,12 @@ protected void executeTasks() throws Exception { final ServiceLoader loader = ServiceLoader.load(DebloatTask.class); for (DebloatTask t : loader) { try { - + // Configure t.setApplication(a); t.setTraces(BackendConnector.getInstance().getAppTraces(this.getGoalContext(), a)); - t.setReachableConstructIds(BackendConnector.getInstance().getAppDependencies(this.getGoalContext(), a)); + t.setReachableConstructIds( + BackendConnector.getInstance().getAppDependencies(this.getGoalContext(), a)); t.setSearchPaths(this.getAppPaths()); t.setGoalClient(this.getGoalClient()); t.setKnownDependencies(this.getKnownDependencies()); @@ -82,19 +79,16 @@ protected void executeTasks() throws Exception { // Execute t.execute(); t.cleanUp(); - // t.getNeededConstructs(); + // t.getNeededConstructs(); } catch (Exception e) { log.error("Error running task " + t + ": " + e.getMessage(), e); } } - // Upload libraries and binaries (if requested) if (a.getDependencies() != null) { for (Dependency dep : a.getDependencies()) { - - // Upload lib final Library lib = dep.getLib(); if (lib != null) { diff --git a/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java b/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java index cd18901f4..bf404d35d 100755 --- a/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java +++ b/lang/src/main/java/org/eclipse/steady/goals/GoalFactory.java @@ -118,8 +118,8 @@ public static AbstractGoal create(@NotNull GoalType _type) "Cannot create instance of class [" + clazzname + "]: " + e.getMessage()); } } else if (_type.equals(GoalType.DEBLOAT)) { - goal = new DebloatGoal(); - }else { + goal = new DebloatGoal(); + } else { throw new IllegalArgumentException("Goal [" + _type + "] is not supported"); } return goal; diff --git a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java index e797c5fc5..de9cfad1e 100644 --- a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java +++ b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java @@ -24,32 +24,32 @@ import org.eclipse.steady.shared.json.model.Dependency; /** - * Methods required to + * Methods required to */ public interface DebloatTask extends Task { -// /** -// * Returns the {@link Application} including (a) all its {@link Construct}s of the respective {@link ProgrammingLanguage}, -// * and (b) the {@link Dependency}s of that application. The {@link Library} of each {@link Dependency} must contain -// * all details such as its {@link Construct}s and properties. -// * -// * @return a {@link org.eclipse.steady.shared.json.model.Application} object. -// */ -// public Set getNeededConstructs(); - - /** - * Sets the traced constructs to be used as starting point for debloating the {@link Application} + // /** + // * Returns the {@link Application} including (a) all its {@link Construct}s of the respective + // {@link ProgrammingLanguage}, + // * and (b) the {@link Dependency}s of that application. The {@link Library} of each {@link + // Dependency} must contain + // * all details such as its {@link Construct}s and properties. + // * + // * @return a {@link org.eclipse.steady.shared.json.model.Application} object. + // */ + // public Set getNeededConstructs(); + + /** + * Sets the traced constructs to be used as starting point for debloating the {@link Application} * (traces resulting from the dynamic analysis) * */ - public void setTraces(Set _traces); - - /** - * Sets the reachable constructs to be used as starting point for debloating the {@link Application} - * (resulting from the static analysis) - * - */ - public void setReachableConstructIds(Set _deps); - + public void setTraces(Set _traces); + /** + * Sets the reachable constructs to be used as starting point for debloating the {@link Application} + * (resulting from the static analysis) + * + */ + public void setReachableConstructIds(Set _deps); } diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java index 68943e2fa..5acdc191a 100644 --- a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java @@ -147,8 +147,8 @@ public final void prepareConfiguration() throws Exception { CoreConfiguration.REP_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "report").toString()); this.vulasConfiguration.setPropertyIfEmpty( - CoreConfiguration.SLICING_DIR, - Paths.get(this.project.getBuild().getDirectory(), "vulas", "slicing").toString()); + CoreConfiguration.SLICING_DIR, + Paths.get(this.project.getBuild().getDirectory(), "vulas", "debloat").toString()); // Read app constructs from src/main/java and target/classes final String p = diff --git a/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java b/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java index ec0174e06..7c98aea36 100644 --- a/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java +++ b/shared/src/test/java/org/eclipse/steady/shared/model/ApplicationTest.java @@ -46,12 +46,12 @@ public void testArgumentTooLong() { public void testAppReachDeserialization() { try { String json = FileUtil.readFile("./src/test/resources/appReachConstructIds.json"); - org.eclipse.steady.shared.json.model.Dependency[] backend_deps = (org.eclipse.steady.shared.json.model.Dependency[]) JacksonUtil - .asObject(json, org.eclipse.steady.shared.json.model.Dependency[].class); + org.eclipse.steady.shared.json.model.Dependency[] backend_deps = + (org.eclipse.steady.shared.json.model.Dependency[]) + JacksonUtil.asObject(json, org.eclipse.steady.shared.json.model.Dependency[].class); assertNotNull(backend_deps[0].getReachableConstructIds()); } catch (IOException e) { - assert(false); + assert (false); } - } } diff --git a/shared/src/test/resources/appReachConstructIds.json b/shared/src/test/resources/appReachConstructIds.json new file mode 100644 index 000000000..eedf8e0ad --- /dev/null +++ b/shared/src/test/resources/appReachConstructIds.json @@ -0,0 +1,2621 @@ +[ + { + "lib": { + "digest": "16CF5A6B78951F50713D29BFAE3230A611DC01F0", + "sha1": "16CF5A6B78951F50713D29BFAE3230A611DC01F0", + "digestAlgorithm": "SHA1", + "createdAt": "2016-12-21T17:46:16.701+0000", + "modifiedAt": "2021-07-22T09:26:14.455+0000", + "properties": [ + { + "source": "JAVA_MANIFEST", + "name": "Manifest-Version", + "value": "1.0" + }, + { + "source": "JAVA_MANIFEST", + "name": "Archiver-Version", + "value": "Plexus Archiver" + }, + { + "source": "JAVA_MANIFEST", + "name": "Created-By", + "value": "Apache Maven" + }, + { + "source": "JAVA_MANIFEST", + "name": "Implementation-Vendor-Id", + "value": "org.apache" + }, + { + "source": "JAVA_MANIFEST", + "name": "Specification-Vendor", + "value": "The Apache Software Foundation" + }, + { + "source": "JAVA_MANIFEST", + "name": "Implementation-Vendor", + "value": "The Apache Software Foundation" + }, + { + "source": "JAVA_MANIFEST", + "name": "X-Compile-Target-JDK", + "value": "1.5" + }, + { + "source": "JAVA_MANIFEST", + "name": "X-Compile-Source-JDK", + "value": "1.5" + }, + { + "source": "JAVA_MANIFEST", + "name": "Build-Jdk", + "value": "1.5.0_22" + }, + { + "source": "JAVA_MANIFEST", + "name": "Implementation-Title", + "value": "HttpComponents HttpClient" + }, + { + "source": "JAVA_MANIFEST", + "name": "Implementation-Version", + "value": "4.1.3" + }, + { + "source": "JAVA_MANIFEST", + "name": "Built-By", + "value": "oleg" + }, + { + "source": "JAVA_MANIFEST", + "name": "Specification-Title", + "value": "HttpComponents HttpClient" + }, + { + "source": "JAVA_MANIFEST", + "name": "url", + "value": "http://hc.apache.org/httpcomponents-client" + }, + { + "source": "JAVA_MANIFEST", + "name": "Implementation-Build", + "value": "tags/4.1.3-RC1/httpclient@r1239556; 2012-02-02 13:14:24+0100" + }, + { + "source": "JAVA_MANIFEST", + "name": "Specification-Version", + "value": "4.1.3" + } + ], + "libraryId": { + "artifact": "httpclient", + "version": "4.1.3", + "group": "org.apache.httpcomponents" + }, + "bundledLibraryIds": [ + { + "artifact": "httpclient", + "version": "4.1.3", + "group": "org.apache.httpcomponents" + } + ], + "wellknownDigest": true, + "digestTimestamp": "2012-02-02T12:15:19.000+0000", + "digestVerificationUrl": "http://search.maven.org/solrsearch/select?q=1:16CF5A6B78951F50713D29BFAE3230A611DC01F0&rows=20&wt=json", + "developedIn": [ + "JAVA" + ], + "constructTypeCounters": { + "FUNC": 0, + "CLASS": 206, + "countExecutable": 1488, + "INTF": 63, + "ENUM": 4, + "INIT": 18, + "CONS": 305, + "METH": 1165, + "MODU": 0, + "countTotal": 1783, + "PACK": 22 + } + }, + "parent": null, + "origin": null, + "declared": true, + "traced": true, + "scope": "COMPILE", + "transitive": false, + "filename": "httpclient-4.1.3.jar", + "path": "/Users/foo/.m2/repository/org/apache/httpcomponents/httpclient/4.1.3/httpclient-4.1.3.jar", + "relativePath": null, + "reachableConstructIds": [ + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultUserTokenHandler.getUserToken(HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.hasThread()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.getWrappedConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.close()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createConnectionReuseStrategy()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.wrapRequest(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.DefaultHttpRoutePlanner(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.notifyWaitingThread(RouteSpecificPool)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.abortConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.getCredentials()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpGet(URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(HttpRequest,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.execute(HttpHost,HttpRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultHttpRequestRetryHandler()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestProxyAuthentication()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer.getMetrics()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.shutdown()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.BrowserCompatSpecFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRedirectStrategy.isRedirected(HttpRequest,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.isStale()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.shutdown()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.handleResponse(RoutedRequest,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.HttpRoute(InetAddress,HttpHost,HttpHost[],boolean,TunnelType,LayerType)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RoutedRequest.getRequest()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.shutdownEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.streamAbort(InputStream)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.getURI()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.isTunnelled()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.AbstractConnPool()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.RouteTracker(HttpHost,InetAddress)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createHttpRequestRetryHandler()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.auth.MalformedChallengeException(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.ClientProtocolException(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.closeConnection(BasicPoolEntry)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultHttpClient(ClientConnectionManager)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnPerRouteBean.getMaxForRoute(HttpRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultResponseParser.parseHead(SessionInputBuffer)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getURI()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.tunnelProxy(HttpHost,boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.ResponseAuthCache()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.removeThread(WaitingThread)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.getRoute()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.params.HttpClientParams.isRedirecting(HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.toRoute()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getHttpProcessor()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getExecCount()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getRequestExecutor()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.abortConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RedirectLocations.add(URI)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.cookie.CookieSpecRegistry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.getState()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.detach()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.AbstractVerifier()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$PoolEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getFreeEntry(RouteSpecificPool,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createHttpContext()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.setAuthScope(AuthScope)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.determineParams(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.RFC2109SpecFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.getProxyHost()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.finalize()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.closeIdleConnections(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer.isEof()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getRequestLine()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.read(byte[])" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.getScheme(HttpHost)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.shutdown()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpHead(URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory.createSSLContext(String,KeyStore,String,KeyStore,SecureRandom,TrustStrategy)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.isUnused()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.createRouteToPoolMap()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.tunnelTarget(boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.isMarkedReusable()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.openCompleted(boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.HttpRoute(HttpHost,InetAddress,HttpHost[],boolean,TunnelType,LayerType)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.StrictHostnameVerifier()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(Socket,int,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.rewriteRequestURI(RequestWrapper,HttpRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getConnectionReuseStrategy()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.auth.BasicSchemeFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpHead.getMethod()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.RouteInfo$LayerType(String,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultUserTokenHandler.getAuthPrincipal(AuthState)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.Scheme.getName()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPoolEntry.updateExpiry(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.checkClose()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultHttpClient.createHttpProcessor()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getProtocolProcessor()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.isTunnelled()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ConnectionPoolTimeoutException(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.Wire(Log)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.RedirectLocations()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.open(HttpRoute,HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.RFC2965SpecFactory()" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.routing.HttpRoute." + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.auth.AuthScope." + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter.getManager()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getTargetAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.getManager()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1(WaitingThreadAborter,HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.close()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.incrementExecCount()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(CharArrayBuffer)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.requestConnection(HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.input(byte[])" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.BasicCookieStore()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.layerProtocol(boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.sendRequestHeader(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getConnectionManager()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.createConnectionOperator(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper$EntityWrapper.writeTo(OutputStream)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.auth.AuthenticationException(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer.writeLine(CharArrayBuffer)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.PlainSocketFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.extractHost(URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler.getAuthPreferences()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.ConnectionShutdownException()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.deleteEntry(BasicPoolEntry)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute(ClientConnectionOperator,ConnPerRoute,int,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getOriginal()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getCookieSpecs()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.auth.NegotiateSchemeFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createCookieSpecRegistry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.finalize()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.RedirectException(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.newRouteSpecificPool(HttpRoute)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.AbstractHttpClient(ClientConnectionManager,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.WaitingThread.await(Date)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.BasicManagedEntity(HttpEntity,ManagedClientConnection,boolean)" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.routing.RouteInfo$LayerType." + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper$EntityWrapper(HttpEntity)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.HttpInetSocketAddress(HttpHost,InetAddress,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer.isDataAvailable(int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer.getMetrics()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper.expectContinue()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.HttpRoute(HttpHost,InetAddress,boolean)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ConnectTimeoutException(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.DefaultResponseParser(SessionInputBuffer,LineParser,HttpResponseFactory,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy.getKeepAliveDuration(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.assertValid(AbstractPoolEntry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.setURI(URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.tryConnect(RoutedRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.output(byte[])" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.createFreeConnQueue()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.setCredentials(Credentials)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter(ThreadSafeClientConnManager,AbstractPoolEntry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.requestPoolEntry(HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer.write(byte[],int,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.toChain(HttpHost)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthSchemeRegistry.register(String,AuthSchemeFactory)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.getPoolEntry()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.WaitingThread(Condition,RouteSpecificPool)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPoolEntry.getPlannedRoute()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getConnectionKeepAliveStrategy()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultHttpRequestRetryHandler.handleAsIdempotent(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.isReadAllowed()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.freeEntry(BasicPoolEntry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.removeDotSegments(URI)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.cookie.CookieIdentityComparator()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter(ClientConnectionManager,OperatedClientConnection)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.isRepeatable()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.releaseConnection()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.auth.AuthState()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getRoutePool(HttpRoute,boolean)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.NonRepeatableRequestException(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getParams()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.SchemeRegistry()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter(PoolEntry,HttpRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.sendRequestHeader(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createHttpRoutePlanner()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.BrowserCompatHostnameVerifier()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createCookieStore()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.getHopTarget(int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.releaseManagedConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.resetHeaders()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.getLocalAddress()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.connectProxy(HttpHost,boolean)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.auth.AuthScope(String,int,String,String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnRouteParams.getDefaultProxy(HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createTargetAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.flush()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter.detach()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator.prepareSocket(Socket,HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper(HttpEntityEnclosingRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper.setEntity(HttpEntity)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.BestMatchSpecFactory()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor(SocketFactory)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseEntity(HttpResponse)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultProxyAuthenticationHandler.getAuthPreferences(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.deleteLeastUsedEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper.isRepeatable()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.RouteInfo$TunnelType(String,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultHttpClient.setDefaultHttpParams(HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.invalidate()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestDefaultHeaders()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultTargetAuthenticationHandler.getAuthPreferences(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.isRepeatable()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.createResponseParser(SessionInputBuffer,HttpResponseFactory,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.BasicPoolEntry(ClientConnectionOperator,HttpRoute,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.BasicRouteDirector.directStep(RouteInfo,RouteInfo)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(HttpRequest,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.tryExecute(RoutedRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.isOpen()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.setIdleDuration(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.setSocketTimeout(int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.setState(Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.streamClosed(InputStream)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.tunnelTarget(boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpGet(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.open(HttpRoute,HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultHttpRoutePlanner.determineRoute(HttpHost,HttpRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.auth.NTLMSchemeFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.createEntry(RouteSpecificPool,ClientConnectionOperator)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool(HttpRoute,ConnPerRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.register(Scheme)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$PoolEntry.shutdown()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.AllowAllHostnameVerifier()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getCookieStore()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.RequestWrapper(HttpRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPoolEntry.getConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createUserTokenHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.releaseConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createCredentialsProvider()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(OperatedClientConnection,HttpHost,InetAddress,HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.determineTarget(HttpUriRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultProxyAuthenticationHandler.getChallenges(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.WaitingThreadAborter.setWaitingThread(WaitingThread)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.setURI(URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter.getPoolEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.getRoute()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.WaitingThread.interrupt()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.getMaxEntries()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.ClientParamsStack(HttpParams,HttpParams,HttpParams,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.establishRoute(HttpRoute,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry(ClientConnectionOperator,HttpRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.PlainSocketFactory.getSocketFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.update(Socket,HttpHost,boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.isResponseAvailable(int)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultProxyAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createProxyAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultRequestDirector(Log,HttpRequestExecutor,ClientConnectionManager,ConnectionReuseStrategy,ConnectionKeepAliveStrategy,HttpRoutePlanner,HttpProcessor,HttpRequestRetryHandler,RedirectStrategy,AuthenticationHandler,AuthenticationHandler,UserTokenHandler,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.isReleased()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.assertStillUp()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getRoutePlanner()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.queueThread(WaitingThread)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler.selectScheme(Map,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.RouteTracker(HttpRoute)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$PoolEntry.close()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.auth.AuthSchemeRegistry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.setAuthScheme(AuthScheme)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultHttpRequestRetryHandler.retryRequest(IOException,int,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultTargetAuthenticationHandler.getChallenges(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer.flush()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.SingleClientConnManager$1(HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.get(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.auth.NegotiateSchemeFactory(SpnegoTokenGenerator,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.normalizePath(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.params.ConnManagerParams$1()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultHttpClient.createHttpParams()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.BasicRouteDirector.nextStep(RouteInfo,RouteInfo)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.tunnelProxy(HttpHost,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.markReusable()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.processChallenges(Map,AuthState,AuthenticationHandler,HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestAuthCache()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.getCapacity()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.createSessionOutputBuffer(Socket,int,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.execute(HttpHost,HttpRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.sendRequestEntity(HttpEntityEnclosingRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.writeTo(OutputStream)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.getSchemeRegistry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper.getEntity()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.execute(HttpUriRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.allocEntry(Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.output(byte[],int,int)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory(SSLContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.isSecure()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1(PoolEntryRequest,HttpRoute)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestTargetAuthentication()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.getHopCount()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.getScheme(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.Scheme(String,int,SchemeSocketFactory)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.enabled()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.createURI(String,String,int,String,String,String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.input(byte[],int,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.layerProtocol(HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.ClientParamsStack.getParameter(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler.parseChallenges(Header[])" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.HttpRoute(HttpHost)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.deleteEntry(BasicPoolEntry)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.IgnoreSpecFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.execute(HttpUriRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.BasicRouteDirector()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.toChain(HttpHost[])" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnRouteParams.getForcedRoute(HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.TrustManagerDecorator(X509TrustManager,TrustStrategy)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.params.HttpClientParams.isAuthenticating(HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpGet.getMethod()" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.params.ConnRouteParams." + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.connectTarget(boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.BasicRouteDirector.proxiedStep(RouteInfo,RouteInfo)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.IdleConnectionHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getAuthSchemes()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createConnectionKeepAliveStrategy()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.TunnelRefusedException(String,HttpResponse)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.freeEntry(BasicPoolEntry,boolean,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.releaseConnection(ManagedClientConnection,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultProxyAuthenticationHandler.isAuthenticationRequested(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultTargetAuthenticationHandler.isAuthenticationRequested(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RoutedRequest.getRoute()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getHttpRequestRetryHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.updateAuthState(AuthState,HttpHost,CredentialsProvider)" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.routing.RouteInfo$TunnelType." + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultRedirectStrategy()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.checkEOF(int)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.Scheme(String,SocketFactory,int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator.updateSecureConnection(OperatedClientConnection,HttpHost,HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultTargetAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.createdEntry(BasicPoolEntry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.isLayered()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.getConnection(HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.tunnelTarget(boolean)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestAddCookies()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.RequestClientConnControl()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer(SessionOutputBuffer,Wire,String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.setConnectionRequest(ClientConnectionRequest)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RedirectLocations.contains(URI)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.RoutedRequest(RequestWrapper,HttpRoute)" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory." + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.isLayered()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpRequestBase()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.SingleClientConnManager(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.closeExpiredConnections()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.params.ConnPerRouteBean(int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.BasicRouteDirector.firstStep(RouteInfo)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.getProtocolVersion()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.unmarkReusable()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.equals(Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.isValid()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.createTunnelToProxy(HttpRoute,int,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.DefaultClientConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRedirectStrategy.createLocationURI(String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.tunnelProxy(HttpHost,boolean,HttpParams)" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.params.ConnManagerParams." + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.setReleaseTrigger(ConnectionReleaseTrigger)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getProxyAuthenticationHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createClientRequestDirector(HttpRequestExecutor,ClientConnectionManager,ConnectionReuseStrategy,ConnectionKeepAliveStrategy,HttpRoutePlanner,HttpProcessor,HttpRequestRetryHandler,RedirectStrategy,AuthenticationHandler,AuthenticationHandler,UserTokenHandler,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnManagerParams.getTimeout(HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnRouteParams.getLocalAddress(HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.resolve(URI,URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.Wire.wire(String,InputStream)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.BasicCredentialsProvider()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.WaitingThreadAborter()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.getSocket()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(HttpRoute,Object,long,TimeUnit,WaitingThreadAborter)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.ensureConsumed()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.invalidateAuthIfSuccessful(AuthState)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.EofSensorInputStream(InputStream,EofSensorWatcher)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer.read(byte[],int,int)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.HttpHostConnectException(HttpHost,ConnectException)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.shutdown()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.createWaitingThreadQueue()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.createTunnelToTarget(HttpRoute,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.NonRepeatableRequestException(String,Throwable)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getProtocolVersion()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.newWaitingThread(Condition,RouteSpecificPool)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultHttpRequestRetryHandler(int,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.setState(Object)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.determineRoute(HttpHost,HttpRequest,HttpContext)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.auth.DigestSchemeFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SingleClientConnManager.requestConnection(HttpRoute,Object)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.LayeredSchemeSocketFactoryAdaptor(LayeredSocketFactory)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractClientConnAdapter.assertValid(OperatedClientConnection)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.auth.AuthState.getAuthScheme()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.RequestWrapper.getMethod()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.SchemeRegistryFactory.createDefault()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createRequestExecutor()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.EntityEnclosingRequestWrapper.access$002(EntityEnclosingRequestWrapper,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.eofDetected(InputStream)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.ClientProtocolException(Throwable)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.BasicManagedEntity.getContent()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.LoggingSessionInputBuffer(SessionInputBuffer,Wire,String)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.EofSensorInputStream.checkAbort()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter.detach()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.routing.HttpRoute(HttpHost,InetAddress,HttpHost,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator.resolveHostname(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.CircularRedirectException(String)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultUserTokenHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.cookie.CookieSpecRegistry.register(String,CookieSpecFactory)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.getTargetHost()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.AbstractPoolEntry.layerProtocol(HttpContext,HttpParams)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.params.ConnPerRouteBean.setDefaultMaxPerRoute(int)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.access$000(ThreadSafeClientConnManager)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.createAuthSchemeRegistry()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.cookie.NetscapeDraftSpecFactory()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getCredentialsProvider()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getRedirectStrategy()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionOperator(SchemeRegistry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.rewriteURI(URI,HttpHost)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnectionOperator.createConnection()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.getUserTokenHandler()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.dropEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.releaseConnection(ManagedClientConnection,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ConnPoolByRoute.shutdown()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.BasicPoolEntry.shutdownEntry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler.getAuthPreferences(HttpResponse,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.rewriteURI(URI,HttpHost,boolean)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.DefaultRequestDirector.createConnectRequest(HttpRoute,HttpContext)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.RouteSpecificPool.nextThread()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionPool(long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager(SchemeRegistry,long,TimeUnit)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.RouteTracker.isConnected()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.isSecure()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.utils.URIUtils.resolveReferenceStartingWithQueryString(URI,URI)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.routing.HttpRoute.getTargetHost()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.protocol.ResponseProcessCookies()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.client.methods.HttpRequestBase.getRequestLine()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory(SSLContext,X509HostnameVerifier)" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.params.ConnPerRouteBean()" + }, + { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.AbstractPooledConnAdapter(ClientConnectionManager,AbstractPoolEntry)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.getSchemeRegistry()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.TunnelRefusedException.getResponse()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.close()" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.DefaultClientConnection.opening(Socket,HttpHost)" + }, + { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.conn.LoggingSessionOutputBuffer.writeLine(String)" + }, + { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.impl.client.AbstractAuthenticationHandler." + } + ], + "touchPoints": [ + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.Scheme(String,SocketFactory,int)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.register(Scheme)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory." + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.execute(HttpUriRequest)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.PlainSocketFactory()" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.conn.scheme.SchemeRegistry.register(Scheme)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpGet(String)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.Scheme(String,SocketFactory,int)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.SchemeRegistry()" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultHttpClient(ClientConnectionManager)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.SchemeRegistry()" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory(SSLContext,X509HostnameVerifier)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager(SchemeRegistry)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory(SSLContext,X509HostnameVerifier)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager(SchemeRegistry)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.conn.scheme.PlainSocketFactory()" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "METH", + "qname": "org.apache.http.impl.client.AbstractHttpClient.execute(HttpUriRequest)" + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "INIT", + "qname": "org.apache.http.conn.ssl.SSLSocketFactory." + }, + "direction": "A2L", + "source": "X2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.client.methods.HttpGet(String)" + }, + "direction": "A2L", + "source": "A2C" + }, + { + "from": { + "lang": "JAVA", + "type": "METH", + "qname": "com.acme.foo.ArchivePrinter.httpRequest2(String)" + }, + "to": { + "lang": "JAVA", + "type": "CONS", + "qname": "org.apache.http.impl.client.DefaultHttpClient(ClientConnectionManager)" + }, + "direction": "A2L", + "source": "X2C" + } + ], + "reachableConstructTypeCounters": { + "FUNC": 0, + "CLASS": 0, + "countExecutable": 438, + "INTF": 0, + "ENUM": 0, + "INIT": 8, + "CONS": 116, + "METH": 314, + "MODU": 0, + "countTotal": 438, + "PACK": 0 + }, + "tracedConstructTypeCounters": null + } +] \ No newline at end of file From ad12b455e0173faa20ea6b3100f70464fb8b29a2 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:29:00 +0200 Subject: [PATCH 19/29] removed useless code and improved handling of jdependency results --- .../steady/java/tasks/JavaDebloatTask.java | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index a2b10a2a9..ec0573694 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -183,22 +183,15 @@ public void execute() throws GoalExecutionException { // Classes considered used final SortedSet needed = new TreeSet(); - final Set classes = cp.getClazzes(); + final Set removable = cp.getClazzes(); // loop over classpathunits (representing the application) marked as entrypoints to find needed // classes for (ClazzpathUnit u : app) { - classes.removeAll(u.getClazzes()); - // TODO: check if getDependencies is also needed or getTransitiveDependencies sufficies - classes.removeAll(u.getDependencies()); - classes.removeAll(u.getTransitiveDependencies()); + removable.removeAll(u.getClazzes()); + removable.removeAll(u.getTransitiveDependencies()); needed.addAll(u.getClazzes()); - needed.addAll(u.getDependencies()); needed.addAll(u.getTransitiveDependencies()); - // loop over dependent classes to add their units among the used dependencies - for (Clazz c : u.getDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); - } for (Clazz c : u.getTransitiveDependencies()) { deps_used.addAll(c.getClazzpathUnits()); } @@ -207,25 +200,26 @@ public void execute() throws GoalExecutionException { // loop over class (representing traces and reachable constructs) marked as entrypoints to find // needed classes for (Clazz c : used_classes) { - classes.remove(c); - classes.removeAll(c.getDependencies()); - classes.removeAll(c.getTransitiveDependencies()); - needed.add(c); - needed.addAll(c.getDependencies()); - needed.addAll(c.getTransitiveDependencies()); - - // loop over dependent classes to add their units among the used dependencies - for (Clazz cc : c.getDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } - for (Clazz cc : c.getTransitiveDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } + if(removable.contains(c)) { + removable.remove(c); + removable.removeAll(c.getTransitiveDependencies()); + needed.add(c); + needed.addAll(c.getTransitiveDependencies()); + + for (Clazz cc : c.getTransitiveDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + } } - final SortedSet removable = new TreeSet(classes); + final SortedSet removable_sorted = new TreeSet(removable); + Set remaining = cp.getClazzes(); + remaining.removeAll(removable_sorted); + final SortedSet remaining_sorted = new TreeSet(removable); + log.info("jdependency classpath classes size: [" + cp.getClazzes().size() + "]"); log.info("Needed classes: [" + needed.size() + "]"); - log.info("Removable classes: [" + removable.size() + "]"); + log.info("Needed by difference: [" + remaining_sorted.size() + "]"); + log.info("Removable classes: [" + removable_sorted.size() + "]"); log.info("Used dependencies: [" + deps_used.size() + "] out of [" + maven_deps.size() + "]"); maven_deps.removeAll(deps_used); @@ -237,7 +231,7 @@ public void execute() throws GoalExecutionException { this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), "removable-classes.txt") .toFile(); - FileUtil.writeToFile(f, StringUtil.join(removable, System.lineSeparator())); + FileUtil.writeToFile(f, StringUtil.join(removable_sorted, System.lineSeparator())); log.info("List of removable classes written to [" + f.toPath() + "]"); f = @@ -247,6 +241,14 @@ public void execute() throws GoalExecutionException { .toFile(); FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); log.info("List of needed classes written to [" + f.toPath() + "]"); + + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "remaining-classes.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(remaining_sorted, System.lineSeparator())); + log.info("List of remaining classes written to [" + f.toPath() + "]"); f = Paths.get( From 139cca78321942c0c9f09a5d0e5dfff3374acfd5 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:29:28 +0200 Subject: [PATCH 20/29] only use compile and runtime dependency in goal debloat --- .../main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java index 82c666f3c..02cb78256 100644 --- a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/MvnPluginDebloat.java @@ -30,7 +30,7 @@ @Mojo( name = "debloat", defaultPhase = LifecyclePhase.PROCESS_CLASSES, - requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyResolution = ResolutionScope.RUNTIME, requiresOnline = true) public class MvnPluginDebloat extends AbstractVulasMojo { From 431f28a7b53b4e3c10a199cb406dc221f4d91022 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Tue, 12 Oct 2021 18:26:43 +0200 Subject: [PATCH 21/29] started adding test to entrypoints --- .../steady/java/tasks/JavaDebloatTask.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index ec0573694..e8ce70eff 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -76,8 +76,11 @@ public void execute() throws GoalExecutionException { final Clazzpath cp = new Clazzpath(); - // list of classpathunits to be used as entrypoints + // list of classpathunits to be used as application entrypoints List app = new ArrayList(); + // list of classpathunits to be used as test entrypoints + List test = new ArrayList(); + // list of classes to be used as entrypoints (from traces and reachable constructs) List used_classes = new ArrayList(); // classpathunits for the application dependencies (as identified by maven) @@ -90,8 +93,14 @@ public void execute() throws GoalExecutionException { // 1) Add application paths (to be then used as entrypoints) if (this.hasSearchPath()) { for (Path p : this.getSearchPath()) { - log.info("Add app path [" + p + "] to classpath"); - app.add(cp.addClazzpathUnit(p)); + if (p.toString().contains(File.separator+"test"+File.separator)) { + log.info("Add test path [" + p + "] to classpath"); + test.add(cp.addClazzpathUnit(p)); + } + else { + log.info("Add app path [" + p + "] to classpath"); + app.add(cp.addClazzpathUnit(p)); + } } } // 2) Add dependencies to jdependency classpath object and populate set of dependencies @@ -106,6 +115,7 @@ public void execute() throws GoalExecutionException { } log.info("[" + app.size() + "] ClasspathUnit for the application to be used as entrypoints "); + log.info("[" + test.size() + "] ClasspathUnit for tests to be used as entrypoints "); // Retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple // classpathUnits) From 7ae7486b2376bd638fbb6ccafb1ae42a4b473a72 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 13 Oct 2021 13:49:48 +0200 Subject: [PATCH 22/29] added debloating using test classes (set as new config value) --- .../steady/java/tasks/JavaDebloatTask.java | 56 +++++++++++++++---- .../steady/core/util/CoreConfiguration.java | 2 + .../steady/java/mvn/AbstractVulasMojo.java | 5 ++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index e8ce70eff..3cd78352c 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -92,17 +92,17 @@ public void execute() throws GoalExecutionException { try { // 1) Add application paths (to be then used as entrypoints) if (this.hasSearchPath()) { - for (Path p : this.getSearchPath()) { - if (p.toString().contains(File.separator+"test"+File.separator)) { - log.info("Add test path [" + p + "] to classpath"); - test.add(cp.addClazzpathUnit(p)); - } - else { - log.info("Add app path [" + p + "] to classpath"); - app.add(cp.addClazzpathUnit(p)); - } + for (Path p : this.getSearchPath()) { + log.info("Add app path [" + p + "] to classpath"); + app.add(cp.addClazzpathUnit(p)); } } + for (Path p : FileUtil.getPaths( + this.vulasConfiguration.getStringArray(CoreConfiguration.TEST_DIRS, null))) + { + log.info("Add test path [" + p + "] to classpath"); + test.add(cp.addClazzpathUnit(p)); + } // 2) Add dependencies to jdependency classpath object and populate set of dependencies if (this.getKnownDependencies() != null) { for (Path p : this.getKnownDependencies().keySet()) { @@ -220,12 +220,12 @@ public void execute() throws GoalExecutionException { deps_used.addAll(cc.getClazzpathUnits()); } } - } + } final SortedSet removable_sorted = new TreeSet(removable); Set remaining = cp.getClazzes(); remaining.removeAll(removable_sorted); - final SortedSet remaining_sorted = new TreeSet(removable); + final SortedSet remaining_sorted = new TreeSet(remaining); log.info("jdependency classpath classes size: [" + cp.getClazzes().size() + "]"); log.info("Needed classes: [" + needed.size() + "]"); log.info("Needed by difference: [" + remaining_sorted.size() + "]"); @@ -278,6 +278,40 @@ public void execute() throws GoalExecutionException { } catch (IOException e) { e.printStackTrace(); } + + // also consider test classes to find needed classes + for (ClazzpathUnit u : test) { + removable.removeAll(u.getClazzes()); + removable.removeAll(u.getTransitiveDependencies()); + needed.addAll(u.getClazzes()); + needed.addAll(u.getTransitiveDependencies()); + for (Clazz c : u.getTransitiveDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); + } + } + maven_deps.removeAll(deps_used); + log.info("Needed classes with test: [" + needed.size() + "]"); + log.info("Removable classes with test: [" + removable.size() + "]"); + log.info("Used dependencies with test: [" + deps_used.size() + "]"); + + try { + File f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "needed-classes-w-test.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); + log.info("List of needed classes with test written to [" + f.toPath() + "]"); + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "removable-deps-w-test.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); + log.info("List of removable dependencies with test written to [" + f.toPath() + "]"); + } catch (IOException e) { + e.printStackTrace(); + } } /** {@inheritDoc} */ diff --git a/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java b/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java index 4c0f45436..bd3bc8b2c 100755 --- a/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java +++ b/lang/src/main/java/org/eclipse/steady/core/util/CoreConfiguration.java @@ -104,6 +104,8 @@ public enum ConnectType { // BOM, fka APP /** Constant APP_DIRS="vulas.core.app.sourceDir" */ public static final String APP_DIRS = "vulas.core.app.sourceDir"; + /** Constant TEST_DIRS="vulas.core.app.testDir" */ + public static final String TEST_DIRS = "vulas.core.app.testDir"; /** Constant APP_PREFIXES="vulas.core.app.appPrefixes" */ public static final String APP_PREFIXES = "vulas.core.app.appPrefixes"; /** Constant APP_JAR_NAMES="vulas.core.app.appJarNames" */ diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java index 5acdc191a..eb84e2d25 100644 --- a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java @@ -156,6 +156,11 @@ public final void prepareConfiguration() throws Exception { + "," + Paths.get(this.project.getBuild().getSourceDirectory()).toString(); this.vulasConfiguration.setPropertyIfEmpty(CoreConfiguration.APP_DIRS, p); + + final String test_paths= Paths.get(this.project.getBuild().getTestOutputDirectory()).toString() + + "," + + Paths.get(this.project.getBuild().getTestSourceDirectory()).toString(); + this.vulasConfiguration.setPropertyIfEmpty(CoreConfiguration.TEST_DIRS,test_paths); // Test how-to get the reactor POM in a reliable manner // The following method call fails if Maven is called with option -pl From ec69c95aa3bc969124e296fd0891649aea71e7b5 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 10 Nov 2021 19:23:19 +0100 Subject: [PATCH 23/29] do not save app after debloating --- .../org/eclipse/steady/goals/DebloatGoal.java | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java index 4ff13ac44..c0b97bd50 100644 --- a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java +++ b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java @@ -86,56 +86,56 @@ protected void executeTasks() throws Exception { } // Upload libraries and binaries (if requested) - if (a.getDependencies() != null) { - for (Dependency dep : a.getDependencies()) { +// if (a.getDependencies() != null) { +// for (Dependency dep : a.getDependencies()) { +// +// // Upload lib +// final Library lib = dep.getLib(); +// if (lib != null) { +// if (lib.hasValidDigest()) { +// BackendConnector.getInstance().uploadLibrary(this.getGoalContext(), lib); +// if (CoreConfiguration.isJarUploadEnabled(this.getGoalContext().getVulasConfiguration())) +// BackendConnector.getInstance() +// .uploadLibraryFile(lib.getDigest(), Paths.get(dep.getPath())); +// } else { +// log.error("Library of dependency [" + dep + "] has no valid digest"); +// } +// } else { +// log.error("Dependency [" + dep + "] has no library"); +// } +// } +// } - // Upload lib - final Library lib = dep.getLib(); - if (lib != null) { - if (lib.hasValidDigest()) { - BackendConnector.getInstance().uploadLibrary(this.getGoalContext(), lib); - if (CoreConfiguration.isJarUploadEnabled(this.getGoalContext().getVulasConfiguration())) - BackendConnector.getInstance() - .uploadLibraryFile(lib.getDigest(), Paths.get(dep.getPath())); - } else { - log.error("Library of dependency [" + dep + "] has no valid digest"); - } - } else { - log.error("Dependency [" + dep + "] has no library"); - } - } - } - - final boolean upload_empty = - this.getConfiguration() - .getConfiguration() - .getBoolean(CoreConfiguration.APP_UPLOAD_EMPTY, false); - final boolean app_exists_in_backend = - BackendConnector.getInstance().isAppExisting(this.getGoalContext(), a); - - // Upload if non-empty or already exists in backend or empty ones shall be uploaded - if (!a.isEmpty() || app_exists_in_backend || upload_empty) { - log.info( - "Save app " - + a - + " with [" - + a.getDependencies().size() - + "] dependencies and [" - + a.getConstructs().size() - + "] constructs (uploadEmpty=" - + upload_empty - + ")"); - BackendConnector.getInstance().uploadApp(this.getGoalContext(), a); - } else { - log.warn( - "Skip save of empty app " - + this.getApplicationContext() - + " (uploadEmpty=" - + upload_empty - + ", existsInBackend=" - + app_exists_in_backend - + ")"); - this.skipGoalUpload(); - } +// final boolean upload_empty = +// this.getConfiguration() +// .getConfiguration() +// .getBoolean(CoreConfiguration.APP_UPLOAD_EMPTY, false); +// final boolean app_exists_in_backend = +// BackendConnector.getInstance().isAppExisting(this.getGoalContext(), a); +// +// // Upload if non-empty or already exists in backend or empty ones shall be uploaded +// if (!a.isEmpty() || app_exists_in_backend || upload_empty) { +// log.info( +// "Save app " +// + a +// + " with [" +// + a.getDependencies().size() +// + "] dependencies and [" +// + a.getConstructs().size() +// + "] constructs (uploadEmpty=" +// + upload_empty +// + ")"); +// BackendConnector.getInstance().uploadApp(this.getGoalContext(), a); +// } else { +// log.warn( +// "Skip save of empty app " +// + this.getApplicationContext() +// + " (uploadEmpty=" +// + upload_empty +// + ", existsInBackend=" +// + app_exists_in_backend +// + ")"); +// this.skipGoalUpload(); +// } } } From e4bb5680a4f2c39af02a60a5ee51ec70cae5fbbc Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Tue, 26 Apr 2022 18:19:41 +0200 Subject: [PATCH 24/29] write file with used classes by steady static and dynamic --- .../org/eclipse/steady/java/tasks/JavaDebloatTask.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 3cd78352c..ab2356d87 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -244,6 +244,14 @@ public void execute() throws GoalExecutionException { FileUtil.writeToFile(f, StringUtil.join(removable_sorted, System.lineSeparator())); log.info("List of removable classes written to [" + f.toPath() + "]"); + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "used-classes-steady.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(used_classes, System.lineSeparator())); + log.info("List of used classes according to steady backend data (no jdependency) written to [" + f.toPath() + "]"); + f = Paths.get( this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), From 1e09b7c225737b8eeb0907d3d2433d93fc33f71a Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 27 Apr 2022 09:41:27 +0200 Subject: [PATCH 25/29] fix code style --- .../steady/java/tasks/JavaDebloatTask.java | 119 +++++++++--------- .../org/eclipse/steady/goals/DebloatGoal.java | 105 ++++++++-------- .../steady/java/mvn/AbstractVulasMojo.java | 8 +- 3 files changed, 116 insertions(+), 116 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index ab2356d87..2909f3a50 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -78,9 +78,9 @@ public void execute() throws GoalExecutionException { // list of classpathunits to be used as application entrypoints List app = new ArrayList(); - // list of classpathunits to be used as test entrypoints + // list of classpathunits to be used as test entrypoints List test = new ArrayList(); - + // list of classes to be used as entrypoints (from traces and reachable constructs) List used_classes = new ArrayList(); // classpathunits for the application dependencies (as identified by maven) @@ -92,16 +92,16 @@ public void execute() throws GoalExecutionException { try { // 1) Add application paths (to be then used as entrypoints) if (this.hasSearchPath()) { - for (Path p : this.getSearchPath()) { - log.info("Add app path [" + p + "] to classpath"); - app.add(cp.addClazzpathUnit(p)); + for (Path p : this.getSearchPath()) { + log.info("Add app path [" + p + "] to classpath"); + app.add(cp.addClazzpathUnit(p)); } } - for (Path p : FileUtil.getPaths( - this.vulasConfiguration.getStringArray(CoreConfiguration.TEST_DIRS, null))) - { - log.info("Add test path [" + p + "] to classpath"); - test.add(cp.addClazzpathUnit(p)); + for (Path p : + FileUtil.getPaths( + this.vulasConfiguration.getStringArray(CoreConfiguration.TEST_DIRS, null))) { + log.info("Add test path [" + p + "] to classpath"); + test.add(cp.addClazzpathUnit(p)); } // 2) Add dependencies to jdependency classpath object and populate set of dependencies if (this.getKnownDependencies() != null) { @@ -210,17 +210,17 @@ public void execute() throws GoalExecutionException { // loop over class (representing traces and reachable constructs) marked as entrypoints to find // needed classes for (Clazz c : used_classes) { - if(removable.contains(c)) { - removable.remove(c); - removable.removeAll(c.getTransitiveDependencies()); - needed.add(c); - needed.addAll(c.getTransitiveDependencies()); - - for (Clazz cc : c.getTransitiveDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } - } - } + if (removable.contains(c)) { + removable.remove(c); + removable.removeAll(c.getTransitiveDependencies()); + needed.add(c); + needed.addAll(c.getTransitiveDependencies()); + + for (Clazz cc : c.getTransitiveDependencies()) { + deps_used.addAll(cc.getClazzpathUnits()); + } + } + } final SortedSet removable_sorted = new TreeSet(removable); Set remaining = cp.getClazzes(); @@ -245,13 +245,16 @@ public void execute() throws GoalExecutionException { log.info("List of removable classes written to [" + f.toPath() + "]"); f = - Paths.get( - this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), - "used-classes-steady.txt") - .toFile(); - FileUtil.writeToFile(f, StringUtil.join(used_classes, System.lineSeparator())); - log.info("List of used classes according to steady backend data (no jdependency) written to [" + f.toPath() + "]"); - + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "used-classes-steady.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(used_classes, System.lineSeparator())); + log.info( + "List of used classes according to steady backend data (no jdependency) written to [" + + f.toPath() + + "]"); + f = Paths.get( this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), @@ -259,14 +262,14 @@ public void execute() throws GoalExecutionException { .toFile(); FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); log.info("List of needed classes written to [" + f.toPath() + "]"); - + f = - Paths.get( - this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), - "remaining-classes.txt") - .toFile(); - FileUtil.writeToFile(f, StringUtil.join(remaining_sorted, System.lineSeparator())); - log.info("List of remaining classes written to [" + f.toPath() + "]"); + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "remaining-classes.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(remaining_sorted, System.lineSeparator())); + log.info("List of remaining classes written to [" + f.toPath() + "]"); f = Paths.get( @@ -289,36 +292,36 @@ public void execute() throws GoalExecutionException { // also consider test classes to find needed classes for (ClazzpathUnit u : test) { - removable.removeAll(u.getClazzes()); - removable.removeAll(u.getTransitiveDependencies()); - needed.addAll(u.getClazzes()); - needed.addAll(u.getTransitiveDependencies()); - for (Clazz c : u.getTransitiveDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); - } + removable.removeAll(u.getClazzes()); + removable.removeAll(u.getTransitiveDependencies()); + needed.addAll(u.getClazzes()); + needed.addAll(u.getTransitiveDependencies()); + for (Clazz c : u.getTransitiveDependencies()) { + deps_used.addAll(c.getClazzpathUnits()); } + } maven_deps.removeAll(deps_used); log.info("Needed classes with test: [" + needed.size() + "]"); log.info("Removable classes with test: [" + removable.size() + "]"); log.info("Used dependencies with test: [" + deps_used.size() + "]"); - + try { - File f = - Paths.get( - this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), - "needed-classes-w-test.txt") - .toFile(); - FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); - log.info("List of needed classes with test written to [" + f.toPath() + "]"); - f = - Paths.get( - this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), - "removable-deps-w-test.txt") - .toFile(); - FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); - log.info("List of removable dependencies with test written to [" + f.toPath() + "]"); + File f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "needed-classes-w-test.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(needed, System.lineSeparator())); + log.info("List of needed classes with test written to [" + f.toPath() + "]"); + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "removable-deps-w-test.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); + log.info("List of removable dependencies with test written to [" + f.toPath() + "]"); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } diff --git a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java index c0b97bd50..be03b87b0 100644 --- a/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java +++ b/lang/src/main/java/org/eclipse/steady/goals/DebloatGoal.java @@ -18,16 +18,12 @@ */ package org.eclipse.steady.goals; -import java.nio.file.Paths; import java.util.ServiceLoader; import org.apache.logging.log4j.Logger; import org.eclipse.steady.backend.BackendConnector; -import org.eclipse.steady.core.util.CoreConfiguration; import org.eclipse.steady.shared.enums.GoalType; import org.eclipse.steady.shared.json.model.Application; -import org.eclipse.steady.shared.json.model.Dependency; -import org.eclipse.steady.shared.json.model.Library; import org.eclipse.steady.tasks.DebloatTask; /** @@ -86,56 +82,57 @@ protected void executeTasks() throws Exception { } // Upload libraries and binaries (if requested) -// if (a.getDependencies() != null) { -// for (Dependency dep : a.getDependencies()) { -// -// // Upload lib -// final Library lib = dep.getLib(); -// if (lib != null) { -// if (lib.hasValidDigest()) { -// BackendConnector.getInstance().uploadLibrary(this.getGoalContext(), lib); -// if (CoreConfiguration.isJarUploadEnabled(this.getGoalContext().getVulasConfiguration())) -// BackendConnector.getInstance() -// .uploadLibraryFile(lib.getDigest(), Paths.get(dep.getPath())); -// } else { -// log.error("Library of dependency [" + dep + "] has no valid digest"); -// } -// } else { -// log.error("Dependency [" + dep + "] has no library"); -// } -// } -// } + // if (a.getDependencies() != null) { + // for (Dependency dep : a.getDependencies()) { + // + // // Upload lib + // final Library lib = dep.getLib(); + // if (lib != null) { + // if (lib.hasValidDigest()) { + // BackendConnector.getInstance().uploadLibrary(this.getGoalContext(), lib); + // if + // (CoreConfiguration.isJarUploadEnabled(this.getGoalContext().getVulasConfiguration())) + // BackendConnector.getInstance() + // .uploadLibraryFile(lib.getDigest(), Paths.get(dep.getPath())); + // } else { + // log.error("Library of dependency [" + dep + "] has no valid digest"); + // } + // } else { + // log.error("Dependency [" + dep + "] has no library"); + // } + // } + // } -// final boolean upload_empty = -// this.getConfiguration() -// .getConfiguration() -// .getBoolean(CoreConfiguration.APP_UPLOAD_EMPTY, false); -// final boolean app_exists_in_backend = -// BackendConnector.getInstance().isAppExisting(this.getGoalContext(), a); -// -// // Upload if non-empty or already exists in backend or empty ones shall be uploaded -// if (!a.isEmpty() || app_exists_in_backend || upload_empty) { -// log.info( -// "Save app " -// + a -// + " with [" -// + a.getDependencies().size() -// + "] dependencies and [" -// + a.getConstructs().size() -// + "] constructs (uploadEmpty=" -// + upload_empty -// + ")"); -// BackendConnector.getInstance().uploadApp(this.getGoalContext(), a); -// } else { -// log.warn( -// "Skip save of empty app " -// + this.getApplicationContext() -// + " (uploadEmpty=" -// + upload_empty -// + ", existsInBackend=" -// + app_exists_in_backend -// + ")"); -// this.skipGoalUpload(); -// } + // final boolean upload_empty = + // this.getConfiguration() + // .getConfiguration() + // .getBoolean(CoreConfiguration.APP_UPLOAD_EMPTY, false); + // final boolean app_exists_in_backend = + // BackendConnector.getInstance().isAppExisting(this.getGoalContext(), a); + // + // // Upload if non-empty or already exists in backend or empty ones shall be uploaded + // if (!a.isEmpty() || app_exists_in_backend || upload_empty) { + // log.info( + // "Save app " + // + a + // + " with [" + // + a.getDependencies().size() + // + "] dependencies and [" + // + a.getConstructs().size() + // + "] constructs (uploadEmpty=" + // + upload_empty + // + ")"); + // BackendConnector.getInstance().uploadApp(this.getGoalContext(), a); + // } else { + // log.warn( + // "Skip save of empty app " + // + this.getApplicationContext() + // + " (uploadEmpty=" + // + upload_empty + // + ", existsInBackend=" + // + app_exists_in_backend + // + ")"); + // this.skipGoalUpload(); + // } } } diff --git a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java index 832e4a1db..57d771f9a 100644 --- a/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java +++ b/plugin-maven/src/main/java/org/eclipse/steady/java/mvn/AbstractVulasMojo.java @@ -169,18 +169,18 @@ private final void setDefaults(VulasConfiguration _cfg, MavenProject _prj) { CoreConfiguration.SLICING_DIR, Paths.get(_prj.getBuild().getDirectory(), "vulas", "debloat").toString()); - // Read app constructs from src/main/java and target/classes final String p = Paths.get(_prj.getBuild().getOutputDirectory()).toString() + "," + Paths.get(_prj.getBuild().getSourceDirectory()).toString(); _cfg.setPropertyIfEmpty(CoreConfiguration.APP_DIRS, p); - - final String test_paths= Paths.get(_prj.getBuild().getTestOutputDirectory()).toString() + + final String test_paths = + Paths.get(_prj.getBuild().getTestOutputDirectory()).toString() + "," + Paths.get(_prj.getBuild().getTestSourceDirectory()).toString(); - _cfg.setPropertyIfEmpty(CoreConfiguration.TEST_DIRS,test_paths); + _cfg.setPropertyIfEmpty(CoreConfiguration.TEST_DIRS, test_paths); } /** From 59e7d11a5f72783414d7fed77a985a35a279d620 Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 27 Apr 2022 16:45:31 +0200 Subject: [PATCH 26/29] fix javadoc error --- lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java index de9cfad1e..62eeae901 100644 --- a/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java +++ b/lang/src/main/java/org/eclipse/steady/tasks/DebloatTask.java @@ -40,14 +40,14 @@ public interface DebloatTask extends Task { // public Set getNeededConstructs(); /** - * Sets the traced constructs to be used as starting point for debloating the {@link Application} + * Sets the traced constructs to be used as starting point for debloating the application * (traces resulting from the dynamic analysis) * */ public void setTraces(Set _traces); /** - * Sets the reachable constructs to be used as starting point for debloating the {@link Application} + * Sets the reachable constructs to be used as starting point for debloating the application * (resulting from the static analysis) * */ From e70cd34fdbaab4883532a999f62b91bacff1e9eb Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 27 Apr 2022 16:47:06 +0200 Subject: [PATCH 27/29] always consider all steady classes --- .../steady/java/tasks/JavaDebloatTask.java | 129 +++++++++--------- 1 file changed, 67 insertions(+), 62 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 2909f3a50..940ba1dd8 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -81,8 +81,8 @@ public void execute() throws GoalExecutionException { // list of classpathunits to be used as test entrypoints List test = new ArrayList(); - // list of classes to be used as entrypoints (from traces and reachable constructs) - List used_classes = new ArrayList(); + // list of classes from Steasy traces/reachableConstructs (also used as entrypoints) + final SortedSet used_classes = new TreeSet(); // classpathunits for the application dependencies (as identified by maven) Set maven_deps = new HashSet(); // classpathunits considered used according to traces, reachable constructs and jdependency @@ -106,7 +106,6 @@ public void execute() throws GoalExecutionException { // 2) Add dependencies to jdependency classpath object and populate set of dependencies if (this.getKnownDependencies() != null) { for (Path p : this.getKnownDependencies().keySet()) { - log.info("Add dep path [" + p + "] to classpath"); maven_deps.add(cp.addClazzpathUnit(p)); } } @@ -116,32 +115,19 @@ public void execute() throws GoalExecutionException { log.info("[" + app.size() + "] ClasspathUnit for the application to be used as entrypoints "); log.info("[" + test.size() + "] ClasspathUnit for tests to be used as entrypoints "); + log.info("[" + cp.getUnits().length + "] classpathUnits in jdependency classpath object"); // Retrieve traces to be used as Clazz entrypoints (1 class may be part of multiple // classpathUnits) for (ConstructId t : traces) { if (t.getType().equals(ConstructType.CLAS) - || t.getType().equals(ConstructType.INTF) - || t.getType().equals(ConstructType.ENUM)) { - Clazz c = cp.getClazz(t.getQname()); - if (c == null) { - log.warn("Could not obtain jdependency clazz for traced class [" + t.getQname() + "]"); - } else { - used_classes.add(c); - Set units = c.getClazzpathUnits(); - if (units.size() > 1) { - log.warn( - "Added as entrypoints multiple ClasspathUnits from single class [" - + c - + "] : [" - + StringUtil.join(units, ",") - + "]"); - } - deps_used.addAll(units); - } + || t.getType().equals(ConstructType.INTF) + || t.getType().equals(ConstructType.ENUM)) { + used_classes.add(t.getQname()); + } } - log.info("Using [" + used_classes.size() + "] jdependency clazzes as entrypoints from traces"); + log.info("Retrieved [" + used_classes.size() + "] clazzes from steady traces"); // Loop reachable constructs (METH, CONS, INIT), find their definition // context (CLASS, ENUM, INTF) and use those as jdependency clazz @@ -156,32 +142,17 @@ public void execute() throws GoalExecutionException { for (ConstructId c : d.getReachableConstructIds()) { JavaId core_construct = (JavaId) JavaId.toCoreType(c); JavaId def_context = (JavaId) core_construct.getDefinitionContext(); - Clazz cl = cp.getClazz(def_context.getQualifiedName()); - if (cl == null) { - log.warn("Could not obtain jdependency clazz for [" + def_context + "]"); - } else { - used_classes.add(cl); - Set units = cl.getClazzpathUnits(); - if (units.size() > 1) { - log.warn( - "Added as entrypoints multiple ClasspathUnits from single class [" - + cl - + "] : [" - + StringUtil.join(units, ",") - + "]"); - } - deps_used.addAll(units); + used_classes.add(def_context.getQualifiedName()); } } } - } + log.info( "Using [" + used_classes.size() - + "] jdependency clazzes as entrypoints from traces and reachable constructs"); + + "] clazzes from Steady traces/reachable constructs"); - log.info("[" + cp.getUnits().length + "] classpathUnits in jdependency classpath object"); // also collect "missing" classes to be able to check their relation with jre objects considered // used @@ -192,35 +163,59 @@ public void execute() throws GoalExecutionException { } // Classes considered used - final SortedSet needed = new TreeSet(); + final SortedSet needed = new TreeSet(); final Set removable = cp.getClazzes(); + // loop over classpathunits (representing the application) marked as entrypoints to find needed // classes for (ClazzpathUnit u : app) { removable.removeAll(u.getClazzes()); removable.removeAll(u.getTransitiveDependencies()); - needed.addAll(u.getClazzes()); - needed.addAll(u.getTransitiveDependencies()); - - for (Clazz c : u.getTransitiveDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); + for (Clazz c: u.getClazzes()) { + needed.add(c.getName()); } + for (Clazz c: u.getTransitiveDependencies()) { + needed.add(c.getName()); + deps_used.addAll(c.getClazzpathUnits()); + } + } - // loop over class (representing traces and reachable constructs) marked as entrypoints to find + + // loop over class (representing traces and reachable constructs) and use them as entrypoints to find // needed classes - for (Clazz c : used_classes) { - if (removable.contains(c)) { - removable.remove(c); - removable.removeAll(c.getTransitiveDependencies()); - needed.add(c); - needed.addAll(c.getTransitiveDependencies()); - - for (Clazz cc : c.getTransitiveDependencies()) { - deps_used.addAll(cc.getClazzpathUnits()); - } - } + for (String class_name : used_classes) { + needed.add(class_name); + + Clazz c = cp.getClazz(class_name); + + if (c == null) { + log.warn("Could not obtain jdependency clazz for steady class [" + class_name + "]"); + } else { + Set units = c.getClazzpathUnits(); + if (units.size() > 1) { + log.warn( + "Added as entrypoints multiple ClasspathUnits from single class [" + + c + + "] : [" + + StringUtil.join(units, ",") + + "]"); + } + deps_used.addAll(units); + + if (removable.contains(c)) { + removable.remove(c); + removable.removeAll(c.getTransitiveDependencies()); + for (Clazz cl: c.getTransitiveDependencies()) { + needed.add(cl.getName()); + deps_used.addAll(cl.getClazzpathUnits()); + } + } + } } + + + final SortedSet removable_sorted = new TreeSet(removable); Set remaining = cp.getClazzes(); @@ -294,10 +289,12 @@ public void execute() throws GoalExecutionException { for (ClazzpathUnit u : test) { removable.removeAll(u.getClazzes()); removable.removeAll(u.getTransitiveDependencies()); - needed.addAll(u.getClazzes()); - needed.addAll(u.getTransitiveDependencies()); - for (Clazz c : u.getTransitiveDependencies()) { - deps_used.addAll(c.getClazzpathUnits()); + for (Clazz c: u.getClazzes()) { + needed.add(c.getName()); + } + for (Clazz c: u.getTransitiveDependencies()) { + needed.add(c.getName()); + deps_used.addAll(c.getClazzpathUnits()); } } maven_deps.removeAll(deps_used); @@ -320,6 +317,14 @@ public void execute() throws GoalExecutionException { .toFile(); FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); log.info("List of removable dependencies with test written to [" + f.toPath() + "]"); + + f = + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "used-deps.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(deps_used, System.lineSeparator())); + log.info("List of used dependencies written to [" + f.toPath() + "]"); } catch (IOException e) { e.printStackTrace(); } From 61100f6c1763fefeb7b1e2ac8b5e72febed74f2b Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 27 Apr 2022 16:49:01 +0200 Subject: [PATCH 28/29] fix style --- .../steady/java/tasks/JavaDebloatTask.java | 115 ++++++++---------- 1 file changed, 53 insertions(+), 62 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 940ba1dd8..3a2fb078e 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -121,10 +121,9 @@ public void execute() throws GoalExecutionException { // classpathUnits) for (ConstructId t : traces) { if (t.getType().equals(ConstructType.CLAS) - || t.getType().equals(ConstructType.INTF) - || t.getType().equals(ConstructType.ENUM)) { - used_classes.add(t.getQname()); - + || t.getType().equals(ConstructType.INTF) + || t.getType().equals(ConstructType.ENUM)) { + used_classes.add(t.getQname()); } } log.info("Retrieved [" + used_classes.size() + "] clazzes from steady traces"); @@ -143,16 +142,11 @@ public void execute() throws GoalExecutionException { JavaId core_construct = (JavaId) JavaId.toCoreType(c); JavaId def_context = (JavaId) core_construct.getDefinitionContext(); used_classes.add(def_context.getQualifiedName()); - } } } - - - log.info( - "Using [" - + used_classes.size() - + "] clazzes from Steady traces/reachable constructs"); + } + log.info("Using [" + used_classes.size() + "] clazzes from Steady traces/reachable constructs"); // also collect "missing" classes to be able to check their relation with jre objects considered // used @@ -165,57 +159,54 @@ public void execute() throws GoalExecutionException { // Classes considered used final SortedSet needed = new TreeSet(); final Set removable = cp.getClazzes(); - + // loop over classpathunits (representing the application) marked as entrypoints to find needed // classes for (ClazzpathUnit u : app) { removable.removeAll(u.getClazzes()); removable.removeAll(u.getTransitiveDependencies()); - for (Clazz c: u.getClazzes()) { - needed.add(c.getName()); + for (Clazz c : u.getClazzes()) { + needed.add(c.getName()); } - for (Clazz c: u.getTransitiveDependencies()) { - needed.add(c.getName()); - deps_used.addAll(c.getClazzpathUnits()); + for (Clazz c : u.getTransitiveDependencies()) { + needed.add(c.getName()); + deps_used.addAll(c.getClazzpathUnits()); } - } - - // loop over class (representing traces and reachable constructs) and use them as entrypoints to find + // loop over class (representing traces and reachable constructs) and use them as entrypoints to + // find // needed classes for (String class_name : used_classes) { - needed.add(class_name); - - Clazz c = cp.getClazz(class_name); - - if (c == null) { - log.warn("Could not obtain jdependency clazz for steady class [" + class_name + "]"); - } else { - Set units = c.getClazzpathUnits(); - if (units.size() > 1) { - log.warn( - "Added as entrypoints multiple ClasspathUnits from single class [" - + c - + "] : [" - + StringUtil.join(units, ",") - + "]"); - } - deps_used.addAll(units); - - if (removable.contains(c)) { - removable.remove(c); - removable.removeAll(c.getTransitiveDependencies()); - for (Clazz cl: c.getTransitiveDependencies()) { - needed.add(cl.getName()); - deps_used.addAll(cl.getClazzpathUnits()); - } - } - } + needed.add(class_name); + + Clazz c = cp.getClazz(class_name); + + if (c == null) { + log.warn("Could not obtain jdependency clazz for steady class [" + class_name + "]"); + } else { + Set units = c.getClazzpathUnits(); + if (units.size() > 1) { + log.warn( + "Added as entrypoints multiple ClasspathUnits from single class [" + + c + + "] : [" + + StringUtil.join(units, ",") + + "]"); + } + deps_used.addAll(units); + + if (removable.contains(c)) { + removable.remove(c); + removable.removeAll(c.getTransitiveDependencies()); + for (Clazz cl : c.getTransitiveDependencies()) { + needed.add(cl.getName()); + deps_used.addAll(cl.getClazzpathUnits()); + } + } + } } - - - + final SortedSet removable_sorted = new TreeSet(removable); Set remaining = cp.getClazzes(); @@ -289,12 +280,12 @@ public void execute() throws GoalExecutionException { for (ClazzpathUnit u : test) { removable.removeAll(u.getClazzes()); removable.removeAll(u.getTransitiveDependencies()); - for (Clazz c: u.getClazzes()) { - needed.add(c.getName()); + for (Clazz c : u.getClazzes()) { + needed.add(c.getName()); } - for (Clazz c: u.getTransitiveDependencies()) { - needed.add(c.getName()); - deps_used.addAll(c.getClazzpathUnits()); + for (Clazz c : u.getTransitiveDependencies()) { + needed.add(c.getName()); + deps_used.addAll(c.getClazzpathUnits()); } } maven_deps.removeAll(deps_used); @@ -317,14 +308,14 @@ public void execute() throws GoalExecutionException { .toFile(); FileUtil.writeToFile(f, StringUtil.join(maven_deps, System.lineSeparator())); log.info("List of removable dependencies with test written to [" + f.toPath() + "]"); - + f = - Paths.get( - this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), - "used-deps.txt") - .toFile(); - FileUtil.writeToFile(f, StringUtil.join(deps_used, System.lineSeparator())); - log.info("List of used dependencies written to [" + f.toPath() + "]"); + Paths.get( + this.vulasConfiguration.getDir(CoreConfiguration.SLICING_DIR).toString(), + "used-deps.txt") + .toFile(); + FileUtil.writeToFile(f, StringUtil.join(deps_used, System.lineSeparator())); + log.info("List of used dependencies written to [" + f.toPath() + "]"); } catch (IOException e) { e.printStackTrace(); } From 1d5cb9f39f3196ced85d87fe07bb28516a42dcae Mon Sep 17 00:00:00 2001 From: serenaponta <42769540+serenaponta@users.noreply.github.com> Date: Wed, 27 Apr 2022 18:11:38 +0200 Subject: [PATCH 29/29] minor change --- .../org/eclipse/steady/java/tasks/JavaDebloatTask.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java index 3a2fb078e..3bd964189 100644 --- a/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java +++ b/lang-java/src/main/java/org/eclipse/steady/java/tasks/JavaDebloatTask.java @@ -185,6 +185,10 @@ public void execute() throws GoalExecutionException { if (c == null) { log.warn("Could not obtain jdependency clazz for steady class [" + class_name + "]"); } else { + for (Clazz cl : c.getTransitiveDependencies()) { + needed.add(cl.getName()); + deps_used.addAll(cl.getClazzpathUnits()); + } Set units = c.getClazzpathUnits(); if (units.size() > 1) { log.warn( @@ -199,10 +203,6 @@ public void execute() throws GoalExecutionException { if (removable.contains(c)) { removable.remove(c); removable.removeAll(c.getTransitiveDependencies()); - for (Clazz cl : c.getTransitiveDependencies()) { - needed.add(cl.getName()); - deps_used.addAll(cl.getClazzpathUnits()); - } } } }