Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KtLint 0.43.0 is missing requisite --add-opens to work in JDK 16+ #1274

Closed
ZacSweers opened this issue Nov 4, 2021 · 7 comments
Closed

KtLint 0.43.0 is missing requisite --add-opens to work in JDK 16+ #1274

ZacSweers opened this issue Nov 4, 2021 · 7 comments
Assignees

Comments

@ZacSweers
Copy link

Expected Behavior

I expect KtLint's fat jar on CLI to add requisite opens to run

Observed Behavior

It crashes when using JDK 16 or later

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private transient java.lang.Object java.lang.Throwable.backtrace accessible: module java.base does not "opens java.lang" to unnamed module @654b5005
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
        at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
        at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
        at org.jetbrains.kotlin.com.intellij.util.ReflectionUtil.findFieldInHierarchy(ReflectionUtil.java:153)
        at org.jetbrains.kotlin.com.intellij.util.ReflectionUtil.getDeclaredField(ReflectionUtil.java:278)
        at org.jetbrains.kotlin.com.intellij.openapi.util.objectTree.ThrowableInterner.<clinit>(ThrowableInterner.java:81)
        ... 31 more

You can see this warning on older JDKs as well

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jetbrains.kotlin.com.intellij.util.ReflectionUtil (file:/Users/zsweers/dev/slack/restructure/slack-android-ng/config/bin/ktlint) to field java.lang.Throwable.backtrace
WARNING: Please consider reporting this to the maintainers of org.jetbrains.kotlin.com.intellij.util.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Steps to Reproduce

Run the KtLint CLI binary with JDK 16

Your Environment

  • Version of ktlint used: 0.43.0
  • Name and version (or code for custom task) of integration used (Gradle plugin, Maven plugin, command line, custom Gradle task): CLI
  • Version of Gradle used (if applicable): N/A
  • Operating System and version: N/A
  • Link to your project (if it's a public repository): N/A
@ZacSweers
Copy link
Author

The way we handle this with google-java-format is to add it to the exec prefix like so

private val EXEC_PREFIX =
  """#!/bin/sh

     exec java \
       -Xmx512m \
       --add-opens java.base/java.util=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
       --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
       -jar "${'$'}0" "${'$'}@"


  """.trimIndent()

You could update this line to do the same with the requisite args

it.write "#!/bin/sh\n\nexec java -Xmx512m -jar \"\$0\" \"\$@\"\n\n".bytes

One down side is it makes the CLI jar unusable on JDK versions <9. Another solution would be to publish two CLI jars - one with the exec prefix and one without (where folks that need to add extra commands can use the latter and repackage it themselves, like we do with GJF)

@paul-dingemans
Copy link
Collaborator

Thx for sharing the solution above. I would not be surprised if this relates to #1271 in which it is reported that ktlint no longer works on jdk8.

@TwoClocks
Copy link

TwoClocks commented Dec 6, 2021

You don't need to add all those opens. You just need to add one. I altered the build.gradle like so :

it.write "#!/bin/sh\n\nexec java --add-opens java.base/java.lang=ALL-UNNAMED -Xmx512m -jar \"\$0\" \"\$@\"\n\n".bytes

And it works fine on Java 17.

I'd put in a PR, but I see in this thread that this would break Java 8? The --add-opens is required for JDK 16+, and that cmd is unknown to JDK 8. You could either remove the reflection (seems unlikely), or have the shell detect the JDK version and use the appropriate cmd-line, or create / release two bins.

@paul-dingemans I do not think it is related to #1271

@nahguam
Copy link

nahguam commented Dec 9, 2021

For maven I've added <jvmarg line="--add-opens java.base/java.lang=ALL-UNNAMED"/> to my maven-antrun-plugin configuration to get it working with Java 17.

@romtsn
Copy link
Collaborator

romtsn commented Dec 14, 2021

Let's track this in #1195

@romtsn romtsn closed this as completed Dec 14, 2021
@dk185173
Copy link

@nahguam

For maven I've added <jvmarg line="--add-opens java.base/java.lang=ALL-UNNAMED"/> to my maven-antrun-plugin configuration to get it working with Java 17.
Can you please help with the complete excerpt of the antrun plugin?

@paul-dingemans
Copy link
Collaborator

See ktlint documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants