Как внедрить объявление модуля в JAR?

Предположим, у меня есть библиотека lib.jar для которого у меня нет исходного кода (или он написан на не-Java языке, который еще не знает о модулях). lib.jar не имеет module-info.class и я не хочу использовать его в качестве автоматического модуля, поэтому я хотел бы ввести module-info.class внутрь.

Я сначала генерирую module-info.java с помощью следующей команды:

jdeps --generate-module-info . lib.jar

Предположим, это сгенерировало что-то вроде этого:

module lib {
    exports package1;
    exports package2;
}

Затем я пытаюсь скомпилировать его, но javac не удается, потому что пакеты package1 а также package2 не существует:

> javac module-info.java
module-info.java:4: error: package is empty or does not exist: package1

Конечно, я могу создавать каталоги package1 а также package2 с фиктивными классами в них, но есть ли лучший подход?

3 ответа

Решение

Да, это возможно с --patch-module вариант. Эта опция чаще всего используется во время выполнения, но она также работает во время компиляции:

javac --patch-module <module name>=<path to jar> module-info.java

Кроме того, чтобы скомпилировать module-info.java Сгенерированный вам необходимо также извлечь содержимое JAR в каталог.

Затем скомпилируйте module-info.java с выходным каталогом (-d), установленным в каталог, в который вы извлекли содержимое.

Кредиты:- Алан

Если вы используете Maven и там доступна исходная библиотека, вы можете использоватьadd-module-infoЦель плагина moditect. Ниже приведен фрагмент файла pom.xml, который я использовал для исправления драйвера и движка jdbc h2. Плагин создает исправленную копию плагина в${project.build.directory}/modulesкоторый затем можно использовать, например, jlinked.

      <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>
Другие вопросы по тегам