1. Введение
Одной из новых функций, которые предлагает нам Java 9 , является возможность создавать JAR-файлы с несколькими выпусками (MRJAR) . Как говорится в предложении по улучшению JDK , это позволяет нам иметь разные версии класса для конкретных выпусков Java в одном и том же JAR.
В этом руководстве мы рассмотрим, как настроить файл MRJAR с помощью Maven.
2. Мавен
Maven — один из наиболее часто используемых инструментов сборки в экосистеме Java; одна из его возможностей — упаковка проекта в JAR.
В следующих разделах мы рассмотрим, как использовать его для создания MRJAR.
3. Пример проекта
Начнем с базового примера.
Во-первых, мы определим класс, который выводит текущую используемую версию Java; до Java 9 одним из подходов, которые мы могли использовать, был метод System.getProperty
:
public class DefaultVersion {
public String version() {
return System.getProperty("java.version");
}
}
Теперь, начиная с Java 9, мы можем использовать метод новой версии
из класса Runtime :
public class DefaultVersion {
public String version() {
return Runtime.version().toString();
}
}
С помощью этого метода мы можем получить экземпляр класса Runtime.Version
, который дает нам информацию о JVM, используемой в новом формате схемы version-string .
Кроме того, давайте добавим класс App
для регистрации версии:
public class App {
private static final Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
logger.info(String.format("Running on %s", new DefaultVersion().version()));
}
}
Наконец, давайте поместим каждую версию DefaultVersion
в свою собственную структуру каталогов src/main
:
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── foreach
│ │ │ └── multireleaseapp
│ │ │ ├── DefaultVersion.java
│ │ │ └── App.java
│ │ └── java9
│ │ └── com
│ │ └── foreach
│ │ └── multireleaseapp
│ │ └── DefaultVersion.java
4. Конфигурация
Чтобы настроить MRJAR из приведенных выше классов, нам нужно использовать два подключаемых модуля Maven: подключаемый модуль компилятора и подключаемый модуль JAR.
4.1. Плагин компилятора Maven
В подключаемом модуле компилятора Maven нам нужно настроить одно выполнение для каждой версии Java, которую мы будем упаковывать.
В этом случае мы добавляем два:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile-java-8</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</execution>
<execution>
<id>compile-java-9</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
</compileSourceRoots>
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/9</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Мы будем использовать первое выполнение compile-java-8
для компиляции нашего класса Java 8 и выполнение compile-java-9
для компиляции нашего класса Java 9.
Мы видим, что необходимо настроить теги compileSourceRoot
и outputDirectory
с соответствующими папками для версии Java 9.
Однако, начиная с maven-compiler-plugin
3.7.1 , нам не нужно устанавливать выходной каталог вручную. Вместо этого все, что нам нужно сделать, это включить свойство multiReleaseOutput
:
<configuration>
<release>9</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
</compileSourceRoots>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
Если установлено значение true
, подключаемый модуль компилятора перемещает все классы, относящиеся к выпуску, в каталог META-INF/versions/${release}
. Обратите внимание, что здесь мы должны установить тег релиза
на желаемую версию Java, иначе подключаемый модуль компилятора выйдет из строя .
4.2. JAR-плагин Maven
Мы используем подключаемый модуль JAR, чтобы установить для записи Multi-Release
значение true
в нашем файле МАНИФЕСТА
. С этой конфигурацией среда выполнения Java будет искать в папке META-INF/versions
нашего JAR-файла классы для конкретной версии; в противном случае используются только базовые классы.
Давайте добавим конфигурацию maven- jar -plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
</plugin>
5. Тестирование
Пришло время протестировать наш сгенерированный файл JAR.
Когда мы выполним с Java 8, мы увидим следующий вывод:
[main] INFO com.foreach.multireleaseapp.App - Running on 1.8.0_252
Но если мы выполним с Java 14, мы увидим:
[main] INFO com.foreach.multireleaseapp.App - Running on 14.0.1+7
Как мы видим, теперь он использует новый формат вывода. Обратите внимание, что хотя наш MRJAR был создан с использованием Java 9, он совместим с несколькими основными версиями платформы Java.
6. Заключение
В этом кратком руководстве мы увидели, как настроить инструмент сборки Maven для создания простого файла MRJAR.
Как всегда, полный код, представленный в этом руководстве, доступен на GitHub .