Don't you love people who reply to their own posts? :) Anyhow, I did find a solution lurking on the JavaLoader forums, and I hope this code snippet helps someone in the future. Basically, this thread was the important one:

http://groups.google.com/group/javaloader-dev/msg/9ac22919da73324f

Basically, ThreadContextClassLoader in combination with dom4j = problem for JavaLoader. Mark's solution is to find out the current thread's ClassLoader, and replace it with the one from JavaLoader. After bouncing my CF 9 Application services, this code snippet works for me. I hope it helps somebody else out in the future:

<cfoutput>
<cfset var.JLKey = "93345778-4949-4725-1235577891134557" />
<cfset var.paths = []>
<cfset var.jarpath = "/Users/mstaver/workspace/Fimble/ExternalCode" />
<cfdirectory action="list" name="files" directory="#var.jarpath#" filter="*.jar" recurse="true" />

<cfloop query="files">
<cfset arrayAppend(var.paths, directory & "/" & name) />
</cfloop>

<cfif NOT structKeyExists(server, var.JLKey)>
<cfset server[var.JLKey] = createObject("component", "component.JavaLoader").init(loadPaths=var.paths, loadColdFusionClassPath=true) />
</cfif>

<cfscript>
_Thread = createObject("java", "java.lang.Thread");
currentClassloader = _Thread.currentThread().getContextClassLoader();
try { // Set the current thread's context class loader as Javaloader's classloader, so dom4j doesn't die _Thread.currentThread().setContextClassLoader(server[var.JLKey].getURLClassLoader());
    fileAndPath = "/Users/mstaver/workspace/Fimble/11g.xlsx";
inp = createObject("java", "java.io.FileInputStream").init("#fileAndPath#"); objWorkBook = server[var.JLKey].create("org.apache.poi.xssf.usermodel.XSSFWorkbook").Init(inp);
}
catch(Any exc) {
    rethrow;
}
finally { // We have to reset the classloader, due to thread pooling.
    _Thread.currentThread().setContextClassLoader(currentClassloader);
}
</cfscript>

</cfoutput>

On 11/28/11 2:45 PM, Mike Staver wrote:
Ok, so I did some digging on Mark's JavaLoader forums. I found an error further down my stack that seems to be common:

org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory

Mark's suggested method of loading JL is:

<cfset server[var.JLKey] = createObject("component", "component.JavaLoader").init(loadPaths=var.paths, loadColdFusionClassPath=true) />

That still didn't work for me. In yet another thread, he suggests:

" Make sure when you create your instance of JL, you tell it to use CF as the parent classloader. Then you should have no issues. Mark"

I see the additional parameter for JL called parentClassLoader. Yet, I'm dense sometimes and I can't figure out what should go there... Being that he is in Australia, I don't see him answering my email until later tonite :)

So, I envision calling JL like so:

<cfset server[var.JLKey] = createObject("component", "component.JavaLoader").init(loadPaths=var.paths, loadColdFusionClassPath=true, parentClassLoader=???) />

I have no idea what to put for the value in that third parameter. Would it be a reference to the classes inside of my CF install in D:\ColdFusion9\?

On 11/24/11 10:56 AM, Mike Staver wrote:
Thanks Charlie and Dawn. I definitely have just one version of poi in that folder at a time. I typically load up those jars in the onApplicationStart in the application.cfc. However, in the example I provided I'm doing everything in one place. I will see what I can find on the java loader forums. Thanks.

-Mike

On Nov 24, 2011, at 10:13 AM, Dawn Hoagland <[email protected] <mailto:[email protected]>> wrote:

I did note in your java loader code that you're loading all of the jars in that subdirectory. Any chance you have multiple versions of POI there?

Looking over the java docs, try this:
*org.apache.poi.POIXMLProperties.CoreProperties.getRevision()*

