JavaLoader – The Order in which Libraries are Loaded.

I realised something today, I've been telling something about the JavaLoader that isn't true.

By default, JavaLoader loads the ColdFusion class path as its parent when loading in custom Java libraries.

This means that if JavaLoader can't find a class that you are loading through it via the Jars that you have loaded, it will look to what ColdFusion has loaded to see if it can find it there.

I had always assumed that if you loaded something, say for example, the newer version of log4j with JavaLoader, for the Jars loaded with JavaLoader, they would see the newer version, rather than the older version of log4j with ColdFusion.

This is actually, completely and utterly false. I apologise for all the frustration I probably incurred on people for making this statement.

Reading the Java docs it explicitly says : 'When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.'

So this means that when looking for log4j – the one in ColdFusion actually takes precedence!

This makes sense in the Java world, as it allows for less confusion from the Java engine to be able to resolve classes – but from a ColdFusion perspective it makes life very difficult as we don't have the ability to modify what is loaded at application startup as we would if we had written a Java application from scratch.

A workaround for this is to pass Java null into the JavaLoader as a second variable like so:

loader = createObject("component", "JavaLoader").init(paths, JavaCast("null", ""));

This will create a JavaLoader that is not set with ColdFusion as the parent.

I am currently working on JavaLoader 0.3, that will make the precedence on the loaded classes that will solve this problem all up, as well as some parameters to avoid loading the ColdFusion classpath altogether, but I thought I would give people a heads up now to avoid frustration down the road.

Leave a Comment

Comments

  • PaulH | December 1, 2006

    told you so 😉 btw i worked around this for iText by simply refactoring the iText lib into iTextNew lib but i’ll give your workaround a spin.

  • Mark | December 2, 2006

    Yeah.. I know.. I’m a little thick sometimes. But I get there in th end.

    I swear it worked with Hiberanate and the new log4j… but have just been one of those weird little programming moments. :oP

  • Steve Brownlee | December 2, 2006

    You actually can set the order of the classpath at application startup. In the web.xml you can add paths to the ‘macromedia_context_88’ context-param. Not sure if that’s specifically what you were focusing on, but thought I’d mention it.

  • Mark | December 3, 2006

    Steve –

    Not sure how you can change the order on a URLClassLoader, as its actually set within the class itself (I looked at the code), and it doesn’t go looking for any J2EE variables, as it is a J2SE core class.

    The neat thing is I can extend the URLCLassLoader, and write my own that does the searching in the order I want, so that will be what I end up doing.

  • Luis Majano | December 6, 2006

    Thanks Mark!! Can you advice when ready so I can in turn place the updated code in the coldbox javaloader plugin?? So I can keep it up to date.

    Thanks.

  • mati | December 23, 2006

    good

  • Qasim Rasheed | December 26, 2006

    Mark,

    I tried your suggestion on a log4j implementation and unfortunuately passing the null as the parent Class Loader argument do not solve the problem either. I end up getting errors in the CF logs that log4j cannot be initialized properly or something like that. FWIW.

    Thanks for great work though.

  • Mark | December 26, 2006

    Qasim,

    Feel free to email me the code, so I can see what your issue is.

    JavaLoader 0.3 should be out in the new year, and that should definitely solve all your problems. Check out javaloader.riaforge.org, and have a look in SVN – its pretty much there already.

  • Hedman Header | September 27, 2007

    Is it possible to tell ColdFusion where to load a Java class dynamically at runtime, rather than basically hard-coding it via ColdFusion administrator? Thanks.

  • Mark Mandel | September 28, 2007

    @Hedman – that’s what JavaLoader is for.