This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git


The following commit(s) were added to refs/heads/master by this push:
     new 3974fe2a Add accessors to model and unit tests, Javadoc (#183)
3974fe2a is described below

commit 3974fe2a94a23a973cc8ebe3124dc272ee950b35
Author: nbauma109 <nbauma...@users.noreply.github.com>
AuthorDate: Fri Jun 21 23:01:25 2024 +0200

    Add accessors to model and unit tests, Javadoc (#183)
    
    * added accessors to model and unit tests, javadoc comments
    
    Co-authored-by: nbauma109 <nbauma...@github.com>
    
    * removed getters that are not useful directly for end users
    
    * test for null LocalVariableTypeTable
    
    * added test for null class attribute
    
    * added test for null LocalVariableTypeTable with Code attribute present
    
    * added module flags and tests
    
    * @since 6.7.1 -> @since 6.8.0
    
    * Fix unit test ConstantPoolModuleAccessTestCase
    
    * Update since tags to 6.10.0
    
    * checkstyles fixes
    
    * checkstyle fix on EmptyClass
    
    * removed expected jdk.internal.org.jline.terminal.spi.JnaSupport
    
    * Fix unit test ConstantPoolModuleAccessTestCase
    
    * ConstantPoolModuleAccessTestCase: add url in assert
    
    * ConstantPoolModuleAccessTestCase: added message in assertion
    
    * ConstantPoolModuleAccessTestCase: remove version number in check
    
    * ConstantPoolModuleAccessTestCase: update test for Java 21
    
    * ConstantPoolModuleAccessTestCase: update for Java 21
    
    ---------
    
    Co-authored-by: nbauma109 <nbauma...@github.com>
---
 src/main/java/org/apache/bcel/classfile/Code.java  |  14 +
 .../org/apache/bcel/classfile/FieldOrMethod.java   |  16 +
 .../java/org/apache/bcel/classfile/JavaClass.java  |  16 +
 .../java/org/apache/bcel/classfile/Method.java     |  15 +-
 .../java/org/apache/bcel/classfile/Module.java     |  60 +++-
 .../org/apache/bcel/classfile/ModuleExports.java   |  47 ++-
 .../org/apache/bcel/classfile/ModuleOpens.java     |  47 ++-
 .../org/apache/bcel/classfile/ModuleProvides.java  |  43 ++-
 .../org/apache/bcel/classfile/ModuleRequires.java  |  37 ++-
 .../org/apache/bcel/AnonymousClassTestCase.java    |  14 +
 .../bcel/LocalVariableTypeTableTestCase.java       |  20 ++
 .../ConstantPoolModuleAccessTestCase.java          | 358 +++++++++++++++++++++
 src/test/java/org/apache/bcel/data/EmptyClass.java |  22 ++
 .../bcel/generic/FieldAnnotationsTestCase.java     |  17 +-
 .../GeneratingAnnotatedClassesTestCase.java        |   4 +
 15 files changed, 695 insertions(+), 35 deletions(-)

diff --git a/src/main/java/org/apache/bcel/classfile/Code.java 
b/src/main/java/org/apache/bcel/classfile/Code.java
index 8ec211fb..d94ba66d 100644
--- a/src/main/java/org/apache/bcel/classfile/Code.java
+++ b/src/main/java/org/apache/bcel/classfile/Code.java
@@ -259,6 +259,20 @@ public final class Code extends Attribute {
         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/FieldOrMethod.java 
b/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java
index 1b2081ed..f67c1be7 100644
--- a/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java
+++ b/src/main/java/org/apache/bcel/classfile/FieldOrMethod.java
@@ -171,6 +171,22 @@ public abstract class FieldOrMethod extends AccessFlags 
implements Cloneable, No
         return attributes;
     }
 
+    /**
+     * 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 extends Attribute> T getAttribute(final byte tag) {
+        for (final Attribute attribute : getAttributes()) {
+            if (attribute.getTag() == tag) {
+                return (T) attribute;
+            }
+        }
+        return null;
+    }
+
     /**
      * @return Constant pool used by this object.
      */
diff --git a/src/main/java/org/apache/bcel/classfile/JavaClass.java 
b/src/main/java/org/apache/bcel/classfile/JavaClass.java
index d52336d0..f5899989 100644
--- a/src/main/java/org/apache/bcel/classfile/JavaClass.java
+++ b/src/main/java/org/apache/bcel/classfile/JavaClass.java
@@ -489,6 +489,22 @@ public class JavaClass extends AccessFlags implements 
Cloneable, Node, Comparabl
         return attributes;
     }
 
+    /**
+     * 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 extends Attribute> T getAttribute(final byte tag) {
+        for (final Attribute attribute : getAttributes()) {
+            if (attribute.getTag() == tag) {
+                return (T) attribute;
+            }
+        }
+        return null;
+    }
+
     /**
      * @return class in binary format
      */
diff --git a/src/main/java/org/apache/bcel/classfile/Method.java 
b/src/main/java/org/apache/bcel/classfile/Method.java
index 57a70ff8..8de79040 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 final class Method extends FieldOrMethod {
     }
 
     /**
-     * @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 final class Method extends FieldOrMethod {
         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 11aea316..5915522c 100644
--- a/src/main/java/org/apache/bcel/classfile/Module.java
+++ b/src/main/java/org/apache/bcel/classfile/Module.java
@@ -109,7 +109,57 @@ public final class Module extends Attribute {
         v.visitModule(this);
     }
 
-    // TODO add more getters and setters?
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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;
+    }
+
+    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;
+    }
 
     /**
      * @return deep copy of this attribute
@@ -214,9 +264,9 @@ public final class Module extends Attribute {
         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 final class Module extends Attribute {
 
         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 463ce4fd..5653e82d 100644
--- a/src/main/java/org/apache/bcel/classfile/ModuleExports.java
+++ b/src/main/java/org/apache/bcel/classfile/ModuleExports.java
@@ -53,6 +53,43 @@ public final class ModuleExports implements Cloneable, Node {
         }
     }
 
+    /**
+     * Gets the flags for this ModuleExports.
+     * @return the exportsFlags
+     * @since 6.10.0
+     */
+    public int getExportsFlags() {
+        return exportsFlags;
+    }
+
+    /**
+     * 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;
+    }
+
+    private static String getToModuleNameAtIndex(final ConstantPool 
constantPool, final int index) {
+        return constantPool.getConstantString(index, Const.CONSTANT_Module);
+    }
+
+    /**
+     * 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);
+    }
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitly 
defined by the contents of a Java class.
      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree 
of objects.
@@ -64,8 +101,6 @@ public final class ModuleExports implements Cloneable, Node {
         v.visitModuleExports(this);
     }
 
-    // TODO add more getters and setters?
-
     /**
      * @return deep copy of this object
      */
@@ -106,13 +141,13 @@ public final class ModuleExports implements Cloneable, 
Node {
      */
     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 00c0f3a3..f8da77c7 100644
--- a/src/main/java/org/apache/bcel/classfile/ModuleOpens.java
+++ b/src/main/java/org/apache/bcel/classfile/ModuleOpens.java
@@ -53,6 +53,43 @@ public final class ModuleOpens implements Cloneable, Node {
         }
     }
 
+    /**
+     * Gets the flags for this ModuleOpens.
+     * @return the opensFlags
+     * @since 6.10.0
+     */
+    public int getOpensFlags() {
+        return opensFlags;
+    }
+
+    /**
+     * 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;
+    }
+
+    private static String getToModuleNameAtIndex(final ConstantPool 
constantPool, final int index) {
+        return constantPool.getConstantString(index, Const.CONSTANT_Module);
+    }
+
+    /**
+     * 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);
+    }
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitly 
defined by the contents of a Java class.
      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree 
of objects.
@@ -64,8 +101,6 @@ public final class ModuleOpens implements Cloneable, Node {
         v.visitModuleOpens(this);
     }
 
-    // TODO add more getters and setters?
-
     /**
      * @return deep copy of this object
      */
@@ -106,13 +141,13 @@ public final class ModuleOpens implements Cloneable, Node 
{
      */
     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 af0778af..8c88f170 100644
--- a/src/main/java/org/apache/bcel/classfile/ModuleProvides.java
+++ b/src/main/java/org/apache/bcel/classfile/ModuleProvides.java
@@ -51,6 +51,39 @@ public final class ModuleProvides implements Cloneable, Node 
{
         }
     }
 
+    /**
+     * 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;
+    }
+
+    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;
+    }
+
+    /**
+     * 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);
+    }
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitly 
defined by the contents of a Java class.
      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree 
of objects.
@@ -62,8 +95,6 @@ public final class ModuleProvides implements Cloneable, Node {
         v.visitModuleProvides(this);
     }
 
-    // TODO add more getters and setters?
-
     /**
      * @return deep copy of this object
      */
@@ -103,12 +134,12 @@ public final class ModuleProvides implements Cloneable, 
Node {
      */
     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 371c35c6..678b0843 100644
--- a/src/main/java/org/apache/bcel/classfile/ModuleRequires.java
+++ b/src/main/java/org/apache/bcel/classfile/ModuleRequires.java
@@ -48,6 +48,35 @@ public final class ModuleRequires implements Cloneable, Node 
{
         requiresVersionIndex = file.readUnsignedShort();
     }
 
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitly 
defined by the contents of a Java class.
      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree 
of objects.
@@ -59,8 +88,6 @@ public final class ModuleRequires implements Cloneable, Node {
         v.visitModuleRequires(this);
     }
 
-    // TODO add more getters and setters?
-
     /**
      * @return deep copy of this object
      */
@@ -98,10 +125,10 @@ public final class ModuleRequires implements Cloneable, 
Node {
      */
     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/test/java/org/apache/bcel/AnonymousClassTestCase.java 
b/src/test/java/org/apache/bcel/AnonymousClassTestCase.java
index 1d65fa96..ed6f0dd7 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 {
@@ -45,6 +50,15 @@ public class AnonymousClassTestCase extends AbstractTestCase 
{
         assertFalse(clazz.isNested(), "regular outer classes are not 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 testStaticInnerClassIsNotAnonymous() throws 
ClassNotFoundException {
         final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + 
".data.AnonymousClassTest$Y");
diff --git a/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java 
b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java
index 6d5068ef..6855069e 100644
--- a/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java
+++ b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java
@@ -21,6 +21,7 @@ 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;
@@ -34,6 +35,9 @@ import org.apache.bcel.generic.MethodGen;
 import org.apache.bcel.generic.Type;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
 public class LocalVariableTypeTableTestCase extends AbstractTestCase {
 
     public class TestClassLoader extends ClassLoader {
@@ -143,4 +147,20 @@ public class LocalVariableTypeTableTestCase extends 
AbstractTestCase {
         method = cls.getDeclaredMethod("d", List.class, String.class);
         method.invoke(null, new LinkedList<>(), "d2");
     }
+
+    @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<T, U, V, 
R> 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());
+    }
 }
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 00000000..5202c4be
--- /dev/null
+++ 
b/src/test/java/org/apache/bcel/classfile/ConstantPoolModuleAccessTestCase.java
@@ -0,0 +1,358 @@
+/*
+ * 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 org.apache.bcel.Const;
+import org.junit.jupiter.api.Test;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests {@code module-info.class} files.
+ */
+public class ConstantPoolModuleAccessTestCase {
+
+    @Test
+    public void testJREModules() throws Exception {
+        final Enumeration<URL> moduleURLs = 
getClass().getClassLoader().getResources("module-info.class");
+        while (moduleURLs.hasMoreElements()) {
+            final URL url = moduleURLs.nextElement();
+            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) {
+                        if (url.getPath().contains("/commons-")) {
+                            assertEquals(4096, obj.getModuleFlags(), 
url.toString());
+                        } else {
+                            assertEquals(0, obj.getModuleFlags(), 
url.toString());
+                        }
+                        final String[] usedClassNames = 
obj.getUsedClassNames(constantPool, true);
+                        if (url.getPath().contains("junit-jupiter-engine")) {
+                            assertEquals(1, usedClassNames.length);
+                            
assertEquals("org.junit.jupiter.api.extension.Extension", usedClassNames[0]);
+                        } else if 
(url.getPath().contains("junit-platform-launcher")) {
+                            final List<String> 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 
(url.getPath().contains("/java.rmi/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("java.rmi.server.RMIClassLoaderSpi");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.xml/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/java.datatransfer/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("sun.datatransfer.DesktopDatatransferService");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.desktop/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/java.naming/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/java.prefs/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("java.util.prefs.PreferencesFactory");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.base/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/jdk.management.agent/module-info.class") && 
javaClass.getMajor() < Const.MAJOR_21) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("jdk.internal.agent.spi.AgentProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.management/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/java.sql/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("java.sql.Driver");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.httpserver/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("com.sun.net.httpserver.spi.HttpServerProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.sql.rowset/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("javax.sql.rowset.RowSetFactory");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.compiler/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("javax.tools.DocumentationTool");
+                            expected.add("javax.tools.JavaCompiler");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/java.scripting/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("javax.script.ScriptEngineFactory");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.dynalink/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("jdk.dynalink.linker.GuardingDynamicLinkerExporter");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.jdi/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/jdk.compiler/module-info.class")) {
+                            final List<String> 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 
(url.getPath().contains("/jdk.jconsole/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("com.sun.tools.jconsole.JConsolePlugin");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.attach/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("com.sun.tools.attach.spi.AttachProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.jshell/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("jdk.jshell.spi.ExecutionControlProvider");
+                            
expected.add("jdk.internal.editor.spi.BuildInEditorProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.internal.le/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.jlink/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("jdk.tools.jlink.plugin.Plugin");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.internal.jvmstat/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("sun.jvmstat.monitor.MonitoredHostService");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.jpackage/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            expected.add("jdk.jpackage.internal.Bundler");
+                            expected.add("jdk.jpackage.internal.Bundlers");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.naming.ldap/module-info.class")) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("com.sun.jndi.ldap.spi.LdapDnsProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/jdk.jsobject/module-info.class") && 
javaClass.getMajor() == Const.MAJOR_11) {
+                            final List<String> expected = new ArrayList<>();
+                            
expected.add("jdk.internal.netscape.javascript.spi.JSObjectProvider");
+                            assertEquals(expected, 
Arrays.asList(usedClassNames));
+                        } else if 
(url.getPath().contains("/org/assertj/assertj-core/")) {
+                            final List<String> 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 " + url.getPath());
+                        }
+                        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<String> 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 visitModuleProvides(final ModuleProvides obj) {
+                        final String interfaceName = 
obj.getInterfaceName(constantPool);
+                        final String[] implementationClassNames = 
obj.getImplementationClassNames(constantPool, true);
+                        if (url.getPath().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 
(url.getPath().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 visitModuleOpens(final ModuleOpens obj) {
+                        assertEquals(0, obj.getOpensFlags(), url.toString());
+                        final String packageName = 
obj.getPackageName(constantPool);
+                        final String[] toModuleNames = 
obj.getToModuleNames(constantPool);
+                        if (url.getPath().contains("junit-jupiter-engine")) {
+                            assertEquals("org.junit.jupiter.engine.extension", 
packageName);
+                            assertEquals(1, toModuleNames.length);
+                            assertEquals("org.junit.platform.commons", 
toModuleNames[0]);
+                        }
+                        if (url.getPath().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 visitModuleRequires(final ModuleRequires obj) {
+                        if (url.getPath().contains("junit-jupiter-engine")) {
+                            final String moduleName = 
obj.getModuleName(constantPool);
+                            final Map<String, Integer> 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/data/EmptyClass.java 
b/src/test/java/org/apache/bcel/data/EmptyClass.java
new file mode 100644
index 00000000..b10c1d03
--- /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/FieldAnnotationsTestCase.java 
b/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java
index 31d66f3b..5ba8db0f 100644
--- a/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java
+++ b/src/test/java/org/apache/bcel/generic/FieldAnnotationsTestCase.java
@@ -17,13 +17,8 @@
 
 package org.apache.bcel.generic;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-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;
@@ -31,6 +26,14 @@ import org.apache.bcel.classfile.JavaClass;
 import org.apache.bcel.util.SyntheticRepository;
 import org.junit.jupiter.api.Test;
 
+import java.io.File;
+import java.io.IOException;
+
+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;
+
 public class FieldAnnotationsTestCase extends AbstractTestCase {
     // helper methods
     public void checkAnnotatedField(final JavaClass clazz, final String 
fieldname, final String AnnotationEntryName, final String 
AnnotationEntryElementName,
@@ -40,6 +43,8 @@ public class FieldAnnotationsTestCase extends 
AbstractTestCase {
             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 056453c1..c2924d34 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 @@ public class GeneratingAnnotatedClassesTestCase extends 
AbstractTestCase {
                 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) {

Reply via email to