Hi Jochen, thanks for the observations. > It could also be solved by using static compilation for the module.
Actually the app is already statically compiled through a compiler configuration: https://github.com/mcolletta/groovy-modular-example/blob/4f9862d87fedd7a883b358ea0619faa0b5834374/build.gradle#L32 https://github.com/mcolletta/groovy-modular-example/blob/main/config/src/main/groovy/compiler-config.groovy > So maybe opens io.modular.example to org.apache.groovy; > in the module info might be already enough? Well, it's worth a try, will see Bye Mirco Il Dom 30 Mar 2025, 18:05 Jochen Theodorou <blackd...@gmx.org> ha scritto: > On 29.03.25 12:18, Mirco Colletta wrote: > > 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? > > the question though is what full modular means. Getting my knowledge > about modules refreshed a bit... we have normal modules, automatic > modules and unnamed modules. Groovy comes as automatic module, so it can > be referenced by name, but does not follow all the rules named modules > do. Latest JVMs might have done relevant changes here of course. > > Then there are the two cases of a script run by Groovy from source and > precompiled Groovy code in a different module. > > I think running scripts works to some extend, a full fledged Groovy app > in a module... maybe not. > > [...] > > 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 > < > https://github.com/mcolletta/groovy-modular-example/blob/main/build.gradle.nm > > > > yes... that is exactly what I expected :( > > > 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 > < > 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 > < > 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 > > <http://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 > > actually this line Mode.$INIT(App.groovy) tells me we are in the > constructor of Mode, that is not explicitly in the code, but would be > related more to the enum definition itself. Even though it is a enum it > still looks roughly like this (same in Java): > > final static class Mode extend Enum { > Mode(){super()} > ... > } > > The call to super is realized by selectConstructorAndTransformArguments > > > > https://github.com/mcolletta/groovy-modular-example/blob/4f9862d87fedd7a883b358ea0619faa0b5834374/src/main/groovy/io/modular/example/App.groovy#L20 > < > https://github.com/mcolletta/groovy-modular-example/blob/4f9862d87fedd7a883b358ea0619faa0b5834374/src/main/groovy/io/modular/example/App.groovy#L20 > > > > my assumption is that because of the module system Groovy cannot see the > the non-public constructor of the enum. I think you need to add an > add-opens... or was it add-exports.... well the groovy modules must be > able to read the hidden methods in the module of the groovy app. So maybe > > opens io.modular.example to org.apache.groovy; > > in the module info might be already enough? > > > It seems that in a modular context something interferes with the groovy > > runtime for (at least) enums. > > It could also be solved by using static compilation for the module. But > the problem will come back for other places > > > (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? > > We tweaked many places already in preparation for the module system and > keep changing things here an there, but we might be missing something > somewhere. I am afraid you would be the one to discover that then. We > will try to support you of course. Just don't expect things to go easy. > > bye Jochen > > > >