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)
It works fine when I run it normally, e. g.
java a.e
I know from reading stack overflow to be sure that I have
poi-ooxml
and xmlbeans
. (20688851, 15831591)
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();
}
}
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
Then, I tried the command
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
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
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.
(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.)
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
)