我试图让基本的HelloWorld JNA示例在使用Maven构建.jar时工作。我从这个目录结构开始:
.
+-- pom.xml
+-- src
+-- main
+-- java
+-- HelloWorld.java
HelloWorld.java包含JNA入门页面中的代码:
package com.sun.jna.examples;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
/** Simple example of JNA interface mapping and usage. */
public class HelloWorld {
// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
CLibrary.class);
void printf(String format, Object... args);
}
public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, World\n");
for (int i=0;i < args.length;i++) {
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
}
}
}
我的pom.xml文件包含以下内容:
<project>
<groupId>edu.berkeley</groupId>
<artifactId>hello-world</artifactId>
<modelVersion>4.0.0</modelVersion>
<name>Hello World</name>
<packaging>jar</packaging>
<version>1.0</version>
<properties>
<jna.version>4.5.0</jna.version>
</properties>
<dependencies>
<dependency> <!-- JNA dependency -->
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency> <!-- JNA platform dependency -->
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.sun.jna.examples.HelloWorld</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
我可以使用mvn package
构建目标.jar而没有问题,但是当我尝试运行它时,我收到标题中提到的错误:
$ java -jar target/hello-world-1.0.jar
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/jna/Library
...
我可以在maven本地存储库中看到JNA和JNA平台.jar文件。构建的.jar的清单文件在其类路径中包含jna相关文件:
$ unzip -p target/hello-world-1.0.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Built-By: root
Class-Path: jna-4.5.0.jar jna-platform-4.5.0.jar
Created-By: Apache Maven 3.0.4
Build-Jdk: 1.8.0_144
Main-Class: com.sun.jna.examples.HelloWorld
如果我手动将JNA .jars复制到目标文件夹,则应用程序会运行,但是当我执行mvn clean
时会删除这些.jars。我假设将那些.jars复制到目标目录是不正确的,因为它们是用干净删除的。我应该做些什么来让这个应用程序运行?
编辑:
从Roman共享的链接中,我发现我需要使用maven-assembly插件或maven-shade插件。我最终使用maven-shade插件并将以下内容添加到我的pom.xml文件中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>net.java.dev.jna:jna</include>
<include>net.java.dev.jna:jna-platform</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
我使用include选项,以便只包含列入白名单的依赖项(JNA),以便将构建时间和.jar文件大小保持在最低限度。