Maven jlink插件:在运行生成的镜像时找不到本地库。

huangapple go评论81阅读模式
英文:

Maven jlink plugin: native libraries not found when running the resulting image

问题

以下是您要翻译的代码部分的翻译:

Context: Linux Mint 21.1, Java Adoptium 17.0.7 JDK, Maven 3.6.3.

My modular application uses LWJGL (and then its native libraries); using the Maven jlink plug-in I generate a Java image. During generation, the jlink plug-in prints the following:

[INFO] --- maven-jlink-plugin:3.1.0:jlink (default-cli) @ treni ---
INFO]  -> module: org.lwjgl.stb ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar )
INFO]  -> module: org.slf4j ( /home/mmg/.m2/repository/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar )
INFO]  -> module: imgui.natives.linux ( /home/mmg/.m2/repository/io/github/spair/imgui-java-natives-linux/1.86.10/imgui-java-natives-linux-1.86.10.jar )
INFO]  -> module: org.lwjgl ( /home/mmg/.m2/repository/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar )
INFO]  -> module: imgui.binding ( /home/mmg/.m2/repository/io/github/spair/imgui-java-binding/1.86.10/imgui-java-binding-1.86.10.jar )
INFO]  -> module: org.lwjgl.stb.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux.jar )
INFO]  -> module: org.lwjgl.glfw ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar )
INFO]  -> module: org.joml ( /home/mmg/.m2/repository/org/joml/joml/1.10.5/joml-1.10.5.jar )
INFO]  -> module: org.lwjgl.opengl ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar )
INFO]  -> module: org.slf4j.jul ( /home/mmg/.m2/repository/org/slf4j/slf4j-jdk14/2.0.7/slf4j-jdk14-2.0.7.jar )
INFO]  -> module: org.lwjgl.opengl.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux.jar )
INFO]  -> module: org.lwjgl.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux.jar )
INFO]  -> module: com.vistamaresoft.treni ( /home/mmg/Documents/projects/Eclipse_workspaces/Treni/treni/target/classes )
INFO]  -> module: org.lwjgl.glfw.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux.jar )
INFO] Building zip: /home/mmg/Documents/projects/Eclipse_workspaces/Treni/treni/target/treni-0.0.1.zip

which shows that the plug-in knows about all the required native library JAR's.

I expected the resulting application to be able to locate the (evidently included, see below) native libraries, but it seems it is not, at least without additional hints I have no idea how to give it (and I could not find described anywhere). In fact, when I run the generated shell script, I receive the error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Failed to locate library: liblwjgl.so

Note that the required library is contained in the lwjgl-3.3.2-natives-linux.jar referenced by the pom.xml dependencies via the appropriate profile (see below for the pom.xml contents).

The shell script is the default one generated by the jlink plug-in (the same for all my jlink-ed apps, only the module/main_class changes from one to another); anyway for completeness, this is its contents:

#!/bin/sh
JLINK_VM_OPTIONS=
DIR=`dirname $0`
$DIR/java $JLINK_VM_OPTIONS -m com.vistamaresoft.treni/com.vistamaresoft.treni.Main "$@"

The generated image DOES contain the native libraries: I tried generating an image WITHOUT the native dependencies and the result is shorter roughly of the same size of those JAR's. The difference, as expected, is in the resulting lib/modules file. So, this file presumably does contain the needed library/ies, but the executable(s) are not able to retrieve them?

I have Googled and 'stackoverflow-ed' for a whole day and I found nothing: any suggestion, help, hint about what it is happening is welcome.

This is the (slightly shortened for brevity) pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

<!-- Several descriptive tags removed for brevity -->
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>17</maven.compiler.source>
		<maven.compiler.target>17</maven.compiler.target>
		<target.name>treni</target.name>
		<!-- Versions -->
		<project.version>0.0.1</project.version>
		<java.version>17</java.version>
		<joml.version>1.10.5</joml.version>
		<joml-primitives.version>1.10.4</joml-primitives.version>
		<lwjgl.version>3.3.2</lwjgl.version>
		<imgui-java.version>1.86.10</imgui-java.version>
		<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
		<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
		<maven-dependency-plugin.version>3.6.0</maven-dependency-plugin.version>
		<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
		<maven-jlink-plugin.version>3.1.0</maven

