janino-compiler / janino

Janino is a super-small, super-fast Java™ compiler.
http://janino-compiler.github.io/janino
Other
1.25k stars 208 forks source link

commons-compiler-jdk: Unable to load class #168

Closed lglauer closed 2 years ago

lglauer commented 2 years ago

Hello!

When only commons-compiler-jdk is on the classpath, but not janino the SimpleCompiler class from commons-compiler-jdk is used. Since release 3.17 it fails to load the annotation class javax.annotation.Nonnull from the classpath. Prior this scenario worked fine, so it seems to be a regression. I created a minimal reproducible example for this case: https://github.com/lglauer/janino-test

When executed it prints the following exception:

Exception in thread "main" org.codehaus.commons.compiler.CompileException: File 'simplecompiler', Line 2, Column 24: package javax.annotation does not exist (compiler.err.doesnt.exist)
    at org.codehaus.commons.compiler.jdk.Compiler$1.report(Compiler.java:329)
    at jdk.compiler/com.sun.tools.javac.api.ClientCodeWrapper$WrappedDiagnosticListener.report(ClientCodeWrapper.java:736)
    at jdk.compiler/com.sun.tools.javac.util.Log.writeDiagnostic(Log.java:734)
    at jdk.compiler/com.sun.tools.javac.util.Log$DefaultDiagnosticHandler.report(Log.java:718)
    at jdk.compiler/com.sun.tools.javac.util.Log.report(Log.java:678)
    at jdk.compiler/com.sun.tools.javac.comp.Resolve.logResolveError(Resolve.java:3714)
    at jdk.compiler/com.sun.tools.javac.comp.Resolve.accessInternal(Resolve.java:2475)
    at jdk.compiler/com.sun.tools.javac.comp.Resolve.accessBase(Resolve.java:2518)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.selectSym(Attr.java:3717)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3603)
    at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:2130)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:655)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.attribType(Attr.java:715)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.attribType(Attr.java:708)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.attribImportType(TypeEnter.java:441)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.doImport(TypeEnter.java:424)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.resolveImports(TypeEnter.java:364)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.runPhase(TypeEnter.java:321)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.doCompleteEnvs(TypeEnter.java:282)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:251)
    at jdk.compiler/com.sun.tools.javac.comp.TypeEnter.complete(TypeEnter.java:198)
    at jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:642)
    at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1326)
    at jdk.compiler/com.sun.tools.javac.comp.Enter.complete(Enter.java:583)
    at jdk.compiler/com.sun.tools.javac.comp.Enter.main(Enter.java:560)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1066)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:937)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
    at org.codehaus.commons.compiler.jdk.Compiler.compile(Compiler.java:359)
    at org.codehaus.commons.compiler.jdk.Compiler.compile(Compiler.java:209)
    at org.codehaus.commons.compiler.jdk.Compiler.compile(Compiler.java:157)
    at org.codehaus.commons.compiler.jdk.SimpleCompiler.cook(SimpleCompiler.java:161)
    at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:82)
    at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:77)
    at main.Main.getClazz(Main.java:24)
    at main.Main.main(Main.java:43)

If janino is added as a dependency or if commons-compiler-jdk 3.16 is used the example code works fine and prints "Hello World!".

Thanks in advance!

naude-r commented 2 years ago

we have run into a similar issue. in our case janino, commons-compiler and commons-compiler-jdk are all on the classpath. compilation fail when importing a class from a dependency.

the exact same code runs as is with 3.1.6. the only change being the dependency bump to 3.1.7.

it should be noted that the problem only manifest itself when using the jdk compiler (org.codehaus.commons.compiler.jdk.CompilerFactory). the janino compiler (org.codehaus.janino.CompilerFactory) works just fine.

lglauer commented 2 years ago

@aunkrig Any comment? Is janino still actively maintained? This is a serious regression and should be fixed ASAP.

aunkrig commented 2 years ago

I'll look into it soon.

aunkrig commented 2 years ago

The answer is very simple: Both "commons-compiler-jdk" and "janino" say "class javax.annotation.Nonnull not found" because -- that class cannot be found! The reason being is that the annotation interface "javax.annotation.Nonnull" is not part of the JRE (tested with 8, 11 and 17), so one needs an extra library that supplies this annotation interface. If found the following libs:

com.google.code.findbugs:jsr305-3.0.2
org.apache.tools.ant:annotations-2.0.1

In other words: When you switched from 3.1.6 to 3.1.7, you must have accidentially removed that library from the classpath!

lglauer commented 2 years ago

@aunkrig Did you have a look at the minimal reproducible example? It has a dependency to com.google.code.findbugs:jsr305 (see here). And as I said it works with commons-compiler-jdk:3.16 and fails with commons-compiler-jdk:3.17, no other difference.

aunkrig commented 2 years ago

Oops, I missed that dependency when I ran the sample program. Now I can reproduce the problem... stay tuned.

aunkrig commented 2 years ago

I think I fixed it (JavaFileManagers.java:120)... please test!

aunkrig commented 2 years ago

I also added a regression test case "testIssue168()" that verifies the absence of the bug.

lglauer commented 2 years ago

Thank you! I will test it in the next days.

naude-r commented 2 years ago

@aunkrig the fix is working for my test case. can you also please include PR #170 ?

lglauer commented 2 years ago

Yes, that solution seems to work! Thanks 👍

aunkrig commented 2 years ago

My pleasure! Thank you for the very useful test case. I added a regression test case org.codehaus.commons.compiler.tests.ReportedBugsTest.testIssue168() that verifies this fix.