On Thu, Nov 24, 2011 at 11:48 AM, Mike Staver <[email protected] <mailto:[email protected]>> wrote:

    Interesting. Since I'm using the same code on two different
    systems and getting the same results - is there any way I can
    see what is loaded in memory currently?

    -Mike

    On Nov 24, 2011, at 7:46 AM, Dawn Hoagland
    <[email protected] <mailto:[email protected]>> wrote:

    I've seen this happen when multiple versions of the library are
    being loaded into memory.  CF/Java SHOULD pick the one loaded
    with the Javaloader, but doesn't always. I've seen this happen
    when multiple versions of POI have been dropped in CF's lib
    folder as well.  When stuff like this happens, I write/test in
    java only to eliminate issues with POI.

    On Wed, Nov 23, 2011 at 9:35 PM, Mike Staver <[email protected]
    <mailto:[email protected]>> wrote:

        I've always been able to use POI via JavaLoader to read in
        standard xls files and extract data out of the cells for
        whatever I want, like storing in a database. Recently, I've
        had to start coding to handle Office 2007 file formats like
        xlsx and xlsm. POI 3.5 and higher should be able to do that
        according to many examples I've found on the internet and
        in Apache's own documentation. So, I'm currently using
        ColdFusion 9, JavaLoader 1.0, and POI 3.8b4. For the
        record, I've also tried POI 3.6 and 3.7 for this test and
        sample code below. Here is my sample code:

        <cfoutput>
        <cfset var.JLKey = "93345778-4949-4705-1235577891134557" />
        <cfset var.paths = []>
        <cfset var.jarpath =
        "/Users/mstaver/workspace/Fimble/ExternalCode" /> <!---
        location of POI jars --->
        <cfdirectory action="list" name="files"
        directory="#var.jarpath#" filter="*.jar" recurse="true" />

        <cfloop query="files">
        <cfset arrayAppend(var.paths, directory & "/" & name) />
        </cfloop>

        <cfif NOT structKeyExists(server, var.JLKey)>
        <cfset server[var.JLKey] = createObject("component",
        "component.JavaLoader").init(loadPaths=var.paths,
        loadColdFusionClassPath=false) />
        </cfif>

        <cfscript>
        fileAndPath = "/Users/mstaver/workspace/Fimble/11g.xlsm";
        inp = createObject("java",
        "java.io.FileInputStream").init("#fileAndPath#");
        objWorkBook =
        
server[var.JLKey].create("org.apache.poi.xssf.usermodel.XSSFWorkbook").Init(inp);
        </cfscript>

        </cfoutput>

        When I write use this code with one small tweak (HSSF
        instead of XSSF) and I feed in an xls file, everything
        works as expected. However, when I use the exact code above
        and feed it xlsx or xlsm, I get this error:


          Object instantiation exception.

        An exception occurred while instantiating a Java object.
        The class must not be an interface or an abstract class.
        Error: ''. The error occurred in
        */Users/mstaver/workspace/Fimble/test.cfm: line 18*
        *Called from*
        /Users/mstaver/workspace/Fimble/Application.cfc: line 97
        *Called from* /Users/mstaver/workspace/Fimble/test.cfm: line 18
        *Called from*
        /Users/mstaver/workspace/Fimble/Application.cfc: line 97

        16 : fileAndPath = "/Users/mstaver/workspace/Fimble/11g.xlsm";
        17 : inp = createObject("java", 
"java.io.FileInputStream").init("#fileAndPath#");
        *18 : objWorkBook = 
server[var.JLKey].create("org.apache.poi.xssf.usermodel.XSSFWorkbook").Init(inp);*


        Further down the error stack, I think this is relevant:

        Caused by: java.lang.NoClassDefFoundError: Could not initialize class 
org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller


        I don't know where to go on this one. I've tried the SS
        method, instead of XSSF - and it works fine, until I feed
        it an xlsx or xlsm again. I don't get it. I've also tried
        this on Windows 2003, besides here on my Macbook. Both
        machines are running CF 9.0.1. I'm getting the impression
        that I'm missing a class or something. I've followed
        examples from all over the web, and from the POI docs.
        Everything works until I feed it Office 2007 format docs...

        -------------------------------------------------------------
        To unsubscribe from this list, manage your profile @
        http://www.acfug.org?fa=login.edituserform

        For more info, see http://www.acfug.org/mailinglists
        Archive @ http://www.mail-archive.com/discussion%40acfug.org/
        List hosted by FusionLink <http://www.fusionlink.com>
-------------------------------------------------------------



-- Dawn




--
Dawn


-------------------------------------------------------------
To unsubscribe from this list, manage your profile @
http://www.acfug.org?fa=login.edituserform

For more info, see http://www.acfug.org/mailinglists
Archive @ http://www.mail-archive.com/discussion%40acfug.org/
List hosted by FusionLink <http://www.fusionlink.com>
-------------------------------------------------------------



-------------------------------------------------------------
To unsubscribe from this list, manage your profile @ http://www.acfug.org?fa=login.edituserform

For more info, see http://www.acfug.org/mailinglists
Archive @ http://www.mail-archive.com/discussion%40acfug.org/
List hosted by http://www.fusionlink.com
-------------------------------------------------------------

Reply via email to