codeql icon indicating copy to clipboard operation
codeql copied to clipboard

Java ExceptionInInitializerError - com.sun.tools.javac.code.TypeTags

Open develop2clickcomputers opened this issue 3 years ago • 6 comments

Below commands works as expected in local but not through codeql integration in github.

mvnw.cmd clean package -f pom.xml -B -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Denforcer.skip -Dmaven.javadoc.skip -DskipTests -Dmaven.test.skip.exec -Dlicense.skip=true -Drat.skip=true

[2022-01-06 22:54:43] [autobuild] WARNING: An illegal reflective access operation has occurred [2022-01-06 22:54:43] [autobuild] WARNING: Illegal reflective access by com.semmle.extractor.java.interceptors.JavacToolInterceptor to method com.sun.tools.javac.file.PathFileObject$SimpleFileObject.toUri() [2022-01-06 22:54:43] [autobuild] WARNING: Please consider reporting this to the maintainers of com.semmle.extractor.java.interceptors.JavacToolInterceptor [2022-01-06 22:54:43] [autobuild] WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations [2022-01-06 22:54:43] [autobuild] WARNING: All illegal access operations will be denied in a future release

develop2clickcomputers avatar Jan 07 '22 13:01 develop2clickcomputers

The warnings you paste are non-fatal: they're warning that our method of integrating with the Java compiler may not be supported in future, but is currently accepted. Is anything else wrong?

smowton avatar Jan 10 '22 11:01 smowton

Yes the autobuild failed with below error.

Error: 1-11 09:33:08] [autobuild] [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project xxxx: Fatal error compiling: java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags -> [Help 1]

mishpra avatar Jan 12 '22 13:01 mishpra

com.sun.tools.javac.file.PathFileObject has several implementations.

  • one of them, only found inside javac.exe, part of the JDK, includes the function SimpleFileObject.toUri().
  • but the alternative implementation found on https://jar-download.com/artifacts/com.dukescript.nbjavac/nb-javac/15.0.0.1/source-code/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java, and used inside "nb-javac", part of NetBeans, was patched and implemented differently, not containing the the function SimpleFileObject.toUri().
  • Other javac-like packages (e.g. used inside Eclipse or Maven for integrating the compiler) have other implementations. Maven chose to implement the internal class SimpleFileObject with its toUri() method, to mimic what was done in the JDK version.

In all these cases, com.sun.tools.javac.file.PathFileObject has never been part of the documented API, not part of any approved standard. It's understandable that Maven emits the deprecation warning, given that Java compilers in the JDK and Netbeans are not compatible with each other for this internal part. If it is needed for integrating the compiler in various tools, such function should be integrated in a supported API, possibly documenting a migration (and offering an additional package that can be installed and used along with legacy tools).

The alternative for not using that internal API is possible but costly (and not completely foolproof): the integration tool needs to monitor the standard stream I/O and implement a message parser if it wants to implement a custom filter for advanced Maven logging options. And yes this affects most Java projects hosted in GitHub and very commonly using Maven with auttobuild options by default and supporting Maven-driven automated tests and various project quality tools based on Maven. for their configuration (such as Snyk for dependency check, security checks, upgradability, integration of fixes or workarounds)

verdy-p avatar Feb 08 '24 06:02 verdy-p

It is not Maven but the JVM that raises the warning that the Java tool interceptor breaks the rules of Java module isolation in order to use the toUri method. If that can't be done, including because the implementation of SimpleFileObject isn't the one we expect, we fall back to parse its toString output instead.

smowton avatar Feb 08 '24 09:02 smowton

We just ran into a similar issue in the Jenkins project in https://github.com/jenkinsci/workflow-cps-plugin/pull/901, but we are using JDK 17, so it was a fatal error rather than a log warning.

Our cause is somewhat unusual, because we are actually using the java.compiler module and JavaCompiler as part of our (Maven) build process. Here is the full stack trace in our case. com.cloudbees.groovy.cps.tool.Driver is our build code, and everything works fine on Java 17 when not using the CodeQL autobuild.

  [2024-06-20 14:11:44] [autobuild] Exception in thread "main" java.lang.RuntimeException: Unknown file object: JarFileObject[/home/runner/work/workflow-cps-plugin/workflow-cps-plugin/lib/target/groovy-cps-dgm-builder-999999-SNAPSHOT-jar-with-dependencies.jar:/org/codehaus/groovy/runtime/StringGroovyMethods.java]
  [2024-06-20 14:11:44] [autobuild] 	at com.semmle.extractor.java.interceptors.JavacToolInterceptor.getTask(JavacToolInterceptor.java:216)
  [2024-06-20 14:11:44] [autobuild] 	at jdk.compiler/com.sun.tools.javac.api.JavacTool.SEMMLE_INTERCEPT$1(JavacTool.java)
  [2024-06-20 14:11:44] [autobuild] 	at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:200)
  [2024-06-20 14:11:44] [autobuild] 	at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:119)
  [2024-06-20 14:11:44] [autobuild] 	at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
  [2024-06-20 14:11:44] [autobuild] 	at com.cloudbees.groovy.cps.tool.Driver.run(Driver.java:59)
  [2024-06-20 14:11:44] [autobuild] 	at com.cloudbees.groovy.cps.tool.Driver.main(Driver.java:23)
  [2024-06-20 14:11:44] [autobuild] Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public java.net.URI com.sun.tools.javac.file.PathFileObject$JarFileObject.toUri() accessible: module jdk.compiler does not "opens com.sun.tools.javac.file" to unnamed module @22d8cfe0
  [2024-06-20 14:11:44] [autobuild] 	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
  [2024-06-20 14:11:44] [autobuild] 	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
  [2024-06-20 14:11:44] [autobuild] 	at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
  [2024-06-20 14:11:44] [autobuild] 	at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
  [2024-06-20 14:11:44] [autobuild] 	at com.semmle.extractor.java.interceptors.JavacToolInterceptor.getTask(JavacToolInterceptor.java:196)
  [2024-06-20 14:11:44] [autobuild] 	... 6 more

We can work around the issue by adding --add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED to our build script as in https://github.com/jenkinsci/workflow-cps-plugin/pull/917, but we would prefer not to have to do this.

For what it's worth, it seems unusual that com.semmle.extractor.java.interceptors.JavacToolInterceptor is trying to change the accessibility of PathFileObject$JarFileObject.toUri(). The class in question implements javax.tools.JavaFileObject, which implements javax.tools.FileObject, which has a public toUri() method, and those interfaces are part of the public API of the java.compiler module.

dwnusbaum avatar Aug 09 '24 22:08 dwnusbaum

@dwnusbaum this is actually quite a different cause from the (ordinary, harmless) case described in this issue, so I've created https://github.com/github/codeql/issues/17204 and will respond there.

smowton avatar Aug 12 '24 14:08 smowton