gradlex-org/extra-java-module-info

provide functionality to automatically "export" / "open" all packages

hendrikebbers opened this issue · 5 comments

We have several dependencies in our project that does not provide any module support. By using your great plugin we can simply convert all that dependencies to be an automatic module:

automaticModule("com.goterl:lazysodium-java", "lazysodium.java")

We (sadly) still have several of that modules and all will be as automatic modules on the module path at compile time. Based on the definition of automatic modules (see overview at https://stackoverflow.com/questions/46741907/what-is-an-automatic-module) we have a limitation:

Automatic modules imply readability on all other automatic modules, which means a module reading one of them, reads all of them.

Based on that we do not get any error at gradle build time when we do not add all the requires foo.bar definitions in the module-info.java files of our modules. Only one requires statement is needed for all automatic modules.

Example

At compile time we depend on the foo and bar libs (import statements in our code). Since the foo and bar libs have no module support we use your plugin to define them as automatic modules:

plugins {
    id("org.gradlex.extra-java-module-info")
}
extraJavaModuleInfo {
    failOnMissingModuleInfo.set(true)
    automaticModule("foo:foo", "foo")
    automaticModule("bar: bar", "bar")
}

Since we have import statements for both libs in our code you would assume that we need to add requires statements for both of them. But only anyone of the is needed and based on the definition of automatic modules both can be accessed.

What we could to do solve the problem

We could use your api to define the dependency as a "real" module and add exports for all internal packages by hand:

module("foo:foo", "foo") {
        exports("com.foo")
        exports("com.foo.impl")
        exports("com.foo.api")
        exports("com.foo.common")
}

Since this is a lot of work for all Jars it would be great to have a functionally that automatically add exports to all packages of a jar:

module("foo:foo", "foo") {
        exportAllPackages(true)
}

Would that be a possible / interesting new feature for the plugin?

Thanks for the suggestion @hendrikebbers and for the detailed explanation on:

Since we have import statements for both libs in our code you would assume that we need to add requires statements for both of them. But only anyone of the is needed and based on the definition of automatic modules both can be accessed.

I have been seeing this as well and I wasn't totally sure why this is.

In a project, we have been using the dependency-analysis-gradle-plugin to reveal missing implementation dependencies (which in combination with java-module-dependencies means missing requires). And found some cases like this through that.

I think this is a great proposal and I could use the feature as well. It's probably not too hard to add. The plugin looks inside the Jars already to add the module-info and it should be straight forward to also extract the packages it contains.

I'll look into implementing this soon.

Additional thought (see #40):
Compared to automatic modules, you are still left with adding the requires. Maybe this could also be automated by computing the requires based on the dependencies declared in metadata using the "Module Name" <-> "GA Coordinates" mappings from java-module-dependencies.

@jjohannes thank you for your response. I'm not familiar with writing gradle plugins. Based on that I can not create such PR but I can test it once it is available. When I can help you with anything just let me know.

This feature is now on main and can be used as follows:

module("org.apache.httpcomponents:httpclient", "org.apache.httpcomponents.httpclient") {
  exportAllPackages()
}

@hendrikebbers I just published 1.2 including the enhancement. Let me know if there are any issues.

See also: https://github.com/gradlex-org/extra-java-module-info#should-i-use-real-modules-or-automatic-modules

Sadly I needed to work on other topics the first weeks of the year but will find some time to look into it the next days.