<details>
<summary>英文:</summary>

Context: Linux Mint 21.1, Java Adoptium 17.0.7 JDK, Maven 3.6.3.

My modular application uses LWJGL (and then its native libraries); using the Maven jlink plug-in I generate a Java image. During generation, the jlink plug-in prints the following:

[INFO] --- maven-jlink-plugin:3.1.0:jlink (default-cli) @ treni ---
INFO] -> module: org.lwjgl.stb ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar )
[INFO] -> module: org.slf4j ( /home/mmg/.m2/repository/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar )
[INFO] -> module: imgui.natives.linux ( /home/mmg/.m2/repository/io/github/spair/imgui-java-natives-linux/1.86.10/imgui-java-natives-linux-1.86.10.jar )
[INFO] -> module: org.lwjgl ( /home/mmg/.m2/repository/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar )
[INFO] -> module: imgui.binding ( /home/mmg/.m2/repository/io/github/spair/imgui-java-binding/1.86.10/imgui-java-binding-1.86.10.jar )
[INFO] -> module: org.lwjgl.stb.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux.jar )
[INFO] -> module: org.lwjgl.glfw ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar )
[INFO] -> module: org.joml ( /home/mmg/.m2/repository/org/joml/joml/1.10.5/joml-1.10.5.jar )
[INFO] -> module: org.lwjgl.opengl ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar )
[INFO] -> module: org.slf4j.jul ( /home/mmg/.m2/repository/org/slf4j/slf4j-jdk14/2.0.7/slf4j-jdk14-2.0.7.jar )
[INFO] -> module: org.lwjgl.opengl.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux.jar )
[INFO] -> module: org.lwjgl.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux.jar )
[INFO] -> module: com.vistamaresoft.treni ( /home/mmg/Documents/projects/Eclipse_workspaces/Treni/treni/target/classes )
[INFO] -> module: org.lwjgl.glfw.natives ( /home/mmg/.m2/repository/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux.jar )
[INFO] Building zip: /home/mmg/Documents/projects/Eclipse_workspaces/Treni/treni/target/treni-0.0.1.zip

which shows that the plug-in knows about all the required native library JAR&#39;s.

I expected the resulting application to be able to locate the (evidently included, see below) native libraries, but it seems it is not, at leat without additional hits I have no idea how to give it (and I could not find described anywhere). In fact, when I run the generate shell script, I receive the error:

`Exception in thread &quot;main&quot; java.lang.UnsatisfiedLinkError: Failed to locate library: liblwjgl.so`

Note that the required library is contained in the `lwjgl-3.3.2-natives-linux.jar` referenced by the `pom.xml` dependencies via the appropriate profile (see below for the `pom.xml` contents).

The shell script is the default one generated by the jlink plug-in (the same for all my jlink-ed apps, only the module/main_class changes from one to another); anyway for completeness, this is its contents:

#!/bin/sh
JLINK_VM_OPTIONS=
DIR=dirname $0
$DIR/java $JLINK_VM_OPTIONS -m com.vistamaresoft.treni/com.vistamaresoft.treni.Main "$@"


The generated image DOES contain the native libraries: I tried generating an image WITHOUT the native dependencies and the result is shorter roughly of the same size of those JAR&#39;s. The difference, as expected, is in the resulting `lib/modules` file. So, this file presumably does contain the needed library/ies, but the executable(s) are not able to retrieve them?

I have Googled and &#39;stackoverflow-ed&#39; for a whole day and I found nothing: any suggestion, help, hint about what it is happening is welcome.

This is the (slightly shortened for brevity) `pom.xml`;

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;>
<modelVersion>4.0.0</modelVersion>

