diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d38dbcb6af..f057524089 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Prepare git run: git config --global core.autocrlf false - - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - uses: actions/cache@v4.2.4 @@ -46,4 +46,4 @@ jobs: distribution: 'temurin' java-version: ${{ matrix.java }} - name: Build with Maven - run: mvn --show-version --batch-mode --no-transfer-progress -DtrimStackTrace=false -Drat.skip=true + run: mvn --errors --show-version --batch-mode --no-transfer-progress -DtrimStackTrace=false -Drat.skip=true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd33383389..0f99265e37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,9 +41,8 @@ Contributing to Apache Commons BCEL ====================== -You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to -the open source community. Before you dig right into the code there are a few guidelines that we need contributors to -follow so that we can have a chance of keeping on top of things. +Have you found a bug or have an idea for a cool new feature? Contributing code is a great way to give something back to the open-source community. +Before you dig right into the code, we need contributors to follow a few guidelines to have a chance of keeping on top of things. Getting Started --------------- @@ -62,7 +61,7 @@ Making Changes + Create a _topic branch_ for your isolated work. * Usually you should base your branch on the `master` branch. - * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `BCEL-123-InputStream`. + * A good topic branch name can be the JIRA bug ID plus a keyword, e.g. `BCEL-123-InputStream`. * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests. + Make commits of logical units. * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue. @@ -72,7 +71,7 @@ Making Changes + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first. + Check for unnecessary whitespace with `git diff` -- check before committing. + Make sure you have added the necessary tests for your changes, typically in `src/test/java`. -+ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken. ++ Run all the tests with `mvn clean verify` to ensure nothing else was accidentally broken. Making Trivial Changes ---------------------- diff --git a/README.md b/README.md index 243719864a..68810a28ce 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,8 @@ Apache Commons BCEL =================== [![Java CI](https://github.com/apache/commons-bcel/actions/workflows/maven.yml/badge.svg)](https://github.com/apache/commons-bcel/actions/workflows/maven.yml) -[![Coverage Status](https://codecov.io/gh/apache/commons-bcel/branch/master/graph/badge.svg)](https://app.codecov.io/gh/apache/commons-bcel) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.bcel/bcel/badge.svg?gav=true)](https://maven-badges.herokuapp.com/maven-central/org.apache.bcel/bcel/?gav=true) -[![Javadocs](https://javadoc.io/badge/org.apache.bcel/bcel/6.9.0.svg)](https://javadoc.io/doc/org.apache.bcel/bcel/6.9.0) +[![Javadocs](https://javadoc.io/badge/org.apache.bcel/bcel/6.10.0.svg)](https://javadoc.io/doc/org.apache.bcel/bcel/6.10.0) [![CodeQL](https://github.com/apache/commons-bcel/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/apache/commons-bcel/actions/workflows/codeql-analysis.yml) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/apache/commons-bcel/badge)](https://api.securityscorecards.dev/projects/github.com/apache/commons-bcel) @@ -69,7 +68,7 @@ Alternatively, you can pull it from the central Maven repositories: org.apache.bcel bcel - 6.9.0 + 6.10.0 ``` @@ -89,7 +88,9 @@ There are some guidelines which will make applying PRs easier for us: + No tabs! Please use spaces for indentation. + Respect the existing code style for each file. + Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change. -+ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn```. ++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running `mvn`. ++ Before you pushing a PR, run `mvn` (by itself), this runs the default goal, which contains all build checks. ++ To see the code coverage report, regardless of coverage failures, run `mvn clean site -Dcommons.jacoco.haltOnFailure=false` If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas). You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md). diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 6677e03765..10c9331991 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,5 +1,76 @@ -Apache Commons BCEL -Version 6.9.0 +Apache Commons BCEL Version 6.10.0 +RELEASE NOTES + + +Introduction +------------ +The Apache Commons BCEL team is pleased to announce the release of +Apache Commons BCEL 6.10.0. + +The Byte Code Engineering Library (BCEL) is intended to give users a convenient +way to analyze, create, and manipulate compiled .class files. Classes are +represented by objects containing all the symbolic information of the given +class: methods, fields, and byte code instructions. + +Maintenance and bug fix release. Requires a minimum of Java 8. + +Changes +------- +* Fix PMD UnnecessaryFullyQualifiedName. Thanks to Gary Gregory. +* Fix PMD EmptyCatchBlock by allowing commented blocks. Thanks to Gary Gregory. +* Fix PMD EmptyControlStatement by allowing commented blocks. Thanks to Gary Gregory. +* Fix SpotBugs RV_RETURN_VALUE_IGNORED_BAD_PRACTICE in JasminVisitor. Thanks to Gary Gregory. +* SpotBugs checks should ignore code generated by JavaCC. Thanks to Gary Gregory. +* Fix SpotBugs URF_UNREAD_FIELD in ClassDumper. Thanks to Gary Gregory. +* Fix SpotBugs DM_DEFAULT_ENCODING in JasminVisitor. Thanks to Gary Gregory. +* Fix SpotBugs RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE in ASTFunAppl. Thanks to Gary Gregory. +* Fix SpotBugs RV_ABSOLUTE_VALUE_OF_HASHCODE in Mini.Environment. Thanks to Gary Gregory. +* Fix SpotBugs DM_DEFAULT_ENCODING in Mini.MiniC. Thanks to Gary Gregory. +* Fix SpotBugs WMI_WRONG_MAP_ITERATOR in Package.go(String[]). Thanks to Gary Gregory. +* Deprecate TransitiveHull.INGORED in favor of TransitiveHull.getIgnored(). Thanks to Gary Gregory. +* Add accessors to model and unit tests, Javadoc #183. Thanks to nbauma109, Gary Gregory, Mark Roberts. +* Add Const.MAJOR_22. Thanks to Gary Gregory. +* Add Const.MINOR_22. Thanks to Gary Gregory. +* Add Const.MAJOR_23. Thanks to Gary Gregory. +* Add Const.MINOR_23. Thanks to Gary Gregory. +* Add Const.MAJOR_24. Thanks to Gary Gregory. +* Add Const.MINOR_24. Thanks to Gary Gregory. +* Bump tests from org.assertj:assertj-core 3.25.3 to 3.26.3 #322, #332. Thanks to Dependabot. +* Bump tests from org.jetbrains.kotlin:kotlin-stdlib 1.9.23 to 2.0.0 #309, #318. Thanks to Dependabot. +* Bump tests from org.apache.commons:commons-collections4 4.4 to 4.5.0-M2. Thanks to Gary Gregory. +* Bump org.apache.commons:commons-parent from 69 to 71. Thanks to Gary Gregory. +* Bump org.codehaus.mojo:taglist-maven-plugin from 3.0.0 to 3.1.0 #331. Thanks to Gary Gregory. + + +Historical list of changes: https://commons.apache.org/proper/commons-bcel/changes-report.html + +For complete information on Apache Commons BCEL, including instructions on how to submit bug reports, +patches, or suggestions for improvement, see the Apache Commons BCEL website: + +https://commons.apache.org/proper/commons-bcel + +Download it from https://commons.apache.org/proper/commons-bcel/download_bcel.cgi + +Have fun! +-Apache Commons BCEL team + +Feedback +-------- +Open source works best when you give feedback: + + https://commons.apache.org/bcel + +Please direct all bug reports to JIRA: + + https://issues.apache.org/jira/browse/BCEL + +Or subscribe to the commons-user mailing list + +The Apache Commons Team + +----------------------------------------------------------------------------- + +Apache Commons BCEL Version 6.9.0 RELEASE NOTES @@ -87,8 +158,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.8.2 +Apache Commons BCEL Version 6.8.2 RELEASE NOTES @@ -144,8 +214,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.8.1 +Apache Commons BCEL Version 6.8.1 RELEASE NOTES @@ -213,8 +282,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.8.0 +Apache Commons BCEL Version 6.8.0 RELEASE NOTES @@ -302,8 +370,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.7.0 +Apache Commons BCEL Version 6.7.0 RELEASE NOTES @@ -415,8 +482,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.6.1 +Apache Commons BCEL Version 6.6.1 RELEASE NOTES @@ -475,8 +541,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.6.0 +Apache Commons BCEL Version 6.6.0 RELEASE NOTES @@ -606,8 +671,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.5.0 +Apache Commons BCEL Version 6.5.0 RELEASE NOTES @@ -680,8 +744,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.4.1 +Apache Commons BCEL Version 6.4.1 RELEASE NOTES @@ -737,8 +800,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.4.0 +Apache Commons BCEL Version 6.4.0 RELEASE NOTES @@ -812,8 +874,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.3.1 +Apache Commons BCEL Version 6.3.1 RELEASE NOTES @@ -863,8 +924,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.3 +Apache Commons BCEL Version 6.3 RELEASE NOTES @@ -921,8 +981,7 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL -Version 6.2 +Apache Commons BCEL Version 6.2 RELEASE NOTES @@ -968,9 +1027,8 @@ The Apache Commons Team ----------------------------------------------------------------------------- -Apache Commons BCEL - Version 6.1 - RELEASE NOTES +Apache Commons BCEL Version 6.1 +RELEASE NOTES Introduction diff --git a/pom.xml b/pom.xml index 363d173629..b199b50219 100644 --- a/pom.xml +++ b/pom.xml @@ -27,13 +27,13 @@ org.apache.commons commons-parent - 69 + 71 org.apache.bcel bcel jar - 6.9.0 + 6.10.0 Apache Commons BCEL Apache Commons Bytecode Engineering Library @@ -43,16 +43,16 @@ UTF-8 UTF-8 - 2024-04-21T16:51:47Z + 2024-07-13T18:11:44Z 1.8 1.8 bcel org.apache.bcel - 6.9.0 - 6.9.1 + 6.10.0 + 6.10.1 true RC1 - 6.8.1 + 6.9.0 (Java 8 or above) https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-bcel scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid} @@ -65,13 +65,12 @@ BCEL 12314220 4.11.0 - 3.25.3 + 3.26.3 5.14.0 false - true - + true 0.89 0.65 0.70 @@ -300,7 +299,7 @@ org.codehaus.mojo taglist-maven-plugin - 3.0.0 + 3.1.0 TODO @@ -423,7 +422,7 @@ org.jetbrains.kotlin kotlin-stdlib - 1.9.23 + 2.0.0 test @@ -482,7 +481,7 @@ org.apache.commons commons-collections4 - 4.4 + 4.5.0-M2 test diff --git a/src/changes/changes.xml b/src/changes/changes.xml index acc9b8b6ca..4323a93cca 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -59,6 +59,35 @@ The type attribute can be add,update,fix,remove. Defining changes.version allows one to create the RN without first removing the SNAPSHOT suffix. --> + + + Fix PMD UnnecessaryFullyQualifiedName. + Fix PMD EmptyCatchBlock by allowing commented blocks. + Fix PMD EmptyControlStatement by allowing commented blocks. + Fix SpotBugs RV_RETURN_VALUE_IGNORED_BAD_PRACTICE in JasminVisitor. + SpotBugs checks should ignore code generated by JavaCC. + Fix SpotBugs URF_UNREAD_FIELD in ClassDumper. + Fix SpotBugs DM_DEFAULT_ENCODING in JasminVisitor. + Fix SpotBugs RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE in ASTFunAppl. + Fix SpotBugs RV_ABSOLUTE_VALUE_OF_HASHCODE in Mini.Environment. + Fix SpotBugs DM_DEFAULT_ENCODING in Mini.MiniC. + Fix SpotBugs WMI_WRONG_MAP_ITERATOR in Package.go(String[]). + Deprecate TransitiveHull.INGORED in favor of TransitiveHull.getIgnored(). + + Add accessors to model and unit tests, Javadoc #183. + Add Const.MAJOR_22. + Add Const.MINOR_22. + Add Const.MAJOR_23. + Add Const.MINOR_23. + Add Const.MAJOR_24. + Add Const.MINOR_24. + + Bump tests from org.assertj:assertj-core 3.25.3 to 3.26.3 #322, #332. + Bump tests from org.jetbrains.kotlin:kotlin-stdlib 1.9.23 to 2.0.0 #309, #318. + Bump tests from org.apache.commons:commons-collections4 4.4 to 4.5.0-M2. + Bump org.apache.commons:commons-parent from 69 to 71. + Bump org.codehaus.mojo:taglist-maven-plugin from 3.0.0 to 3.1.0 #331. + Add Support for Java 16 records #290. diff --git a/src/changes/release-notes.vm b/src/changes/release-notes.vm index ae8ae40b00..ed53833d3d 100644 --- a/src/changes/release-notes.vm +++ b/src/changes/release-notes.vm @@ -15,8 +15,7 @@ ## specific language governing permissions and limitations ## under the License. ## -${project.name} -Version ${version} +${project.name} Version ${version} RELEASE NOTES diff --git a/src/conf/checkstyle-suppressions.xml b/src/conf/checkstyle-suppressions.xml index bf3c1e6815..643d511e5d 100644 --- a/src/conf/checkstyle-suppressions.xml +++ b/src/conf/checkstyle-suppressions.xml @@ -17,8 +17,8 @@ limitations under the License. --> + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> diff --git a/src/conf/checkstyle.xml b/src/conf/checkstyle.xml index 21cee04dbc..581c1dee71 100644 --- a/src/conf/checkstyle.xml +++ b/src/conf/checkstyle.xml @@ -103,17 +103,7 @@ limitations under the License. - - diff --git a/src/conf/pmd-ruleset.xml b/src/conf/pmd-ruleset.xml index 9cafbb480d..89eb9b8d2b 100644 --- a/src/conf/pmd-ruleset.xml +++ b/src/conf/pmd-ruleset.xml @@ -19,11 +19,9 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> - This ruleset checks the code for discouraged programming constructs. - @@ -32,7 +30,6 @@ - @@ -54,7 +51,6 @@ - @@ -67,9 +63,7 @@ - - + + + + + + + + + + + diff --git a/src/conf/spotbugs-exclude-filter.xml b/src/conf/spotbugs-exclude-filter.xml index f917b60c7f..f7c0cdf0c1 100644 --- a/src/conf/spotbugs-exclude-filter.xml +++ b/src/conf/spotbugs-exclude-filter.xml @@ -65,14 +65,19 @@ - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/examples/ClassDumper.java b/src/examples/ClassDumper.java index 6ebaaab9bb..d4d810c0e7 100644 --- a/src/examples/ClassDumper.java +++ b/src/examples/ClassDumper.java @@ -25,8 +25,6 @@ import org.apache.bcel.classfile.ClassFormatException; import org.apache.bcel.classfile.Constant; import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.Field; -import org.apache.bcel.classfile.Method; import org.apache.bcel.util.BCELifier; /** @@ -36,7 +34,6 @@ final class ClassDumper { private final FileImageInputStream file; private final String fileName; - private int classNameIndex; private int superclassNameIndex; private int major; private int minor; // Compiler version @@ -44,8 +41,8 @@ final class ClassDumper { private int[] interfaces; // Names of implemented interfaces private ConstantPool constantPool; // collection of constants private Constant[] constantItems; // collection of constants - private Field[] fields; // class fields, i.e., its variables - private Method[] methods; // methods defined in the class + // private Field[] fields; // class fields, i.e., its variables + // private Method[] methods; // methods defined in the class private Attribute[] attributes; // attributes defined in the class /** @@ -59,7 +56,7 @@ public ClassDumper(final FileImageInputStream file, final String fileName) { this.file = file; } - private final String constantToString(final int index) { + private String constantToString(final int index) { final Constant c = constantItems[index]; return constantPool.constantToString(c); } @@ -108,7 +105,7 @@ public void dump() throws IOException, ClassFormatException { * @throws IOException * @throws ClassFormatException */ - private final void processAttributes() throws IOException, ClassFormatException { + private void processAttributes() throws IOException, ClassFormatException { final int attributesCount = file.readUnsignedShort(); attributes = new Attribute[attributesCount]; @@ -130,7 +127,7 @@ private final void processAttributes() throws IOException, ClassFormatException * @throws IOException * @throws ClassFormatException */ - private final void processClassInfo() throws IOException, ClassFormatException { + private void processClassInfo() throws IOException, ClassFormatException { accessFlags = file.readUnsignedShort(); /* * Interfaces are implicitly abstract, the flag should be set according to the JVM specification. @@ -144,7 +141,7 @@ private final void processClassInfo() throws IOException, ClassFormatException { System.out.printf("%nClass info:%n"); System.out.println(" flags: " + BCELifier.printFlags(accessFlags, BCELifier.FLAGS.CLASS)); - classNameIndex = file.readUnsignedShort(); + int classNameIndex = file.readUnsignedShort(); System.out.printf(" this_class: %d (", classNameIndex); System.out.println(constantToString(classNameIndex) + ")"); @@ -162,7 +159,7 @@ private final void processClassInfo() throws IOException, ClassFormatException { * @throws IOException * @throws ClassFormatException */ - private final void processConstantPool() throws IOException, ClassFormatException { + private void processConstantPool() throws IOException, ClassFormatException { byte tag; final int constantPoolCount = file.readUnsignedShort(); constantItems = new Constant[constantPoolCount]; @@ -198,7 +195,7 @@ private final void processConstantPool() throws IOException, ClassFormatExceptio * @throws IOException * @throws ClassFormatException */ - private final void processFieldOrMethod() throws IOException, ClassFormatException { + private void processFieldOrMethod() throws IOException, ClassFormatException { final int accessFlags = file.readUnsignedShort(); final int nameIndex = file.readUnsignedShort(); System.out.printf(" nameIndex: %d (", nameIndex); @@ -247,9 +244,9 @@ private final void processFieldOrMethod() throws IOException, ClassFormatExcepti * @throws IOException * @throws ClassFormatException */ - private final void processFields() throws IOException, ClassFormatException { + private void processFields() throws IOException, ClassFormatException { final int fieldsCount = file.readUnsignedShort(); - fields = new Field[fieldsCount]; + // fields = new Field[fieldsCount]; // sometimes fields[0] is magic used for serialization System.out.printf("%nFields(%d):%n", fieldsCount); @@ -268,7 +265,7 @@ private final void processFields() throws IOException, ClassFormatException { * @throws IOException * @throws ClassFormatException */ - private final void processID() throws IOException, ClassFormatException { + private void processID() throws IOException, ClassFormatException { final int magic = file.readInt(); if (magic != Const.JVM_CLASSFILE_MAGIC) { throw new ClassFormatException(fileName + " is not a Java .class file"); @@ -285,7 +282,7 @@ private final void processID() throws IOException, ClassFormatException { * @throws IOException * @throws ClassFormatException */ - private final void processInterfaces() throws IOException, ClassFormatException { + private void processInterfaces() throws IOException, ClassFormatException { final int interfacesCount = file.readUnsignedShort(); interfaces = new int[interfacesCount]; @@ -311,9 +308,9 @@ private final void processInterfaces() throws IOException, ClassFormatException * @throws IOException * @throws ClassFormatException */ - private final void processMethods() throws IOException, ClassFormatException { + private void processMethods() throws IOException, ClassFormatException { final int methodsCount = file.readUnsignedShort(); - methods = new Method[methodsCount]; + // methods = new Method[methodsCount]; System.out.printf("%nMethods(%d):%n", methodsCount); @@ -331,7 +328,7 @@ private final void processMethods() throws IOException, ClassFormatException { * @throws IOException * @throws ClassFormatException */ - private final void processVersion() throws IOException, ClassFormatException { + private void processVersion() throws IOException, ClassFormatException { minor = file.readUnsignedShort(); System.out.printf(" minor version: %s%n", minor); diff --git a/src/examples/JasminVisitor.java b/src/examples/JasminVisitor.java index 16ef15c55b..12f4a92282 100644 --- a/src/examples/JasminVisitor.java +++ b/src/examples/JasminVisitor.java @@ -15,10 +15,13 @@ * limitations under the License. */ +import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Hashtable; import java.util.StringTokenizer; @@ -73,8 +76,10 @@ public static void main(final String[] argv) throws Exception { className = className.substring(index + 1); if (!path.isEmpty()) { - final File f = new File(path); - f.mkdirs(); + final File file = new File(path); + if (!file.mkdirs()) { + System.err.println("Couldn't create directories for " + file); + } } final String name = path + className + ".j"; @@ -85,19 +90,19 @@ public static void main(final String[] argv) throws Exception { } } - private final JavaClass clazz; - private final PrintWriter out; + private final JavaClass javaClass; + private final PrintWriter printWriter; private final String className; private final ConstantPoolGen cp; - private Method _method; + private Method method; private Hashtable map; public JasminVisitor(final JavaClass clazz, final OutputStream out) { - this.clazz = clazz; - this.out = new PrintWriter(out); + this.javaClass = clazz; + this.printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)), false); this.className = clazz.getClassName(); this.cp = new ConstantPoolGen(clazz.getConstantPool()); } @@ -106,8 +111,8 @@ public JasminVisitor(final JavaClass clazz, final OutputStream out) { * Start traversal using DefaultVisitor pattern. */ public void disassemble() { - new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit(); - out.close(); + new org.apache.bcel.classfile.DescendingVisitor(javaClass, this).visit(); + printWriter.close(); } private String get(final InstructionHandle ih) { @@ -120,10 +125,10 @@ private String get(final InstructionHandle ih) { * attributes if it's the last one and print ".end method" then. */ private void printEndMethod(final Attribute attr) { - final Attribute[] attributes = _method.getAttributes(); + final Attribute[] attributes = method.getAttributes(); if (attr == attributes[attributes.length - 1]) { - out.println(".end method"); + printWriter.println(".end method"); } } @@ -145,10 +150,10 @@ private void put(final InstructionHandle ih, final String line) { public void visitCode(final Code code) { int labelCounter = 0; - out.println(".limit stack " + code.getMaxStack()); - out.println(".limit locals " + code.getMaxLocals()); + printWriter.println(".limit stack " + code.getMaxStack()); + printWriter.println(".limit locals " + code.getMaxLocals()); - final MethodGen mg = new MethodGen(_method, className, cp); + final MethodGen mg = new MethodGen(method, className, cp); final InstructionList il = mg.getInstructionList(); final InstructionHandle[] ihs = il.getInstructionHandles(); @@ -199,18 +204,18 @@ public void visitCode(final Code code) { // Pass 2: Output code. for (final LocalVariableGen l : lvs) { - out.println( + printWriter.println( ".var " + l.getIndex() + " is " + l.getName() + " " + l.getType().getSignature() + " from " + get(l.getStart()) + " to " + get(l.getEnd())); } - out.print("\n"); + printWriter.print("\n"); for (InstructionHandle ih : ihs) { final Instruction inst = ih.getInstruction(); String str = map.get(ih); if (str != null) { - out.println(str); + printWriter.println(str); } if (inst instanceof BranchInstruction) { @@ -220,40 +225,40 @@ public void visitCode(final Code code) { final InstructionHandle[] targets = s.getTargets(); if (s instanceof TABLESWITCH) { - out.println("\ttableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); + printWriter.println("\ttableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); for (final InstructionHandle target : targets) { - out.println("\t\t" + get(target)); + printWriter.println("\t\t" + get(target)); } } else { // LOOKUPSWITCH - out.println("\tlookupswitch "); + printWriter.println("\tlookupswitch "); for (int j = 0; j < targets.length; j++) { - out.println("\t\t" + matchs[j] + " : " + get(targets[j])); + printWriter.println("\t\t" + matchs[j] + " : " + get(targets[j])); } } - out.println("\t\tdefault: " + get(s.getTarget())); // Applies for both + printWriter.println("\t\tdefault: " + get(s.getTarget())); // Applies for both } else { final BranchInstruction bi = (BranchInstruction) inst; ih = bi.getTarget(); str = get(ih); - out.println("\t" + Const.getOpcodeName(bi.getOpcode()) + " " + str); + printWriter.println("\t" + Const.getOpcodeName(bi.getOpcode()) + " " + str); } } else { - out.println("\t" + inst.toString(cp.getConstantPool())); + printWriter.println("\t" + inst.toString(cp.getConstantPool())); } } - out.print("\n"); + printWriter.print("\n"); for (final CodeExceptionGen c : ehs) { final ObjectType caught = c.getCatchType(); final String className = caught == null ? // catch any exception, used when compiling finally "all" : Utility.packageToPath(caught.getClassName()); - out.println(".catch " + className + " from " + get(c.getStartPC()) + " to " + get(c.getEndPC()) + " using " + get(c.getHandlerPC())); + printWriter.println(".catch " + className + " from " + get(c.getStartPC()) + " to " + get(c.getEndPC()) + " using " + get(c.getHandlerPC())); } printEndMethod(code); @@ -261,7 +266,7 @@ public void visitCode(final Code code) { @Override public void visitConstantValue(final ConstantValue cv) { - out.println(" = " + cv); + printWriter.println(" = " + cv); } @Override @@ -272,7 +277,7 @@ public void visitDeprecated(final Deprecated attribute) { @Override public void visitExceptionTable(final ExceptionTable e) { for (final String name : e.getExceptionNames()) { - out.println(".throws " + Utility.packageToPath(name)); + printWriter.println(".throws " + Utility.packageToPath(name)); } printEndMethod(e); @@ -280,45 +285,45 @@ public void visitExceptionTable(final ExceptionTable e) { @Override public void visitField(final Field field) { - out.print(".field " + Utility.accessToString(field.getAccessFlags()) + " \"" + field.getName() + "\"" + field.getSignature()); + printWriter.print(".field " + Utility.accessToString(field.getAccessFlags()) + " \"" + field.getName() + "\"" + field.getSignature()); if (field.getAttributes().length == 0) { - out.print("\n"); + printWriter.print("\n"); } } @Override public void visitJavaClass(final JavaClass clazz) { - out.println(";; Produced by JasminVisitor (BCEL)"); - out.println(";; https://commons.apache.org/bcel/"); - out.println(";; " + new Date() + "\n"); + printWriter.println(";; Produced by JasminVisitor (BCEL)"); + printWriter.println(";; https://commons.apache.org/bcel/"); + printWriter.println(";; " + new Date() + "\n"); - out.println(".source " + clazz.getSourceFileName()); - out.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " + Utility.accessToString(clazz.getAccessFlags(), true) + " " + printWriter.println(".source " + clazz.getSourceFileName()); + printWriter.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " + Utility.accessToString(clazz.getAccessFlags(), true) + " " + Utility.packageToPath(clazz.getClassName())); - out.println(".super " + Utility.packageToPath(clazz.getSuperclassName())); + printWriter.println(".super " + Utility.packageToPath(clazz.getSuperclassName())); for (final String iface : clazz.getInterfaceNames()) { - out.println(".implements " + Utility.packageToPath(iface)); + printWriter.println(".implements " + Utility.packageToPath(iface)); } - out.print("\n"); + printWriter.print("\n"); } @Override - public void visitMethod(final Method method) { - this._method = method; // Remember for use in subsequent visitXXX calls + public void visitMethod(final Method visitMethod) { + this.method = visitMethod; // Remember for use in subsequent visitXXX calls - out.println("\n.method " + Utility.accessToString(_method.getAccessFlags()) + " " + _method.getName() + _method.getSignature()); + printWriter.println("\n.method " + Utility.accessToString(method.getAccessFlags()) + " " + method.getName() + method.getSignature()); - final Attribute[] attributes = _method.getAttributes(); + final Attribute[] attributes = method.getAttributes(); if (attributes == null || attributes.length == 0) { - out.println(".end method"); + printWriter.println(".end method"); } } @Override public void visitSynthetic(final Synthetic attribute) { - if (_method != null) { + if (method != null) { printEndMethod(attribute); } } diff --git a/src/examples/Mini/ASTExpr.java b/src/examples/Mini/ASTExpr.java index 03b31f13ec..124c8185b0 100644 --- a/src/examples/Mini/ASTExpr.java +++ b/src/examples/Mini/ASTExpr.java @@ -41,7 +41,7 @@ * * A node with kind == -1 denotes the fact that this expression node has just one child branch and thus may be replaced * by this branch (or leaf) directly without altering the expression semantics. Term and Factor nodes are used only to - * build the parse tree obeying the aritmetical precedences (* stronger than +, etc.) and are discarded in the first + * build the parse tree obeying the arithmetical precedences (* stronger than +, etc.) and are discarded in the first * pass. */ public class ASTExpr extends SimpleNode implements MiniParserConstants, MiniParserTreeConstants { diff --git a/src/examples/Mini/ASTFunAppl.java b/src/examples/Mini/ASTFunAppl.java index d5e9a4756d..95c04b3737 100644 --- a/src/examples/Mini/ASTFunAppl.java +++ b/src/examples/Mini/ASTFunAppl.java @@ -25,6 +25,7 @@ import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.Type; +import org.apache.commons.lang3.ArrayUtils; /** */ @@ -72,7 +73,7 @@ public void byte_code(final InstructionList il, final MethodGen method, final Co ASTFunDecl.pop(); il.append(new INVOKESTATIC(cp.addMethodref(className, "_writeInt", "(I)I"))); } else { // Normal function - final int size = exprs.length; + final int size = ArrayUtils.getLength(exprs); Type[] argv = null; if (exprs != null) { diff --git a/src/examples/Mini/ASTFunDecl.java b/src/examples/Mini/ASTFunDecl.java index 2a3fadf591..f404c8aa0e 100644 --- a/src/examples/Mini/ASTFunDecl.java +++ b/src/examples/Mini/ASTFunDecl.java @@ -111,6 +111,7 @@ private static void optimizeIFs(final InstructionList il) { final InstructionTargeter[] targeters = target.getTargeters(); for (final InstructionTargeter targeter : targeters) { + // TODO Is this really identity equality and not object equality? if (target != match[4] || targeter != match[2]) { System.err.println("Unexpected: " + e); } @@ -317,7 +318,7 @@ public void code(final PrintWriter out) { } if (!ignore) { - final StringBuilder buf = new StringBuilder(); + final StringBuffer buf = new StringBuffer(); body.code(buf); out.println(getVarDecls()); diff --git a/src/examples/Mini/Environment.java b/src/examples/Mini/Environment.java index 3913e0a572..ead9561424 100644 --- a/src/examples/Mini/Environment.java +++ b/src/examples/Mini/Environment.java @@ -16,96 +16,44 @@ */ package Mini; -import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; /** * For efficiency and convenience reasons we want our own hash table. It does not conform to java.util.Dictionary(yet). * - * That environment contains all function definitions and identifiers. Hash keys are Strings (identifiers), which are - * mapped to a table index. + * That environment contains all function definitions and identifiers. Hash keys are Strings (identifiers), which are mapped to a table index. * - * The table consists of 'SIZE' fields which have 'SLOTS' subfields. Thus the maximum number of storable items is - * 'SLOTS' * 'SIZE'. + * The table consists of 'SIZE' fields which have 'SLOTS' subfields. Thus the maximum number of storable items is 'SLOTS' * 'SIZE'. */ public class Environment implements Cloneable { - private static final int SIZE = 127; // Prime number large enough for most cases - private static final int SLOTS = 3; // Number of slots of each field - - private static int lookup(final Vector v, final String key) throws ArrayIndexOutOfBoundsException { - final int len = v.size(); - - for (int i = 0; i < len; i++) { - final EnvEntry entry = v.elementAt(i); - if (entry.getHashKey().equals(key)) { - return i; - } - } - - return -1; - } - - private final int size; // The table is an array of - private final Vector[] table; // Vectors + private static final int SIZE = 127; // Prime number large enough for most cases - private int elements; + private final ConcurrentHashMap table; public Environment() { this(SIZE); } - public Environment(final int size) { - this.size = size; - table = new Vector[size]; + private Environment(final ConcurrentHashMap table) { + this.table = table; } - private Environment(final Vector[] table) { - size = table.length; - this.table = table; + public Environment(final int size) { + table = new ConcurrentHashMap<>(size); } @Override public Object clone() { - final Vector[] copy = new Vector[size]; - - for (int i = 0; i < size; i++) { - if (table[i] != null) { - copy[i] = (Vector) table[i].clone(); // Copies references - - /* - * int len = table[i].size(); - * - * copy[i] = new Vector(len); try { for(int j=0; j < len; j++) copy[i].addElement(table[i].elementAt(j)); } - * catch (ArrayIndexOutOfBoundsException e) {} - */ - } - } - - return new Environment(copy); + return new Environment(new ConcurrentHashMap<>(table)); } /** * Delete an object if it does exist. */ public void delete(final String key) { - int hash; - Vector v; - - hash = hashCode(key); - v = table[hash]; - - if (v == null) { - return; - } - - try { - final int index = lookup(v, key); - - if (index >= 0) { - elements--; // Count - v.removeElementAt(index); - } - } catch (final ArrayIndexOutOfBoundsException e) { + if (key != null) { + table.remove(key); } } @@ -113,94 +61,24 @@ public void delete(final String key) { * Gets entry from hash table. */ public EnvEntry get(final String key) { - int hash; - Vector v; - EnvEntry entry = null; - - hash = hashCode(key); - v = table[hash]; - - if (v == null) { - return null; - } - - try { - final int index = lookup(v, key); - - if (index >= 0) { - entry = v.elementAt(index); - } - } catch (final ArrayIndexOutOfBoundsException e) { - } - - return entry; + return key != null ? table.get(key) : null; } public EnvEntry[] getEntries() { - final EnvEntry[] entries = new EnvEntry[elements]; - int k = 0; - Vector v; - - for (int i = 0; i < size; i++) { - if ((v = table[i]) != null) { - final int len = v.size(); - try { - for (int j = 0; j < len; j++) { - entries[k++] = v.elementAt(j); - } - } catch (final ArrayIndexOutOfBoundsException e) { - } - } - } - - return entries; - } - - private int hashCode(final String key) { - return Math.abs(key.hashCode()) % size; + return table.values().toArray(new EnvEntry[0]); } /** * Inserts macro into table or overwrite old contents if it was already stored. + * + * @param obj the entry to add. */ public void put(final EnvEntry obj) { - int hash; - Vector v; - final String key = obj.getHashKey(); - - hash = hashCode(key); - v = table[hash]; - - elements++; // Count - - if (v == null) { - table[hash] = v = new Vector<>(SLOTS); - } else { - try { - final int index = lookup(v, key); - - if (index >= 0) { - v.setElementAt(obj, index); // Overwrite - return; - } - } catch (final ArrayIndexOutOfBoundsException e) { - } - } - - // Not found in Vector -> add it - v.addElement(obj); + table.put(obj.getHashKey(), obj); } @Override public String toString() { - final StringBuilder buf = new StringBuilder(); - - for (int i = 0; i < size; i++) { - if (table[i] != null) { - buf.append(table[i] + "\n"); - } - } - - return buf.toString(); + return table.toString(); } } diff --git a/src/examples/Mini/MiniC.java b/src/examples/Mini/MiniC.java index 62e3b9e2ae..685ca43917 100644 --- a/src/examples/Mini/MiniC.java +++ b/src/examples/Mini/MiniC.java @@ -18,8 +18,9 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.Vector; import org.apache.bcel.Const; @@ -64,11 +65,12 @@ final static String fillup(final int n, final int len) { } public static void main(final String[] argv) { - final String[] file_name = new String[argv.length]; + final String[] fileName = new String[argv.length]; + int files = 0; - MiniParser parser = null; - String base_name = null; - boolean byte_code = true; + MiniParser parser; + String baseName; + boolean byteCode = true; try { /* @@ -77,14 +79,14 @@ public static void main(final String[] argv) { for (final String element : argv) { if (element.charAt(0) == '-') { // command line switch if (element.equals("-java")) { - byte_code = false; + byteCode = false; } else if (element.equals("-bytecode")) { - byte_code = true; + byteCode = true; } else { throw new Exception("Unknown option: " + element); } } else { // add file name to list - file_name[files++] = element; + fileName[files++] = element; } } @@ -98,40 +100,42 @@ public static void main(final String[] argv) { pass = 0; if (j == 0) { - parser = new MiniParser(new FileInputStream(file_name[0])); + // side-effects + parser = new MiniParser(new FileInputStream(fileName[0])); + Objects.requireNonNull(parser, "parser"); } else { - MiniParser.ReInit(new FileInputStream(file_name[j])); + MiniParser.ReInit(new FileInputStream(fileName[j])); } - int index = file_name[j].lastIndexOf('.'); + int index = fileName[j].lastIndexOf('.'); if (index > 0) { - base_name = file_name[j].substring(0, index); + baseName = fileName[j].substring(0, index); } else { - base_name = file_name[j]; + baseName = fileName[j]; } - if ((index = base_name.lastIndexOf(File.separatorChar)) > 0) { - base_name = base_name.substring(index + 1); + if ((index = baseName.lastIndexOf(File.separatorChar)) > 0) { + baseName = baseName.substring(index + 1); } - file = file_name[j]; + file = fileName[j]; - System.out.println("Parsing ..."); + System.out.println("Parsing..."); MiniParser.Program(); ASTProgram program = (ASTProgram) MiniParser.jjtree.rootNode(); - System.out.println("Pass 1: Optimizing parse tree ..."); + System.out.println("Pass 1: Optimizing parse tree..."); pass = 1; program = program.traverse(); // program.dump(">"); if (errors.isEmpty()) { - System.out.println("Pass 2: Type checking (I) ..."); + System.out.println("Pass 2: Type checking (I)..."); program.eval(pass = 2); } if (errors.isEmpty()) { - System.out.println("Pass 3: Type checking (II) ..."); + System.out.println("Pass 3: Type checking (II)..."); program.eval(pass = 3); } @@ -140,24 +144,24 @@ public static void main(final String[] argv) { warnings.forEach(System.out::println); if (errors.isEmpty()) { - if (byte_code) { - System.out.println("Pass 5: Generating byte code ..."); - final ClassGen class_gen = new ClassGen(base_name, "java.lang.Object", file_name[j], + if (byteCode) { + System.out.println("Pass 5: Generating byte code..."); + final ClassGen classGen = new ClassGen(baseName, "java.lang.Object", fileName[j], Const.ACC_PUBLIC | Const.ACC_FINAL | Const.ACC_SUPER, null); - final ConstantPoolGen cp = class_gen.getConstantPool(); + final ConstantPoolGen cp = classGen.getConstantPool(); - program.byte_code(class_gen, cp); - final JavaClass clazz = class_gen.getJavaClass(); - clazz.dump(base_name + JavaClass.EXTENSION); + program.byte_code(classGen, cp); + final JavaClass clazz = classGen.getJavaClass(); + clazz.dump(baseName + JavaClass.EXTENSION); } else { - System.out.println("Pass 5: Generating Java code ..."); - try (final PrintWriter out = new PrintWriter(new FileOutputStream(base_name + ".java"))) { - program.code(out, base_name); + System.out.println("Pass 5: Generating Java code..."); + try (final PrintWriter out = new PrintWriter(baseName + ".java", StandardCharsets.UTF_8.name())) { + program.code(out, baseName); } - System.out.println("Pass 6: Compiling Java code ..."); + System.out.println("Pass 6: Compiling Java code..."); - final String[] args = { "javac", base_name + ".java" }; + final String[] args = { "javac", baseName + ".java" }; // sun.tools.javac.Main compiler = new sun.tools.javac.Main(System.err, "javac"); try { final Process p = Runtime.getRuntime().exec(args); diff --git a/src/examples/Package.java b/src/examples/Package.java index 484b0072e0..051bb76199 100644 --- a/src/examples/Package.java +++ b/src/examples/Package.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.TreeMap; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; @@ -217,9 +218,9 @@ void go(final String[] args) throws IOException { try (final JarOutputStream jarFile = new JarOutputStream(new FileOutputStream(defaultJar))) { jarFile.setLevel(5); // use compression int written = 0; - for (final String name : allClasses.keySet()) { // add entries for every class - final JavaClass claz = allClasses.get(name); - final ZipEntry zipEntry = new ZipEntry(name + JavaClass.EXTENSION); + for (final Entry entry : allClasses.entrySet()) { // add entries for every class + final JavaClass claz = allClasses.get(entry.getKey()); + final ZipEntry zipEntry = new ZipEntry(entry.getValue() + JavaClass.EXTENSION); final byte[] bytes = claz.getBytes(); final int length = bytes.length; jarFile.putNextEntry(zipEntry); diff --git a/src/examples/PatchClass.java b/src/examples/PatchClass.java index d1c4b2967e..8e3da974a9 100644 --- a/src/examples/PatchClass.java +++ b/src/examples/PatchClass.java @@ -32,7 +32,7 @@ public static void main(final String[] argv) throws Exception { int files = 0; if (argv.length < 3) { - System.err.println("Usage: patch file1.class ..."); + System.err.println("Usage: patch file1.class..."); System.exit(-1); } diff --git a/src/examples/ProxyCreator.java b/src/examples/ProxyCreator.java index 995f607191..0dde45fe2d 100644 --- a/src/examples/ProxyCreator.java +++ b/src/examples/ProxyCreator.java @@ -116,7 +116,7 @@ public static void main(final String[] argv) throws Exception { final String s = Utility.encode(bytes, true); System.out.println("Encoded class: " + s.length()); - System.out.print("Creating proxy ... "); + System.out.print("Creating proxy... "); final ActionListener a = (ActionListener) createProxy("foo.bar.", s); System.out.println("Done. Now calling actionPerformed()"); diff --git a/src/examples/TransitiveHull.java b/src/examples/TransitiveHull.java index 719eb42921..9a34c1dbdd 100644 --- a/src/examples/TransitiveHull.java +++ b/src/examples/TransitiveHull.java @@ -35,6 +35,7 @@ import org.apache.bcel.generic.Type; import org.apache.bcel.util.ClassQueue; import org.apache.bcel.util.ClassSet; +import org.apache.commons.lang3.ArrayUtils; /** * Find all classes referenced by given start class and all classes referenced by those and so on. In other words: @@ -52,6 +53,12 @@ */ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor { + /** + * Should be private. + * + * @deprecated Use {@link #getIgnored()}. + */ + @Deprecated public static final String[] IGNORED = {"java[.].*", "javax[.].*", "sun[.].*", "sunw[.].*", "com[.]sun[.].*", "org[.]omg[.].*", "org[.]w3c[.].*", "org[.]xml[.].*", "net[.]jini[.].*"}; @@ -129,7 +136,7 @@ public String[] getClassNames() { } public String[] getIgnored() { - return ignored; + return ignored != null ? ignored.clone() : null; } /** @@ -138,7 +145,7 @@ public String[] getIgnored() { * @param v Value to assign to ignored. */ public void setIgnored(final String[] v) { - ignored = v; + ignored = ArrayUtils.clone(v); } /** diff --git a/src/main/java/org/apache/bcel/Const.java b/src/main/java/org/apache/bcel/Const.java index fd554493fd..de00efa9ea 100644 --- a/src/main/java/org/apache/bcel/Const.java +++ b/src/main/java/org/apache/bcel/Const.java @@ -292,6 +292,30 @@ public final class Const { */ public static final short MINOR_21 = 0; + /** + * Minor version number of class files for Java 22: {@value}. + * + * @see #MAJOR_22 + * @since 6.10.0 + */ + public static final short MINOR_22 = 0; + + /** + * Minor version number of class files for Java 23: {@value}. + * + * @see #MAJOR_23 + * @since 6.10.0 + */ + public static final short MINOR_23 = 0; + + /** + * Minor version number of class files for Java 24: {@value}. + * + * @see #MAJOR_24 + * @since 6.10.0 + */ + public static final short MINOR_24 = 0; + /** * Major version number of class files for Java 14: {@value}. * @@ -356,6 +380,30 @@ public final class Const { */ public static final short MAJOR_21 = 65; + /** + * Major version number of class files for Java 22: {@value}. + * + * @see #MINOR_22 + * @since 6.10.0 + */ + public static final short MAJOR_22 = 66; + + /** + * Major version number of class files for Java 23: {@value}. + * + * @see #MINOR_23 + * @since 6.10.0 + */ + public static final short MAJOR_23 = 67; + + /** + * Major version number of class files for Java 24: {@value}. + * + * @see #MINOR_24 + * @since 6.10.0 + */ + public static final short MAJOR_24 = 68; + /** * Default major version number. Class file is for Java 1.1: {@value}. * diff --git a/src/main/java/org/apache/bcel/Constants.java b/src/main/java/org/apache/bcel/Constants.java index e3e733471b..824073b982 100644 --- a/src/main/java/org/apache/bcel/Constants.java +++ b/src/main/java/org/apache/bcel/Constants.java @@ -2415,7 +2415,7 @@ public interface Constants { byte ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS = 15; byte ATTR_ANNOTATION_DEFAULT = 16; - short KNOWN_ATTRIBUTES = 12;// should be 17 + short KNOWN_ATTRIBUTES = 12; // should be 17 // TODO: mutable public array!! String[] ATTRIBUTE_NAMES = {"SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", "InnerClasses", "Synthetic", diff --git a/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java b/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java index d932b112e2..e7c7e1d302 100644 --- a/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java +++ b/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java @@ -31,7 +31,7 @@ public ArrayElementValue(final int type, final ElementValue[] elementValues, fin if (type != ARRAY) { throw new ClassFormatException("Only element values of type array can be built with this ctor - type specified: " + type); } - this.elementValues = elementValues != null ? elementValues : ElementValue.EMPTY_ARRAY; + this.elementValues = elementValues != null ? elementValues : EMPTY_ARRAY; } @Override diff --git a/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java b/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java index ff4b93b01a..32d2acfcec 100644 --- a/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java +++ b/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java @@ -86,7 +86,7 @@ public BootstrapMethod(final int bootstrapMethodRef, final int[] bootstrapArgume public BootstrapMethod copy() { try { return (BootstrapMethod) clone(); - } catch (final CloneNotSupportedException e) { + } catch (final CloneNotSupportedException ignore) { // TODO should this throw? } return null; diff --git a/src/main/java/org/apache/bcel/classfile/Code.java b/src/main/java/org/apache/bcel/classfile/Code.java index 8ec211fba4..e20b70d1e7 100644 --- a/src/main/java/org/apache/bcel/classfile/Code.java +++ b/src/main/java/org/apache/bcel/classfile/Code.java @@ -103,7 +103,7 @@ public Code(final Code code) { final int attributesCount = file.readUnsignedShort(); attributes = new Attribute[attributesCount]; for (int i = 0; i < attributesCount; i++) { - attributes[i] = Attribute.readAttribute(file, constantPool); + attributes[i] = readAttribute(file, constantPool); } /* * Adjust length, because of setAttributes in this(), s.b. length is incorrect, because it didn't take the internal @@ -259,6 +259,20 @@ public LocalVariableTable getLocalVariableTable() { return null; } + /** + * Gets the local variable type table attribute {@link LocalVariableTypeTable}. + * @return LocalVariableTypeTable of Code, if it has one, null otherwise. + * @since 6.10.0 + */ + public LocalVariableTypeTable getLocalVariableTypeTable() { + for (final Attribute attribute : attributes) { + if (attribute instanceof LocalVariableTypeTable) { + return (LocalVariableTypeTable) attribute; + } + } + return null; + } + /** * @return Number of local variables. */ diff --git a/src/main/java/org/apache/bcel/classfile/ConstantUtf8.java b/src/main/java/org/apache/bcel/classfile/ConstantUtf8.java index 7ac35fb5a7..01cc7d42c8 100644 --- a/src/main/java/org/apache/bcel/classfile/ConstantUtf8.java +++ b/src/main/java/org/apache/bcel/classfile/ConstantUtf8.java @@ -77,7 +77,7 @@ protected boolean removeEldestEntry(final Map.Entry eldest private static final int MAX_ENTRY_SIZE = Integer.getInteger(SYS_PROP_CACHE_MAX_ENTRY_SIZE, 200).intValue(); static boolean isEnabled() { - return Cache.MAX_ENTRIES > 0 && MAX_ENTRY_SIZE > 0; + return MAX_ENTRIES > 0 && MAX_ENTRY_SIZE > 0; } } diff --git a/src/main/java/org/apache/bcel/classfile/ElementValue.java b/src/main/java/org/apache/bcel/classfile/ElementValue.java index 5619f48623..2ad5b14e03 100644 --- a/src/main/java/org/apache/bcel/classfile/ElementValue.java +++ b/src/main/java/org/apache/bcel/classfile/ElementValue.java @@ -121,7 +121,7 @@ public static ElementValue readElementValue(final DataInput input, final Constan final int numArrayVals = input.readUnsignedShort(); final ElementValue[] evalues = new ElementValue[numArrayVals]; for (int j = 0; j < numArrayVals; j++) { - evalues[j] = ElementValue.readElementValue(input, cpool, arrayNesting); + evalues[j] = readElementValue(input, cpool, arrayNesting); } return new ArrayElementValue(ARRAY, evalues, cpool); diff --git a/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java b/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java index 1b2081ed9c..bc13135a73 100644 --- a/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java +++ b/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java @@ -164,6 +164,22 @@ public AnnotationEntry[] getAnnotationEntries() { return annotationEntries; } + /** + * Gets attribute for given tag. + * @return Attribute for given tag, null if not found. + * Refer to {@link org.apache.bcel.Const#ATTR_UNKNOWN} constants named ATTR_* for possible values. + * @since 6.10.0 + */ + @SuppressWarnings("unchecked") + public final T getAttribute(final byte tag) { + for (final Attribute attribute : getAttributes()) { + if (attribute.getTag() == tag) { + return (T) attribute; + } + } + return null; + } + /** * @return Collection of object attributes. */ diff --git a/src/main/java/org/apache/bcel/classfile/JavaClass.java b/src/main/java/org/apache/bcel/classfile/JavaClass.java index d52336d011..29f76eedf3 100644 --- a/src/main/java/org/apache/bcel/classfile/JavaClass.java +++ b/src/main/java/org/apache/bcel/classfile/JavaClass.java @@ -467,7 +467,7 @@ public JavaClass[] getAllInterfaces() throws ClassNotFoundException { queue.enqueue(iface); } } - return allInterfaces.toArray(JavaClass.EMPTY_ARRAY); + return allInterfaces.toArray(EMPTY_ARRAY); } /** @@ -482,6 +482,22 @@ public AnnotationEntry[] getAnnotationEntries() { return annotations; } + /** + * Gets attribute for given tag. + * @return Attribute for given tag, null if not found. + * Refer to {@link org.apache.bcel.Const#ATTR_UNKNOWN} constants named ATTR_* for possible values. + * @since 6.10.0 + */ + @SuppressWarnings("unchecked") + public final T getAttribute(final byte tag) { + for (final Attribute attribute : getAttributes()) { + if (attribute.getTag() == tag) { + return (T) attribute; + } + } + return null; + } + /** * @return Attributes of the class. */ @@ -665,7 +681,7 @@ public JavaClass[] getSuperClasses() throws ClassNotFoundException { for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { allSuperClasses.add(clazz); } - return allSuperClasses.toArray(JavaClass.EMPTY_ARRAY); + return allSuperClasses.toArray(EMPTY_ARRAY); } /** @@ -703,7 +719,7 @@ public boolean implementationOf(final JavaClass inter) throws ClassNotFoundExcep if (!inter.isInterface()) { throw new IllegalArgumentException(inter.getClassName() + " is no interface"); } - if (this.equals(inter)) { + if (equals(inter)) { return true; } final JavaClass[] superInterfaces = getAllInterfaces(); @@ -722,7 +738,7 @@ public boolean implementationOf(final JavaClass inter) throws ClassNotFoundExcep * @throws ClassNotFoundException if superclasses or superinterfaces of this object can't be found */ public final boolean instanceOf(final JavaClass superclass) throws ClassNotFoundException { - if (this.equals(superclass)) { + if (equals(superclass)) { return true; } for (final JavaClass clazz : getSuperClasses()) { diff --git a/src/main/java/org/apache/bcel/classfile/Method.java b/src/main/java/org/apache/bcel/classfile/Method.java index 57a70ff8e7..8de79040fb 100644 --- a/src/main/java/org/apache/bcel/classfile/Method.java +++ b/src/main/java/org/apache/bcel/classfile/Method.java @@ -177,7 +177,7 @@ public LineNumberTable getLineNumberTable() { } /** - * @return LocalVariableTable of code attribute if any, i.e. the call is forwarded to the Code atribute. + * @return LocalVariableTable of code attribute if any, i.e. the call is forwarded to the Code attribute. */ public LocalVariableTable getLocalVariableTable() { final Code code = getCode(); @@ -187,6 +187,19 @@ public LocalVariableTable getLocalVariableTable() { return code.getLocalVariableTable(); } + /** + * Gets the local variable type table attribute {@link LocalVariableTypeTable}. + * @return LocalVariableTypeTable of code attribute if any, i.e. the call is forwarded to the Code attribute. + * @since 6.10.0 + */ + public LocalVariableTypeTable getLocalVariableTypeTable() { + final Code code = getCode(); + if (code == null) { + return null; + } + return code.getLocalVariableTypeTable(); + } + /** * @return Annotations on the parameters of a method * @since 6.0 diff --git a/src/main/java/org/apache/bcel/classfile/Module.java b/src/main/java/org/apache/bcel/classfile/Module.java index 11aea31697..3e8c9fb9b1 100644 --- a/src/main/java/org/apache/bcel/classfile/Module.java +++ b/src/main/java/org/apache/bcel/classfile/Module.java @@ -40,15 +40,23 @@ public final class Module extends Attribute { */ public static final String EXTENSION = ".jmod"; + private static String getClassNameAtIndex(final ConstantPool cp, final int index, final boolean compactClassName) { + final String className = cp.getConstantString(index, Const.CONSTANT_Class); + if (compactClassName) { + return Utility.compactClassName(className, false); + } + return className; + } private final int moduleNameIndex; private final int moduleFlags; - private final int moduleVersionIndex; + private final int moduleVersionIndex; private ModuleRequires[] requiresTable; private ModuleExports[] exportsTable; private ModuleOpens[] opensTable; private final int usesCount; private final int[] usesIndex; + private ModuleProvides[] providesTable; /** @@ -109,8 +117,6 @@ public void accept(final Visitor v) { v.visitModule(this); } - // TODO add more getters and setters? - /** * @return deep copy of this attribute */ @@ -182,6 +188,25 @@ public ModuleExports[] getExportsTable() { return exportsTable; } + /** + * Gets flags for this module. + * @return module flags + * @since 6.10.0 + */ + public int getModuleFlags() { + return moduleFlags; + } + + /** + * Gets module name. + * @param cp Array of constants + * @return module name + * @since 6.10.0 + */ + public String getModuleName(final ConstantPool cp) { + return cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module); + } + /** * @return table of provided interfaces * @see ModuleOpens @@ -206,6 +231,31 @@ public ModuleRequires[] getRequiresTable() { return requiresTable; } + /** + * Gets the array of class names for this module's uses. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @param compactClassName false for original constant pool value, true to replace '/' with '.' + * @return array of used class names + * @since 6.10.0 + */ + public String[] getUsedClassNames(final ConstantPool constantPool, final boolean compactClassName) { + final String[] usedClassNames = new String[usesCount]; + for (int i = 0; i < usesCount; i++) { + usedClassNames[i] = getClassNameAtIndex(constantPool, usesIndex[i], compactClassName); + } + return usedClassNames; + } + + /** + * Gets version for this module. + * @param cp Array of constants + * @return version from constant pool, "0" if version index is 0 + * @since 6.10.0 + */ + public String getVersion(final ConstantPool cp) { + return moduleVersionIndex == 0 ? "0" : cp.getConstantString(moduleVersionIndex, Const.CONSTANT_Utf8); + } + /** * @return String representation, i.e., a list of packages. */ @@ -214,9 +264,9 @@ public String toString() { final ConstantPool cp = super.getConstantPool(); final StringBuilder buf = new StringBuilder(); buf.append("Module:\n"); - buf.append(" name: ").append(Utility.pathToPackage(cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module))).append("\n"); + buf.append(" name: ").append(Utility.pathToPackage(getModuleName(cp))).append("\n"); buf.append(" flags: ").append(String.format("%04x", moduleFlags)).append("\n"); - final String version = moduleVersionIndex == 0 ? "0" : cp.getConstantString(moduleVersionIndex, Const.CONSTANT_Utf8); + final String version = getVersion(cp); buf.append(" version: ").append(version).append("\n"); buf.append(" requires(").append(requiresTable.length).append("):\n"); @@ -236,8 +286,8 @@ public String toString() { buf.append(" uses(").append(usesIndex.length).append("):\n"); for (final int index : usesIndex) { - final String className = cp.getConstantString(index, Const.CONSTANT_Class); - buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); + final String className = getClassNameAtIndex(cp, index, true); + buf.append(" ").append(className).append("\n"); } buf.append(" provides(").append(providesTable.length).append("):\n"); diff --git a/src/main/java/org/apache/bcel/classfile/ModuleExports.java b/src/main/java/org/apache/bcel/classfile/ModuleExports.java index 463ce4fd90..34460c4205 100644 --- a/src/main/java/org/apache/bcel/classfile/ModuleExports.java +++ b/src/main/java/org/apache/bcel/classfile/ModuleExports.java @@ -32,9 +32,13 @@ */ public final class ModuleExports implements Cloneable, Node { + private static String getToModuleNameAtIndex(final ConstantPool constantPool, final int index) { + return constantPool.getConstantString(index, Const.CONSTANT_Module); + } private final int exportsIndex; // points to CONSTANT_Package_info private final int exportsFlags; private final int exportsToCount; + private final int[] exportsToIndex; // points to CONSTANT_Module_info /** @@ -64,8 +68,6 @@ public void accept(final Visitor v) { v.visitModuleExports(this); } - // TODO add more getters and setters? - /** * @return deep copy of this object */ @@ -93,6 +95,39 @@ public void dump(final DataOutputStream file) throws IOException { } } + /** + * Gets the flags for this ModuleExports. + * @return the exportsFlags + * @since 6.10.0 + */ + public int getExportsFlags() { + return exportsFlags; + } + + /** + * Gets the exported package name. + * @param constantPool the constant pool from the ClassFile + * @return the exported package name + * @since 6.10.0 + */ + public String getPackageName(final ConstantPool constantPool) { + return constantPool.constantToString(exportsIndex, Const.CONSTANT_Package); + } + + /** + * Gets an array of module names for this ModuleExports. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @return array of module names following 'exports to' + * @since 6.10.0 + */ + public String[] getToModuleNames(final ConstantPool constantPool) { + final String[] toModuleNames = new String[exportsToCount]; + for (int i = 0; i < exportsToCount; i++) { + toModuleNames[i] = getToModuleNameAtIndex(constantPool, exportsToIndex[i]); + } + return toModuleNames; + } + /** * @return String representation */ @@ -106,13 +141,13 @@ public String toString() { */ public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String packageName = constantPool.constantToString(exportsIndex, Const.CONSTANT_Package); - buf.append(Utility.compactClassName(packageName, false)); + final String packageName = getPackageName(constantPool); + buf.append(packageName); buf.append(", ").append(String.format("%04x", exportsFlags)); buf.append(", to(").append(exportsToCount).append("):\n"); for (final int index : exportsToIndex) { - final String moduleName = constantPool.getConstantString(index, Const.CONSTANT_Module); - buf.append(" ").append(Utility.compactClassName(moduleName, false)).append("\n"); + final String moduleName = getToModuleNameAtIndex(constantPool, index); + buf.append(" ").append(moduleName).append("\n"); } return buf.substring(0, buf.length() - 1); // remove the last newline } diff --git a/src/main/java/org/apache/bcel/classfile/ModuleOpens.java b/src/main/java/org/apache/bcel/classfile/ModuleOpens.java index 00c0f3a377..c3b916eb93 100644 --- a/src/main/java/org/apache/bcel/classfile/ModuleOpens.java +++ b/src/main/java/org/apache/bcel/classfile/ModuleOpens.java @@ -32,9 +32,13 @@ */ public final class ModuleOpens implements Cloneable, Node { + private static String getToModuleNameAtIndex(final ConstantPool constantPool, final int index) { + return constantPool.getConstantString(index, Const.CONSTANT_Module); + } private final int opensIndex; // points to CONSTANT_Package_info private final int opensFlags; private final int opensToCount; + private final int[] opensToIndex; // points to CONSTANT_Module_info /** @@ -64,8 +68,6 @@ public void accept(final Visitor v) { v.visitModuleOpens(this); } - // TODO add more getters and setters? - /** * @return deep copy of this object */ @@ -93,6 +95,39 @@ public void dump(final DataOutputStream file) throws IOException { } } + /** + * Gets the flags for this ModuleOpens. + * @return the opensFlags + * @since 6.10.0 + */ + public int getOpensFlags() { + return opensFlags; + } + + /** + * Gets the opened package name. + * @param constantPool the constant pool from the ClassFile + * @return the opened package name + * @since 6.10.0 + */ + public String getPackageName(final ConstantPool constantPool) { + return constantPool.constantToString(opensIndex, Const.CONSTANT_Package); + } + + /** + * Gets an array of module names for this ModuleOpens. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @return array of module names following 'opens to' + * @since 6.10.0 + */ + public String[] getToModuleNames(final ConstantPool constantPool) { + final String[] toModuleNames = new String[opensToCount]; + for (int i = 0; i < opensToCount; i++) { + toModuleNames[i] = getToModuleNameAtIndex(constantPool, opensToIndex[i]); + } + return toModuleNames; + } + /** * @return String representation */ @@ -106,13 +141,13 @@ public String toString() { */ public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String packageName = constantPool.constantToString(opensIndex, Const.CONSTANT_Package); - buf.append(Utility.compactClassName(packageName, false)); + final String packageName = getPackageName(constantPool); + buf.append(packageName); buf.append(", ").append(String.format("%04x", opensFlags)); buf.append(", to(").append(opensToCount).append("):\n"); for (final int index : opensToIndex) { - final String moduleName = constantPool.getConstantString(index, Const.CONSTANT_Module); - buf.append(" ").append(Utility.compactClassName(moduleName, false)).append("\n"); + final String moduleName = getToModuleNameAtIndex(constantPool, index); + buf.append(" ").append(moduleName).append("\n"); } return buf.substring(0, buf.length() - 1); // remove the last newline } diff --git a/src/main/java/org/apache/bcel/classfile/ModuleProvides.java b/src/main/java/org/apache/bcel/classfile/ModuleProvides.java index af0778afb7..108b5dc6fe 100644 --- a/src/main/java/org/apache/bcel/classfile/ModuleProvides.java +++ b/src/main/java/org/apache/bcel/classfile/ModuleProvides.java @@ -32,8 +32,16 @@ */ public final class ModuleProvides implements Cloneable, Node { + private static String getImplementationClassNameAtIndex(final ConstantPool constantPool, final int index, final boolean compactClassName) { + final String className = constantPool.getConstantString(index, Const.CONSTANT_Class); + if (compactClassName) { + return Utility.compactClassName(className, false); + } + return className; + } private final int providesIndex; // points to CONSTANT_Class_info private final int providesWithCount; + private final int[] providesWithIndex; // points to CONSTANT_Class_info /** @@ -62,8 +70,6 @@ public void accept(final Visitor v) { v.visitModuleProvides(this); } - // TODO add more getters and setters? - /** * @return deep copy of this object */ @@ -90,6 +96,31 @@ public void dump(final DataOutputStream file) throws IOException { } } + /** + * Gets the array of implementation class names for this ModuleProvides. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @param compactClassName false for original constant pool value, true to replace '/' with '.' + * @return array of implementation class names + * @since 6.10.0 + */ + public String[] getImplementationClassNames(final ConstantPool constantPool, final boolean compactClassName) { + final String[] implementationClassNames = new String[providesWithCount]; + for (int i = 0; i < providesWithCount; i++) { + implementationClassNames[i] = getImplementationClassNameAtIndex(constantPool, providesWithIndex[i], compactClassName); + } + return implementationClassNames; + } + + /** + * Gets the interface name for this ModuleProvides. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @return interface name + * @since 6.10.0 + */ + public String getInterfaceName(final ConstantPool constantPool) { + return constantPool.constantToString(providesIndex, Const.CONSTANT_Class); + } + /** * @return String representation */ @@ -103,12 +134,12 @@ public String toString() { */ public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String interfaceName = constantPool.constantToString(providesIndex, Const.CONSTANT_Class); - buf.append(Utility.compactClassName(interfaceName, false)); + final String interfaceName = getInterfaceName(constantPool); + buf.append(interfaceName); buf.append(", with(").append(providesWithCount).append("):\n"); for (final int index : providesWithIndex) { - final String className = constantPool.getConstantString(index, Const.CONSTANT_Class); - buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); + final String className = getImplementationClassNameAtIndex(constantPool, index, true); + buf.append(" ").append(className).append("\n"); } return buf.substring(0, buf.length() - 1); // remove the last newline } diff --git a/src/main/java/org/apache/bcel/classfile/ModuleRequires.java b/src/main/java/org/apache/bcel/classfile/ModuleRequires.java index 371c35c6e7..5c97e70c7a 100644 --- a/src/main/java/org/apache/bcel/classfile/ModuleRequires.java +++ b/src/main/java/org/apache/bcel/classfile/ModuleRequires.java @@ -59,8 +59,6 @@ public void accept(final Visitor v) { v.visitModuleRequires(this); } - // TODO add more getters and setters? - /** * @return deep copy of this object */ @@ -85,6 +83,35 @@ public void dump(final DataOutputStream file) throws IOException { file.writeShort(requiresVersionIndex); } + /** + * Gets the module name from the constant pool. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @return module name + * @since 6.10.0 + */ + public String getModuleName(final ConstantPool constantPool) { + return constantPool.constantToString(requiresIndex, Const.CONSTANT_Module); + } + + /** + * Gets the flags for this ModuleRequires. + * @return the requiresFlags + * @since 6.10.0 + */ + public int getRequiresFlags() { + return requiresFlags; + } + + /** + * Gets the required version from the constant pool. + * @param constantPool Array of constants usually obtained from the ClassFile object + * @return required version, "0" if version index is 0. + * @since 6.10.0 + */ + public String getVersion(final ConstantPool constantPool) { + return requiresVersionIndex == 0 ? "0" : constantPool.getConstantString(requiresVersionIndex, Const.CONSTANT_Utf8); + } + /** * @return String representation */ @@ -98,10 +125,10 @@ public String toString() { */ public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String moduleName = constantPool.constantToString(requiresIndex, Const.CONSTANT_Module); - buf.append(Utility.compactClassName(moduleName, false)); + final String moduleName = getModuleName(constantPool); + buf.append(moduleName); buf.append(", ").append(String.format("%04x", requiresFlags)); - final String version = requiresVersionIndex == 0 ? "0" : constantPool.getConstantString(requiresVersionIndex, Const.CONSTANT_Utf8); + final String version = getVersion(constantPool); buf.append(", ").append(version); return buf.toString(); } diff --git a/src/main/java/org/apache/bcel/classfile/Signature.java b/src/main/java/org/apache/bcel/classfile/Signature.java index f36c08ad86..24ece2869d 100644 --- a/src/main/java/org/apache/bcel/classfile/Signature.java +++ b/src/main/java/org/apache/bcel/classfile/Signature.java @@ -105,7 +105,7 @@ private static void matchIdent(final MyByteArrayInputStream in, final StringBuil if ((ch = in.read()) == -1) { throw new IllegalArgumentException("Illegal signature: " + in.getData() + " no ident, reaching EOF"); } - // System.out.println("return from ident:" + (char)ch); + // System.out.println("return from ident:" + (char) ch); if (!identStart(ch)) { final StringBuilder buf2 = new StringBuilder(); int count = 1; @@ -123,7 +123,7 @@ private static void matchIdent(final MyByteArrayInputStream in, final StringBuil buf.append(buf2); ch = in.read(); in.unread(); - // System.out.println("so far:" + buf2 + ":next:" +(char)ch); + // System.out.println("so far:" + buf2 + ":next:" +(char) ch); } else { for (int i = 0; i < count; i++) { in.unread(); @@ -136,10 +136,10 @@ private static void matchIdent(final MyByteArrayInputStream in, final StringBuil do { buf2.append((char) ch); ch = in.read(); - // System.out.println("within ident:"+ (char)ch); + // System.out.println("within ident:"+ (char) ch); } while (ch != -1 && (Character.isJavaIdentifierPart((char) ch) || ch == '/')); buf.append(Utility.pathToPackage(buf2.toString())); - // System.out.println("regular return ident:"+ (char)ch + ":" + buf2); + // System.out.println("regular return ident:"+ (char) ch + ":" + buf2); if (ch != -1) { in.unread(); } diff --git a/src/main/java/org/apache/bcel/classfile/Utility.java b/src/main/java/org/apache/bcel/classfile/Utility.java index 76fc8932ab..2e54d2a374 100644 --- a/src/main/java/org/apache/bcel/classfile/Utility.java +++ b/src/main/java/org/apache/bcel/classfile/Utility.java @@ -1466,8 +1466,8 @@ public static String typeSignatureToString(final String signature, final boolean } else { type.append(typeSignatureToString(signature.substring(consumedChars), chopit)); // update our consumed count by the number of characters the for type argument - consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; - wrap(Utility.CONSUMER_CHARS, consumedChars); + consumedChars = unwrap(CONSUMER_CHARS) + consumedChars; + wrap(CONSUMER_CHARS, consumedChars); } // are there more TypeArguments? @@ -1487,8 +1487,8 @@ public static String typeSignatureToString(final String signature, final boolean } else { type.append(typeSignatureToString(signature.substring(consumedChars), chopit)); // update our consumed count by the number of characters the for type argument - consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; - wrap(Utility.CONSUMER_CHARS, consumedChars); + consumedChars = unwrap(CONSUMER_CHARS) + consumedChars; + wrap(CONSUMER_CHARS, consumedChars); } } @@ -1505,14 +1505,14 @@ public static String typeSignatureToString(final String signature, final boolean // update our consumed count by the number of characters the for type argument // note that this count includes the "L" we added, but that is ok // as it accounts for the "." we didn't consume - consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; - wrap(Utility.CONSUMER_CHARS, consumedChars); + consumedChars = unwrap(CONSUMER_CHARS) + consumedChars; + wrap(CONSUMER_CHARS, consumedChars); return type.toString(); } if (signature.charAt(consumedChars) != ';') { throw new ClassFormatException("Invalid signature: " + signature); } - wrap(Utility.CONSUMER_CHARS, consumedChars + 1); // remove final ";" + wrap(CONSUMER_CHARS, consumedChars + 1); // remove final ";" return type.toString(); } case 'S': @@ -1533,9 +1533,9 @@ public static String typeSignatureToString(final String signature, final boolean // The rest of the string denotes a '' type = typeSignatureToString(signature.substring(n), chopit); // corrected concurrent private static field acess - // Utility.consumed_chars += consumed_chars; is replaced by: - final int temp = unwrap(Utility.CONSUMER_CHARS) + consumedChars; - wrap(Utility.CONSUMER_CHARS, temp); + // consumed_chars += consumed_chars; is replaced by: + final int temp = unwrap(CONSUMER_CHARS) + consumedChars; + wrap(CONSUMER_CHARS, temp); return type + brackets.toString(); } case 'V': diff --git a/src/main/java/org/apache/bcel/generic/AnnotationEntryGen.java b/src/main/java/org/apache/bcel/generic/AnnotationEntryGen.java index e0e04ec4aa..30eeaead6b 100644 --- a/src/main/java/org/apache/bcel/generic/AnnotationEntryGen.java +++ b/src/main/java/org/apache/bcel/generic/AnnotationEntryGen.java @@ -280,12 +280,12 @@ public int getTypeIndex() { } public final String getTypeName() { - return getTypeSignature();// BCELBUG: Should I use this instead? + return getTypeSignature(); // BCELBUG: Should I use this instead? // Utility.signatureToString(getTypeSignature()); } public final String getTypeSignature() { - // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex); + // ConstantClass c = (ConstantClass) cpool.getConstant(typeIndex); final ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex/* c.getNameIndex() */); return utf8.getBytes(); } diff --git a/src/main/java/org/apache/bcel/generic/ArrayElementValueGen.java b/src/main/java/org/apache/bcel/generic/ArrayElementValueGen.java index 21442263d5..97a15b6896 100644 --- a/src/main/java/org/apache/bcel/generic/ArrayElementValueGen.java +++ b/src/main/java/org/apache/bcel/generic/ArrayElementValueGen.java @@ -43,7 +43,7 @@ public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen evalues = new ArrayList<>(); final ElementValue[] in = value.getElementValuesArray(); for (final ElementValue element : in) { - evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries)); + evalues.add(copy(element, cpool, copyPoolEntries)); } } @@ -57,7 +57,7 @@ public ArrayElementValueGen(final int type, final ElementValue[] elementValues, if (type != ARRAY) { throw new IllegalArgumentException("Only element values of type array can be built with this ctor - type specified: " + type); } - this.evalues = Streams.of(elementValues).map(e -> ElementValueGen.copy(e, cpool, true)).collect(Collectors.toList()); + this.evalues = Streams.of(elementValues).map(e -> copy(e, cpool, true)).collect(Collectors.toList()); } public void addElement(final ElementValueGen gen) { diff --git a/src/main/java/org/apache/bcel/generic/ClassElementValueGen.java b/src/main/java/org/apache/bcel/generic/ClassElementValueGen.java index bf2538b8f6..2a95d40a44 100644 --- a/src/main/java/org/apache/bcel/generic/ClassElementValueGen.java +++ b/src/main/java/org/apache/bcel/generic/ClassElementValueGen.java @@ -43,12 +43,12 @@ public ClassElementValueGen(final ClassElementValue value, final ConstantPoolGen } protected ClassElementValueGen(final int typeIdx, final ConstantPoolGen cpool) { - super(ElementValueGen.CLASS, cpool); + super(CLASS, cpool); this.idx = typeIdx; } public ClassElementValueGen(final ObjectType t, final ConstantPoolGen cpool) { - super(ElementValueGen.CLASS, cpool); + super(CLASS, cpool); // this.idx = cpool.addClass(t); idx = cpool.addUtf8(t.getSignature()); } @@ -62,9 +62,9 @@ public void dump(final DataOutputStream dos) throws IOException { public String getClassString() { final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); return cu8.getBytes(); - // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); + // ConstantClass c = (ConstantClass) getConstantPool().getConstant(idx); // ConstantUtf8 utf8 = - // (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); + // (ConstantUtf8) getConstantPool().getConstant(c.getNameIndex()); // return utf8.getBytes(); } diff --git a/src/main/java/org/apache/bcel/generic/ElementValuePairGen.java b/src/main/java/org/apache/bcel/generic/ElementValuePairGen.java index 6722d3c430..96be7a74c9 100644 --- a/src/main/java/org/apache/bcel/generic/ElementValuePairGen.java +++ b/src/main/java/org/apache/bcel/generic/ElementValuePairGen.java @@ -39,7 +39,7 @@ public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpo // Could assert nvp.getNameString() points to the same thing as // constantPoolGen.getConstant(nvp.getNameIndex()) // if - // (!nvp.getNameString().equals(((ConstantUtf8)constantPoolGen.getConstant(nvp.getNameIndex())).getBytes())) + // (!nvp.getNameString().equals(((ConstantUtf8) constantPoolGen.getConstant(nvp.getNameIndex())).getBytes())) // { // throw new IllegalArgumentException("envp buggered"); // } @@ -81,7 +81,7 @@ public int getNameIndex() { } public final String getNameString() { - // ConstantString cu8 = (ConstantString)constantPoolGen.getConstant(nameIdx); + // ConstantString cu8 = (ConstantString) constantPoolGen.getConstant(nameIdx); return ((ConstantUtf8) constantPoolGen.getConstant(nameIdx)).getBytes(); } diff --git a/src/main/java/org/apache/bcel/generic/EnumElementValueGen.java b/src/main/java/org/apache/bcel/generic/EnumElementValueGen.java index ef1f5f4c90..89fee99b01 100644 --- a/src/main/java/org/apache/bcel/generic/EnumElementValueGen.java +++ b/src/main/java/org/apache/bcel/generic/EnumElementValueGen.java @@ -35,10 +35,8 @@ public class EnumElementValueGen extends ElementValueGen { public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { super(ENUM_CONSTANT, cpool); if (copyPoolEntries) { - typeIdx = cpool.addUtf8(value.getEnumTypeString());// was - // addClass(value.getEnumTypeString()); - valueIdx = cpool.addUtf8(value.getEnumValueString()); // was - // addString(value.getEnumValueString()); + typeIdx = cpool.addUtf8(value.getEnumTypeString()); // was addClass(value.getEnumTypeString()); + valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString()); } else { typeIdx = value.getTypeIndex(); valueIdx = value.getValueIndex(); @@ -50,7 +48,7 @@ public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen c * This ctor is used for deserialization */ protected EnumElementValueGen(final int typeIdx, final int valueIdx, final ConstantPoolGen cpool) { - super(ElementValueGen.ENUM_CONSTANT, cpool); + super(ENUM_CONSTANT, cpool); if (super.getElementValueType() != ENUM_CONSTANT) { throw new IllegalArgumentException("Only element values of type enum can be built with this ctor - type specified: " + super.getElementValueType()); } @@ -59,9 +57,9 @@ protected EnumElementValueGen(final int typeIdx, final int valueIdx, final Const } public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) { - super(ElementValueGen.ENUM_CONSTANT, cpool); - typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); - valueIdx = cpool.addUtf8(value);// was addString(value); + super(ENUM_CONSTANT, cpool); + typeIdx = cpool.addUtf8(t.getSignature()); // was addClass(t); + valueIdx = cpool.addUtf8(value); // was addString(value); } @Override @@ -85,9 +83,9 @@ public ElementValue getElementValue() { public String getEnumTypeString() { // Constant cc = getConstantPool().getConstant(typeIdx); // ConstantClass cu8 = - // (ConstantClass)getConstantPool().getConstant(typeIdx); + // (ConstantClass) getConstantPool().getConstant(typeIdx); // return - // ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); + // ((ConstantUtf8) getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getBytes(); // return Utility.signatureToString(cu8.getBytes()); } @@ -95,9 +93,9 @@ public String getEnumTypeString() { public String getEnumValueString() { return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes(); // ConstantString cu8 = - // (ConstantString)getConstantPool().getConstant(valueIdx); + // (ConstantString) getConstantPool().getConstant(valueIdx); // return - // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + // ((ConstantUtf8) getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); } public int getTypeIndex() { @@ -113,8 +111,8 @@ public String stringifyValue() { final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx); return cu8.getBytes(); // ConstantString cu8 = - // (ConstantString)getConstantPool().getConstant(valueIdx); + // (ConstantString) getConstantPool().getConstant(valueIdx); // return - // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + // ((ConstantUtf8) getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); } } diff --git a/src/main/java/org/apache/bcel/generic/Instruction.java b/src/main/java/org/apache/bcel/generic/Instruction.java index 2e8fa151cc..1d82913202 100644 --- a/src/main/java/org/apache/bcel/generic/Instruction.java +++ b/src/main/java/org/apache/bcel/generic/Instruction.java @@ -456,7 +456,7 @@ public int consumeStack(final ConstantPoolGen cpg) { public Instruction copy() { Instruction i = null; // "Constant" instruction, no need to duplicate - if (InstructionConst.getInstruction(this.getOpcode()) != null) { + if (InstructionConst.getInstruction(getOpcode()) != null) { i = this; } else { try { diff --git a/src/main/java/org/apache/bcel/generic/InstructionList.java b/src/main/java/org/apache/bcel/generic/InstructionList.java index 0f4340b70f..0f2eece988 100644 --- a/src/main/java/org/apache/bcel/generic/InstructionList.java +++ b/src/main/java/org/apache/bcel/generic/InstructionList.java @@ -1137,7 +1137,7 @@ public void setPositions(final boolean check) { // called by code in other packa index += i.getLength(); } /* - * Pass 2: Expand the variable-length (Branch)Instructions depending on the target offset (short or int) and ensure that + * Pass 2: Expand the variable-length (Branch) Instructions depending on the target offset (short or int) and ensure that * branch targets are within this list. */ for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { diff --git a/src/main/java/org/apache/bcel/generic/InstructionTargeter.java b/src/main/java/org/apache/bcel/generic/InstructionTargeter.java index f958a25e73..856cd611b9 100644 --- a/src/main/java/org/apache/bcel/generic/InstructionTargeter.java +++ b/src/main/java/org/apache/bcel/generic/InstructionTargeter.java @@ -18,7 +18,7 @@ package org.apache.bcel.generic; /** - * Denote that a class targets InstructionHandles within an InstructionList. Namely the following implementers: + * Denotes that a class targets InstructionHandles within an InstructionList. * * @see BranchHandle * @see LocalVariableGen @@ -29,9 +29,12 @@ public interface InstructionTargeter { // static final InstructionTargeter[] EMPTY_ARRAY = new InstructionTargeter[0]; /** - * Checks whether this targeter targets the specified instruction handle. + * Tests whether this targeter targets the specified instruction handle. + * + * @param instructionHandle the instruction handle to test. + * @return whether this targeter targets the specified instruction handle. */ - boolean containsTarget(InstructionHandle ih); + boolean containsTarget(InstructionHandle instructionHandle); /** * Replaces the target of this targeter from this old handle to the new handle. diff --git a/src/main/java/org/apache/bcel/generic/ObjectType.java b/src/main/java/org/apache/bcel/generic/ObjectType.java index 95a4df3f4c..b1e93b3da8 100644 --- a/src/main/java/org/apache/bcel/generic/ObjectType.java +++ b/src/main/java/org/apache/bcel/generic/ObjectType.java @@ -146,7 +146,7 @@ public boolean referencesInterfaceExact() throws ClassNotFoundException { * @throws ClassNotFoundException if any of this class's superclasses can't be found */ public boolean subclassOf(final ObjectType superclass) throws ClassNotFoundException { - if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { + if (referencesInterfaceExact() || superclass.referencesInterfaceExact()) { return false; } return Repository.instanceOf(this.className, superclass.className); diff --git a/src/main/java/org/apache/bcel/generic/ReferenceType.java b/src/main/java/org/apache/bcel/generic/ReferenceType.java index 546bf0ae19..4468dcb2ff 100644 --- a/src/main/java/org/apache/bcel/generic/ReferenceType.java +++ b/src/main/java/org/apache/bcel/generic/ReferenceType.java @@ -38,10 +38,10 @@ protected ReferenceType(final byte t, final String s) { /** * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an - * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t - * is returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If - * "this" or t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an - * interface, then Type.OBJECT is returned. If not all of the two classes' superclasses cannot be found, "null" is + * interface). If one of the types is a superclass of the other, the former is returned. If "this" is NULL, then t + * is returned. If t is NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then {@link #OBJECT} is returned. If "this" or t is a ReferenceType referencing an + * interface, then {@link #OBJECT} is returned. If not all of the two classes' superclasses cannot be found, "null" is * returned. See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier". * * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. @@ -49,45 +49,45 @@ protected ReferenceType(final byte t, final String s) { */ @Deprecated public ReferenceType firstCommonSuperclass(final ReferenceType t) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { + if (equals(NULL)) { return t; } - if (t.equals(Type.NULL) || this.equals(t)) { + if (t.equals(NULL) || equals(t)) { return this; /* - * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also - * say all the objects referenced by Type.NULL were derived from {@link Object}. However, the Java Language's + * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by {@link #NULL} so we can also + * say all the objects referenced by {@link #NULL} were derived from {@link Object}. However, the Java Language's * "instanceof" operator proves us wrong: "null" is not referring to an instance of {@link Object} :) */ } if (this instanceof ArrayType || t instanceof ArrayType) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + return OBJECT; + // TODO: Is there a proof of {@link #OBJECT} being the direct ancestor of every ArrayType? } return getFirstCommonSuperclassInternal(t); } /** * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an - * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t - * is returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If - * "this" or t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the + * interface). If one of the types is a superclass of the other, the former is returned. If "this" is NULL, then t + * is returned. If t is NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then {@link #OBJECT} is returned; unless their dimensions match. Then an ArrayType of the * same number of dimensions is returned, with its basic type being the first common super class of the basic types of - * "this" and t. If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. If not all of + * "this" and t. If "this" or t is a ReferenceType referencing an interface, then {@link #OBJECT} is returned. If not all of * the two classes' superclasses cannot be found, "null" is returned. See the JVM specification edition 2, "�4.9.2 The * Bytecode Verifier". * * @throws ClassNotFoundException on failure to find superclasses of this type, or the type passed as a parameter */ public ReferenceType getFirstCommonSuperclass(final ReferenceType t) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { + if (equals(NULL)) { return t; } - if (t.equals(Type.NULL) || this.equals(t)) { + if (t.equals(NULL) || equals(t)) { return this; /* - * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also - * say all the objects referenced by Type.NULL were derived from {@link Object}. However, the Java Language's + * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by {@link #NULL} so we can also + * say all the objects referenced by {@link #NULL} were derived from {@link Object}. However, the Java Language's * "instanceof" operator proves us wrong: "null" is not referring to an instance of {@link Object} :) */ } @@ -102,8 +102,8 @@ public ReferenceType getFirstCommonSuperclass(final ReferenceType t) throws Clas } } if (this instanceof ArrayType || t instanceof ArrayType) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + return OBJECT; + // TODO: Is there a proof of {@link #OBJECT} being the direct ancestor of every ArrayType? } return getFirstCommonSuperclassInternal(t); } @@ -111,7 +111,7 @@ public ReferenceType getFirstCommonSuperclass(final ReferenceType t) throws Clas private ReferenceType getFirstCommonSuperclassInternal(final ReferenceType t) throws ClassNotFoundException { if (this instanceof ObjectType && ((ObjectType) this).referencesInterfaceExact() || t instanceof ObjectType && ((ObjectType) t).referencesInterfaceExact()) { - return Type.OBJECT; + return OBJECT; // TODO: The above line is correct comparing to the vmspec2. But one could // make class file verification a bit stronger here by using the notion of // superinterfaces or even castability or assignment compatibility. @@ -138,7 +138,7 @@ private ReferenceType getFirstCommonSuperclassInternal(final ReferenceType t) th } } } - // Huh? Did you ask for Type.OBJECT's superclass?? + // Huh? Did you ask for OBJECT's superclass?? return null; } @@ -154,7 +154,7 @@ public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundExce return false; } final ReferenceType T = (ReferenceType) t; - if (this.equals(Type.NULL)) { + if (equals(NULL)) { return true; // This is not explicitly stated, but clear. Isn't it? } /* @@ -165,7 +165,7 @@ public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundExce * If T is a class type, then this must be the same class as T, or this must be a subclass of T; */ if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() - && (this.equals(T) || Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { + && (equals(T) || Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { return true; } /* @@ -183,14 +183,14 @@ public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundExce /* * If T is a class type, then T must be Object (�2.4.7). */ - if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(Type.OBJECT)) { + if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(OBJECT)) { return true; } /* * If T is an interface type, then T must be the same interface as this or a superinterface of this (�2.13.2). */ if (T instanceof ObjectType && ((ObjectType) T).referencesInterfaceExact() - && (this.equals(T) || Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { + && (equals(T) || Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { return true; } } @@ -201,7 +201,7 @@ public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundExce /* * If T is a class type, then T must be Object (�2.4.7). */ - if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(Type.OBJECT)) { + if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(OBJECT)) { return true; } /* @@ -242,14 +242,14 @@ public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundExce /** * Return true iff this type is castable to another type t as defined in the JVM specification. The case where this is - * Type.NULL is not defined (see the CHECKCAST definition in the JVM specification). However, because e.g. CHECKCAST + * {@link #NULL} is not defined (see the CHECKCAST definition in the JVM specification). However, because e.g. CHECKCAST * doesn't throw a ClassCastException when casting a null reference to any Object, true is returned in this case. * * @throws ClassNotFoundException if any classes or interfaces required to determine assignment compatibility can't be * found */ public boolean isCastableTo(final Type t) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { + if (equals(NULL)) { return t instanceof ReferenceType; // If this is ever changed in isAssignmentCompatible() } return isAssignmentCompatibleWith(t); diff --git a/src/main/java/org/apache/bcel/generic/TargetLostException.java b/src/main/java/org/apache/bcel/generic/TargetLostException.java index 94abf59415..1fb3bf80ec 100644 --- a/src/main/java/org/apache/bcel/generic/TargetLostException.java +++ b/src/main/java/org/apache/bcel/generic/TargetLostException.java @@ -17,16 +17,16 @@ package org.apache.bcel.generic; /** - * Thrown by InstructionList.remove() when one or multiple disposed instructions are still being referenced by an - * InstructionTargeter object. I.e. the InstructionTargeter has to be notified that (one of) the InstructionHandle it is - * referencing is being removed from the InstructionList and thus not valid anymore. + * Thrown by {@link InstructionList} when one or multiple disposed instructions are still being referenced by an {@link InstructionTargeter} object. I.e. the + * {@link InstructionTargeter} has to be notified that (one of) the {@link InstructionHandle} it is referencing is being removed from the + * {@link InstructionList} and thus not valid anymore. * *

- * Making this an exception instead of a return value forces the user to handle these case explicitly in a try { ... } - * catch. The following code illustrates how this may be done: + * Making this an exception instead of a return value forces the user to handle these case explicitly in a try { ... } catch. The following code illustrates how + * this may be done: *

* - *
+ * 
  *     ...
  *     try {
  *         il.delete(start_ih, end_ih);
@@ -37,7 +37,7 @@
  *             }
  *         }
  *     }
