2 versions of log4j-core.jar [message #127068] |
Fri, 06 March 2009 12:07  |
Eclipse User |
|
|
|
Hi experts,
In the midst of the integrating a osgi/eclipse based program to an
existing Java program, I am running into a problem with the double loading
of log4j-core.jar. The original java program already has a log4j-core.jar
loaded as part of the CLASSPATH when it is started. The said program in
turns will launch the new osgi/eclipse based program through
EclipseStarter:
***
EclipseStarter.setInitialProperties(buildDefaultProps());
EclipseStarter.startup(launcherArgs, null);
EclipseStarter.run(launcherArgs);
***
The osgi/eclipse program has another version of the log4-core.jar in the
org.apache.jakarta_log4j_0.0.0. bundle. This bundle is a required bundle.
As you can see, that the same classes will be loaded twice when my
original Java program attempts to load the osgi/eclipse program. Hence I
am getting a class cast error:
***
log4j:ERROR Could not create an Appender. Reported error follows.
java.lang.ClassCastException: org.apache.log4j.ConsoleAppender cannot be
cast to org.apache.log4j.Appender
at
org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfig urator.java:165)
at
org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMC onfigurator.java:140)
at
org.apache.log4j.xml.DOMConfigurator.findAppenderByReference (DOMConfigurator.java:153)
at
org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerEl ement(DOMConfigurator.java:415)
at
org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurat or.java:384)
at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.j ava:783)
at
org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigur ator.java:666)
at
org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigur ator.java:616)
at
org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigur ator.java:584)
at org.apache.log4j.xml.XMLWatchdog.doOnChange(DOMConfigurator. java:815)
at
org.apache.log4j.helpers.FileWatchdog.checkAndConfigure(File Watchdog.java:80)
at org.apache.log4j.helpers.FileWatchdog.<init>(FileWatchdog.java:49)
at org.apache.log4j.xml.XMLWatchdog.<init>(DOMConfigurator.java:807)
at
org.apache.log4j.xml.DOMConfigurator.configureAndWatch(DOMCo nfigurator.java:574)
at
org.apache.log4j.xml.DOMConfigurator.configureAndWatch(DOMCo nfigurator.java:557)
...
***
Can someone advise me on how to solve this issue? I am thinking about ways
like:
1. Make the OSGI know that log4j-core.jar is already present so don't load
it again. Not sure how to do this or if this is even feasible.
2. Modify the bundle requirement of the various bundles in the plugins
directory so the org.jakarta bundle will not be needed? I'd like to avoid
this since this means I have to change someone else's nicely packaged
bundles.
Regards,
Tom
|
|
|
|
|
|
|
Re: 2 versions of log4j-core.jar [message #127220 is a reply to message #127131] |
Mon, 09 March 2009 19:01  |
Eclipse User |
|
|
|
In order to debug as suggested, I added the following code snippet to my
Application.java in order to examine the potential conflicts:
****
printClassLoaders(this, 0);
Object instance = null;
try {
instance = Loader.loadClass(
org.apache.log4j.ConsoleAppender.class.getName())
.newInstance();
...
}
System.out.println("Instance is not null");
printClassLoaders(instance, 0);
Appender appender;
appender = (Appender) instance;
****
printClassLoaders print the parent class loader chain back to the NULL
one. I get the following:
***
class my.Application,
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@ec436
....sun.misc.Launcher$AppClassLoader@12498b5
......null
class org.apache.log4j.ConsoleAppender,
sun.misc.Launcher$AppClassLoader@12498b5
....null
java.lang.ClassCastException: org.apache.log4j.ConsoleAppender
***
Looks like that my.Application is being loaded by the OSGI class loader,
but the instance object (which uses log4j helper classes) get's loaded
through AppClassLoader.
So the (instance, AppClassLoader) cannot be cast to Appender which is
(my.application, DefaultClassLoader).
Is my reasoning correct? The org.apache.log4j has internals that load
through some special mechanism which is not compatible with osgi loading:
*** Loader.loadClass
static public Class loadClass (String clazz) throws
ClassNotFoundException {
// Just call Class.forName(clazz) if we are running under JDK 1.1
// or if we are instructed to ignore the TCL.
if(java1 || ignoreTCL) {
return Class.forName(clazz);
} else {
try {
return getTCL().loadClass(clazz);
} catch(Throwable e) {
// we reached here because tcl was null or because of a
// security exception, or because clazz could not be loaded...
// In any case we now try one more time
return Class.forName(clazz);
}
}
}
***
|
|
|
Powered by
FUDForum. Page generated in 0.28996 seconds