![](/img/trans.png)
[英]Apache POI on an exported .jar is not running on a different computer
[英]Running .jar file using Apache POI in Maven project
我正在努力運行一個使用Apache POI創建Excel文檔的簡單程序。 這也是我第一次參與Maven項目,因此可能與它有關:
我的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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>calendar</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>calendar</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
</dependencies>
</project>
據我所知,我的依賴關系還不錯。
這是我的Java代碼,我跳過了import語句,但是它們都在那里,根據我的判斷,此代碼中沒有錯誤:
public class App
{
private static final String FILE_NAME = "/tmp/MyFirstExcel.xlsx";
public static void main( String[] args ) throws IOException
{
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Datatypes in Java");
Object[][] datatypes = {
{"Datatype", "Type", "Size(in bytes)"},
{"int", "Primitive", 2},
{"float", "Primitive", 4},
{"double", "Primitive", 8},
{"char", "Primitive", 1},
{"String", "Non-Primitive", "No fixed size"}
};
int rowNum = 0;
System.out.println("Creating excel");
for(Object[] datatype : datatypes) {
Row row = sheet.createRow(rowNum++);
int colNum = 0;
for(Object field : datatype) {
Cell cell = row.createCell(colNum++);
if(field instanceof String) {
cell.setCellValue((String) field);
}
else if(field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
try {
FileOutputStream outputStream = new FileOutputStream(FILE_NAME);
workbook.write(outputStream);
//workbook.close()
} catch (FileNotFoundException e) {
System.out.println("Couldn't find file to write out to");
} catch (IOException e) {
System.out.println("IO Exception in printing");
}
}
}
我已經注釋掉了workbook.close()
,因為這導致了錯誤(不建議使用的方法?)。
使用上面的代碼在我的源文件夾中,我可以運行mvn package
,該mvn package
可以成功構建並在目標文件夾中生成.jar文件calendar-1.0-SNAPSHOT.jar
。
我正在嘗試使用運行此文件
java -cp target/calendar-1.0-SNAPSHOT.jar com.mycompany.app.App
...並且我收到以下錯誤消息
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Workbook
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.poi.ss.usermodel.Workbook
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 7 more
如果這個問題需要更多信息,請告訴我。 我在這里茫然。
您需要使用Maven Assembly Plugin創建一個胖子/超級瓶子。 這意味着將一個Jar及其依賴的Jar一起創建到一個可執行的Jar文件中。 當您運行它時,它將具有所有可用的依賴項。
在您的POM中添加以下插件
<build>
<plugins>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>com.your.path.to.main.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
運行以下命令:
mvn package
將在目標文件夾中創建兩個jar文件。
calendar-1.0-SNAPSHOT.jar – Only your project classes
calendar-1.0-SNAPSHOT-with-dependencies.jar – Project and dependency classes in a single jar.
您可以按照以下方式運行它;
java -cp target/calendar-1.0-SNAPSHOT-with-dependencies.jarcom.mycompany.app.App
您可以查看calendar-1.0-SNAPSHOT-with-dependencies.jar的內容
jar tf target/calendar-1.0-SNAPSHOT-with-dependencies.jar
您將maven工件打包為jar,並且默認情況下,由maven jar插件打包的jar不包含帶有已構建工件的依賴項jar。 而運行時缺少的類。
如果要在jar中包含應用程序的依賴jar,則應使用maven程序集插件,並為描述符ref參數指定jar-with-dependencies
。
您可以將程序集的single
目標執行綁定到程序包階段,以便您正在使用的mvn package
執行實際上自動創建預期的jar。
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>YourMainClassPrefixedByItsPackage</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
問題是在編譯時POI庫可用,但在運行時不可用。 它們可用的原因是它們處於Maven依賴關系中。 另外,我在pom文件中看不到任何構建包裝器。 您將需要添加構建包裝器來構建可以在IDE外部運行的jar文件。
現在回到您的問題,您需要在CLASSPATH環境變量中添加POI jar,以便Java運行時可以訪問它或構建包含依賴項的胖jar。
您可以使用此模板在pom文件中添加構建包裝器,以構建具有依賴項的jar。
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven package
任務只是將項目的已編譯類打包到單個jar文件中。 所有第三方庫均未包括在內,這就是為什么您會報錯-未找到POI類。
您應該構建一個包含所有依賴項的可運行jar文件。 請參考這個問題-您應該使用一些其他的Maven插件來實現這一目標
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.