How to add java compiler "release" flag to scala project using gradle - scala

I have a scala based project built with gradle, it contains java and scala code. We are upgrading to OpenJDK11 from oracle jdk 8. We are upgrading with binaries compatible with JDK8 by adding release flag to compiler.
I achieved that for java files by
if(JavaVersion.current() > JavaVersion.VERSION_1_9) {
subprojects {
tasks.withType(JavaCompile) {
options.compilerArgs += ["--release", "8"]
}
tasks.withType(ScalaCompile) {
options.compilerArgs += ["--release", "8"]
}
}
}
in build.gradle. This works fine ie the build seems to add the release flag, to test this I added a JDK 11 specific change to java class. ie Used String.repeat in java class and compiler throws error but if I add the same to a scala class it compiles without reporting the error that repeat() is not an method available.
What am I missing does adding release flag to scala compilation mean nothing or how can I achieve this?
The intention is to have binaries that run on JDK 8 or JDK11 we are ok for now to compromise on using JDK11 based new features. So I need to make sure no other developers add jdk11 specific code so that we end up on runtime issues.

Related

Scala-reflect not found

I have a Kotlin based Gradle project, where I'm using Scala. All my dependencies are coming from the internal repository, so I cannot use any Scala version, but only the ones available.
Because of that I have the following list of dependencies:
plugins {
java
}
//...
apply(plugin = "scala")
//...
dependencies {
implementation("org.scala-lang.scala-reflect:2.12.5")
compileOnly("org.scala-lang.scala-library:2.12.9") {
exclude("org.scala-lang.scala-reflect")
}
On paper it should work - I defined dependencies available on internal nexus.
However, when I try to build the project, I'm getting the following error:
Execution failed for task ':compileScala'.
> Could not resolve all files for configuration ':zinc'.
> Could not find scala-reflect-2.12.10.jar (org.scala-lang.scala-reflect:2.10.10).
> Searched in the following locations:
<nexus_url>
Is it because of scala plugin?
UPDATE
I have checked that the error occurs, because the version of Zinc I have is built on top of Scala 2.12.10. And since the version is not available on the nexus, it cannot be ran.
Is there a way to change the Scala version Zinc is using?
After searching through Gradle Scala plugin documentation (https://docs.gradle.org/current/userguide/scala_plugin.html#sec:configure_zinc_compiler)
I have found the solution.
What I had to do was changing the Zinc version:
scala {
zincVersion.set("1.3.1")
}

Scala not builds on Java 10

while building through Intellij Idea, I got the following message:
Error:scalac: 'jvm-1.10' is not a valid choice for '-target'
Error:scalac: bad option: '-target:jvm-1.10'
later, after a Java upgrade
Build, Execution, Deployment -> Build Tools -> Gradle -> Gradle JVM:
1.8 Build, Execution, Deployment -> Complier -> Scala Complier -> Scala Compile Server -> JDK: 1.8
in build.gradle
compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false
Nothing helps!
upd:
this helps: in build.gradle
tasks.withType(ScalaCompile) {
scalaCompileOptions.useAnt = false
}
not needed:
compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false
"Error:scalac: 'jvm-1.10' is not a valid choice for '-target' Error:scalac: bad option: '-target:jvm-1.10'"
In the JDK compatibility notes as mentioned below, it also indicates
that the Java 10 is not fully supporting Scala 2.12.6 JDK 9 & 10
compatibility notes
As you were saying you build this through IntelliJ IDEA, I suspect
you haven't configure your java version (Java 10) or scala version
(2.12.6) inside running configuration project settings.
And also please try out building/compile your application through
commandline in order to check whether you are getting the same error
with that (Otherwise this is just bad configuration in IDEA tht you
need to change)
JDK 9 & 10 compatibility notes (Mentioned in Scala Docs)
JDK 9 & 10 compatibility notes
As of Scala 2.12.6 and 2.11.12, JDK 9 & 10 support is incomplete. Notably, scalac will not enforce the restrictions of the Java Platform Module System, which means that code that typechecks may incur linkage errors at runtime.
JDK 9 & 10 support requires minimum sbt version 1.1.0, or 0.13.17 in the 0.13.x series.
For more information on JDK 9 & 10 compatibility, watch the “Support JDK 9” issue on GitHub.
The same issue can happen with mixed multi-module gradle projects that use java 11 and scala 2.12.10.
In that case, it may help to reconfigure IntelliJ (2019.2) via
Settings > Build, Execution, Deployment > Scala Compiler
by removing the targets defined in Additional compiler options for the affected scala modules.
I stumbled over this issue when having the same problem with Java 11. The reconfiguration comment of Roland Ewald solved the problem. It is important to mention, that this reconfiguration has to be made for all modules of the project (at least for me this was necessary) as well as that IntelliJ sometimes hides parts of the Additional compiler options, so be sure to click on expand even if they seem empty or correct.

Error:scalac: 'jvm-1.9' is not a valid choice for '-target'

Created a new clean Scala project using Gradle.
This is the only dependency:
compile "org.scala-lang:scala-library:2.12.4"
When building on the command line ./gradlew build works perfectly fine. However, when using IntelliJ it gives me this warning:
Error:scalac: 'jvm-1.9' is not a valid choice for '-target'
Error:scalac: bad option: '-target:jvm-1.9'
I have both the JDK with java 8 and 9 installed, but I'm currently using JDK 1.8. But I'm not sure if that's related.
In Scala 2.12, the Scala compiler always compiles to Java 8 compatible bytecode.
You can find more info below:
Compiling and testing Scala 2.12
Scala-lang: JAVA 8 BYTECODE FOR LAMBDAS
Add the following lines to your build.gradle:
compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false
I had the same problem and my issue was that gradle JDK was set to 9. I changed the JDK to 8 (Settings -> Build, Execution, Deployment -> Build Tools -> Gradle -> Gradle JVM) and it worked

How to setup JUnit testing in Gluon Project with Gradle

I am trying to setup JUnit testing in my Gluon JavaFX Application. I am using the Gluon Eclipse Plugin with Gradle and Java 8.
My build.gradle file looks like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b10'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
dependencies {
compile 'com.gluonhq:ignite-dagger:1.0.0'
compile 'org.elasticsearch:elasticsearch:1.6.0'
compile 'ch.qos.logback:logback-classic:1.1.5'
testCompile 'junit:junit:4.12'
}
mainClassName = 'com.me.MyApplication'
jfxmobile {
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
}
}
Resolving the dependency is no problem, but when running the 'test' task, gradle throws an error like this:
When running gradle with java 8, you must set the path to the old jdk, either with property retrolambda.oldJdk or environment variable JAVA6_HOME/JAVA7_HOME
Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-2.2.1-all.zip'.
I already tried to add the retrolambda plugin to gradle according to the plugin's README on GitHub, but it doesn't work so far. Could someone tell me what to do to configure my Gluon project so that I am able to run my JUnit tests with Gradle?
Some important addidtions:
For the plugin version it says: Gluon Tools 1.0.0.201508201514
I think I fogot to mention that I want to use Dagger dependency injection with Gluon Ignite which might be the real problem in my case as it requires Java 8 and might conflict with javafxports or something else. However, I'm not able to make full sense of the various error messages I've seen.
My tests are empty, but they aren't even run, because it fails before.
Your problem seems like a retroLambda configuration issue. If you go through the configuration page for the plugin, it states that if you don't have an environment variable set for JAVA6_HOME or JAVA7_HOME than you need to explicitly define oldJdk for the plugin to work properly.

How to instruct gradle's scala plugin to pick specific JVM among installed ones?

I want to run scala compilation with specific JVM. I'm using Scalatra, and my default JVM is 1.8. With such setup, I run into this problem: Compilation failed: error while loading AnnotatedElement, ConcurrentMap, CharSequence from Java 8 under Scala 2.10?
So I want to use JVM 1.7 for this, how to set it up for gradle "scala" plugin?
How to instruct gradle's scala plugin to pick specific JVM among installed ones?
This isn't currently supported. The best solution is to run Gradle itself with the desired JVM. It might be possible to instead set a different JVM bootstrap class path via...
tasks.withType(ScalaCompile) {
scalaCompileOptions.with {
useAnt = false
fork = true
forkOptions.jvmArgs = [...]
}
}
..., but you would have to figure out the details yourself (see JVM docs). Also you would have to know the JVM installation path.
The scalac compiler has special parameters
–javabootclasspath path
Override Java boot classpath.
–javaextdirs path
Override Java extdirs classpath.
You have to pass those parameters from gradle scala plugin using an additionalParameters parameter
this approach does not requires forking
allprojects {
tasks.withType(ScalaCompile) {
if (sourceCompatibility == '1.7') {
scalaCompileOptions.with {
def jdk7rt = new File("$System.env.JAVA7_HOME", "jre/lib/rt.jar").canonicalPath
def jdk7ext = new File("$System.env.JAVA7_HOME", "jre/lib/ext").canonicalPath
additionalParameters = ["-javabootclasspath $jdk7rt".toString(), "-javaextdirs $jdk7ext".toString()]
}
}
}
}
I used this approach on my OS with JVM 1.7 as default for compiling with JDK8 some subprojects that requires javafx8. So it should work in your case.