Thursday, January 29, 2015

External log4j configuration in WebSphere AS7

TL;DR - Zip your log4j.xml into an archive, and assign it as a Shared Library reference in an isolated ClassLoader for the deployed ear file.

We had all our configurations stored somewhere in our single EAR file. Somebody didn't like it this way, and we had to externalise the logging properties.

Our interim solution of setting the -Dlog4j.configuration= into the JVM runtime parameters was not well received. My next idea was to make use of the WebSphere Variables, but this old article proved that it will be costly to implement the AdminOperations MBean. This did not help either.

My colleague had attempted to reference the log4j XML file directly in the Shared Libraries reference, but did not succeed in getting WebSphere to adopt the properties. I tried referencing ${LOG_DIR} within the XML file, to a JVM custom property linked to the WebSphere ${LOG_ROOT} also to no avail.

What finally did work, was this:
  1. I extracted the log4j.xml from our EAR,
  2. Zipped this lone XML into an archive, 
  3. Placed it on the server in a path accessible by WebSphere,
  4. Create a Shared Library (WebSphere > Environment > Shared Libraries) mapping the classpath to this archive,
  5. Make sure to select "Use an isolated class loader for this shared library" or you'd have to assign reference for each module of your application rather than just the parent EAR.
  6. Assigning the reference within our EAR (WebSphere > ...Applications... > References > Shared library references),
  7. Restart the server node
Checks via the Class loader viewer (WebSphere > Troubleshooting > Class loader viewer) proved that the lone XML in our newly added archive is loaded for our application, overriding what we'd placed within the EAR file.

An additional tip useful for deployment I found was this. Simply put, the deployment.xml for WebSphere I had created (probably deserves another post after this) just needed another entry added as a child node of the <classloader> module to our EAR file:
<libraries libraryName="Log4j_XML" sharedClassloader="true"/>

Adding this would relieve us of extra steps that can potentially be missed out during deployment, because the shared library would already be configured by default. Keep in mind though, that the libraryName has to be an exact match to what was configured in the WebSphere Shared Libraries.

2 comments:

  1. Hello, I am having the same situation described above. I created a new java project and placed the log4j.xml in that project, created a shared library, restarted the server but still I could not see it working. Any help or suggestions.

    ReplyDelete
    Replies
    1. hi there, what server are you running from? assuming if you are also running WebSphere, have you taken a look at the classloader parent last settings?

      Delete