spreadsheet-cfml icon indicating copy to clipboard operation
spreadsheet-cfml copied to clipboard

java.io.FileInputStream incompatible with org.apache.poi.openxml4j.opc.OPCPackage

Open ivanionut opened this issue 4 years ago • 20 comments
trafficstars

Hello @cfsimplicity, I'm having an error in the production environment but in my development environment (which uses the same stack) it works fine.

Version: Lucee 5.3.8.138-SNAPSHOT
Servlet Container: Apache Tomcat/9.0.19
Java: 11.0.8 (AdoptOpenJDK) 64bit
OS: Linux (4.15.0-130-generic) 64bit
LuceeSpreadsheet: 2.13.0

this is the error:

java.lang.ClassCastException Error: java.io.FileInputStream incompatible with org.apache.poi.openxml4j.opc.OPCPackage 
  File "com/spreadsheet/Spreadsheet.cfc", line 1842
    return loadClass( className ).create( file );
  File "com/spreadsheet/Spreadsheet.cfc", line 1280
    var workbook = passwordProtected? workbookFromFile( arguments.src, arguments.password ): workbookFromFile( arguments.src );
  File "model/services/catalog.cfc", line 60
    variables.q_catalog = spreadsheet.read(src=variables.local_path_catalog, headerRow=1, format="query");
  File "controllers/schedule.cfc", line 41
    rc.updateCatalogo = recorditService.updateCatalog();
  File "framework/one.cfc", line 1635
    invoke( cfc, method, { rc : request.context, headers : request._fw1.headers } );
  File "framework/one.cfc", line 896
    doController( tuple, tuple.item, 'item' );

error

what am I doing wrong?

ivanionut avatar Jan 10 '21 12:01 ivanionut

Hi Ivan. I don't really know. I've run the test suite with that version of Lucee and it passes ok. There must be a difference somewhere between your environments.

Are you reading the same spreadsheet file in both dev and production? Is it an xls or xlsx file?

cfsimplicity avatar Jan 10 '21 13:01 cfsimplicity

hi. yes, I confirm, I read the same file, the xlsx file exists and the complete path is correct.

I thought about a permissions issue and set permissions 777 on the xlsx file, but it didn't solve. what other tests could I do?

ivanionut avatar Jan 10 '21 14:01 ivanionut

Sorry, I don't know what else to suggest. The OPCPackage class is internal to POI, but if the environment and parameters are the same then I would expect it to behave in the same way.

cfsimplicity avatar Jan 10 '21 14:01 cfsimplicity

Is it possible the file is password protected? I think OPCPackage is normally only needed for encryption.

Does the code work on your prod server with a simple test xls/xslx file?

cfsimplicity avatar Jan 10 '21 14:01 cfsimplicity

hi @cfsimplicity, it's really weird ... i downloaded the xlsx file from the production server and tried it in my local environment and it works fine. the xlsx file is not password protected, furthermore the error occurs here:

Spreadsheet.cfc:1842

1840: 				var file = CreateObject( "java", "java.io.FileInputStream" ).init( arguments.path );
1841: 				if( arguments.KeyExists( "password" ) ) return loadClass( className ).create( file, arguments.password );
1842: 				return loadClass( className ).create( file );
1843: 			}
1844: 		}

I don't understand what I'm doing wrong ...

ivanionut avatar Jan 11 '21 18:01 ivanionut

Ivan, the error is coming from the POI class not the Spreadsheet library, which is just loading that class.

Is it just that particular file that is problematic? Does it work with a simple test file on your production server?

cfsimplicity avatar Jan 11 '21 20:01 cfsimplicity

i also tried with a new one line xlsx file but i have the same problem ... Referenze.xlsx

ivanionut avatar Jan 11 '21 20:01 ivanionut

In that case there must be something different about your prod environment. Sorry but I can't tell you what that might be.

cfsimplicity avatar Jan 11 '21 20:01 cfsimplicity

hmmm, I'm getting a doubt.

this is the production server (where there are so many other websites). on the production server the virtual directory "javaloader" is mapped (as you see in the screen) and points to a path used for another site. can this be a problem? mapping

ivanionut avatar Jan 11 '21 20:01 ivanionut

By default the library should use the JavaLoader package which ships with it in the same directory. Even if it was using the mapped JavaLoader elsewhere on your server, I'd expect it to behave in the same way.

cfsimplicity avatar Jan 11 '21 20:01 cfsimplicity

you won't believe it but I solved it by doing a reboot of the production server (it was already scheduled) ... this job is really demoralizing ... :cry:

thanks anyway for the support!

ivanionut avatar Jan 11 '21 21:01 ivanionut

hi @cfsimplicit, i'm getting exactly the same error ... :sob: i just don't know how to fix ... if you have any ideas, just let me know.

ivanionut avatar Jan 13 '21 21:01 ivanionut

Is it possible the Lucee installation on the server is loading POI jars from anywhere else?

Try adding the following script to check the location of the jars being loaded:

spreadsheet.dumpPathToClass( "org.apache.poi.ss.usermodel.WorkbookFactory" );
abort;

It should point to a jar inside the /lib folder within the spreadsheet library folder.

PS: run it just before the line which is erroring.

cfsimplicity avatar Jan 13 '21 21:01 cfsimplicity

this is the result of the dump:

file:/var/www/mywebsite/app/com/spreadsheet/lib/poi-4.1.2.jar!/org/apache/poi/ss/usermodel/WorkbookFactory.class

ivanionut avatar Jan 13 '21 21:01 ivanionut

That looks correct. How about: spreadsheet.dumpPathToClass( "org.apache.poi.openxml4j.opc.OPCPackage" );?

