Reputation: 39654
Suppose I have some library lib.jar
for which I do not have the source code (or it is written in some non-Java language which is unaware of modules yet). lib.jar
does not have module-info.class
and I do not want to use it as an automatic module, so I would like to inject module-info.class
into it.
I first generate module-info.java
with the following command:
jdeps --generate-module-info . lib.jar
Suppose this generated something like that:
module lib {
exports package1;
exports package2;
}
Then I try to compile it but javac
fails because the packages package1
and package2
do not exist:
> javac module-info.java
module-info.java:4: error: package is empty or does not exist: package1
Of course, I can create directories package1
and package2
with dummy classes in them, but is there some better approach?
Upvotes: 26
Views: 8713
Reputation: 31
If you are using Maven and the original library is available there, you can use the add-module-info
goal of the moditect plugin. Below is a snippet of pom.xml I used to patch the h2 jdbc driver and engine. The plugin creates a patched copy of the plugin in ${project.build.directory}/modules
which can then be used e.g. jlinked in.
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
<version>1.0.0.RC2</version>
<executions>
<execution>
<id>add-module-infos</id>
<phase>generate-resources</phase>
<goals>
<goal>add-module-info</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/modules</outputDirectory>
<modules>
<module>
<artifact>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</artifact>
<moduleInfoSource>
module com.h2database {
requires java.compiler;
requires jdk.net;
requires static lucene.core;
requires static lucene.queryparser;
requires static slf4j.api;
requires static jakarta.servlet;
requires transitive java.desktop;
requires transitive java.instrument;
requires java.logging;
requires transitive java.management;
requires static java.naming;
requires transitive java.scripting;
requires java.sql;
requires transitive java.transaction.xa;
requires transitive java.xml;
requires static javax.servlet.api;
requires static org.locationtech.jts;
requires static org.osgi.service.jdbc;
requires static osgi.core;
provides java.sql.Driver with org.h2.Driver;
}
</moduleInfoSource>
</module>
</modules>
</configuration>
</execution>
</executions>
</plugin>
Upvotes: 0
Reputation: 39654
Yes, this is possible with the --patch-module
option. This option is most often used at runtime, but it also works at compile time:
javac --patch-module <module name>=<path to jar> module-info.java
Upvotes: 24
Reputation: 32036
Alternatively, to compile the module-info.java
generated you need to also extract the contents of the JAR to a directory.
Then compile the module-info.java
with the output directory (-d) set to the directory where you extracted the contents.
Upvotes: 8