我正在使用Apache POI处理XLS电子表格文件,然后生成DOCX word文档。程序运行正常,但是从jar运行它时会收到一条错误消息。
以下是详细信息。该程序成功编译:
javac -classpath poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;. reviewReport.java
该程序成功运行:
java -classpath poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;. reviewReport
我设置了这个清单文件:
Manifest-Version: 1.0
Class-Path: poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;.
Main-Class: reviewReport
(清单文件底部有一个空白行)
使用以下方法创建jar成功:
jar cfm reviewReport.jar manifest.mf *.class
我尝试使用此命令从jar运行程序:
java -classpath poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;. -jar reviewReport.jar
但是我没有运行,而是收到以下错误消息:
Exception in thread "main" java.lang.NoClassDefFoundError: org.apache.poi.openxm
l4j.exceptions.InvalidFormatException
at java.lang.J9VMInternals.prepareClassImpl(Native Method)
at java.lang.J9VMInternals.prepare(J9VMInternals.java:430)
at java.lang.Class.getMethod(Class.java:1061)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:506)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:498)
Caused by: java.lang.ClassNotFoundException: org.apache.poi.openxml4j.exceptions
.InvalidFormatException
at java.net.URLClassLoader.findClass(URLClassLoader.java:665)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:942)
at java.lang.ClassLoader.loadClass(ClassLoader.java:851)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:827)
... 5 more
我试图理解是什么原因导致我自己可以运行的程序无法从jar运行,当我在构建该jar时使用相同的类路径。研究之后,似乎问题可能是由于以下两点之一:(1)尝试使用POI的代码来处理实际上是XLSX或DOCX的文件上的XLS和DOC文件(反之亦然),或者(2)类加载器在运行时没有找到InvalidFormatException类。
我已经看过两个潜在的问题。对于(1),我的程序处理XLS电子表格。我已经完成了代码,我相信我总是正确使用POI的HSSF类。然后我的程序创建一个DOCX word文档。我已经完成了代码,我相信它总能正确地使用XWPF类。
对于(2),当我使用http://www.ibm.com/developerworks/java/library/j-dclp1/index.html文章中讨论的详细类功能时,运行该程序的命令是:
java -Dibm.cl.verbose=org.apache.poi.openxml4j.exceptions.InvalidFormatException -classpath poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;. reviewSearchReport
系统显示类加载器如何在各个位置搜索该类。它以这一成功的声明结束:
AppClassLoader found org/apache/poi/openxml4j/exceptions/InvalidFormatException.
class in \poi-3.10.1\poi-ooxml-3.10.1-20140818.jar
AppClassLoader found org.apache.poi.openxml4j.exceptions.InvalidFormatException
但是当我从jar中运行它时,我得到了不同的结果。命令
java -Dibm.cl.verbose=org.apache.poi.openxml4j.exceptions.InvalidFormatException -classpath poi-3.10.1/*;poi-3.10.1/ooxml-lib/*;commons-io-2.4/*;commons-lang3-3.3.2/*;guava-libaries/*;MigLayout-4.0/*;. -jar reviewReport.jar
以下是显示的内容:
AppClassLoader attempting to find org.apache.poi.openxml4j.exceptions.InvalidFor
matException
AppClassLoader using classpath C:\reviewReport.jar
AppClassLoader could not find org/apache/poi/openxml4j/exceptions/InvalidFormatE
xception.class in C:\reviewReport.jar
AppClassLoader could not find org.apache.poi.openxml4j.exceptions.InvalidFormatE
xception
有人能指出我正确的方向吗?我这里是否有类加载器问题,或者我的程序中的代码是否错误地显示了POI(例如DOCX上使用的DOCX类,或XLS文件上使用的XLSX类)?
答案 0 :(得分:1)
是的,Gagravarr,我发现jar命令没有使用" -classpath"参数(尽管如果将其包含在命令行中,则不会出现错误)。
更重要的是,manifest.mf文件的Class-Path部分使用空格来分隔项目,而不是用于在使用&时分隔项目的分号(&#34 ;;") #34; -classpath" javac语句中的参数。
我更改了manifest.mf文件以分隔Class-Path部分中的项目,我还专门列出了jar而不是依赖于" poi-3.10.1 / *"通配符格式。