feat: allow for a non-local Java Compiler to be used#1988
feat: allow for a non-local Java Compiler to be used#1988lefou merged 2 commits intocom-lihaoyi:mainfrom
Conversation
Currently if you want to pass in some `javacOptions` that start with
`-J` the Java compiler will reject them since the local java compiler
won't accept `-J` flags. You can see this in an example on JDK 17 where
you need some `-J` flags to get the java semantidb compiler plugin to
work:
```scala
object javaModule extends JavaModule {
def ivyDeps = Agg(ivy"com.sourcegraph:semanticdb-javac:0.8.2")
def javacOptions = Seq(
"-J--add-exports",
"-Jjdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"-J--add-exports",
"-Jjdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"-J--add-exports",
"-Jjdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
"-J--add-exports",
"-Jjdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"-J--add-exports",
"-Jjdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
s"-Xplugin:semanticdb -sourceroot:${T.workspace} -targetroot:${T.dest}"
)
}
```
Which will result in:
```
❯ mill javaModule.compile
[19/19] javaModule.compile
[info] compiling 1 Java source to /Users/ckipp/Documents/scala-workspace/minimal/out/javaModule/compile.dest/classes ...
[warn] Javac is running in 'local' mode. These flags have been removed:
[warn] -J--add-exports, -Jjdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED, -J--add-exports, -Jjdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED, -J--add-exports, -Jjdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED, -J--add-exports, -Jjdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED, -J--add-exports, -Jjdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
[error] An exception has occurred in the compiler (17.0.4). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
[error] java.lang.IllegalAccessError: class com.sourcegraph.semanticdb_javac.SemanticdbPlugin (in unnamed module @0x4e59433c) cannot access class com.sun.tools.javac.api.BasicJavacTask (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x4e59433c
...
```
This change looks at the `javacOptions` when creating the java comipler
and if detected makes sure you get a non-local compiler. If none are
detected, then the behavior basically is the same as it was before where
a local instance is used.
We also cache this to ensure it's not created over and over. However if
your `javacOption` change, then we do give a new instance.
Fixes com-lihaoyi#1983
lefou
left a comment
There was a problem hiding this comment.
This change looks reasonable. I think we should limit the newly introduced cache though, as it will grow indefinitely when the user frequently changes options. Either, we introduce a limit, which we probably also want to control via some settings, or we use a SoftReference[Compilers].
I was actually thinking that this would be super rare in the lifetime of this? Even if a user changes this 10 times, that's not a huge deal right? What would too large be in your opinion, and in what scenario do you think a user would be constantly updating these? I might be missing that use case in my mind. |
If we don't expect the cache to be large, there is no reason to let it grow to exactly that. Even if this is not a critical spot in Mill, out of experience, sometimes, this will blow up. Imagine an unnoticed bug in Mill server is expected to run in the background and this can be very long. Also, BSP is starting an instance and keeps it for the full IDE session. If one plays around with some |
|
Alright, refactored to use a |
Now that com-lihaoyi/mill#1988 is in a stable release we can start supporting pure javaModules when the user is on Java 17 on Mill >= 0.10.6.
…2231) We need this feature to support SemanticDB generation (#2227) via a Java compiler plugin in mixed Scala/Java projects. We already introduced non-local Java compilers in #1988. This change now also allows the use of a non-local Java compiler in mixed Java/Scala modules, if any `-J` option is given. As compilers are cached, I added the `hashCode` of the relevant runtime `javacOptions` to the cache key. I took the opportunity to remove non-relevant options from the existing Java compiler cache, to reduce the amount of cached compiler instances. Pull request: #2231
Currently if you want to pass in some
javacOptionsthat start with-Jthe Java compiler will reject them since the local java compilerwon't accept
-Jflags. You can see this in an example on JDK 17 whereyou need some
-Jflags to get the java semantidb compiler plugin towork:
Which will result in:
This change looks at the
javacOptionswhen creating the java comiplerand if detected makes sure you get a non-local compiler. If none are
detected, then the behavior basically is the same as it was before where
a local instance is used.
We also cache this to ensure it's not created over and over. However if
your
javacOptionchange, then we do give a new instance.Fixes #1983