- * 
+ *
* * @see InstructionHandle * @see InstructionList @@ -48,12 +48,14 @@ public final class TargetLostException extends Exception { private static final long serialVersionUID = -6857272667645328384L; private final InstructionHandle[] targets; - TargetLostException(final InstructionHandle[] t, final String mesg) { - super(mesg); - targets = t; + TargetLostException(final InstructionHandle[] targets, final String message) { + super(message); + this.targets = targets; } /** + * Gets the list of instructions still being targeted. + * * @return list of instructions still being targeted. */ public InstructionHandle[] getTargets() { diff --git a/src/main/java/org/apache/bcel/generic/Type.java b/src/main/java/org/apache/bcel/generic/Type.java index 76b833907f..058157a5ba 100644 --- a/src/main/java/org/apache/bcel/generic/Type.java +++ b/src/main/java/org/apache/bcel/generic/Type.java @@ -158,7 +158,7 @@ public static Type getReturnType(final String signature) { static int getReturnTypeSize(final String signature) { final int index = signature.lastIndexOf(')') + 1; - return Type.size(getTypeSize(signature.substring(index))); + return size(getTypeSize(signature.substring(index))); } public static String getSignature(final java.lang.reflect.Method meth) { @@ -385,14 +385,14 @@ public int hashCode() { } /** - * boolean, short and char variable are considered as int in the stack or local variable area. Returns {@link Type#INT} - * for {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise returns the given type. + * boolean, short and char variable are considered as int in the stack or local variable area. Returns {@link #INT} + * for {@link #BOOLEAN}, {@link #SHORT} or {@link #CHAR}, otherwise returns the given type. * * @since 6.0 */ public Type normalizeForStackOrLocal() { - if (this == Type.BOOLEAN || this == Type.BYTE || this == Type.SHORT || this == Type.CHAR) { - return Type.INT; + if (this == BOOLEAN || this == BYTE || this == SHORT || this == CHAR) { + return INT; } return this; } @@ -402,6 +402,6 @@ public Type normalizeForStackOrLocal() { */ @Override public String toString() { - return this.equals(Type.NULL) || type >= Const.T_UNKNOWN ? signature : Utility.signatureToString(signature, false); + return equals(NULL) || type >= Const.T_UNKNOWN ? signature : Utility.signatureToString(signature, false); } } diff --git a/src/main/java/org/apache/bcel/util/BCELFactory.java b/src/main/java/org/apache/bcel/util/BCELFactory.java index b00ab70396..e22c6ce304 100644 --- a/src/main/java/org/apache/bcel/util/BCELFactory.java +++ b/src/main/java/org/apache/bcel/util/BCELFactory.java @@ -83,7 +83,7 @@ private void createConstant(final Object value) { if (value instanceof String) { embed = '"' + Utility.convertString(embed) + '"'; } else if (value instanceof Character) { - embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); + embed = "(char) 0x" + Integer.toHexString(((Character) value).charValue()); } else if (value instanceof Float) { final Float f = (Float) value; if (Float.isNaN(f)) { diff --git a/src/main/java/org/apache/bcel/util/ClassPath.java b/src/main/java/org/apache/bcel/util/ClassPath.java index e48a63222e..0f1c342fc0 100644 --- a/src/main/java/org/apache/bcel/util/ClassPath.java +++ b/src/main/java/org/apache/bcel/util/ClassPath.java @@ -42,6 +42,7 @@ import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Utility; +import org.apache.commons.lang3.SystemProperties; /** * Loads class files from the CLASSPATH. Inspired by sun.tools.ClassPath. @@ -466,14 +467,14 @@ private static void addJdkModules(final String javaHome, final List list */ // @since 6.0 no longer final public static String getClassPath() { - final String classPathProp = System.getProperty("java.class.path"); + final String classPathProp = SystemProperties.getJavaClassPath(); final String bootClassPathProp = System.getProperty("sun.boot.class.path"); - final String extDirs = System.getProperty("java.ext.dirs"); + final String extDirs = SystemProperties.getJavaExtDirs(); // System.out.println("java.version = " + System.getProperty("java.version")); // System.out.println("java.class.path = " + classPathProp); // System.out.println("sun.boot.class.path=" + bootClassPathProp); // System.out.println("java.ext.dirs=" + extDirs); - final String javaHome = System.getProperty("java.home"); + final String javaHome = SystemProperties.getJavaHome(); final List list = new ArrayList<>(); // Starting in JRE 9, .class files are in the modules directory. Add them to the path. diff --git a/src/main/java/org/apache/bcel/verifier/VerifierAppFrame.java b/src/main/java/org/apache/bcel/verifier/VerifierAppFrame.java index e8482cc2ab..e7a26db2f5 100644 --- a/src/main/java/org/apache/bcel/verifier/VerifierAppFrame.java +++ b/src/main/java/org/apache/bcel/verifier/VerifierAppFrame.java @@ -128,11 +128,11 @@ JList getClassNamesJList() { /** Initizalization of the components. */ private void jbInit() { // setIconImage(Toolkit.getDefaultToolkit().createImage(Frame1.class.getResource("[Ihr Symbol]"))); - contentPane = (JPanel) this.getContentPane(); + contentPane = (JPanel) getContentPane(); contentPane.setLayout(cardLayout1); - this.setJMenuBar(jMenuBar1); + setJMenuBar(jMenuBar1); this.setSize(new Dimension(708, 451)); - this.setTitle("JustIce"); + setTitle("JustIce"); jPanel1.setMinimumSize(new Dimension(100, 100)); jPanel1.setPreferredSize(new Dimension(100, 100)); jPanel1.setLayout(gridLayout1); diff --git a/src/main/java/org/apache/bcel/verifier/VerifyDialog.java b/src/main/java/org/apache/bcel/verifier/VerifyDialog.java index 88ef3b3ffd..a276ec4dbc 100644 --- a/src/main/java/org/apache/bcel/verifier/VerifyDialog.java +++ b/src/main/java/org/apache/bcel/verifier/VerifyDialog.java @@ -29,7 +29,6 @@ import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JPanel; -import javax.swing.WindowConstants; import org.apache.bcel.Repository; import org.apache.bcel.classfile.JavaClass; @@ -51,16 +50,16 @@ final class IvjEventHandler implements ActionListener { @Override public void actionPerformed(final ActionEvent e) { - if (e.getSource() == VerifyDialog.this.getPass1Button()) { + if (e.getSource() == getPass1Button()) { connEtoC1(e); } - if (e.getSource() == VerifyDialog.this.getPass2Button()) { + if (e.getSource() == getPass2Button()) { connEtoC2(e); } - if (e.getSource() == VerifyDialog.this.getPass3Button()) { + if (e.getSource() == getPass3Button()) { connEtoC3(e); } - if (e.getSource() == VerifyDialog.this.getFlushButton()) { + if (e.getSource() == getFlushButton()) { connEtoC4(e); } } @@ -197,7 +196,7 @@ private void connEtoC1(final ActionEvent arg1) { try { // user code begin {1} // user code end - this.pass1Button_ActionPerformed(arg1); + pass1Button_ActionPerformed(arg1); // user code begin {2} // user code end } catch (final Throwable ivjExc) { @@ -212,7 +211,7 @@ private void connEtoC2(final ActionEvent arg1) { try { // user code begin {1} // user code end - this.pass2Button_ActionPerformed(arg1); + pass2Button_ActionPerformed(arg1); // user code begin {2} // user code end } catch (final Throwable ivjExc) { @@ -227,7 +226,7 @@ private void connEtoC3(final ActionEvent arg1) { try { // user code begin {1} // user code end - this.pass4Button_ActionPerformed(arg1); + pass4Button_ActionPerformed(arg1); // user code begin {2} // user code end } catch (final Throwable ivjExc) { @@ -242,7 +241,7 @@ private void connEtoC4(final ActionEvent arg1) { try { // user code begin {1} // user code end - this.flushButton_ActionPerformed(arg1); + flushButton_ActionPerformed(arg1); // user code begin {2} // user code end } catch (final Throwable ivjExc) { @@ -464,7 +463,7 @@ private void initialize() { // user code begin {1} // user code end setName("VerifyDialog"); - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); setSize(430, 280); setVisible(true); setModal(true); diff --git a/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java b/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java index 6ea0d18d1a..83f287cb44 100644 --- a/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java +++ b/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java @@ -1444,7 +1444,7 @@ private void finalMethodsAreNotOverridden() { * Leave that to JustIce. */ public LocalVariablesInfo getLocalVariablesInfo(final int methodNr) { - if (this.verify() != VerificationResult.VR_OK) { + if (verify() != VerificationResult.VR_OK) { return null; // It's cached, don't worry. } if (methodNr < 0 || methodNr >= localVariablesInfos.length) { diff --git a/src/main/java/org/apache/bcel/verifier/structurals/ControlFlowGraph.java b/src/main/java/org/apache/bcel/verifier/structurals/ControlFlowGraph.java index e2be0bf5b0..c67c7875ba 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/ControlFlowGraph.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/ControlFlowGraph.java @@ -238,7 +238,7 @@ public ExceptionHandler[] getExceptionHandlers() { * the surrounding ControlFlowGraph. */ private String getExecutionChain() { - final StringBuilder s = new StringBuilder(this.toString()); + final StringBuilder s = new StringBuilder(toString()); for (int i = executionPredecessors.size() - 1; i >= 0; i--) { s.insert(0, executionPredecessors.get(i) + "\n"); } diff --git a/src/main/java/org/apache/bcel/verifier/structurals/GenericArray.java b/src/main/java/org/apache/bcel/verifier/structurals/GenericArray.java index 0fa6e412f0..505e1b7ce4 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/GenericArray.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/GenericArray.java @@ -20,7 +20,7 @@ /** * A placeholder class that can be used to create an ObjectType of which has some of the properties arrays have. They - * implement {@link Cloneable} and {@link java.io.Serializable} and they extend {@link Object}. + * implement {@link Cloneable} and {@link Serializable} and they extend {@link Object}. */ public class GenericArray implements Cloneable, Serializable { diff --git a/src/main/java/org/apache/bcel/verifier/structurals/LocalVariables.java b/src/main/java/org/apache/bcel/verifier/structurals/LocalVariables.java index 1b27bb6769..05c8e1515a 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/LocalVariables.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/LocalVariables.java @@ -87,7 +87,7 @@ public Type get(final int slotIndex) { * @return a (correctly typed) clone of this object. */ public LocalVariables getClone() { - return (LocalVariables) this.clone(); + return (LocalVariables) clone(); } /** diff --git a/src/main/java/org/apache/bcel/verifier/structurals/OperandStack.java b/src/main/java/org/apache/bcel/verifier/structurals/OperandStack.java index c9250c4dbb..036297226e 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/OperandStack.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/OperandStack.java @@ -48,7 +48,7 @@ public OperandStack(final int maxStack) { */ public OperandStack(final int maxStack, final ObjectType obj) { this.maxStack = maxStack; - this.push(obj); + push(obj); } /** @@ -89,7 +89,7 @@ public boolean equals(final Object o) { * @see #clone() */ public OperandStack getClone() { - return (OperandStack) this.clone(); + return (OperandStack) clone(); } /** diff --git a/src/main/java/org/apache/bcel/verifier/structurals/Pass3bVerifier.java b/src/main/java/org/apache/bcel/verifier/structurals/Pass3bVerifier.java index 7e3413b585..c35b81f29c 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/Pass3bVerifier.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/Pass3bVerifier.java @@ -276,14 +276,14 @@ private void circulationPump(final MethodGen m, final ControlFlowGraph cfg, fina final LocalVariables lvs = f.getLocals(); for (int i = 0; i < lvs.maxLocals(); i++) { if (lvs.get(i) instanceof UninitializedObjectType) { - this.addMessage("Warning: ReturnInstruction '" + ic + "' may leave method with an uninitialized object in the local variables array '" + addMessage("Warning: ReturnInstruction '" + ic + "' may leave method with an uninitialized object in the local variables array '" + lvs + "'."); } } final OperandStack os = f.getStack(); for (int i = 0; i < os.size(); i++) { if (os.peek(i) instanceof UninitializedObjectType) { - this.addMessage( + addMessage( "Warning: ReturnInstruction '" + ic + "' may leave method with an uninitialized object on the operand stack '" + os + "'."); } } diff --git a/src/main/java/org/apache/bcel/verifier/structurals/Subroutines.java b/src/main/java/org/apache/bcel/verifier/structurals/Subroutines.java index 565c95362e..d79a9a0613 100644 --- a/src/main/java/org/apache/bcel/verifier/structurals/Subroutines.java +++ b/src/main/java/org/apache/bcel/verifier/structurals/Subroutines.java @@ -219,7 +219,7 @@ public int[] getRecursivelyAccessedLocalsIndices() { for (final int lv : lvs) { s.add(Integer.valueOf(lv)); } - getRecursivelyAccessedLocalsIndicesHelper(s, this.subSubs()); + getRecursivelyAccessedLocalsIndicesHelper(s, subSubs()); final int[] ret = new int[s.size()]; int j = -1; for (final Integer index : s) { diff --git a/src/site/xdoc/download_bcel.xml b/src/site/xdoc/download_bcel.xml index 1aee8987df..e26048f0f6 100644 --- a/src/site/xdoc/download_bcel.xml +++ b/src/site/xdoc/download_bcel.xml @@ -113,32 +113,32 @@ limitations under the License.

-
+
- - - + + + - - - + + +
bcel-6.9.0-bin.tar.gzsha512pgpbcel-6.10.0-bin.tar.gzsha512pgp
bcel-6.9.0-bin.zipsha512pgpbcel-6.10.0-bin.zipsha512pgp
- - - + + + - - - + + +
bcel-6.9.0-src.tar.gzsha512pgpbcel-6.10.0-src.tar.gzsha512pgp
bcel-6.9.0-src.zipsha512pgpbcel-6.10.0-src.zipsha512pgp
diff --git a/src/test/java/org/apache/bcel/AnonymousClassTestCase.java b/src/test/java/org/apache/bcel/AnonymousClassTestCase.java index 1d65fa965b..b6420642a4 100644 --- a/src/test/java/org/apache/bcel/AnonymousClassTestCase.java +++ b/src/test/java/org/apache/bcel/AnonymousClassTestCase.java @@ -17,10 +17,15 @@ package org.apache.bcel; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.apache.bcel.classfile.InnerClass; +import org.apache.bcel.classfile.InnerClasses; import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.data.EmptyClass; import org.junit.jupiter.api.Test; public class AnonymousClassTestCase extends AbstractTestCase { @@ -38,6 +43,15 @@ public void testNamedInnerClassIsNotAnonymous() throws ClassNotFoundException { assertTrue(clazz.isNested(), "regular inner classes are nested"); } + @Test + public void testRegularClassInnerClasses() throws ClassNotFoundException { + final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnonymousClassTest"); + final InnerClasses innerClasses = clazz.getAttribute(Const.ATTR_INNER_CLASSES); + final InnerClass[] innerClassArray = innerClasses.getInnerClasses(); + assertEquals(3, innerClassArray.length); + assertNull(Repository.lookupClass(EmptyClass.class).getAttribute(Const.ATTR_INNER_CLASSES)); + } + @Test public void testRegularClassIsNotAnonymous() throws ClassNotFoundException { final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnonymousClassTest"); diff --git a/src/test/java/org/apache/bcel/ConstTest.java b/src/test/java/org/apache/bcel/ConstTest.java new file mode 100644 index 0000000000..94310df8d1 --- /dev/null +++ b/src/test/java/org/apache/bcel/ConstTest.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.bcel; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Tests {@link Const}. + */ +public class ConstTest { + + @Test + public void testJava22() throws Exception { + assertEquals(66, Const.MAJOR_22); + assertEquals(0, Const.MINOR_22); + } + + @Test + public void testJava23() throws Exception { + assertEquals(67, Const.MAJOR_23); + assertEquals(0, Const.MINOR_23); + } + + @Test + public void testJava24() throws Exception { + assertEquals(68, Const.MAJOR_24); + assertEquals(0, Const.MINOR_24); + } +} diff --git a/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java index 6d5068efc1..0079a20ed5 100644 --- a/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java +++ b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java @@ -16,11 +16,15 @@ */ package org.apache.bcel; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + import java.lang.reflect.InvocationTargetException; import java.util.LinkedList; import java.util.List; import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.LocalVariableTypeTable; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.ACONST_NULL; import org.apache.bcel.generic.ALOAD; @@ -128,6 +132,22 @@ public InstructionList makeWillBeAddedInstructionList(final MethodGen methodGen, return createPrintln(methodGen.getConstantPool(), instruction); } + @Test + public void testGetLocalVariableTypeTable() throws ClassNotFoundException, NoSuchMethodException, SecurityException { + final JavaClass testJavaClass = getTestJavaClass("org/apache/commons/lang3/function/TriFunction"); + final String expectedToString = "LocalVariableTypes(startPc = 0, length = 17, index = 0:org.apache.commons.lang3.function.TriFunction this)"; + for (final Method method : testJavaClass.getMethods()) { + if ("lambda$andThen$0".equals(method.getName())) { + final LocalVariableTypeTable localVariableTypeTable = method.getLocalVariableTypeTable(); + assertEquals(expectedToString, localVariableTypeTable.toString()); + } + if ("apply".equals(method.getName())) { + assertNull(method.getLocalVariableTypeTable()); + } + } + assertNull(Repository.lookupClass(Object.class).getMethod(Object.class.getMethod("toString")).getLocalVariableTypeTable()); + } + @Test public void testWithGenericArguement() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { final String targetClass = PACKAGE_BASE_NAME + ".data.SimpleClassHasMethodIncludeGenericArgument"; diff --git a/src/test/java/org/apache/bcel/PerformanceTest.java b/src/test/java/org/apache/bcel/PerformanceTest.java index 7191d6d44b..7b7dff4bbd 100644 --- a/src/test/java/org/apache/bcel/PerformanceTest.java +++ b/src/test/java/org/apache/bcel/PerformanceTest.java @@ -34,6 +34,7 @@ import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.MethodGen; +import org.apache.commons.lang3.SystemProperties; import org.junit.jupiter.api.Test; public final class PerformanceTest { @@ -130,7 +131,7 @@ private static void test(final File lib) throws IOException { @Test public void testPerformance() { - final File javaLib = new File(System.getProperty("java.home"), "lib"); + final File javaLib = new File(SystemProperties.getJavaHome(), "lib"); javaLib.listFiles(file -> { if (file.getName().endsWith(".jar")) { try { diff --git a/src/test/java/org/apache/bcel/classfile/ConstantPoolModuleAccessTestCase.java b/src/test/java/org/apache/bcel/classfile/ConstantPoolModuleAccessTestCase.java new file mode 100644 index 0000000000..2c4eb29045 --- /dev/null +++ b/src/test/java/org/apache/bcel/classfile/ConstantPoolModuleAccessTestCase.java @@ -0,0 +1,369 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.bcel.classfile; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.apache.bcel.Const; +import org.apache.commons.lang3.stream.Streams; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * Tests {@code module-info.class} files. + */ +public final class ConstantPoolModuleAccessTestCase { + + static Stream testJREModules() throws IOException { + return Streams.of(ConstantPoolModuleAccessTestCase.class.getClassLoader().getResources("module-info.class")); + } + + @ParameterizedTest + @MethodSource + public void testJREModules(final URL url) throws Exception { + try (InputStream inputStream = url.openStream()) { + final ClassParser classParser = new ClassParser(inputStream, "module-info.class"); + final JavaClass javaClass = classParser.parse(); + final ConstantPool constantPool = javaClass.getConstantPool(); + final EmptyVisitor visitor = new EmptyVisitor() { + @Override + public void visitModule(final Module obj) { + final String urlPath = url.getPath(); + if (urlPath.contains("/commons-")) { + assertEquals(4096, obj.getModuleFlags(), url.toString()); + } else { + assertEquals(0, obj.getModuleFlags(), url.toString()); + } + final String[] usedClassNames = obj.getUsedClassNames(constantPool, true); + if (urlPath.contains("junit-jupiter-engine")) { + assertEquals(1, usedClassNames.length); + assertEquals("org.junit.jupiter.api.extension.Extension", usedClassNames[0]); + } else if (urlPath.contains("junit-platform-launcher")) { + final List expected = new ArrayList<>(); + expected.add("org.junit.platform.engine.TestEngine"); + expected.add("org.junit.platform.launcher.LauncherDiscoveryListener"); + expected.add("org.junit.platform.launcher.LauncherInterceptor"); + expected.add("org.junit.platform.launcher.LauncherSessionListener"); + expected.add("org.junit.platform.launcher.PostDiscoveryFilter"); + expected.add("org.junit.platform.launcher.TestExecutionListener"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("junit-platform-engine")) { + final List expected = new ArrayList<>(); + expected.add("org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.rmi/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("java.rmi.server.RMIClassLoaderSpi"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.xml/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.xml.datatype.DatatypeFactory"); + expected.add("javax.xml.parsers.DocumentBuilderFactory"); + expected.add("javax.xml.parsers.SAXParserFactory"); + expected.add("javax.xml.stream.XMLEventFactory"); + expected.add("javax.xml.stream.XMLInputFactory"); + expected.add("javax.xml.stream.XMLOutputFactory"); + expected.add("javax.xml.transform.TransformerFactory"); + expected.add("javax.xml.validation.SchemaFactory"); + expected.add("javax.xml.xpath.XPathFactory"); + expected.add("org.xml.sax.XMLReader"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.datatransfer/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("sun.datatransfer.DesktopDatatransferService"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.desktop/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("java.awt.im.spi.InputMethodDescriptor"); + expected.add("javax.accessibility.AccessibilityProvider"); + expected.add("javax.imageio.spi.ImageInputStreamSpi"); + expected.add("javax.imageio.spi.ImageOutputStreamSpi"); + expected.add("javax.imageio.spi.ImageReaderSpi"); + expected.add("javax.imageio.spi.ImageTranscoderSpi"); + expected.add("javax.imageio.spi.ImageWriterSpi"); + expected.add("javax.print.PrintServiceLookup"); + expected.add("javax.print.StreamPrintServiceFactory"); + expected.add("javax.sound.midi.spi.MidiDeviceProvider"); + expected.add("javax.sound.midi.spi.MidiFileReader"); + expected.add("javax.sound.midi.spi.MidiFileWriter"); + expected.add("javax.sound.midi.spi.SoundbankReader"); + expected.add("javax.sound.sampled.spi.AudioFileReader"); + expected.add("javax.sound.sampled.spi.AudioFileWriter"); + expected.add("javax.sound.sampled.spi.FormatConversionProvider"); + expected.add("javax.sound.sampled.spi.MixerProvider"); + expected.add("sun.swing.InteropProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.naming/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.naming.ldap.StartTlsResponse"); + expected.add("javax.naming.spi.InitialContextFactory"); + if (javaClass.getMajor() > Const.MAJOR_11) { + expected.add("javax.naming.ldap.spi.LdapDnsProvider"); + } + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.prefs/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("java.util.prefs.PreferencesFactory"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.base/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("java.lang.System$LoggerFinder"); + expected.add("java.net.ContentHandlerFactory"); + if (javaClass.getMajor() > Const.MAJOR_17) { + expected.add("java.net.spi.InetAddressResolverProvider"); + } + expected.add("java.net.spi.URLStreamHandlerProvider"); + expected.add("java.nio.channels.spi.AsynchronousChannelProvider"); + expected.add("java.nio.channels.spi.SelectorProvider"); + expected.add("java.nio.charset.spi.CharsetProvider"); + expected.add("java.nio.file.spi.FileSystemProvider"); + expected.add("java.nio.file.spi.FileTypeDetector"); + expected.add("java.security.Provider"); + expected.add("java.text.spi.BreakIteratorProvider"); + expected.add("java.text.spi.CollatorProvider"); + expected.add("java.text.spi.DateFormatProvider"); + expected.add("java.text.spi.DateFormatSymbolsProvider"); + expected.add("java.text.spi.DecimalFormatSymbolsProvider"); + expected.add("java.text.spi.NumberFormatProvider"); + expected.add("java.time.chrono.AbstractChronology"); + expected.add("java.time.chrono.Chronology"); + expected.add("java.time.zone.ZoneRulesProvider"); + if (javaClass.getMajor() > Const.MAJOR_11) { + expected.add("java.util.random.RandomGenerator"); + } + expected.add("java.util.spi.CalendarDataProvider"); + expected.add("java.util.spi.CalendarNameProvider"); + expected.add("java.util.spi.CurrencyNameProvider"); + expected.add("java.util.spi.LocaleNameProvider"); + expected.add("java.util.spi.ResourceBundleControlProvider"); + expected.add("java.util.spi.ResourceBundleProvider"); + expected.add("java.util.spi.TimeZoneNameProvider"); + expected.add("java.util.spi.ToolProvider"); + expected.add("javax.security.auth.spi.LoginModule"); + if (javaClass.getMajor() > Const.MAJOR_17) { + expected.add("jdk.internal.io.JdkConsoleProvider"); + } + expected.add("jdk.internal.logger.DefaultLoggerFinder"); + expected.add("sun.text.spi.JavaTimeDateTimePatternProvider"); + expected.add("sun.util.locale.provider.LocaleDataMetaInfo"); + expected.add("sun.util.resources.LocaleData$CommonResourceBundleProvider"); + expected.add("sun.util.resources.LocaleData$SupplementaryResourceBundleProvider"); + expected.add("sun.util.spi.CalendarProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.management.agent/module-info.class") && javaClass.getMajor() < Const.MAJOR_21) { + final List expected = new ArrayList<>(); + expected.add("jdk.internal.agent.spi.AgentProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.management/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.management.remote.JMXConnectorProvider"); + expected.add("javax.management.remote.JMXConnectorServerProvider"); + expected.add("sun.management.spi.PlatformMBeanProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.sql/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("java.sql.Driver"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.httpserver/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("com.sun.net.httpserver.spi.HttpServerProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.sql.rowset/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.sql.rowset.RowSetFactory"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.compiler/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.tools.DocumentationTool"); + expected.add("javax.tools.JavaCompiler"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/java.scripting/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.script.ScriptEngineFactory"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.dynalink/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("jdk.dynalink.linker.GuardingDynamicLinkerExporter"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jdi/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("com.sun.jdi.connect.Connector"); + expected.add("com.sun.jdi.connect.spi.TransportService"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.compiler/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("javax.annotation.processing.Processor"); + expected.add("com.sun.source.util.Plugin"); + if (javaClass.getMajor() > Const.MAJOR_11) { + expected.add("com.sun.tools.doclint.DocLint"); + } + expected.add("com.sun.tools.javac.platform.PlatformProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jconsole/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("com.sun.tools.jconsole.JConsolePlugin"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.attach/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("com.sun.tools.attach.spi.AttachProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jshell/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("jdk.jshell.spi.ExecutionControlProvider"); + expected.add("jdk.internal.editor.spi.BuildInEditorProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.internal.le/module-info.class")) { + final List expected = new ArrayList<>(); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jlink/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("jdk.tools.jlink.plugin.Plugin"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.internal.jvmstat/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("sun.jvmstat.monitor.MonitoredHostService"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jpackage/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("jdk.jpackage.internal.Bundler"); + expected.add("jdk.jpackage.internal.Bundlers"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.naming.ldap/module-info.class")) { + final List expected = new ArrayList<>(); + expected.add("com.sun.jndi.ldap.spi.LdapDnsProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/jdk.jsobject/module-info.class") && javaClass.getMajor() == Const.MAJOR_11) { + final List expected = new ArrayList<>(); + expected.add("jdk.internal.netscape.javascript.spi.JSObjectProvider"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else if (urlPath.contains("/org/assertj/assertj-core/")) { + final List expected = new ArrayList<>(); + expected.add("org.assertj.core.configuration.Configuration"); + expected.add("org.assertj.core.presentation.Representation"); + assertEquals(expected, Arrays.asList(usedClassNames)); + } else { + assertEquals(0, usedClassNames.length, "Found " + Arrays.toString(usedClassNames) + " in " + urlPath); + } + super.visitModule(obj); + } + + @Override + public void visitModuleExports(final ModuleExports obj) { + assertEquals(0, obj.getExportsFlags(), url.toString()); + final String packageName = obj.getPackageName(constantPool); + final String[] toModuleNames = obj.getToModuleNames(constantPool); + if (url.getPath().contains("junit-platform-commons")) { + final List expected = new ArrayList<>(); + expected.add("org.junit.jupiter.api"); + expected.add("org.junit.jupiter.engine"); + expected.add("org.junit.jupiter.migrationsupport"); + expected.add("org.junit.jupiter.params"); + expected.add("org.junit.platform.console"); + expected.add("org.junit.platform.engine"); + expected.add("org.junit.platform.launcher"); + expected.add("org.junit.platform.reporting"); + expected.add("org.junit.platform.runner"); + expected.add("org.junit.platform.suite.api"); + switch (packageName) { + case "org.junit.platform.commons.util": + expected.add("org.junit.platform.suite.commons"); + expected.add("org.junit.platform.suite.engine"); + expected.add("org.junit.platform.testkit"); + expected.add("org.junit.vintage.engine"); + assertEquals(expected, Arrays.asList(toModuleNames)); + break; + case "org.junit.platform.commons.logging": + expected.add("org.junit.platform.suite.engine"); + expected.add("org.junit.platform.testkit"); + expected.add("org.junit.vintage.engine"); + assertEquals(expected, Arrays.asList(toModuleNames)); + break; + default: + assertEquals(0, toModuleNames.length); + break; + } + } + super.visitModuleExports(obj); + } + + @Override + public void visitModuleOpens(final ModuleOpens obj) { + assertEquals(0, obj.getOpensFlags(), url.toString()); + final String packageName = obj.getPackageName(constantPool); + final String[] toModuleNames = obj.getToModuleNames(constantPool); + final String urlPath = url.getPath(); + if (urlPath.contains("junit-jupiter-engine")) { + assertEquals("org.junit.jupiter.engine.extension", packageName); + assertEquals(1, toModuleNames.length); + assertEquals("org.junit.platform.commons", toModuleNames[0]); + } else if (urlPath.contains("junit-jupiter-api")) { + assertEquals("org.junit.jupiter.api.condition", packageName); + assertEquals(1, toModuleNames.length); + assertEquals("org.junit.platform.commons", toModuleNames[0]); + } + super.visitModuleOpens(obj); + } + + @Override + public void visitModuleProvides(final ModuleProvides obj) { + final String interfaceName = obj.getInterfaceName(constantPool); + final String[] implementationClassNames = obj.getImplementationClassNames(constantPool, true); + final String urlPath = url.getPath(); + if (urlPath.contains("junit-jupiter-engine")) { + assertEquals("org.junit.platform.engine.TestEngine", interfaceName); + assertEquals(1, implementationClassNames.length); + assertEquals("org.junit.jupiter.engine.JupiterTestEngine", implementationClassNames[0]); + } else if (urlPath.contains("junit-platform-launcher")) { + assertEquals("org.junit.platform.launcher.TestExecutionListener", interfaceName); + assertEquals(1, implementationClassNames.length); + assertEquals("org.junit.platform.launcher.listeners.UniqueIdTrackingListener", implementationClassNames[0]); + } + super.visitModuleProvides(obj); + } + + @Override + public void visitModuleRequires(final ModuleRequires obj) { + if (url.getPath().contains("junit-jupiter-engine")) { + final String moduleName = obj.getModuleName(constantPool); + final Map expected = new HashMap<>(); + expected.put("java.base", 32768); + expected.put("org.apiguardian.api", 64); + expected.put("org.junit.jupiter.api", 0); + expected.put("org.junit.platform.commons", 0); + expected.put("org.junit.platform.engine", 0); + expected.put("org.opentest4j", 0); + assertTrue(expected.containsKey(moduleName)); + assertEquals(expected.get(moduleName), obj.getRequiresFlags(), moduleName); + } + super.visitModuleRequires(obj); + } + }; + javaClass.accept(new DescendingVisitor(javaClass, visitor)); + } + } +} diff --git a/src/test/java/org/apache/bcel/classfile/RecordTestCase.java b/src/test/java/org/apache/bcel/classfile/RecordTestCase.java index 8056250a7d..62e139ec04 100644 --- a/src/test/java/org/apache/bcel/classfile/RecordTestCase.java +++ b/src/test/java/org/apache/bcel/classfile/RecordTestCase.java @@ -50,8 +50,8 @@ public void recordsCanBeVisited() throws ClassNotFoundException, IOException { final CountingVisitor countVisitor = new CountingVisitor(); final DescendingVisitor desendingVisitor = new DescendingVisitor(clazz, countVisitor); desendingVisitor.visit(); - assertEquals(1,countVisitor.recordCount, "should count one record"); - assertEquals(2,countVisitor.recordComponentCount, "should count two record components"); + assertEquals(1, countVisitor.recordCount, "should count one record"); + assertEquals(2, countVisitor.recordComponentCount, "should count two record components"); } @@ -62,13 +62,13 @@ public void recordsCanBeVisited() throws ClassNotFoundException, IOException { public void testAttributeSerializtion() throws ClassNotFoundException, IOException { final JavaClass clazz = new ClassParser("src/test/resources/record/SimpleRecord.class").parse(); final File tfile = createTestdataFile("SimpleRecord.class"); - final Record recordAttribute = (Record)findAttribute("Record",clazz)[0]; + final Record recordAttribute = (Record) findAttribute("Record", clazz)[0]; clazz.dump(tfile); // Read in the new version and check it is OK final SyntheticRepository repos2 = createRepos("."); final JavaClass clazzFromRepo = repos2.loadClass("SimpleRecord"); assertNotNull(clazzFromRepo); // Use the variable to avoid a warning - final Record recordAttributeFromRepo = (Record)findAttribute("Record",clazzFromRepo)[0]; + final Record recordAttributeFromRepo = (Record) findAttribute("Record", clazzFromRepo)[0]; assertEquals(recordAttribute.toString(), recordAttributeFromRepo.toString(), "Both attributes needs to be equal"); tfile.deleteOnExit(); } @@ -101,20 +101,19 @@ public void testRecordClassSaysItIs() throws ClassNotFoundException, ClassFormat public void testRecordToString() throws ClassNotFoundException, ClassFormatException, IOException { final JavaClass clazz = new ClassParser("src/test/resources/record/SimpleRecord.class").parse(); final Attribute[] attributes = clazz.getAttributes(); - final Record recordAttribute = (Record) findAttribute("Record",clazz)[0]; + final Record recordAttribute = (Record) findAttribute("Record", clazz)[0]; assertEquals(4, attributes.length); assertEquals("SourceFile: SimpleRecord.java", attributes[0].toString()); assertEquals("Record(2):\n" + " RecordComponentInfo(aNumber,I,0):\n" + " RecordComponentInfo(aString,Ljava/lang/String;,1):\n" + " RuntimeVisibleAnnotations:\n" - + " @Ljavax/annotation/Nonnull;" - ,recordAttribute.toString()); + + " @Ljavax/annotation/Nonnull;", recordAttribute.toString()); final RecordComponentInfo firstComponent = recordAttribute.getComponents()[0]; assertEquals(5, firstComponent.getIndex()); assertEquals(6, firstComponent.getDescriptorIndex()); assertEquals(0, firstComponent.getAttributes().length); - assertEquals(recordAttribute.getConstantPool(),firstComponent.getConstantPool()); + assertEquals(recordAttribute.getConstantPool(), firstComponent.getConstantPool()); assertEquals("RecordComponentInfo(aNumber,I,0):", firstComponent.toString()); } diff --git a/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java b/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java index 7d6095d0c2..192c2b5937 100644 --- a/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java +++ b/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java @@ -80,7 +80,7 @@ final class CodeToString { assertTrue(code.contains("33: getfield\t\torg.apache.bcel.classfile.UtilityTestCase$1CodeToString.a [[I"), code); assertTrue(code.contains("36: invokestatic\tjava.util.Arrays.asList ([Ljava/lang/Object;)Ljava/util/List;"), code); assertTrue(code.contains("39: invokeinterface\tjava.util.List.size ()I1\t0"), code); - assertTrue(code.contains("44: invokevirtual\tjava.io.PrintStream.print (I)V"), code); + assertTrue(code.contains("44: invokevirtual\tjava.io.PrintStream.print "), code); assertTrue(code.contains("47: return"), code); } } diff --git a/src/test/java/org/apache/bcel/data/EmptyClass.java b/src/test/java/org/apache/bcel/data/EmptyClass.java new file mode 100644 index 0000000000..b10c1d03d6 --- /dev/null +++ b/src/test/java/org/apache/bcel/data/EmptyClass.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.bcel.data; + +public class EmptyClass { +} + diff --git a/src/test/java/org/apache/bcel/generic/BranchHandleTestCase.java b/src/test/java/org/apache/bcel/generic/BranchHandleTestCase.java index 2927bdc455..9d0f879f46 100644 --- a/src/test/java/org/apache/bcel/generic/BranchHandleTestCase.java +++ b/src/test/java/org/apache/bcel/generic/BranchHandleTestCase.java @@ -30,7 +30,7 @@ public void testGetBHnull() { @Test public void testsetInstructionBI() { - final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null));// have to start with a valid BI + final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null)); // have to start with a valid BI assertNotNull(bh); bh.setInstruction(new GOTO(null)); assertNotNull(bh); @@ -38,7 +38,7 @@ public void testsetInstructionBI() { @Test public void testsetInstructionnotBI() { - final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null));// have to start with a valid BI + final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null)); // have to start with a valid BI assertNotNull(bh); assertThrows(ClassGenException.class, () -> bh.setInstruction(new NOP())); } @@ -46,7 +46,7 @@ public void testsetInstructionnotBI() { // Test that setInstruction only allows BranchInstructions @Test public void testsetInstructionNull() { - final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null));// have to start with a valid BI + final BranchHandle bh = BranchHandle.getBranchHandle(new GOTO(null)); // have to start with a valid BI assertNotNull(bh); assertThrows(ClassGenException.class, () -> bh.setInstruction(null)); } diff --git a/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java b/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java index 31d66f3bd2..32794cdc81 100644 --- a/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java +++ b/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java @@ -18,12 +18,15 @@ package org.apache.bcel.generic; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.io.IOException; import org.apache.bcel.AbstractTestCase; +import org.apache.bcel.Const; import org.apache.bcel.classfile.AnnotationEntry; import org.apache.bcel.classfile.ElementValuePair; import org.apache.bcel.classfile.Field; @@ -40,6 +43,8 @@ public void checkAnnotatedField(final JavaClass clazz, final String fieldname, f final AnnotationEntry[] fieldAnnotationEntrys = f.getAnnotationEntries(); if (f.getName().equals(fieldname)) { checkAnnotationEntry(fieldAnnotationEntrys[0], AnnotationEntryName, AnnotationEntryElementName, AnnotationEntryElementValue); + assertNotNull(f.getAttribute(Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS)); + assertNull(f.getAttribute(Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS)); } } } diff --git a/src/test/java/org/apache/bcel/generic/GeneratingAnnotatedClassesTestCase.java b/src/test/java/org/apache/bcel/generic/GeneratingAnnotatedClassesTestCase.java index 056453c1b0..c2924d3408 100644 --- a/src/test/java/org/apache/bcel/generic/GeneratingAnnotatedClassesTestCase.java +++ b/src/test/java/org/apache/bcel/generic/GeneratingAnnotatedClassesTestCase.java @@ -17,6 +17,8 @@ package org.apache.bcel.generic; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -89,6 +91,8 @@ private void assertParameterAnnotations(final Method method, final int... expect assertSimpleElementValue(annos[0]); } } + assertNotNull(method.getAttribute(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS)); + assertNull(method.getAttribute(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS)); } private void assertSimpleElementValue(final AnnotationEntry anno) { diff --git a/src/test/java/org/apache/bcel/generic/InstructionHandleTestCase.java b/src/test/java/org/apache/bcel/generic/InstructionHandleTestCase.java index 4d79927370..81ea857141 100644 --- a/src/test/java/org/apache/bcel/generic/InstructionHandleTestCase.java +++ b/src/test/java/org/apache/bcel/generic/InstructionHandleTestCase.java @@ -40,7 +40,7 @@ public void testGetIHnull() { @Test public void testsetInstructionI() { - final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP());// have to start with a valid non BI + final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP()); // have to start with a valid non BI assertNotNull(ih); ih.setInstruction(new NOP()); assertNotNull(ih); @@ -48,14 +48,14 @@ public void testsetInstructionI() { @Test public void testsetInstructionnotI() { - final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP());// have to start with a valid non BI + final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP()); // have to start with a valid non BI assertNotNull(ih); assertThrows(ClassGenException.class, () -> ih.setInstruction(new GOTO(null))); } @Test public void testsetInstructionNull() { - final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP());// have to start with a valid non BI + final InstructionHandle ih = InstructionHandle.getInstructionHandle(new NOP()); // have to start with a valid non BI assertNotNull(ih); assertThrows(ClassGenException.class, () -> ih.setInstruction(null)); } diff --git a/src/test/java/org/apache/bcel/util/BCELifierTestCase.java b/src/test/java/org/apache/bcel/util/BCELifierTestCase.java index 9e66445464..7467104bb5 100644 --- a/src/test/java/org/apache/bcel/util/BCELifierTestCase.java +++ b/src/test/java/org/apache/bcel/util/BCELifierTestCase.java @@ -35,6 +35,7 @@ import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Utility; import org.apache.bcel.generic.BinaryOpCreator; +import org.apache.commons.lang3.SystemProperties; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -42,7 +43,7 @@ public class BCELifierTestCase extends AbstractTestCase { private static final String EOL = System.lineSeparator(); - public static final String CLASSPATH = "." + File.pathSeparator + System.getProperty("java.class.path"); + public static final String CLASSPATH = "." + File.pathSeparator + SystemProperties.getJavaClassPath(); // Canonicalise the javap output so it compares better private String canonHashRef(String input) { diff --git a/src/test/java/org/apache/bcel/verifier/VerifierMainTestCase.java b/src/test/java/org/apache/bcel/verifier/VerifierMainTestCase.java index f1b4b4ff6d..76495b8d22 100644 --- a/src/test/java/org/apache/bcel/verifier/VerifierMainTestCase.java +++ b/src/test/java/org/apache/bcel/verifier/VerifierMainTestCase.java @@ -36,6 +36,7 @@ import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.SWAP; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemProperties; import org.eclipse.jdt.internal.compiler.batch.Main; import org.junit.jupiter.api.Test; @@ -52,7 +53,7 @@ public void testSWAP() throws Exception { args.add(javaAgent.replace("jacoco.exec", "jacoco_org.apache.bcel.data.SWAP.exec")); } args.add("-cp"); - args.add(System.getProperty("java.class.path")); + args.add(SystemProperties.getJavaClassPath()); args.add("org.apache.bcel.verifier.Verifier"); args.add("org/apache/bcel/data/SWAP.class"); final ProcessBuilder pb = new ProcessBuilder(args); diff --git a/src/test/java/org/apache/bcel/verifier/VerifierTestCase.java b/src/test/java/org/apache/bcel/verifier/VerifierTestCase.java index 314fb6b6d6..3496191a63 100644 --- a/src/test/java/org/apache/bcel/verifier/VerifierTestCase.java +++ b/src/test/java/org/apache/bcel/verifier/VerifierTestCase.java @@ -38,6 +38,7 @@ import org.apache.bcel.verifier.input.StaticFieldVerifierChildClass; import org.apache.bcel.verifier.statics.StringRepresentation; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemProperties; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledForJreRange; @@ -89,7 +90,7 @@ private static void testJarFile(final File file, final String... excludes) throw } private static void testNestHostWithJavaVersion(final String className) throws ClassNotFoundException { - final String version = System.getProperty("java.version"); + final String version = SystemProperties.getJavaVersion(); assertNotNull(version); try { testDefaultMethodValidation(className); diff --git a/src/test/java/org/apache/bcel/verifier/VerifyBadClassesTestCase.java b/src/test/java/org/apache/bcel/verifier/VerifyBadClassesTestCase.java index 46af8c80fd..4d46730ea7 100644 --- a/src/test/java/org/apache/bcel/verifier/VerifyBadClassesTestCase.java +++ b/src/test/java/org/apache/bcel/verifier/VerifyBadClassesTestCase.java @@ -35,6 +35,7 @@ import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.SystemProperties; import org.junit.jupiter.api.Test; /** @@ -49,7 +50,7 @@ private List buildVerifyCommand(final String className, final String tes command.add("-ea"); command.add("-classpath"); - command.add(System.getProperty("java.class.path") + ":" + testDir); + command.add(SystemProperties.getJavaClassPath() + ":" + testDir); command.add("org.apache.bcel.verifier.Verifier"); command.add(className);