Hi all,
I'd like to know if some of you has experience on how to create a full
modular (JPMS, JSR 376) groovy application.
First of all, is it possible, at the moment, to create a full modular
groovy application? If yes, what is the recommended approach?
An illustrative example.
Since JavaFX is distributed with a set of modules, up until now I've used a
non modular strategy with some gradle tricks to make it works: a task that
moves the javafx modules inside a build folder and an Exec task with all
the necessary javac arguments (--module-path, --add-modules, --add-exports,
etc.).
Just for the sake of reproducibility I created a very minimal example (few
lines of code) on this repository:
https://github.com/mcolletta/groovy-modular-example/

running the app using the NON modular (gradle) build file it works just
fine: (Gradle v. 8.13)
gradle --build-file=build.gradle.nm runApp

but as you can see this solution is not ideal nor elegant due to these
jvmArgs "--add-exports" to all unnamed modules (the many exports are
extracted from my real project)
https://github.com/mcolletta/groovy-modular-example/blob/main/build.gradle.nm

Eventually I've tried a different approach. I created a *module-info.java*
file with all the necessary "requires", including

> requires org.apache.groovy;

https://github.com/mcolletta/groovy-modular-example/blob/main/src/main/java/module-info.java

this way the application somewhat compiles with:

> gradle build

https://github.com/mcolletta/groovy-modular-example/blob/main/build.gradle

but for strange reasons it starts to give very weird errors at runtime
when *enums
*are present

> gradle run


Caused by: java.lang.ExceptionInInitializerError
>         at io.modular.example/io.modular.example.App.<init>(App.groovy)
>         at
> java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
>         ... 11 more
> Caused by: groovy.lang.GroovyRuntimeException: Could not find matching
> constructor for: io.modular.example.Mode(String, Integer)
>         at org.apache.groovy@4.0.26
> /groovy.lang.MetaClassImpl.createCachedConstructor(MetaClassImpl.java:1726)
>         at org.apache.groovy@4.0.26
> /groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments1(MetaClassImpl.java:1752)
>         at org.apache.groovy@4.0.26
> /groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments(MetaClassImpl.java:1679)
>         at org.apache.groovy@4.0.26
> /org.codehaus.groovy.runtime.ScriptBytecodeAdapter.selectConstructorAndTransformArguments(ScriptBytecodeAdapter.java:252)
>         at io.modular.example/io.modular.example.Mode.$INIT(App.groovy)
>         at io.modular.example/io.modular.example.Mode.<clinit>(App.groovy)


Here "Mode" is a simple *enum *and the problematic statement is this one:

> Mode mode = Mode.Edit

https://github.com/mcolletta/groovy-modular-example/blob/4f9862d87fedd7a883b358ea0619faa0b5834374/src/main/groovy/io/modular/example/App.groovy#L20

It seems that in a modular context something interferes with the groovy
runtime for (at least) enums.
(Beside the opaque behavior of the "run" task of the application plugin I
got however the same error adding my module explicitly with the command
line argument --module-path)
However as I stated above I'm not sure if this is a lecit and correct
strategy to make a groovy modular application.

Do you have any suggestions/advice?

Thanks in advance,

Mirco

Reply via email to