使用 maven 的具有依赖关系和 dll 依赖关系的可执行 jar
Executable jar with dependencies and dll dependency using maven
我有一个 Java 项目,使用我收到的 4 个 OpenGL jar 和 1 个 dll 作为计算机图形学课程的项目。
我想让 maven 为我将它构建成一个可执行的 jar,这样我就可以 git 从另一台计算机克隆我的 repo 并使用 maven 构建它来执行。 (最好使用 maven clean install
)
到目前为止我做了什么:
将 4 个 jar 和 dll 安装到项目内的本地存储库中。
这样,我只是设置依赖项,文件是从 git 存储库复制的,例如:
<repositories>
<repository>
<id>local-maven-repo</id>
<url>file:///${project.basedir}/local-maven-repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.computer.graphics</groupId>
<artifactId>jogl</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.computer.graphics</groupId>
<artifactId>gluegenrt</artifactId>
<version>1.0</version>
<scope>runtime</scope>
<type>dll</type>
</dependency>
...
在 src/assembly 中使用 assembly.xml 设置 maven 程序集插件。xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- Configure a class for executable jar -->
<archive>
<manifest>
<mainClass>Main class</mainClass>
</manifest>
</archive>
<!-- Points to the assembly descriptor to use -->
<descriptors>
<descriptor>src/assembly.xml</descriptor>
</descriptors>
</configuration>
<!-- Bind goal assembly:single into build process -->
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
试图将 jar 和 dll 包含到可执行 jar 中:
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>graphics-assembly</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<scope>runtime</scope>
<unpack>true</unpack>
<includes>
<include>*:jar:*</include>
</includes>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<includes>
<include>*:dll*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
据我了解,dll 文件应该位于可执行 jar 附近的目标文件夹中,但即使我手动复制该文件,当我尝试使用 java -jar executable-jar.jar
运行 jar 时例如,
我收到以下错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:170)
at javax.media.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:422)
at javax.media.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1516)
at javax.media.opengl.awt.GLCanvas.addNotify(GLCanvas.java:614)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/java.awt.Window.addNotify(Window.java:787)
at java.desktop/java.awt.Frame.addNotify(Frame.java:493)
at java.desktop/java.awt.Window.show(Window.java:1049)
at java.desktop/java.awt.Component.show(Component.java:1720)
at java.desktop/java.awt.Component.setVisible(Component.java:1667)
at java.desktop/java.awt.Window.setVisible(Window.java:1032)
- 我正在使用 intellij 并使用 File -> Project Structure -> Libraries -> 添加包含 jars 和 dll 的文件夹来简单地链接文件。
当我 运行 / 使用 intellij 构建项目时,一切正常。
我做错了什么?有更好的方法吗?
我最终从程序集文件中删除了 dll 的 dependencySet,并使用 maven-dependency-plugin 复制了 dll 依赖,如下所示:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.computer.graphics</groupId>
<artifactId>gluegenrt</artifactId>
<version>1.0</version>
<type>dll</type>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>gluegen-rt.dll</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</plugin>
ArrayIndexOutOfBoundsException 发生是因为我使用 jdk 16 而不是 jdk 12 到 运行 jar。
希望这对其他人有帮助。
我最近 运行 遇到了同样的问题。这似乎是 jogl / jogamp 中的一些已知错误,但一开始我并不清楚该怎么做。
只需将 --illegal-access=permit
添加到 VM 选项。在我的示例中,它与 OpenJDK-15 开箱即用,但在使用 OpenJDK-16 时我必须添加该 VM-Option。
我在使用 Jogamp 2.3.2 时遇到了同样的异常,在 Jogamp 2.4.0 中同样的修补程序有所帮助,但异常更改为:
Exception in thread "AWT-EventQueue-0" com.jogamp.opengl.GLException: Unable to determine GraphicsConfiguration: WindowsWGLGraphicsConfiguration[DefaultGraphicsScreen[WindowsGraphicsDevice[type .windows, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x1dc258d9]], idx 0], pfdID 7, ARB-Choosen true,
requested GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]],
chosen GLCaps[wgl vid 7 arb: rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, dp/st/ms 24/0/0, dbl, mono , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]]]
at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:182)
at com.jogamp.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:424)
at com.jogamp.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1513)
at com.jogamp.opengl.awt.GLCanvas.addNotify(GLCanvas.java:609)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/java.awt.Window.addNotify(Window.java:787)
at java.desktop/java.awt.Frame.addNotify(Frame.java:493)
at java.desktop/java.awt.Window.show(Window.java:1049)
at java.desktop/java.awt.Component.show(Component.java:1720)
at java.desktop/java.awt.Component.setVisible(Component.java:1667)
at java.desktop/java.awt.Window.setVisible(Window.java:1032)
at global.WindowSingleCanvas.createFrame(WindowSingleCanvas.java:122)
at global.WindowSingleCanvas.setWindowType(WindowSingleCanvas.java:86)
at global.WindowSingleCanvas.lambda$new(WindowSingleCanvas.java:39)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
另请参阅:http://forum.jogamp.org/JogAmp-Build-v2-4-0-rc-20210111-td4040955i20.html
我有一个 Java 项目,使用我收到的 4 个 OpenGL jar 和 1 个 dll 作为计算机图形学课程的项目。
我想让 maven 为我将它构建成一个可执行的 jar,这样我就可以 git 从另一台计算机克隆我的 repo 并使用 maven 构建它来执行。 (最好使用 maven clean install
)
到目前为止我做了什么:
将 4 个 jar 和 dll 安装到项目内的本地存储库中。 这样,我只是设置依赖项,文件是从 git 存储库复制的,例如:
<repositories> <repository> <id>local-maven-repo</id> <url>file:///${project.basedir}/local-maven-repo</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.computer.graphics</groupId> <artifactId>jogl</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.computer.graphics</groupId> <artifactId>gluegenrt</artifactId> <version>1.0</version> <scope>runtime</scope> <type>dll</type> </dependency> ...
在 src/assembly 中使用 assembly.xml 设置 maven 程序集插件。xml:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <!-- Configure a class for executable jar --> <archive> <manifest> <mainClass>Main class</mainClass> </manifest> </archive> <!-- Points to the assembly descriptor to use --> <descriptors> <descriptor>src/assembly.xml</descriptor> </descriptors> </configuration> <!-- Bind goal assembly:single into build process --> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
试图将 jar 和 dll 包含到可执行 jar 中:
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>graphics-assembly</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<scope>runtime</scope>
<unpack>true</unpack>
<includes>
<include>*:jar:*</include>
</includes>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<includes>
<include>*:dll*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
据我了解,dll 文件应该位于可执行 jar 附近的目标文件夹中,但即使我手动复制该文件,当我尝试使用 java -jar executable-jar.jar
运行 jar 时例如,
我收到以下错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:170)
at javax.media.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:422)
at javax.media.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1516)
at javax.media.opengl.awt.GLCanvas.addNotify(GLCanvas.java:614)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/java.awt.Window.addNotify(Window.java:787)
at java.desktop/java.awt.Frame.addNotify(Frame.java:493)
at java.desktop/java.awt.Window.show(Window.java:1049)
at java.desktop/java.awt.Component.show(Component.java:1720)
at java.desktop/java.awt.Component.setVisible(Component.java:1667)
at java.desktop/java.awt.Window.setVisible(Window.java:1032)
- 我正在使用 intellij 并使用 File -> Project Structure -> Libraries -> 添加包含 jars 和 dll 的文件夹来简单地链接文件。 当我 运行 / 使用 intellij 构建项目时,一切正常。
我做错了什么?有更好的方法吗?
我最终从程序集文件中删除了 dll 的 dependencySet,并使用 maven-dependency-plugin 复制了 dll 依赖,如下所示:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.computer.graphics</groupId>
<artifactId>gluegenrt</artifactId>
<version>1.0</version>
<type>dll</type>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>gluegen-rt.dll</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</plugin>
ArrayIndexOutOfBoundsException 发生是因为我使用 jdk 16 而不是 jdk 12 到 运行 jar。 希望这对其他人有帮助。
我最近 运行 遇到了同样的问题。这似乎是 jogl / jogamp 中的一些已知错误,但一开始我并不清楚该怎么做。
只需将 --illegal-access=permit
添加到 VM 选项。在我的示例中,它与 OpenJDK-15 开箱即用,但在使用 OpenJDK-16 时我必须添加该 VM-Option。
我在使用 Jogamp 2.3.2 时遇到了同样的异常,在 Jogamp 2.4.0 中同样的修补程序有所帮助,但异常更改为:
Exception in thread "AWT-EventQueue-0" com.jogamp.opengl.GLException: Unable to determine GraphicsConfiguration: WindowsWGLGraphicsConfiguration[DefaultGraphicsScreen[WindowsGraphicsDevice[type .windows, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x1dc258d9]], idx 0], pfdID 7, ARB-Choosen true,
requested GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]],
chosen GLCaps[wgl vid 7 arb: rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, dp/st/ms 24/0/0, dbl, mono , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]]]
at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:182)
at com.jogamp.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:424)
at com.jogamp.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1513)
at com.jogamp.opengl.awt.GLCanvas.addNotify(GLCanvas.java:609)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4792)
at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
at java.desktop/java.awt.Container.addNotify(Container.java:2801)
at java.desktop/java.awt.Window.addNotify(Window.java:787)
at java.desktop/java.awt.Frame.addNotify(Frame.java:493)
at java.desktop/java.awt.Window.show(Window.java:1049)
at java.desktop/java.awt.Component.show(Component.java:1720)
at java.desktop/java.awt.Component.setVisible(Component.java:1667)
at java.desktop/java.awt.Window.setVisible(Window.java:1032)
at global.WindowSingleCanvas.createFrame(WindowSingleCanvas.java:122)
at global.WindowSingleCanvas.setWindowType(WindowSingleCanvas.java:86)
at global.WindowSingleCanvas.lambda$new(WindowSingleCanvas.java:39)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
另请参阅:http://forum.jogamp.org/JogAmp-Build-v2-4-0-rc-20210111-td4040955i20.html