可执行jar中的Apache POI [英] Apache POI in executable jar

查看:65
本文介绍了可执行jar中的Apache POI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序成功运行Apache POI功能以读取 Excel文件.当我使用java类名运行它时,它可以正常工作. 当我打包为可执行jar时,它不起作用.这里是 我不断收到错误消息:

My program successfully runs the Apache POI functionality to read Excel Files. It works fine when I run it with java class name. When I package as an executable jar it does not work. Here is the error message I keep getting:

java -jar some.jar

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/Row
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.apache.poi.ss.usermodel.Row
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

正常运行时,它可以正常工作,例如g.

It works fine when I run it normally, e. g.

java a.e

我从阅读堆栈溢出中知道,以确保我有 poi-ooxmlxmlbeans. (20688851,15831591)

I know from reading stack overflow to be sure that I have poi-ooxml and xmlbeans. (20688851, 15831591)

这是我的可执行jar根目录中的jar文件.

Here are the jar files in the root of my executable jar.

5924600 Wed Sep 12 13:02:26 CDT 2018 poi-ooxml-schemas-3.17.jar
1479023 Wed Sep 12 13:02:26 CDT 2018 poi-ooxml-3.17.jar
1390360 Tue Oct 02 13:04:14 CDT 2018 poi-scratchpad-3.17.jar
313359 Tue Oct 02 13:17:34 CDT 2018 dom4j.jar
 25863 Tue Oct 02 13:19:46 CDT 2018 stax-api.jar
1950905 Wed Sep 12 13:02:26 CDT 2018 poi-3.10-FINAL-20140208.jar
2730866 Tue Oct 02 12:43:34 CDT 2018 xmlbeans-2.6.0.jar

这是我演示该问题的最小测试用例.

Here is my minimal test case that demonstrates the problem.

package a;
import java.io.*;
import java.lang.*;
import java.lang.reflect.*;
import java.util.*;

public class e {

    static PrintWriter F;
    static FileInputStream ConfigurationFile; 
        static String iSheet = "TAB2";

    private static final String strResourceName = "11in35tr.xls";


    static
    {
            java.io.InputStream streamData = null;
            try
            {
                            streamData=a.e.class.getResourceAsStream(strResourceName);
            }
            catch(NullPointerException e)
            {
                System.out.println("Unable to load the resource stream for '" + strResourceName + "'");

                assert false;
            }
System.out.println (" stream Data |"  + streamData+"|");
            org.apache.poi.hssf.usermodel.HSSFWorkbook workbook = null;
            try
            {
                workbook = new org.apache.poi.hssf.usermodel.HSSFWorkbook(streamData);
            }
            catch(java.io.IOException e)
            {
                System.out.println("Unable to create a HSSFWorkbook for the stream.  Is it really an Excel file?");

                assert false;
            }
                        String Sheet;
            org.apache.poi.hssf.usermodel.HSSFSheet sheet = workbook.getSheet(iSheet);
            if(sheet == null) {
                System.out.println("While we were able to open the resource as an Excel file, it doesn't appear to contain sheet " + sheet.toString() + " as specified in the config file");
                       }
               for(int iCurRow = 0;iCurRow<3;iCurRow++)
                {
                    org.apache.poi.ss.usermodel.Row rowCur = sheet.getRow(iCurRow);
                    if(rowCur == null)
                    {
                        System.out.println("We're supposed to get a row title from row " + 
                          Integer.toString(iCurRow) + " in sheet " + iSheet + ", but that row doesn't exist");

                        break;
                    }
for (int iCol=0;iCol<3;iCol++) {
                    org.apache.poi.ss.usermodel.Cell 
cellWithTitle = rowCur.getCell(iCol);
                    if(cellWithTitle == null)
                    {
                        System.out.println("We're supposed to get a row title from cell " + Integer.toString(iCol) + " in row " + Integer.toString(iCurRow) + " in sheet " + iSheet + ", but that column doesn't appear to exist in the specified sheet.");

                        break;
                    }
                String strNewRowTitle = cellWithTitle.toString();

                System.out.println("Created row: '" + strNewRowTitle + "'");
}
            } // for


    } // end of static

   static void Init () throws java.io.IOException {
      ConfigurationFile = new FileInputStream ("config.in");
      F = new PrintWriter (new FileOutputStream ("config.out"));
   }

     public static void main (String args[]) throws IOException {
        Init();

        F.close();
    }
}


不幸的是,这些无效.首先,我更新了manifest.txt文件. (如所示)


Unfortunately, these do not work. At first, I updated the manifest.txt file. (as indicated)

Main-Class: a.c
Class-path: poi-ooxml-schemas-3.17.jar poi-ooxml-3.17.jar poi-scratchpad-3.17.jar dom4j.jar stax-api.jar poi-3.10-FINAL-2014028.jar xmlbeans-2.6.0.jar

然后,我尝试了该命令

java -classpath *.jar -jar some.jar 
java -classpath "poi-ooxml-schemas-3.17.jar:poi-ooxml-3.17.jar:poi-scatchpad-3.17.jar:dom4.jar:stax-api.jar:poi-3.10-FINAL-2014028.jar:xmlbeans-2.6.0.jar" -jar some.jar

我的理解是,当我们使用可执行jar时,-classpath会被忽略.

My understanding is that -classpath is ignored when we use an executable jar.

因此,在下载了我在原始帖子中列出的一组罐子之后,我确实尝试了以下变化.

Thus, I did try variations on the following, after download the set of jars that I listed in the original post.

set CLASSPATH=".;poi-ooxml-schemas-3.17.jar;poi-ooxml-3.17.jar;poi-scatchpad-3.17.jar;dom4.jar;stax-api.jar;poi-3.10-FINAL-2014028.jar;xmlbeans-2.6.0.jar" 
echo %CLASSPATH%
java a.e

它们以相同的方式失败.但是,我可以在Linux系统上很好地运行该程序.因此,显然有一些东西 在Windows计算机上不在POI所需的LINUX系统上.

They fail the same way. However, I can run the program fine on the Linux system. Thus, apparently, there is something on the LINUX system that the POI needs that is not on the Windows computer.

(注意a.e在LINUX上运行良好.它不能在PC ==上运行,因此在我在LINUX上设置的环境中需要一些东西,但不知道那是什么. 但是,我还再次检查了将a.e放入可执行jar并在相同的LINUX环境中运行它.会产生同样的问题.)

(Note a.e runs fine on LINUX. It does not run on the PC== so something is needed on that environment that I set up in LINUX, but don't know what that is. However, i also checked again putting the a.e in an executable jar and running it on the same LINUX environment. It generates the same problem.)

当然,我也尝试从poi.apache.org下载新的4.0,并将六个jar文件包含在zip文件poi-bin-4.0.0...zip中)

Of course, I also tried getting the new 4.0 download from poi.apache.org and including the six jar files in the zip file poi-bin-4.0.0...zip)

推荐答案

您有2种可能性

将这些jar包含在您的jar中,并在META-INF/MANIFEST.MF中设置类路径

Include those jars inside yours and set classpath inside META-INF/MANIFEST.MF

Manifest-Version: 1.0
Class-Path: file1.jar file2.jar file3.jar

或在调用Java时将这些jar添加到classpath

or on your call to java add those jars to classpath

java -classpath \path_to_jars\*.jar your.package.YourMainClass

这篇关于可执行jar中的Apache POI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