My approach for instrumentation is based on the CoreTutorial example, finding classes based on class name.
```
final byte[] instrumented;
final String resource = '/' + className.replace('.', '/') + ".class";
InputStream original = getClass().getResourceAsStream(resource);
if (original == null) {
System.err.println("No resource with name: " + resource + " found!");
continue;
}
try {
// Instrument the class to prepare for coverage collection later.
instrumented = instrumenter.instrument(original, className);
original.close();
} catch (IOException e) {
e.printStackTrace();
continue;
}
```
After instrumenting a class which contains a nested class, I load the class with the MemoryClassLoader (based on the example) and then I call:
Class<?>[] result = c.getDeclaredClasses();
where c is of type Class<?>, and is the instrumented class.
However, I'm facing an IllegalAccessError of the form:
Throwable thrown while handling command: java.lang.IllegalAccessError: org/apache/commons/collections4/CollectionUtils$EquatorWrapper
java.lang.IllegalAccessError: org/apache/commons/collections4/CollectionUtils$EquatorWrapper
at java.lang.Class.getDeclaredClasses0(Native Method)
at java.lang.Class.getDeclaredClasses(Class.java:1867)
at randoop.reflection.ClassUtil.getDeclaredClasses(ClassUtil.java:60)
at randoop.reflection.ReflectionManager.apply(ReflectionManager.java:156)
at randoop.reflection.OperationModel.addOperationsFromClasses(OperationModel.java:584)
at randoop.reflection.OperationModel.createModel(OperationModel.java:163)
at randoop.main.GenTests.handle(GenTests.java:275)
at randoop.main.Main.nonStaticMain(Main.java:65)
at randoop.main.Main.main(Main.java:29)
The stacktrace indicates that the illegal access occurred when the outer class attempted to get the nested class.
After reading the documentation on IllegalAccessError, it appears that such an error occurs if a class's definition changes "incompatibly".
I'm wondering if this is somehow related to if a nested class gets instrumented or not.
Throwable thrown while handling command: java.lang.IllegalAccessError: tried to access class org.apache.commons.collections4.multiset.SynchronizedMultiSet$SynchronizedSet from class org.apache.commons.collections4.multiset.SynchronizedMultiSet
java.lang.IllegalAccessError: tried to access class org.apache.commons.collections4.multiset.SynchronizedMultiSet$SynchronizedSet from class org.apache.commons.collections4.multiset.SynchronizedMultiSet
at java.lang.Class.getDeclaredClasses0(Native Method)
at java.lang.Class.getDeclaredClasses(Class.java:1867)
at randoop.reflection.ClassUtil.getDeclaredClasses(ClassUtil.java:60)
at randoop.reflection.ReflectionManager.apply(ReflectionManager.java:156)
at randoop.reflection.ReflectionManager.apply(ReflectionManager.java:83)
at randoop.reflection.OperationModel.addClassTypes(OperationModel.java:513)
at randoop.reflection.OperationModel.createModel(OperationModel.java:153)
at randoop.main.GenTests.handle(GenTests.java:275)
at randoop.main.Main.nonStaticMain(Main.java:65)
at randoop.main.Main.main(Main.java:29)
This trace shows the behavior that I described in the above post. (Without any additional error handling that I haven't described). The outer class accessing the inner class causes the IllegalAccessError.
I'm wondering if this is somehow related to if a nested class gets instrumented or not.
When I instrument a class with Jacoco, do nested classes also get instrumented as well?
Thank you for your response! It really helped clarify things and I have resolved the issue! Like you said, it was exactly a class loader problem that occurred when dealing with classes and nested classes.
Thank you!