Unexpected ClassnotFoundException on reflective Class#getMethod
Alex Buckley
alex.buckley at oracle.com
Wed Mar 30 22:07:24 UTC 2016
The JDK 9b111 runtime image includes the java.transaction module which
exports the javax.transaction package. The application class loader will
try to load javax.transaction.* types from there, not from a JAR on the
classpath. As you probably guess, the JDK's java.transaction module does
not contain the javax.transaction.Synchronization type.
You can either supply an alternate java.transaction module to override
the one in the JDK (-upgrademodulepath), or you can inject your
additional classes directly into the module in the JDK (-Xpatch). Please
see JEP 261.
Alex
On 3/30/2016 2:39 PM, Sanne Grinovero wrote:
> Hello all,
> looks like I've found an issue on invoking Class#getMethod.
>
> This method is used by Maven when scanning the project's classpath to
> identify JUnit tests - which it does by default on any Maven project -
> so I'm afraid the impact could be quite large.
>
> I've been able to narrow it down to this small test which doesn't need
> neither Maven nor JUnit, however to reproduce the issue the project
> must have a dependency to some third party jar.
> In this reproducer I'm using javax.transaction.Synchronization, a copy
> can be obtained from:
> - https://repository.jboss.org/nexus/service/local/repositories/central/content/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Final/jboss-transaction-api_1.2_spec-1.0.0.Final.jar
>
>
> ==== Main.java ====
> public class Main {
>
> public static void main(String[] args) {
> Class clazz = SecondClass.class;
> try {
> clazz.getMethod("notexisting", new Class[0]);
> } catch (NoSuchMethodException e) {
> e.printStackTrace();
> }
> System.out.println("All good");
> }
>
> }
> ==== SecondClass.java ====
> import javax.transaction.Synchronization;
>
> public class SecondClass {
>
> public void registerSynchronization(Synchronization synchronization) {
> }
>
> }
> ==== EOF ====
>
>
> On Java8 or Java9 build 9-ea+110 the output is, as expected:
>
>> java.lang.NoSuchMethodException: SecondClass.notexisting()
>> at java.lang.Class.getMethod(Class.java:1786)
>> at Main.main(Main.java:6)
>> All good
>
>
> On Java9 build 9-ea+111 though I'll have this:
>
>> Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/Synchronization
>> at java.lang.Class.getDeclaredMethods0(java.base at 9-ea/Native Method)
>> at java.lang.Class.privateGetDeclaredMethods(java.base at 9-ea/Class.java:2937)
>> at java.lang.Class.privateGetMethodRecursive(java.base at 9-ea/Class.java:3282)
>> at java.lang.Class.getMethod0(java.base at 9-ea/Class.java:3252)
>> at java.lang.Class.getMethod(java.base at 9-ea/Class.java:1961)
>> at Main.main(Main.java:6)
>> Caused by: java.lang.ClassNotFoundException: javax.transaction.Synchronization
>> at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base at 9-ea/BuiltinClassLoader.java:368)
>> at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base at 9-ea/ClassLoaders.java:185)
>> at java.lang.ClassLoader.loadClass(java.base at 9-ea/ClassLoader.java:419)
>> ... 6 more
>
> I hope I have sent this to the right mailing list.
> I've reported the same issue on bugreport.java.com, but the only ID I
> have about that report is the "Review ID": JI-9033943
> The reproducer in this email is much better than in the other report,
> I can't check what I sent but I believe I might have sent an outdated
> version; apologies for any confusion.
>
> Thanks,
> Sanne Grinovero
>
More information about the jigsaw-dev
mailing list