cfsimplicity avatar Jan 14 '21 09:01 cfsimplicity

To rule out a problem with the server mapped JavaLoader instance you mentioned earlier, you could explicitly point the library to the version bundled with it.

  1. Create an application mapping called bundledJavaLoader in your Application.cfc which points to the bundled javaloader folder:
this.mappings[ "bundledJavaLoader" ] = "/var/www/mywebsite/app/com/spreadsheet/javaLoader/";
  1. When initializing the library, add the javaLoaderDotPath argument to override the default dot path:
spreadsheet = New luceeSpreadsheet.SpreadSheet( javaLoaderDotPath: "bundledJavaLoader.JavaLoader" );
  1. Check the path has been overridden:
dump( spreadsheet.getEnvironment().javaLoaderDotPath );
  1. Flush the previous cached JavaLoader instance:
spreadsheet.flushPoiLoader();

cfsimplicity avatar Jan 14 '21 09:01 cfsimplicity

hi, first of all sorry for the delay.

I did the tests you indicated:

function test( struct rc = {} ) localmode="modern"{

	spreadsheet = new com.spreadsheet.Spreadsheet( javaLoaderDotPath: "bundledJavaLoader.JavaLoader" );
	dump( spreadsheet.getEnvironment().javaLoaderDotPath );
	spreadsheet.flushPoiLoader();
	dump( spreadsheet.getEnvironment().javaLoaderDotPath );
	spreadsheet.dumpPathToClass( "org.apache.poi.openxml4j.opc.OPCPackage" );

	q_catalog = spreadsheet.read(src='/var/www/mywebsite/app/media/schedule/catalog/Referenze.xlsx', headerRow=1, format="query");
	dump( q_catalog );
	abort;
}

error

and this is the error (referring to the lineq_catalog = spreadsheet.read(...)):

application.logERROR 21:32:32, 14 gen, 2021http-nio-8888-exec-5
"java.io.FileInputStream incompatible with org.apache.poi.openxml4j.opc.OPCPackage;java.io.FileInputStream incompatible with org.apache.poi.openxml4j.opc.OPCPackage;lucee.runtime.exp.NativeException: java.io.FileInputStream incompatible with org.apache.poi.openxml4j.opc.OPCPackage
/com/spreadsheet/Spreadsheet.cfc:1842
/com/spreadsheet/Spreadsheet.cfc:1280
/controllers/schedule.cfc:53
/framework/one.cfc:1635
/framework/one.cfc:896


at org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.lambda$static$0(XSSFWorkbookFactory.java:36)
at org.apache.poi.xssf.usermodel.XSSFWorkbookFactory$$Lambda$172/000000000000000000.apply(Unknown Source)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:196)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at lucee.runtime.reflection.pairs.MethodInstance.invoke(MethodInstance.java:56)
at lucee.runtime.java.JavaObject.call(JavaObject.java:266)
at lucee.runtime.java.JavaObject.call(JavaObject.java:288)
at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:785)
at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1732)
at com.spreadsheet.spreadsheet_cfc$cf.udfCallb(/com/spreadsheet/Spreadsheet.cfc:1842)
at com.spreadsheet.spreadsheet_cfc$cf.udfCall(/com/spreadsheet/Spreadsheet.cfc)
at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217)
at lucee.runtime.type.scope.UndefinedImpl.call(UndefinedImpl.java:784)
at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:785)
at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1732)
at com.spreadsheet.spreadsheet_cfc$cf.udfCall7(/com/spreadsheet/Spreadsheet.cfc:1280)
at com.spreadsheet.spreadsheet_cfc$cf.udfCall(/com/spreadsheet/Spreadsheet.cfc)
at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:683)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:570)
at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1919)
at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:864)
at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1751)
at controllers.schedule_cfc$cf$d.udfCall(/controllers/schedule.cfc:53)
at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:683)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:570)
at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1919)
at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:898)
at lucee.runtime.functions.dynamicEvaluation.Invoke.call(Invoke.java:49)
at framework.one_cfc$cf.udfCallb(/framework/one.cfc:1635)
at framework.one_cfc$cf.udfCall(/framework/one.cfc)
at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217)
at lucee.runtime.type.scope.UndefinedImpl.call(UndefinedImpl.java:784)
at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:785)
at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1732)
at framework.one_cfc$cf.udfCall6(/framework/one.cfc:896)
at framework.one_cfc$cf.udfCall(/framework/one.cfc)
at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:682)
at lucee.runtime.ComponentImpl._call(ComponentImpl.java:570)
at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1900)
at lucee.runtime.listener.Modern
-- very long stack, omitted 2869 bytes

I really don't know why this error comes up. ... for the moment I have rewritten the function that does the manipulation of the xlsx file in python (callable with cfexecute()).

ivanionut avatar Jan 14 '21 20:01 ivanionut

OK, no change then. As I say it was just to rule out a problem with the JavaLoader mapping.

Thanks for posting the full stack trace. That shows where the error is happening, which is inside the POI java classes. I don't understand why the OPCPackage class is being invoked when the file is being read, or why it's rejecting the FileInputStream. But I didn't write that code. A proper java expert would probably know.

Glad you've been able to work around it for now. Let's leave this ticket open in case anything comes up to shed any light on it.

cfsimplicity avatar Jan 14 '21 21:01 cfsimplicity

@ivanionut It might be worth trying the latest release 2.14.0 which uses a new version of POI and no longer requires JavaLoader to load it in Lucee.

cfsimplicity avatar Jan 21 '21 10:01 cfsimplicity

hi I like the new implementation! as soon as I can I will do new tests and I will communicate the results!

thanks!

ivanionut avatar Jan 21 '21 22:01 ivanionut