Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

Java, the OLPC, and community responsibility

The "One Laptop Per Child" project has a great device ready to ship, but there's no Java on there. Let's think about working together to put Java on OLPC!
Replies: 15 - Pages: 2   [ 1 2 | Next ]
  Click to reply to this thread Reply

Universal Logger Plug-ins for RCP Applications

URL: Universal Logger Plug-ins for RCP Applications

At 9:35 PM on Dec 1, 2005, Ed Burnette Javalobby Junkies wrote:

A new EclipseZone article by John Franey will help RCP application and plug-in developers incorporate logging using a variety of standard APIs. A group of logger plug-ins are created that can become part of your development toolbox. The article covers Apache's Logging LOG4J, Sun's JDK 1.4 Logging, Eclipse logging framework using org.eclipse.core.runtime.ILog, Apache's Jakarta Commons Logging, and the Simple Logging Framework for Java.
In the first section, creating plug-ins from common logger frameworks and facade libraries will be described. A logger facade plug-in upon a custom logging framework, such as PDE ILog API is developed. Then for LOG4J and the JDK 1.4 Logger frameworks a strategy for controlling logger configuration in a single file is presented. Finally, in a demonstration of the flexibility of these plug-ins, instructions for swapping one plug-in for another is given.

This article is not a tutorial about Eclipse plug-in development. If you are new to Eclipse, you can find better introductory articles elsewhere. However, if you have read those introductory articles and are looking for examples of developing plug-ins, this article can be useful.

Read the full article by John Franey.
  Click to reply to this thread Reply
1. At 9:09 AM on Dec 13, 2005, Ravshan Kosimov Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

I create org.apache.log4j plugin and test RCP application.
In application I just log start and stop of application.

If I run this application from Eclipse IDE all works fine.
If I export this application and run on Sun's JVM all works fine too.

But if I run exorted application on IBM's JVM I got this in console:
osgi> log4j:ERROR A "org.apache.log4j.FileAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
log4j:ERROR [org.eclipse.core.runtime.adaptor.EclipseClassLoader@3c9e6d88] whereas object of type
log4j:ERROR "org.apache.log4j.FileAppender" was loaded by [sun.misc.Launcher$AppClassLoader@3ca06d88].
log4j:ERROR Could not instantiate appender named "A1".
log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
log4j:ERROR [org.eclipse.core.runtime.adaptor.EclipseClassLoader@3c9e6d88] whereas object of type
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [sun.misc.Launcher$AppClassLoader@3ca06d88].
log4j:ERROR Could not instantiate appender named "A2".
log4j:WARN No appenders could be found for logger (testLogger.TestLoggerPlugin).
log4j:WARN Please initialize the log4j system properly.

Have any suggestions why this occured? And how it solve?
  Click to reply to this thread Reply
2. At 10:28 AM on Dec 14, 2005, John J. Franey Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

This error is due to one class loader (org.eclipse.core.runtime.adaptor.EclipseClassLoader@3c9e6d88) has loaded the core log4j framework library, and another classloader (sun.misc.Launcher$AppClassLoader@3ca06d88) has loaded Appender implementation classes.

The problem will be found if its discovered why the implementation classes are loaded by sun.misc.Launcher$AppClassLoader (the application classloader). They should be loaded by the same eclipse classloader that loads the log4j framework (the classloader of org.apache.log4j plugin).

The bigger mystery is why behaviour is dependent on the JVM, the byte code interpretor. When the JVM is different and byte code is the same, then the same behavior should be expected. Otherwise, one or more implementation is not living up to its contract. If the root cause is JVM implementation specific, then someone (IBM, Sun, or Eclipse) is due a bug report, I think.

Assuming for the moment that the problem is a configuration issue that doesn't show up in SUN JVM:

How many plug-ins are using log4j API? How are each configured to resolve the log4j packages: import, required...? Does any plug-in bundle log4j within?

What is your start configuration? Do you override osgi.parentClassloader property? Is log4j on the JVM classpath?


John
  Click to reply to this thread Reply
3. At 11:41 AM on Dec 14, 2005, Ravshan Kosimov Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

