currently I am working on a java project that uses the repast java library (repast.jar, colt.jar and trove.jar). The project works fine with jdk-11, but currently, I am trying to migrate to jdk-17 and I am not able to run the project because of the next exception:
Exception in thread "main" java.lang.IllegalAccessError: class com.go.trove.classfile.AccessFlags tried to access private method 'void java.lang.reflect.Modifier.<init>()' (com.go.trove.classfile.AccessFlags is in unnamed module of loader 'app'; java.lang.reflect.Modifier is in module java.base of loader 'bootstrap')
at com.go.trove.classfile.AccessFlags.<init>(AccessFlags.java:75)
at com.go.trove.classfile.ClassFile.<init>(ClassFile.java:160)
at com.go.trove.classfile.ClassFile.<init>(ClassFile.java:138)
at uchicago.src.sim.util.ByteCodeBuilder.generateBasicAction(Unknown Source)
at uchicago.src.sim.engine.ActionUtilities.createActionFor(Unknown Source)
at uchicago.src.sim.engine.ScheduleBase.scheduleActionBeginning(Unknown Source)
at uchicago.src.sim.engine.ScheduleBase.scheduleActionBeginning(Unknown Source)
I remember reading that in a recent version of java some changes on the reflection API occurred. Would this be a possible cause?
Any idea of how to solve it? Is that hard to solve?
Thanks so much!
Yea ...
The Tea / Trove project is ancient code that hasn't been maintained by the original developers (Disney Corp!). There is fork on Github at https://github.com/teatrove/teatrove ... but that has had no activity since 2013 either. Not promising.
As to your problem. Well it seems that the original designers decided to make the org.teatrove.trove.classfile.Modifiers
a subclass of java.lang.reflect.Modifier
.
The problem is that Modifier
used to have a default public
constructor ... but in Java 14 they deprecated this constructor (javadoc). In Java 17 there is now a private
no-args constructor. That means that when Trove attempts to create a Modifiers
instance on Java 17, it fails with a binary compatibility error.
One way to solve this would be to modify Trove so that Modifiers
is no longer a subclass of Modifier
. I don't know how feasible that would be. The feasibility will depend on whether the codebase makes use of the fact that Modifiers
is a subtype of Modifier
. That would be for you to investigate ...
If you take this approach, be a good citizen and submit your changes as a pull request against the "TeaTrove" codebase on Github.
Another approach would be to look for a replacement for the Trove dependency in your application. Again, without knowing how / why you are using Trove, it is difficult to suggest an alternative.
Your application's dependency may be due to your using an old version of Repast. I can't find any information on old Repast versions ... but this suggests another approach would be to upgrade to a newer Repast version that (hopefully1) avoids the Trove dependency.
Finally, given that the Repast developers still recommend Java 11 for the most recent versions of Repast, you could just stick with that.
1 - The Repast codebase doesn't use a modern build tool like Maven or Gradle that take a declarative approach to dependencies2. Instead they have snarfed copies of the dependency JARs and put them into their source repo. This makes dependency analysis difficult.
2 - See https://github.com/Repast/repast.simphony/issues/4