我正在努力运行一个使用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
并在目标文件夹中生成.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
如果此问题需要更多信息,请告知我们。我在这里不知所措。
答案 0 :(得分:1)
你需要使用Maven Assembly Plugin创建一个胖/超级jar。这意味着将Jar与其依赖项Jars一起创建到一个可执行的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
答案 1 :(得分:1)
您正在将maven工件打包为jar,默认情况下,maven jar插件打包的jar不包含带有构建工件的依赖jar。 而在运行时缺少类。
如果要在jar中包含应用程序的依赖项jar,则应使用maven程序集插件并为descriptorRef参数指定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>
答案 2 :(得分:0)
问题是在编译时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>
答案 3 :(得分:0)
Maven package
任务只是将项目的已编译类打包到一个jar文件中。所有第三方库都不包括在内,这就是您收到错误的原因 - 找不到POI类。
你应该构建一个包含所有依赖项的可运行jar 文件。请参考this问题 - 你应该使用一些额外的maven插件来实现这个目标