<!-- Several descriptive tags removed for brevity -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<target.name>treni</target.name>
<!-- Versions -->
<project.version>0.0.1</project.version>
<java.version>17</java.version>
<joml.version>1.10.5</joml.version>
<joml-primitives.version>1.10.4</joml-primitives.version>
<lwjgl.version>3.3.2</lwjgl.version>
<imgui-java.version>1.86.10</imgui-java.version>
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
<maven-dependency-plugin.version>3.6.0</maven-dependency-plugin.version>
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<maven-jlink-plugin.version>3.1.0</maven-jlink-plugin.version>
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
</properties>

&lt;profiles&gt;
	&lt;profile&gt;
		&lt;id&gt;lwjgl-natives-linux-amd64&lt;/id&gt;
		&lt;activation&gt;
			&lt;os&gt;
				&lt;family&gt;unix&lt;/family&gt;
				&lt;arch&gt;amd64&lt;/arch&gt;
			&lt;/os&gt;
		&lt;/activation&gt;
		&lt;properties&gt;
			&lt;lwjgl.natives&gt;natives-linux&lt;/lwjgl.natives&gt;
			&lt;imgui.native&gt;natives-linux&lt;/imgui.native&gt;
			&lt;imgui.native.module&gt;linux&lt;/imgui.native.module&gt;
		&lt;/properties&gt;
	&lt;/profile&gt;
	&lt;!-- Windows and MacOs profiles removed for brevity --&gt;
&lt;/profiles&gt;

&lt;dependencies&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-glfw&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-opengl&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-stb&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
		&lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
		&lt;version&gt;2.0.7&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
		&lt;artifactId&gt;slf4j-jdk14&lt;/artifactId&gt;
		&lt;version&gt;2.0.7&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.joml&lt;/groupId&gt;
		&lt;artifactId&gt;joml&lt;/artifactId&gt;
		&lt;version&gt;${joml.version}&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;io.github.spair&lt;/groupId&gt;
		&lt;artifactId&gt;imgui-java-binding&lt;/artifactId&gt;
		&lt;version&gt;${imgui-java.version}&lt;/version&gt;
	&lt;/dependency&gt;

<!-- Natives -->

	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
		&lt;classifier&gt;${lwjgl.natives}&lt;/classifier&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-glfw&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
		&lt;classifier&gt;${lwjgl.natives}&lt;/classifier&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-opengl&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
		&lt;classifier&gt;${lwjgl.natives}&lt;/classifier&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.lwjgl&lt;/groupId&gt;
		&lt;artifactId&gt;lwjgl-stb&lt;/artifactId&gt;
		&lt;version&gt;${lwjgl.version}&lt;/version&gt;
		&lt;classifier&gt;${lwjgl.natives}&lt;/classifier&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;io.github.spair&lt;/groupId&gt;
		&lt;artifactId&gt;imgui-java-${imgui.native}&lt;/artifactId&gt;
		&lt;version&gt;${imgui-java.version}&lt;/version&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;

&lt;/dependencies&gt;

