Win a copy of Production-Ready Serverless (Operational Best Practices) this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Junilu Lacar
  • Paul Clapham
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Ron McLeod
  • Tim Moores
  • salvin francis
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Vijitha Kumara

Log4j PropertyConfigurator called by different applications on the same JVM  RSS feed

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens when different applications running on the same JVM call the static method PropertyConfigurator.configure passing different log4.properties files?
 
Bartender
Posts: 20562
120
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the JavaRanch, Luca!

This depends on how things are organized. While a JVM is a single program with a single classpath, it's a program that can run multiple applications within itself. The most familiar example of this is a webapp server, such as Tomcat.

In cases like this, each application has its own classpath, and even its own logging system. So one webapp might be using Apache logging and 2 other webapps might use log4j. And each webapp's log4j configuration has to be configured separately by the webapp itself. Meanwhile, the Tomcat server has its own logging system (by default, that's the "juli", or java.util.logging system).

And while webapp servers are probably the most common example, other multi-application containers, such as OSGi containers, also may have multiple internal classpaths.

Since the classes on each classpath are distinct from classes on any other non-parent classpath, you have a tree of classpaths, and each branch can have its own logging classes and configuration.
 
Luca Giovanni
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I'm referring to a web server, in particular I'm referring to Websphere Application Server, where multiple web apps are deployed. I found this article that explains classloaders on WAS https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/crun_classload.html

It seems that each applications has its own classloader, but I'm not sure I understood well, especially the tree hierarchy and which classloder loads the application classes...
 
Tim Holloway
Bartender
Posts: 20562
120
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Multiple webapps are possible on every webapp server I know of, even the Tomcat and jetty servers, which don't support the full JEE stack (EJB, JMS and so forth).

If you want to learn interesting things, write a quick app that obtains its current classloader and walk up through its parents.

An over-simplified view of things is that when the JVM starts up, it has a classpath that allows access to the native and core JSE classes. In Tomcat, that classpath is then extended (at least in certain threads) by a classpath that includes all of the classes in the jars in the TOMCAT_HOME/lib directory. Among other things, that's where the connection pool classes and the JDBC drivers are located. If you use the WebSphere management webapp, that structure won't be as apparent, but something like it is still there. Actually, it used to be even worse in Tomcat's case, since there were 3 different server library directories, and which classpaths employed them depended on what server subsystem you were talking about. Fortunately, that was later simplified.

All of these classes are in the base classpath for the webapps. As each webapp is deployed, it is assigned a classloader of its own. That classloader takes the base classpath and chains it to a new classpath for each webapp. The tip of the new classpath has a classloader that can load classes (and other classpath resources like log4.properties) from the WAR's WEB-INF/classes directory and from each of the jars in the WEB-INF/lib directory. Since each of these classpaths is distinct, a given webapp can see its own classes, and classes in the server's classpath, but not classes in any other webapp's classpath.

I'm being a little simplistic here, since an EAR can have multiple WARs, JARs, and other resources in it, and the rules about sharing class resources between them tend to be confusing even when it hasn't been years since I worked in a full-stack environment. But I hope you can see how the separation works.

And one final note. A webapp isn't a "program". It isn't running under a continous thread. Instead worker threads are assigned from the server's request thread pool as HTTP requests come in for servicing and released once the request servlet (or JSP) has returned the response. So the classpaths are bound to the application, not to a thread.
 
Sheriff
Posts: 24282
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So following on from what Tim just said: if you put a copy of the Log4J jar in each webapp, then calling the PropertyConfigurator will affect only the Log4J processing in that webapp.

However if you put a single copy of the Log4J jar in a certain place in Websphere, then it will be in the server's classpath and, basically, there will be only one copy of Log4J in the system which will be used by all of the webapps. It's been a long time since I had to work with Websphere so I don't know the name of that place, but usually it's not recommended to use it unless you know exactly what you're doing -- you should understand those classpaths and classloaders which Tim described. It may be that you want all of the webapps to be logged in a uniform standardized way, but you should still be careful because it might not be all that simple.
 
Tim Holloway
Bartender
Posts: 20562
120
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:
However if you put a single copy of the Log4J jar in a certain place in Websphere, then it will be in the server's classpath and, basically, there will be only one copy of Log4J in the system which will be used by all of the webapps.



Don't do this. Webapps are supposed to be self-contained. The minute they start looking outside their own environment for resources, they lose their "write once/run anywhere" powers. Worse, you could end up deploying a webapp in a server where it actively conflicts with other webapps deployed in that server. Not good.

In particular, every webapp is expected to manage its own logging independent of the webapp server. I consider this to be unfortunate in many ways, but it's true. Logging wasn't given enough attention when J2EE was initially designed. There's minimal builtin logging (Servlet.log()), but it's not up to real-world needs, which is why webapps rely on external systems like log4j.

It's OK to inject log configuration information into a webapp via JNDI from server administration, but neither configuration nor logging classes should be placed into the server's shared application classpath. That resource has strictly limited usages. For example, the JDBC drivers (to insulate webapps from database dependencies), the Connection Pools (which can be shared between webapps, and again, benefit from not being hard-coded in the app, and things that change the essential character of the webapp server (for example, to use JPA in Tomcat, I have to include a pair of libraries which support Spring Data code weaving - essentially adding stuff that would be natively part of a full-stack server.)
 
Won't you please? Please won't you be my neighbor? - Fred Rogers. Tiny ad:
global solutions you can do at home or in your backyard
https://www.kickstarter.com/projects/paulwheaton/better-world-boo
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!