Javaloader Version 0.3 Released

I quietly released version 0.3 of JavaLoader today. I'm not sure if anyone actually noticed. Mind you, I didn't actually tell very many people, so I guess I should proclaim a little.

The main purpose of this release is to give greater control over the ClassPath loading behaviour. There are two new optional arguments on the JavaLoader library

loadColdFusionClassPath – this tells JavaLoader whether or not to load the ColdFusion Java libraries.

By default this is set to false.

This is a change from the previous JavaLoader, as it would load all the libraries associated with ColdFusion by default.

loadedClassPathBias – this tells JavaLoader to use a ClassLoader that searches the JAR libraries it has been passed, before it looks to the parent.

This is true by default.

This is also a change from the previous version of the JavaLoader library, which would automatically load the parent's classes before the JavaLoader classes.

This is particularly useful when ColdFusion classes are required, but you need to overload certain libraries that are loaded with ColdFusion.   

More details can be found in the readme.txt file inside the JavaLoader download .

For questions or comments, feel free to email me , fire off a message to the forum , or file a bug report .

Leave a Comment

Comments

  • PaulH | January 3, 2007

    cool. look forward to taking it for a spin.

  • Andy | January 5, 2007

    There’s an error in the function queryJars: In line 131 "directory" should be replaced by "path".

  • Mark | January 5, 2007

    Thanks for that Andy, I always forget about the fact 6.1 doesn’t create the directory column off a cffile directory read. Change made, and I re-uploaded the .zip to riaforge.

  • denny | January 18, 2007

    I tried to use this to load jasperreports. Still get the error with commons-logging though. I had high hopes after seeing the log4j comment, but no dice apparently.
    Works great for other stuff. Nice job!

  • Mark | January 19, 2007

    Denny –

    What error are you getting?
    Are you loading the commons-logging along with you other libs?
    What arguments are you using when loading JavaLoader?

  • Denny | January 19, 2007

    Hey Mark, here’s how I’m loading it:
    paths = arrayNew(1);
    paths[1] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-logging-1.0.2.jar";
    paths[2] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-logging-api-1.0.2.jar";
    paths[3] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-beanutils-1.7.jar";
    paths[4] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/jdt-compiler-3.1.1.jar";
    paths[5] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-digester-1.7.jar";
    paths[6] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-javaflow-20060411.jar";
    paths[7] = getDirectoryFromPath(getCurrentTemplatePath()) & "lib/commons-collections-2.1.jar";
    paths[8] = getDirectoryFromPath(getCurrentTemplatePath()) & "jasperreports-1.3.0.jar";
    loader = createObject("component", "javaloader.JavaLoader").init(paths,false,true);

    And here’s a bit of the stack:
    java.lang.ClassCastException at org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:554) at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:345) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:409) at org.apache.commons.digester.Digester.<init>(Digester.java:304) at net.sf.jasperreports.engine.xml.JRXmlDigester.<init>

    I’ve messed with the order, in case it mattered, and tried various settings for the classpaths. It’s totally possible I’m just doing something wrong, but from my past forays into the matter, it seems that commons-logging is one of those things that’s almost impossible to /not/ use once it’s been loaded /anywhere/. Some inherent design thing, iirc.

    Could be blowing smoke up your ass- it’s been a while since I was tackling the specific problem of jasperreports (ended up doing the brute force search and replace package name whatnot, replaced cf’s commons, etc.– ugly).

    I can throw the full code up on google, along with a test report, if you’re curious.

    It’s been a tough one for me to solve elegantly– the commons-logging thing, so it would be cool to find a way, even if I end up running with jboss and an intelligence report server. =]

    Frankly, I doubt there is a way. It would be cool if I’m wrong tho.

    Have you successfully loaded anything that needed a newer version of commons-logging? JR is the only thing I’ve tried that needed it, iirc. Eh…

    Again, this is a cool bit of work, gratz fer putting it out there.

  • MArk | January 20, 2007

    Denny,

    It all *looks* okay.

    It would be really handy if you could post a .zip test bed with some sample code and the .jars to download so I can have a play.

    Some questions/things to note:
    – Where exactly is the error occuring?
    – Don’t forget you can’t mix’n’match calls to createObject() and calls to javaLoader. Once you’re working with objects for JavaLoader, that’s all you can use. This has caught out a few people.

    More than happy to put the software out there. Thanks for having a good bash at it. Hopefully we can get this problem solved.

  • Denny | January 22, 2007

    I’ll put all the source up on google, but a comment you made give me pause- mixing createobject and javaloader.
    Does that mean this is not ok?:

    outStream = CreateObject("java","java.io.ByteArrayOutputStream").init();
    daFactory = CreateObject ("Java","coldfusion.server.ServiceFactory");
    jr.jasperDesign = jr.jRXmlLoader.load(xmlInputStream);

    I think part of the issue is that jasperreports itself compiles some java code, perhaps.

  • Mark | January 22, 2007

    Assuming that ‘jr’ came from the JavaLoader, yes, it is best to keep it in the same classpath – so what you just wrote would be bad.

  • Amir | February 1, 2007

    I’m struggling with the above… I’m trying to do the same with the logging commons stuff but it seems BOTH jars are being loaded and the logging framework is complaining.

    [code]
    @4000000045c0ad8b25580154 [1]org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed.) (Caused by org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed.))
    [code]

    How can I get it to ONLY use the jars that I provide and ignore the ones that the CF webapp is using?

    ……..SNIP……..
    <cfscript>
    paths = arrayNew(1);

    /*
    This points to the jar we want to load.
    Could also load a directory of .class files

    */

    paths[1] ="/opt/commons-httpclient-3.0.1/commons-httpclient-3.0.1.jar";
    paths[2] ="/opt/acquirehttp/acquirehttp.jar";
    paths[3] ="/opt/commons-logging-1.0.4/commons-logging.jar";

    //create the loader
    loader = createObject("component", "epsys.legacy.cfcs.JavaLoader").init(paths);

    //at this stage we only have access to the class, but we don’t have an instance
    HelloWorld = loader.create("uk.co.test.http.client.AcquireHTTPClient");
    ……..SNIP……..

    Dies at HelloWorld line as classloader is invoked 🙁

  • Amir | February 1, 2007

    The interesting thing is if i use false for both arguments then I get an invocation exception..

    i.e.

    …………..SNIP……………
    java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedConstructorAccessor60.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at coldfusion.runtime.java.JavaProxy.CreateObject(JavaProxy.java:128)
    at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:56)
    at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:1634)
    at cfJavaLoader2ecfc826846312$funcCREATE.runFunction(/home/www/epsys/code/legacy/cfcs/JavaLoader.cfc:98)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:344)
    at coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47)
    at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:290)
    at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:254)
    at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:56)
    at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:207)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:169)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:194)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:146)
    at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:1634)
    at cfexample2ecfm740453036.runPage(/home/www/epsys/code/legacy/abstracted/example.cfm:38)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:152)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:349)
    at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:225)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
    at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:69)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:115)
    at coldfusion.CfmServlet.service(CfmServlet.java:107)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:78)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:257)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:541)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:204)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:426)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
    Caused by: java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod
    at java.lang.Class.getDeclaredFields0(Native Method)
    at java.lang.Class.privateGetDeclaredFields(Class.java:1522)
    at java.lang.Class.privateGetPublicFields(Class.java:1554)
    at java.lang.Class.getFields(Class.java:789)
    ………….SNIP………

    We can see its got the CF version of the jar loaded and that version does not have the same package structure hence its throwing a fit, but if i say false to both argument two and three then it should be using a different classloader and not looking at the cf (webapp) class path is it?

  • Mark | February 1, 2007

    Amir –

    If you could bundle up a test bed for download somewhere, and post it to the forum, that would be great. Trying to solve this through blog comments is a little bit tricky.

    Cheers,

    Mark

  • Amir | February 2, 2007

    um, where’s the forum? 🙂

  • Amir | February 2, 2007

    Found the forum, posted.

  • ironyx | June 22, 2007

    Not that this is of course the place, so I apologize but I am terribly desparate, I was wondering if Denny ever got his jasperreports call in coldfusion to work…

  • denny | June 22, 2007

    Only up to version 0.6.2 or so, otherwise, you run into the common loggings problem, I think.

    If your running jboss, I’ve got a CF webservice that will run reports off of the JasperServer, which runs on jboss (easily;).

    But I never found a way around commons logging… just seemed like an intrinsic problem to the way commons logging works.

  • Virginia | June 22, 2007

    Alright, well I am doing 1.3.3, and I am thinking of giving up. But then, I am new to java and trying to incorporate this into coldfusion as my first project (not by choice). I am changing direction though… I would love to know about other things you have worked on… virginia.older@gmail.com if you ever have the time!

    Thanks for responding so quickly!
    Va.

  • Virginia | June 22, 2007

    Oh, and I am running coldfusion on weblogic with Oracle, and had to wrestle with Weblogic for the first time… we like overkill apparently!

    Thanks again!
    Va.

  • Denny | June 22, 2007

    I’ll put something up at coldshen.com, which is my personal site for random stuff. Course, I said I’d post the original code somewhere, which I never did… Yeah, right now my site is very bare, so… I’ll drop you a line when I’ve got some jasper stuff up. =]

    JasperServer is awesome tho… stores the JRXML files, pictures, everything, and takes the load off the CF server… ties directly into iReport, which is awesome!

    Since you’re on weblogic, which is a different kind of beast, maybe there is a way to get around the commons logging bit… I’ve only tried (and failed =[ )with jrun. I kind of doubt it tho… :-/

  • derec | January 18, 2008

    Are you loading the commons-logging along with you other libs?

  • Kenneth | June 15, 2009

    Anybody solves this issue so far?
    I’m having the same problem with CF8. CF8 has commons logging 1.0.4, but the library I’m using uses commons logging 1.1.

  • Mark Mandel | June 15, 2009

    You may want to try JavaLoader 0.6, since it is the latest version.

  • max | December 12, 2009

    thanks