jsweet icon indicating copy to clipboard operation
jsweet copied to clipboard

Java 17 LTS minimal support

Open workmanw opened this issue 2 years ago • 10 comments

Hello,

We are in the process of upgrading to Java 17 LTS and noticed this issue when trying to compile our library with jsweet. This appears to be an issue with the jsweet transpiler itself, but if I'm mistaken please let me know and I'll file the issue where ever.

Version:

  • Maven: 3.8.3 (ff8e977a158738155dc465c6a97ffaf31982d739)
  • JDK: openjdk version "17" 2021-09-14
  • jsweet-maven-plugin: 3.1.0
  • jsweet-transplier: 3.1.0
  • jsweet-core: 6.3.0
[ERROR] failed to create transpiler
java.lang.RuntimeException: fail to initialize extension classpath
    at org.jsweet.transpiler.extension.ExtensionManager.initExtensionClassPath (ExtensionManager.java:157)
    at org.jsweet.transpiler.extension.ExtensionManager.checkAndCompileExtension (ExtensionManager.java:73)
    at org.jsweet.transpiler.JSweetTranspiler.<init> (JSweetTranspiler.java:535)
    at org.jsweet.AbstractJSweetMojo.createJSweetTranspiler (AbstractJSweetMojo.java:309)
    at org.jsweet.JSweetMojo.execute (JSweetMojo.java:41)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:972)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.net.URLClassLoader.addURL(java.net.URL) accessible: module java.base does not "opens java.net" to unnamed module @1467f2e9
    at java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:354)
    at java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:297)
    at java.lang.reflect.Method.checkCanSetAccessible (Method.java:199)
    at java.lang.reflect.Method.setAccessible (Method.java:193)
    at org.jsweet.transpiler.extension.ExtensionManager.initExtensionClassPath (ExtensionManager.java:144)
    at org.jsweet.transpiler.extension.ExtensionManager.checkAndCompileExtension (ExtensionManager.java:73)
    at org.jsweet.transpiler.JSweetTranspiler.<init> (JSweetTranspiler.java:535)
    at org.jsweet.AbstractJSweetMojo.createJSweetTranspiler (AbstractJSweetMojo.java:309)
    at org.jsweet.JSweetMojo.execute (JSweetMojo.java:41)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:972)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

workmanw avatar Oct 27 '21 00:10 workmanw

Hello. Thanks for reporting. Did you try with another JDK (oracle’s one for instance)?

lgrignon avatar Oct 27 '21 04:10 lgrignon

@lgrignon Hello. Thanks for the quick response and suggestion. This morning I tried with both Oracle's JDK 17 and Adoptium's Temurin. Both JDKs have this issue as well.

Oracle JDK 17:

$ java -version

java version "17.0.1" 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)

Oracle OpenJDK 17:

$ java -version

openjdk version "17" 2021-09-14
OpenJDK Runtime Environment Homebrew (build 17+0)
OpenJDK 64-Bit Server VM Homebrew (build 17+0, mixed mode, sharing)

Adoptium/Temurin

$ java -version

openjdk version "17" 2021-09-14
OpenJDK Runtime Environment Temurin-17+35 (build 17+35)
OpenJDK 64-Bit Server VM Temurin-17+35 (build 17+35, mixed mode, sharing)

workmanw avatar Oct 27 '21 13:10 workmanw

It definitely sounds like a problem of access to an API in the latest JDK. In the trace we can see that access to addUrl is refused while trying to make it accessible. We need another way to add URL to class loader if this is not possible anymore.

Anyway I am not sure we will find time to dig into this in the near future. Will you? It does not seem too complicated. I would be glad to review PR, if you file one :) I am not sure that you won't encounter more errors after this with J17 though since we didn't try it yet :)

lgrignon avatar Oct 27 '21 20:10 lgrignon

Hey @lgrignon . Yea I can make sometime over the next few weeks. Do you have the background on what's actually happening with this initialization? Why is jsweet patching this method to use it?

Also, I know it's kind of a nit, but this feels more like a bug than an enhancement.

workmanw avatar Oct 28 '21 00:10 workmanw

That's amazing :)

Please see here: https://github.com/cincheo/jsweet/blob/develop/transpiler/src/main/java/org/jsweet/transpiler/extension/ExtensionManager.java#L133

This URLClassLoader hack is used to add extension directory to the current class path, and allow extension classes to be compiled on the fly here: https://github.com/cincheo/jsweet/blob/develop/transpiler/src/main/java/org/jsweet/transpiler/extension/ExtensionManager.java#L121

(At least it is my understanding of it :))

I guess there is a more modern approach of doing this because it's a very old technique.

Note : I tagged this issue as enhancement because Java 17 support is an enhancement ;) I will change this issue's subject to reflect it

lgrignon avatar Nov 02 '21 15:11 lgrignon

Note : for a full Java 17 support, we would need to implement new language constructs (from https://docs.oracle.com/en/java/javase/17/docs/api/jdk.compiler/com/sun/source/tree/TreeVisitor.html)

I will change again the subject because I think this is beyond the scope of this issue

lgrignon avatar Nov 02 '21 15:11 lgrignon

I was able to run JSweet on Java 17 by adding the following to gradle.properties:

org.gradle.jvmargs=-Dfile.encoding=UTF-8 \
  --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
  --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

nedtwigg avatar Feb 22 '22 17:02 nedtwigg

Hey @nedtwigg that’s amazing! Well done. Do you want to file a PR ? I would merge it right away

lgrignon avatar Feb 22 '22 18:02 lgrignon

My workaround has to be added to the gradle.properties of the project that is using JSweet, I don't know of a way to implement this fix as a PR.

nedtwigg avatar Feb 22 '22 18:02 nedtwigg

You are my hero, @nedtwigg! This unblocked me, and I'm back to normal transpiler error fixing. Thank you!

vorth avatar Aug 14 '22 23:08 vorth