&lt;build&gt;
	&lt;pluginManagement&gt;
		&lt;plugins&gt;

			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
				&lt;version&gt;${maven-compiler-plugin.version}&lt;/version&gt;
				&lt;configuration&gt; &lt;!--
					&lt;release&gt;S${java.version}&lt;/release&gt; --&gt;
					&lt;source&gt;${java.version}&lt;/source&gt;
					&lt;target&gt;${java.version}&lt;/target&gt;
					&lt;showDeprecation&gt;true&lt;/showDeprecation&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;

			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
				&lt;configuration&gt;
					&lt;archive&gt;
						&lt;manifest&gt;
							&lt;addClasspath&gt;true&lt;/addClasspath&gt;
							&lt;mainClass&gt;com.vistamaresoft.treni.Main&lt;/mainClass&gt;
						&lt;/manifest&gt;
					&lt;/archive&gt;
					&lt;outputDirectory&gt;${project.build.directory}/${target.name}&lt;/outputDirectory&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;

			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
				&lt;version&gt;3.5.0&lt;/version&gt;
				&lt;!-- run with `mvn javadoc:javadoc` --&gt;
				&lt;configuration&gt;
					&lt;reportOutputDirectory&gt;${project.basedir}/doc&lt;/reportOutputDirectory&gt;
					&lt;show&gt;public&lt;/show&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;

			&lt;plugin&gt;
				&lt;groupId&gt;org.moditect&lt;/groupId&gt;
				&lt;artifactId&gt;moditect-maven-plugin&lt;/artifactId&gt;
				&lt;version&gt;1.0.0.Final&lt;/version&gt;
					&lt;configuration&gt;
						&lt;outputDirectory&gt;${project.build.directory}/modules&lt;/outputDirectory&gt;
						&lt;overwriteExistingFiles&gt;true&lt;/overwriteExistingFiles&gt;
						&lt;modules&gt;
							&lt;module&gt;
								&lt;artifact&gt;
									&lt;groupId&gt;io.github.spair&lt;/groupId&gt;
									&lt;artifactId&gt;imgui-java-binding&lt;/artifactId&gt;
									&lt;version&gt;${imgui-java.version}&lt;/version&gt;
								&lt;/artifact&gt;
								&lt;moduleInfoFile&gt;${project.basedir}/src/main/moduleInfos/imgui.binding.module-info.java&lt;/moduleInfoFile&gt;
							&lt;/module&gt;

							&lt;module&gt;
								&lt;artifact&gt;
									&lt;groupId&gt;io.github.spair&lt;/groupId&gt;
									&lt;artifactId&gt;imgui-java-${imgui.native}&lt;/artifactId&gt;
									&lt;version&gt;${imgui-java.version}&lt;/version&gt;
								&lt;/artifact&gt;
								&lt;moduleInfoFile&gt;${project.basedir}/src/main/moduleInfos/imgui.natives.${imgui.native.module}.module-info.java&lt;/moduleInfoFile&gt;
							&lt;/module&gt;
						&lt;/modules&gt;
					&lt;/configuration&gt;
			&lt;/plugin&gt;

			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-jlink-plugin&lt;/artifactId&gt;
				&lt;version&gt;${maven-jlink-plugin.version}&lt;/version&gt;
				&lt;!-- run with `mvn jlink:jlink` separately from `mvn package` as combining both into `mvn package jlink:jlink` raises an error --&gt;
				&lt;extensions&gt;true&lt;/extensions&gt;
				&lt;configuration&gt;
					&lt;!-- Module paths overriding the Mavem local repo path for non-modular JAR, modularised with moditect-maven-plugin --&gt;
					&lt;modulePaths&gt;
						&lt;modulePath&gt;${project.build.directory}/modules/imgui-java-binding-${imgui-java.version}.jar&lt;/modulePath&gt;
						&lt;modulePath&gt;${project.build.directory}/modules/imgui-java-natives-${imgui.native.module}-${imgui-java.version}.jar&lt;/modulePath&gt;
					&lt;/modulePaths&gt;
					&lt;compress&gt;2&lt;/compress&gt;
					&lt;noHeaderFiles&gt;true&lt;/noHeaderFiles&gt;
					&lt;noManPages&gt;true&lt;/noManPages&gt;
					&lt;stripDebug&gt;true&lt;/stripDebug&gt;
					&lt;launcher&gt;treni=com.vistamaresoft.treni/com.vistamaresoft.treni.Main&lt;/launcher&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;

		&lt;/plugins&gt;
	&lt;/pluginManagement&gt;

	&lt;!-- PLUG-IN EXECUTIONS --&gt;

	&lt;plugins&gt;
		&lt;plugin&gt;
			&lt;groupId&gt;org.moditect&lt;/groupId&gt;
			&lt;artifactId&gt;moditect-maven-plugin&lt;/artifactId&gt;
			&lt;executions&gt;
				&lt;execution&gt;
					&lt;id&gt;add-module-infos&lt;/id&gt;
					&lt;phase&gt;generate-resources&lt;/phase&gt;
					&lt;goals&gt;
					&lt;goal&gt;add-module-info&lt;/goal&gt;
					&lt;/goals&gt;
				&lt;/execution&gt;
			&lt;/executions&gt;
		&lt;/plugin&gt;
	&lt;/plugins&gt;