I checked my CLASSPATH, and i found there another copy of log4j. I'm sorry for misinformation and mine inattention.
I was misleaded that on Sun's JVM it works, but on IBM's JVM not works.
  Click to reply to this thread Reply
4. At 1:29 PM on Dec 14, 2005, John J. Franey Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

No problem at all. Thank you for reading the article.

John
  Click to reply to this thread Reply
5. At 3:41 PM on Dec 30, 2005, Timothy J Vogel Javalobby Newcomers wrote:

Re: Universal Logger Plug-ins for RCP Applications

John,
Thanks for the excellent article! I am working through it and learned several new concepts.

I do have one part that I am unable to get working. The test application does not read the log4j.properties file to format the messages. I added the VM argument -Dlog4j.configuration=/bin/log4j.properties and tried several variants based on different paths, none of which displayed the custom format.

Also when I put debug breaks in PluginLogAppender, they are never hit.

Can you give me some pointers on where to look to determine how to get this working?

Thanks for taking the time to help!
Timothy Vogel
  Click to reply to this thread Reply
6. At 9:29 PM on Dec 30, 2005, John J. Franey Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

Timothy,

Thanks for reading the article. I'm happy it has helped.




Its clear that log4j is not finding your log4j.properties file. Another symptom you are probably having, too, is something like the following to the console view:

log4j:WARN No appenders could be found for logger (logTest.Log4jTest).
log4j:WARN Please initialize the log4j system properly.



Check that log4j.properties file exists in your project's bin directory. (In my case, this is logTest/bin/log4j.properties).

Be wary of typographical errors: fat-finger is a possible cause. Make sure the spelling of the filename matches the spelling in the vmarg.

The path to your log4j.properties file would have to be adjusted if you are not using 'bin' as the name of your project's build output directory.

Are you running on Windows? I run eclipse on linux and so use the forward-slash for path seperator. Windows' path seperator is '\'. If you run on Windows, maybe \bin\log4j.properites is the right spelling.

By default, log4j doesn't seem to complain when it cannot find the configuration file. I wonder if there is a system property that will cause log4j to be verbose during startup. I looked for a bit in the log4j web site, but didn't find anything. You could post a question in their mail list, or maybe download the log4j source code and trace through it while it starts up.

Sorry I couldn't provide a solution.


John
  Click to reply to this thread Reply
7. At 2:01 PM on Feb 21, 2006, Don Young Javalobby Newcomers wrote:

Re: Universal Logger Plug-ins for RCP Applications

This is a great article.
However, has anyone try to deploy on webstart. I managed to get it work within Eclipse but when deployed as webstarted, it fails:

java.lang.ExceptionInInitializerError
at com.inpowersoft.inpowerforms.IpsApplication$1.run(IpsApplication.java:47)
at java.lang.Thread.run(Unknown Source)
Caused by: 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.))
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:543)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
at com.inpowersoft.hibernate.HibernateConnector. (HibernateConnector.java:34)
... 2 more
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.)
at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:397)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529)
... 6 more
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.
at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:385)
... 7 more
  Click to reply to this thread Reply
8. At 4:24 PM on Feb 21, 2006, Alex Blewitt DeveloperZone Top 100 wrote:

Re: Universal Logger Plug-ins for RCP Applications

That sounds like you've got a log4j.jar kicking around in the JRE that's being used to run webstart, but not the one that's being used to run Eclipse (are you using a JDK for this?) Sun, in their infinite wisdom, install a separate JRE into the c:\Program Files\JavaSoft\jre\1.2.3.4betacarrotine directory, which is separate from the JRE in a JDK (sorry, SDK, sorry J2SDK) install.

In a nutshell; check the JREs in c:\Program Files\ and have a look in the lib\ext folder to check that you haven't put a log4j in there yourself at some point in the past.

Alex.
  Click to reply to this thread Reply
9. At 4:48 PM on Feb 21, 2006, Don Young Javalobby Newcomers wrote:

Re: Universal Logger Plug-ins for RCP Applications

It turns out that org.eclipse.core.runtime.adaptor.EclipseClassLoader
loads one copy and com.sun.jnlp.JNLPClassLoader
loads another copy. I have 2 plugins one is code-only plugin that has the log library and a "user" plugin that uses the code-only plugin.

