Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Equinox » 2 versions of log4j-core.jar
2 versions of log4j-core.jar [message #127068] Fri, 06 March 2009 17:07 Go to next message
Tom H is currently offline Tom HFriend
Messages: 18
Registered: July 2009
Junior Member
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 #127084 is a reply to message #127068] Fri, 06 March 2009 17:10 Go to previous messageGo to next message
Tom H is currently offline Tom HFriend
Messages: 18
Registered: July 2009
Junior Member
Received a response from Simon.Kaegi:
***
Hi Tom,

Resources from you classpath should not be leaking into your OSGi
environment unless the "osgi.parentClassLoader" is set to either app or
framework and you're doing something like setting
'org.osgi.framework.bootdelegation=*'.
Can you look at these settings and tell us a bit about the environment
you're running.
Also, this is really the dev list. Could we continue this thread in the
user newsgroup -- eclipse.technology.equinox.

Thanks.
-Simon
***
Re: 2 versions of log4j-core.jar [message #127105 is a reply to message #127084] Fri, 06 March 2009 17:47 Go to previous messageGo to next message
Tom H is currently offline Tom HFriend
Messages: 18
Registered: July 2009
Junior Member
I am using EclipseStarter to start the osgi application.

EclipseStarter.setInitialProps sets:
osgi.clean = true
osgi.syspath = <path_A>/plugins
osgi.install.area = <path_A>

EclipseStarter.startup with the following launcher args:
-application = my.application

The config.ini in <path_A>/configuration/ contains:
#Configuration File
#Fri May 09 14:20:34 EDT 2008
osgi.bundles=org.eclipse.equinox.common@2:start,
org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
osgi.bundles.defaultStartLevel=4
osgi.instance.area.default=@user.dir/workspace
osgi.configuration.cascaded=false
eclipse.application=my.application
# End of file marker - must be here

I am not sure of any other runtime configuration. What else should I check?

Thanks.
Re: 2 versions of log4j-core.jar [message #127118 is a reply to message #127105] Fri, 06 March 2009 18:05 Go to previous messageGo to next message
Tom H is currently offline Tom HFriend
Messages: 18
Registered: July 2009
Junior Member
I also found lines on in the DOMConfigurator where it is throwing a class
cast exception:

log4j 1.2.8 version:
protected
Appender parseAppender (Element appenderElement) {
String className = subst(appenderElement.getAttribute(CLASS_ATTR));
LogLog.debug("Class name: [" + className+']');
try {
Object instance = Loader.loadClass(className).newInstance();
Appender appender = (Appender)instance;

The last line is where the cast fails. The preceding code are all public
static API calls. Here is the first instance where a classloader is
involved. Does this break anything?

Tom wrote:

> I am using EclipseStarter to start the osgi application.

> EclipseStarter.setInitialProps sets:
> osgi.clean = true
> osgi.syspath = <path_A>/plugins
> osgi.install.area = <path_A>

> EclipseStarter.startup with the following launcher args:
> -application = my.application

> The config.ini in <path_A>/configuration/ contains:
> #Configuration File
> #Fri May 09 14:20:34 EDT 2008
> osgi.bundles=org.eclipse.equinox.common@2:start,
> org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
> osgi.bundles.defaultStartLevel=4
> osgi.instance.area.default=@user.dir/workspace
> osgi.configuration.cascaded=false
> eclipse.application=my.application
> # End of file marker - must be here

> I am not sure of any other runtime configuration. What else should I check?

> Thanks.
Re: 2 versions of log4j-core.jar [message #127131 is a reply to message #127118] Fri, 06 March 2009 18:32 Go to previous messageGo to next message
Simon Kaegi is currently offline Simon KaegiFriend
Messages: 381
Registered: July 2009
Senior Member
Strange. That all looks fine. (e.g. the log4j conflict you're seeing does
not appear to be coming in externally)
I'd first verify that you have just the one copy of log4j in your set of
bundles however after that I think you're going to have do some debugging at
the point where the class is loaded (and also where the cast occurs) in
order to figure this out.
From what you've shown it doesn't appear to be a problem in how you're
embedding so you mght also try just running your application like a regular
eclipse/equinox application to see if you still have the same problem.

HTH
-Simon

" Tom" <tomhsu@gmail.com> wrote in message
news:ec825d18beff71759dfe1c99ccb80007$1@www.eclipse.org...
>I also found lines on in the DOMConfigurator where it is throwing a class
>cast exception:
>
> log4j 1.2.8 version:
> protected
> Appender parseAppender (Element appenderElement) {
> String className = subst(appenderElement.getAttribute(CLASS_ATTR));
> LogLog.debug("Class name: [" + className+']'); try {
> Object instance = Loader.loadClass(className).newInstance();
> Appender appender = (Appender)instance;
>
> The last line is where the cast fails. The preceding code are all public
> static API calls. Here is the first instance where a classloader is
> involved. Does this break anything?
>
> Tom wrote:
>
>> I am using EclipseStarter to start the osgi application.
>
>> EclipseStarter.setInitialProps sets:
>> osgi.clean = true
>> osgi.syspath = <path_A>/plugins
>> osgi.install.area = <path_A>
>
>> EclipseStarter.startup with the following launcher args:
>> -application = my.application
>
>> The config.ini in <path_A>/configuration/ contains:
>> #Configuration File
>> #Fri May 09 14:20:34 EDT 2008
>> osgi.bundles=org.eclipse.equinox.common@2:start,
>> org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
>> osgi.bundles.defaultStartLevel=4
>> osgi.instance.area.default=@user.dir/workspace
>> osgi.configuration.cascaded=false
>> eclipse.application=my.application
>> # End of file marker - must be here
>
>> I am not sure of any other runtime configuration. What else should I
>> check?
>
>> Thanks.
>
>
Re: 2 versions of log4j-core.jar [message #127220 is a reply to message #127131] Mon, 09 March 2009 23:01 Go to previous message
Tom H is currently offline Tom HFriend
Messages: 18
Registered: July 2009
Junior Member
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);
}
}
}
***
Previous Topic:P2 Software Update UI shows .qualifier, but Help/About does not
Next Topic:Process name (within the Equinox) in the Jconsole
Goto Forum:
  


Current Time: Thu Apr 25 05:14:42 GMT 2024

Powered by FUDForum. Page generated in 0.03283 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top