&lt;/build&gt;

</project>

And this is the `module-info.java` of the app (currently in a single module):

module com.vistamaresoft.treni
{
exports com.vistamaresoft.treni;
exports com.vistamaresoft.treni.engine;
exports com.vistamaresoft.treni.engine.elements;
exports com.vistamaresoft.treni.objectviewer;
exports com.vistamaresoft.treni.sim;

requires			imgui.binding;
requires transitive	org.joml;
requires			org.lwjgl;
requires			org.lwjgl.glfw;
requires			org.lwjgl.opengl;
requires			org.lwjgl.stb;
requires transitive	org.slf4j;
requires java.prefs;
requires java.base;
requires java.logging;

}



</details>


# 答案1
**得分**: 0

我不确定这是否是最佳解决方案,因为它相当繁琐,但目前我只找到这一个,它(大部分)有效,并且可能对其他人也有用。我要感谢在[LWJGL论坛][1]中极大帮助我找到这个解决方案的SPASI。

1) **将本地库模块添加到`module-info.java`**:这确保了这些库将在jlink插件生成的可运行镜像中找到。实际上,对于每个本地库,将以下一行添加到`module-info.java`中:
```java
requires transitive org.lwjgl.natives;
  1. 不幸的是,无论是Eclipse还是Maven编译器,似乎都无法在本地Maven仓库.m2中找到这些模块。解决方法有三个部分:

2a) 复制依赖项从仓库到本地文件夹,例如target/modules,使用Maven依赖插件的copy-dependencies目标;这必须在Maven编译阶段之前完成(我使用generate-resources阶段),例如:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-dependency-plugin</artifactId>
	<version>3.6.0</version>
	<configuration>
		<outputDirectory>${project.build.directory}/modules</outputDirectory>
		<overWriteReleases>false</overWriteReleases>
		<overWriteSnapshots>false</overWriteSnapshots>
		<overWriteIfNewer>true</overWriteIfNewer>
	</configuration>
	<executions>
		<execution>
			<id>copy-dependencies</id>
			<phase>generate-resources</phase>
			<goals>
				<goal>copy-dependencies</goal>
			</goals>
		</execution>
	</executions>
</plugin>

2b) Maven编译器插件:将该插件指向依赖项已复制的文件夹,将以下指令添加到插件配置中:

<compilerArgs>
	<arg>--module-path</arg>
	<arg>${project.build.directory}/modules</arg>
</compilerArgs>

2c) Maven jlink插件:同样将该插件指向相同的文件夹,将以下指令添加到插件配置中:

<modulePaths>
	<modulePath>${project.build.directory}/modules</modulePath>
</modulePaths>

现在,Maven应该能够正确编译项目并创建可运行的应用程序。

  1. Eclipse(以及可能其他Java IDE):这仍然没有解决Eclipse无法解析在步骤1中添加到module-info.java的本地库模块的问题。

这意味着不能在Eclipse中构建项目,至少对于调试来说我觉得非常有用。也许可以解决那些JAR已经模块化的库的问题(但我不知道如何),但对于那些不是模块化的JAR并且需要被模块化的库,这是无法解决的(例如io.github.spair:imgui-java-natives-<platform>,它不是模块化的,通常用于OpenGL / Vulkan项目,其模块根本不存在于任何众所周知的位置,是在源代码之外生成的)。

由于我只通过命令行使用Maven,我通过准备(在Java源代码之外并与主项目的pom.xml平行)两个版本的module-info.java来解决这个问题,一个版本没有本地库模块,一个版本添加了本地库模块。

通常,项目的module-info.java与第一个较短版本保持一致;当我需要启动Maven构建时,一个小的shell脚本将module-info覆盖为扩展版本,运行所需的mvn命令,最后将module-info.java覆盖为“正常”的版本。虽然不是百分之百可靠,但还是可用的。

英文:

I am far from sure this is the best solution, as it is rather cumbersome, but it is the only one I found so far, it works (mostly) and may be useful to someone else too. I want to thank SPASI in the LWJGL forum, who greatly helped me in finding it.

  1. Add native libraries modules to module-info.java: this ensures that the libraries will be found within the runnable image generated by the jlink pug-in. In practice, add to module-info.java one line like
requires transitive org.lwjgl.natives;

for each native library.

  1. Unfortunately, both Eclipse and the Maven compiler seem unable to locate these modules within the local Maven repo .m2. The solution is three-fold:

2a) Copy the dependencies from the repo to a local folder, for instance target/modules using the copy-dependencies goal of the Maven dependency plug-in; this must be done before the Maven compile phase (I use the generate-resources phase), for instance:

&lt;plugin&gt;
	&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
	&lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
	&lt;version&gt;3.6.0&lt;/version&gt;
	&lt;configuration&gt;
		&lt;outputDirectory&gt;${project.build.directory}/modules&lt;/outputDirectory&gt;
		&lt;overWriteReleases&gt;false&lt;/overWriteReleases&gt;
		&lt;overWriteSnapshots&gt;false&lt;/overWriteSnapshots&gt;
		&lt;overWriteIfNewer&gt;true&lt;/overWriteIfNewer&gt;
	&lt;/configuration&gt;
	&lt;executions&gt;
		&lt;execution&gt;
			&lt;id&gt;copy-dependencies&lt;/id&gt;
			&lt;phase&gt;generate-resources&lt;/phase&gt;
			&lt;goals&gt;
				&lt;goal&gt;copy-dependencies&lt;/goal&gt;
			&lt;/goals&gt;
		&lt;/execution&gt;
	&lt;/executions&gt;
&lt;/plugin&gt;

2b) Maven compiler plug-in: point this plug-in to the folder where the dependencies have been copied, adding this directive to the plug-in configuration:

&lt;compilerArgs&gt;
	&lt;arg&gt;--module-path&lt;/arg&gt;
	&lt;arg&gt;${project.build.directory}/modules&lt;/arg&gt;
&lt;/compilerArgs&gt;

2c) Maven jlink plug-in: point this plug-in also to the same folder, adding the following directive to the plug-in configuration:

&lt;modulePaths&gt;
	&lt;modulePath&gt;${project.build.directory}/modules&lt;/modulePath&gt;
&lt;/modulePaths&gt;

Now, Maven should correctly compile the project and jlink a runnable application.

  1. Eclipse (and perhaps other Java IDE's too): this leaves unsolved the issue with Eclipse not resolving the native library modules added to the module-info.java in step 1.

This precludes building the project from within Eclipse, which I find very useful at least for debugging. Maybe this can be solved for the libraries whose JAR's are already modular (but I do not know how), but surely it cannot be solved for the JAR's which are NOT modular and have to be modularised (for instance with the org.moditect:moditect-maven-plugin): their modules simply do not exist in any well-known location and are generated out-of-source (this happen to me with the io.github.spair:imgui-java-natives-&lt;platform&gt; which is not modular and is often used with openGL / Vulkan projects).

As I use Maven only via command line, I work-around this preparing (our of the Java source and parallel to the main project pom.xml) 2 versions of the module-info.java, one without and one with the added modules.

Normally the project module-info.java is kept equal to the first, shorter, version; when I have to launch a Maven build, a small shell script overwrites module-info with the extended version, run the required mvn command(s) and finally overwrites module-info.java back with the 'normal' version. Not really fool-proof, but usable.

huangapple
  • 本文由 发表于 2023年7月17日 23:51:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706172.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定