Anyone has idea to resolve this problem? I was able to use slf4j-log4j12.jar which does not raise an exception but print an message graciously. The problem still exists.
  Click to reply to this thread Reply
10. At 5:12 PM on Feb 21, 2006, John J. Franey Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

Thanks. I'm glad you found the article useful.

Alex Blewitt's preceding analysis is right on. The exception you report is very clear: webstart is finding two (or more?) log4j jar files in your runtime.

However, the classloading algorithm, as explained in McAffer's RCP book, won't find jars in lib/ext unless a plug-in has the 'ext' buddy policy. At least, that's how I understand it. Setting buddy policy is a deliberate act; its default is: none. I'm not familiar with webstart and so maybe these rules are all 'off' in that environment, so please let me know if cleaning the lib/ext clears the problem.

Do you have any plug-ins with the 'ext' buddy policy?

I think that even though this is launched under webstart, the Eclipse classloading rules prevail. Am I wrong?

My thinking is that another plug-in also contains the log4j.jar. This other plug-in must have snuck into your rcp applicaton between your success in Eclipse solely and your trial within webstart.


Regards,
John
  Click to reply to this thread Reply
11. At 5:37 PM on Feb 21, 2006, Don Young Javalobby Newcomers wrote:

Re: Universal Logger Plug-ins for RCP Applications

John,

My code-only plugin has the logger code and hibernate library and is named org.hibernate.libs. The consumer plugin is setup as in the buddy list and has "Eclipse-RegisterBuddy: org.hibernate.libs" in its Manifest. Everything works fine within the eclipse environment as the buddy mechanism suggested. As soon as the plugins are deployed into webstart, the same library is being loaded by two different loaders as stated in previous posting and thus causing conflict. The consuming plugin does not contain the logger code. I think this is a webstart eclipse problem.
I found the problem described here: http://jcleclipse.sourceforge.net/


-Don
  Click to reply to this thread Reply
12. At 9:23 PM on Feb 21, 2006, John J. Franey Blooming Javalobby Member wrote:

Re: Universal Logger Plug-ins for RCP Applications

Don,

The article you quote discusses a problem using the apache's implementation of JCL. As you know, apache's implementation uses the dynamic class discovery mechanism. Mixing dynamic discovery, eclipse and webstart apperently is bad brew. sfl4j's implementation of JCL doesn't use dynamic discovery and avoids the issue entirely.

Sorry, maybe I have misunderstood. I had thought you were following along the article and it wasn't working for you in the webstart environment. Now, after reading the article you refer to and taking a close look at the stack trace, I think you are using apache's implementation and not slf4j's implementation of JCL. Am I wrong?



John
  Click to reply to this thread Reply
13. At 10:03 PM on Feb 21, 2006, Don Young Javalobby Newcomers wrote:

Re: Universal Logger Plug-ins for RCP Applications

John,

I used JCL but with the problem I switched to slf4j. My need is even simpler than the article such that I want to package into a code-only plugin a bunch of common libraries. Although slf4j does not raise an exception but the fact that there are two class loaders exist present the same problem. I've tried every possible work around I can found on the web . I assume this is a very common practice and wonder what others are doing with it.

Below is the problem with slf4j with two class loaders under webstart:

log4j:
ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
log4j:ERROR [org.eclipse.core.runtime.adaptor.EclipseClassLoader@1ad98ef] whereas object of type
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [com.sun.jnlp.JNLPClassLoader@83cc67].
log4j:ERROR Could not instantiate appender named "stdout".
log4j:WARN No appenders could be found for logger (com.inpowersoft.hibernate.HibernateConnector).

Thanks.

-Don
  Click to reply to this thread Reply
14. At 4:34 PM on Nov 3, 2006, Ali Naddaf Occasional Javalobby Visitor wrote:

Re: Universal Logger Plug-ins for RCP Applications

Thanks for the great article, I just came across that. Do you think you can also write up something, or point me to some existing work, to use log4j with eclipse in a way that by providing an appropriate appender, I can redirect the log output to a, say, StyledText or some other widget of that sort?

Many thanks,
Ali.

thread.rss_message