How does one combine ScalaFXML with Gradle? - scala

Let me set up my end goal first:
I want to build a scala only gui application, that I can design with scene builder and later port with gluon to any platform I want to.
I was able to find out, that one needs to use JavaFXPorts in Scala to make that happen. I also found out that I need to use gradle to apply gluon successfully, or so it seems (please correct me if I am wrong because that's where the headache starts)
So in short that means: ScalaFXML and Gradle need to work together, but how?
I've found some interesting projects, but sadly none of these hit my criteria just right:
This one used JavaFX instead of ScalaFX
This one added Java to the project instead of using pure scala
After a long time searching I found a project, that was almost right. Sadly, this was built in sbt and not in gradle.
None the less I used that project as a base/example, as this was the first to use sfxml in way that was easily understood.
I have a gradle script, that almost works
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
// during build, we depend on the jfxmobile-plugin
classpath 'org.javafxports:jfxmobile-plugin:1.3.10'
}
}
plugins {
id 'java'
id 'scala'
id 'application'
}
apply plugin: 'org.javafxports.jfxmobile'
configurations {
scalaCompiler
scalaCompilerPlugin
}
configurations.scalaCompiler.transitive = false
compileScala.targetCompatibility = "1.8"
mainClassName = 'sfxml.Main'
repositories {
mavenCentral()
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
dependencies {
compile 'org.scala-lang:scala-library:2.12.6'
compile 'org.scala-lang:scala-compiler:2.12.6'
compile 'com.gluonhq:particle:1.1.3'
compile group: 'org.scalafx', name: 'scalafx_2.12', version: '8.0.144-R12'
compile group: 'org.scalafx', name: 'scalafxml-core-sfx8_2.12', version: '0.4'
compile group: 'org.scalamacros', name: 'paradise_2.12.6', version: '2.1.1'
scalaCompiler "org.scalamacros:paradise_2.12.6:2.1.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
tasks.withType(ScalaCompile) {
scalaCompileOptions.additionalParameters = [
"-Xplugin:" + configurations.scalaCompilerPlugin.asPath,
"-Ymacro-debug-lite"
]
options.compilerArgs = ["-Xdebug", "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=9999"]
}
After finally finding all the right repositories (or so I thought) no errors were marked down during the import process from IDEA, but at last I got the following error:
Error:(10, 7) macro annotation could not be expanded (the most common reason for that is that you need to enable the macro paradise plugin; another possibility is that you try to use macro annotation in the same compilation run that defines it)
class AdoptionFormPresenter(private val sizeTextField: TextField,
But as you might have figured out - if you've read the gradle script - I already tried enabling the plugin. So how do I fix this and achieve the goal stated at the beginning?
Btw: I already found the following solutions, but those also didn't work
This uses maven, but I want to use gradle, soo... thx google?
This sadly doesn't work
This sadly... also does not work :/
Footnote: All SDKs are freshly downloaded at the time of this posting

So after revisiting my gradle script and checking against the previously mentioned work arrounds, I found my mistake.
I didn't include the complete answer from here. So after editing my build.gradle to only include the necessary things, I got the following:
plugins {
id 'java'
id 'scala'
}
apply plugin: 'org.javafxports.jfxmobile'
configurations {
scalaCompiler
}
configurations.scalaCompiler.transitive = false
compileScala.targetCompatibility = "1.8"
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile 'org.scala-lang:scala-library:2.12.6'
compile group: 'org.scalafx', name: 'scalafx_2.12', version: '8.0.144-R12'
compile group: 'org.scalafx', name: 'scalafxml-core-sfx8_2.12', version: '0.4'
scalaCompiler "org.scalamacros:paradise_2.12.6:2.1.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
def String scalaCompilerOptions="-Xplugin:$configurations.scalaCompiler.singleFile.path"
compileScala.scalaCompileOptions.additionalParameters = [scalaCompilerOptions]
compileTestScala.scalaCompileOptions.additionalParameters = [scalaCompilerOptions]
That script will run this project with gradle instead of sbt.
Side note:
If you get the error "Cannot load resource: AdoptionForm.fxml" read the following post
I didn't complete my previously stated goal just yet, since I haven't used gluon for now. But the main problem of this post is solved, so I will mark this as the right answer.
I might add the gluon integration later if I get it to work.

Related

Eclipse is not using gradle dependencies jar during run or debug

I am trying to do basic hibernate task using Gradle project.
Dependency jars are download by Gradle and placed in Project and External Dependencies library.
I don't get any compile time error. But when I try to run or debug the main class in Eclipse, I am getting class not found NoClassDefFoundError.
Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
When I checked the build path, I could see the dependency library is configured with required jars but still eclipse is not using it.
But when I add the jar manually in the build path, I am not getting this exception.
Build.gradle File
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
apply plugin: "eclipse"
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final'
// https://mvnrepository.com/artifact/com.oracle.jdbc/ojdbc6
runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
// https://mvnrepository.com/artifact/com.oracle/ojdbc6
runtime group: 'com.oracle', name: 'ojdbc6', version: '11.2.0.4.0-atlassian-hosted'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
Thanks in advance!!!
I think you should update the classpath with the latest changes in the build file. Eclipse does not do that automatically in all versions.
Go to package explorer, right-click the build.gradle file, then from the context menu select gradle->refresh gradle project.
You can also enable auto sync from the preferences menus, go to gradle, and check the "Automatic Project Synchronization" checkbox.
Remove/comment this dependency and try.
runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
My Build.gradle:
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final'
// https://mvnrepository.com/artifact/com.oracle.jdbc/ojdbc6
// runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
// https://mvnrepository.com/artifact/com.oracle/ojdbc6
runtime group: 'com.oracle', name: 'ojdbc6', version: '11.2.0.4.0-atlassian-hosted'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
With the eclipse plugin, there are different build tasks being added:
./gradlew cleanEclipse eclipse

How to generate Spock reports with Eclipse

How do I generate html reports using the spock reports extension (https://github.com/renatoathaydes/spock-reports). I've added the dependency to my build.gradle file which, as far as I can tell, is the only thing I need to do. But when I run my tests on Eclipse I can't find any report appearing anywhere.
Here's my build.gradle file, spock reports dependency are at the end.
apply plugin: 'java-library'
apply plugin: 'groovy'
repositories {
jcenter()
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:22.0'
testImplementation 'org.codehaus.groovy:groovy-all:2.4.11'
testImplementation 'org.spockframework:spock-core:1.0-groovy-2.4'
testImplementation 'junit:junit:4.12'
testCompile( 'com.athaydes:spock-reports:1.3.1' ) {
transitive = false // this avoids affecting your version of Groovy/Spock
}
testCompile 'org.slf4j:slf4j-api:1.7.13'
testCompile 'org.slf4j:slf4j-simple:1.7.13'
}
EDIT: The build.gradle file is wrong.
I generated the build with "gradle init --type java-library --test-framework spock" which worked fine, I added some groovy classes and could run tests successfully on eclipse, but it gave me a "Cannot infer Groovy class path because no Groovy Jar was found on class path [...]" error when I tried to use gradle.build.
I changed the Groovy dependency from "testImplementatiuon" to "compile". It made it so that the project could compile and run tests from the command line. This also generated spock reports.
Running tests on eclipse still doesn't generate test reports.
I build a new project from the command line with this build.gradle file:
apply plugin: 'groovy'
apply plugin: 'java-library'
repositories { jcenter() }
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.11'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile( 'com.athaydes:spock-reports:1.3.1' ) {
transitive = false // this avoids affecting your version of Groovy/Spock
}
testCompile 'org.slf4j:slf4j-api:1.7.13'
testCompile 'org.slf4j:slf4j-simple:1.7.13'
}
And copied the same groovy files on it. Then imported the project to eclipse. This one works when I run tests from eclipse (it generates spock reports). I still don't know what the problem was exactly but I guess my issue is solved.

Using Gradle for Scala and ScalaTest (IntelliJ 2016.3.6)

Here is a quick build.gradle file I put together:
apply plugin: 'scala'
apply plugin: 'idea'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile "org.scala-lang:scala-library:2.12.2"
compile "org.scala-lang:scala-compiler:2.12.2"
testCompile 'org.scalatest:scalatest_2.11:3.0.1'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
If understood correctly, when running gradle idea, the external dependencies defined above appear in the External Libraries folder.
While I do see the dependencies in the folder, the issue I am facing is that I am unable to import anything from my external libraries provided by Gradle. Anything I manually provide (i.e. a downloaded version of the Scala SDK) works perfectly fine.
I have src and test marked as my sources root and test sources root, respectively.
What could possibly be the issue? Detailed explanations are also appreciated; I'm coming from a Maven background and struggling with the Gradle documentation.

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.

Provided dependency failing to provide

I got a Scalding (a hadoop abstraction layer in Scala) project that I'm trying to build using Gradle.
Looks like Hadoop became a provided dependency in latest releases and it requires some workaround.
So I patched my build.gradle script like so:
apply plugin: 'scala'
apply plugin: 'idea'
configurations {
provided
}
sourceSets {
main { compileClasspath += configurations.provided }
}
repositories {
mavenLocal()
mavenCentral()
maven{
url 'http://conjars.org/repo/'
}
}
ext.cascadingVersion = '2.1.6'
ext.hadoopVersion = '1.1.2'
dependencies {
compile 'org.scala-lang:scala-compiler:2.9.2'
compile 'org.scala-lang:scala-library:2.9.2'
compile 'bixo:bixo-core:0.9.1'
compile 'org.testng:testng:6.8.7'
testCompile 'org.scala-tools.testing:specs:1.6.2.2_1.5.0'
compile( 'com.twitter:scalding_2.9.2:0.8.1' )
compile( group: 'cascading', name: 'cascading-core', version: cascadingVersion )
compile( group: 'cascading', name: 'cascading-hadoop', version: cascadingVersion )
provided "org.apache.hadoop:hadoop-client:${hadoopVersion}"
}
jar {
description = "Assembles a Hadoop-ready JAR file"
doFirst {
into( 'lib' ) {
from configurations.compile
}
}
manifest {
attributes( "Main-Class": "com.Crawler" )
}
}
Which I thought would solve the problem. But I keep getting the following error at when trying to build:
[ant:scalac] Element '/Users/tkmafj4/Projects/AIT/Crawler/build/resources/main' does not exist.
[ant:scalac] scala.tools.nsc.symtab.Types$TypeError: class file needed by Source is missing.
[ant:scalac] reference value hadoop of package org.apache refers to nonexisting symbol.
Which looks a lot like there's something missing in my configuration.
How can I check that sources are being fetched?
What is the proper workaround to get this to compile?
hadoop becoming a "provided" dependency of cascading means that depending on cascading will no longer pull in hadoop, because hadoop is meant to be provided by the target environment or by whoever creates the ultimate deployable archive. If the hadoop dependency needs to go into your fat Jar, you need to make it (at least) a runtime dependency. But since there appears to be some problem with compilation, I'd try to make it a compile dependency.
If the hadoop dependency should go on the compile class path but not into the fat Jar, you'll need to add something like sourceSets.main.compileClasspath += configurations.provided.
PS: Your fat Jar task needs to package configurations.runtime rather than configurations.compile, and the doFirst { line (as well as the corresponding closing brace) should be removed.