2

This follows on from this excellent solution to the question of how to get Gradle to bundle up JavaFX with your distributions.

NB specs: Linux Mint 18.3, Java 11, JavaFX 13.

That stuff, involving jlink and a module-info.java, is beyond my pay grade (although I'm trying to read up on these things).

I want to move to using Groovy in my app and test code (i.e. Spock) rather than Java. The trouble is, the minute I include the "normal" dependency in my build.gradle i.e.

implementation 'org.codehaus.groovy:groovy-all:2.5.9'

and try to build, I get multiple errors:

mike@M17A ~/IdeaProjects/TestProj $  ./gradlew build

> Configure project :
Found module name 'javafx.jlink.example.main'

> Task :compileTestJava FAILED
error: the unnamed module reads package org.codehaus.groovy.tools.shell.util from both org.codehaus.groovy.groovysh and org.codehaus.groovy
[...]
error: the unnamed module reads package groovy.xml from both org.codehaus.groovy and org.codehaus.groovy.xml
[...]
error: module org.codehaus.groovy.ant reads package groovy.lang from both org.codehaus.groovy and org.codehaus.groovy.test
error: module org.codehaus.groovy.ant reads package groovy.util from both org.codehaus.groovy.xml and org.codehaus.groovy.ant
100 errors

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileTestJava'.

Yes, 100 errors... probably more! By commenting out various things I think I've come to the conclusion that some Groovy dependency is being injected by the jlink stuff. Fine, I can live with that (although it'd be nice to know what version of Groovy it is).

The trouble is, even if I omit the Groovy dependency line, the same errors occur when I try to introduce the Spock dependency:

testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'

Has anyone got any idea what's going on here and what to do about it?

mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • You can see JLink as a way to "include" java in a native exe file, to distribute your application to clients easily (without asking them to install java). Modules can be seen as a way to improve the concept of visibility (public, private, ...). You can separate your classes into different modules. If you define a class or a method as "public" in a module, but you don't export the package to other modules, your class will be public inside the module, but not visible from another ones. It can be useful for libraries (useful internal class that the users should not use directly) – Flpe Mar 07 '20 at 11:33
  • Modules are also used inside the java architecture. The Java standard libraries are separated into modules. It allows your application to depends only on a few part of the standard modules of java (instead of depending on the complete library). It can be great for an embedded application (you don't have to embed all java classes if the storage of the system is limited). – Flpe Mar 07 '20 at 11:38
  • I will check if I find something about your problem (I never used Groovy before). Thanks for finding my sample project useful (I shared it because it took me time to make it work) – Flpe Mar 07 '20 at 11:40

1 Answers1

3

I searched for an answer. I didn't find a good solution.

According to this, it seems that Groovy is currently not really compatible with Java modules. It is due to the fact that some packages are contained by multiple jars of the library (not compatible with modules). You will have to wait for Groovy 4 for a compatible version.

I discovered that the JavaFX plugin use this plugin internally. This plugin seems to consider that all dependencies are modules (it is not the default Gradle behaviour).

To make your application works, it seems that you have to:

  • force Gradle to put Groovy in the classpath instead of the modulepath (it will not be considerered as a module, but seems impossible if you use the javafx plugin)
  • use the "patch-module" system: it allows Gradle to make a fusion of the library jars into a single module, to prevent the problem of packages that are in different jars

I searched the Groovy jars with IDEA (Project structure/Libraries), and I tried to use the syntax offered by the plugin to use "patch-module":

patchModules.config = [
    "org.codehaus.groovy=groovy-ant-3.0.1.jar",
    "org.codehaus.groovy=groovy-cli-picocli-3.0.1.jar",
    "org.codehaus.groovy=groovy-console-3.0.1.jar",
    "org.codehaus.groovy=groovy-datetime-3.0.1.jar",
    "org.codehaus.groovy=groovy-docgenerator-3.0.1.jar",
    "org.codehaus.groovy=groovy-groovydoc-3.0.1.jar",
    "org.codehaus.groovy=groovy-groovysh-3.0.1.jar",
    "org.codehaus.groovy=groovy-jmx-3.0.1.jar",
    "org.codehaus.groovy=groovy-json-3.0.1.jar",
    "org.codehaus.groovy=groovy-jsr-3.0.1.jar",
    "org.codehaus.groovy=groovy-macro-3.0.1.jar",
    "org.codehaus.groovy=groovy-nio-3.0.1.jar",
    "org.codehaus.groovy=groovy-servlet-3.0.1.jar",
    "org.codehaus.groovy=groovy-sql-3.0.1.jar",
    "org.codehaus.groovy=groovy-swing-3.0.1.jar",
    "org.codehaus.groovy=groovy-templates-3.0.1.jar",
    "org.codehaus.groovy=groovy-test-junit-3.0.1.jar",
    "org.codehaus.groovy=groovy-test-3.0.1.jar",
    "org.codehaus.groovy=groovy-testng-3.0.1.jar",
    "org.codehaus.groovy=groovy-xml-3.0.1.jar"
]

It only works with a single line "org.codehaus.groovy=X.jar", but a bug prevents it to work with all of the library jars (Look at this issue on Github).

So you have multiple choices:

  • Use Java instead of Groovy
  • Wait for a new Groovy release, or new releases of plugins (modules-plugin, and a version of javafx-plugin that use this one internally)
  • Use old javafx configuration: dependencies are not module by default, and you have to specify manually in build.gradle that JavaFX dependencies should be considered as a module (check my "obsolete" answer to this question)
mike rodent
  • 14,126
  • 11
  • 103
  • 157
Flpe
  • 771
  • 1
  • 8
  • 12
  • Thanks for looking into this, you've clarified the issue. I'll have a look at your older answer. If it's a choice between Java modules and Groovy I will be sticking with Groovy! – mike rodent Mar 08 '20 at 10:36
  • Sorry, I'm a bit confused. The "other" answer in that thread of yours also seems to use Java 9+ modules. Could you maybe clarify either here or there? – mike rodent Mar 08 '20 at 11:52
  • With this other answer, we have to add the "--add-modules" part to build.gradle to add the javafx dependency to the modulepath. So I suppose that if you don't write a "--add-module" line in build.gradle for Groovy, it will be added to the classpath instead of the modulepath (and it will not be considerated as a module). I didn't test it, but it should work if my understanding of modules in gradle is correct. – Flpe Mar 08 '20 at 12:45