Search code examples
javagroovyjava-9java-modulejava-platform-module-system

Groovy Java 9 modules support


I've spent some time to migrate my project written in Groovy to Java 10. Now it's possible to compile and run it. But still it doesn't use any benefits of Java 9 modularity.
Googling about Groovy and Java 9 modules gives almost nothing.

So is it possible to migrate Groovy project to use JDK 10 with Project Jigsaw modules?


Solution

  • Well, after a few days of experiments I come up with the answer - yes, it is possible to use Groovy with Project Jigsaw modules.
    But it needs some additional effort.

    Let's say we have following file structure:

    ├── build
    ├── jigsaw
    │   └── module
    │       └── test
    │           └── Application.groovy
    ├── lib
    │   └── groovy.all.jar
    └── module-info.java  
    

    module-info.java

    module main {
        requires groovy.all;
    }
    

    Application.groovy

    package jigsaw.module.test
    
    class Application {
        static void main(String[] args) {
            println "Hello module!"
        }
    }
    

    First of all we need to compile module-info.java file with javac instead of compiling all files using groovyc because groovy treats module file as closure.

    Let's do it:

    javac -d build --module-path lib/ module-info.java
    

    --module-path will include our groovy.all.jar as automatic module with name derived from JAR-file name.

    Next we need to compile Application.groovy

    groovyc -d build jigsaw/module/test/Application.groovy
    

    It goes smoothly.
    After compilation we have module-info.class (aka module descriptor) and Application.class.

    ├── build
    │   ├── jigsaw
    │   │   └── module
    │   │       └── test
    │   │           └── Application.class
    │   └── module-info.class
    ├── jigsaw
    │   └── module
    │       └── test
    │           └── Application.groovy
    ├── lib
    │   └── groovy.all.jar
    └── module-info.java
    

    Now let's try to run our compiled module.

    java --module-path build:lib --module main/jigsaw.module.test.Application
    

    And this is what we get

    Error occurred during initialization of boot layer
    java.lang.module.FindException: Unable to derive module descriptor for lib/groovy.all.jar
    Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class moduleName=groovy-all not in module
    

    And what does it mean? I don't know. After a lot of googling I found something similar.

    So we need to manually remove from JAR these files:

    • /META-INF/services/org.codehaus.groovy.source.Extensions
    • /META-INF/services/org.codehaus.groovy.runtime.ExtensionModule

    Finally our Java module is able to start

    java --module-path build:lib --module main/jigsaw.module.test.Application
    Hello module!
    

    All manipulations were done using Oracle JDK 10 and Groovy 2.4.15.