Saturday, April 19, 2008

How do i use my own log4j properties or xml file in JBoss

This article is mainly for those who had a hard time configuring "their own" log4j.properties or log4j.xml within their application on JBoss. For a brief background on this, please read through this JBoss wiki. As explained in that wiki, JBoss uses its own version of log4j.xml and log4j jar, making it difficult to use your own version of the log4j properties/xml files. The wiki also lists down the steps required to configure your application to use its own log4j config file. However, i have seen people complain in the forums that those steps either dont work for them or the steps are too involved and not worth a try.

People at JBoss had taken note of these issues (see the related JIRA) and starting JBoss-4.2.x, the steps involved to configure your own log4j config file in JBoss are pretty simple and straight-forward. In this example, i will try to explain these steps for a EAR file as well as a WAR file. The version that i am using here is JBoss-4.2.2GA (which is the latest stable version at this point). In the examples here, i use a log4j.properties file. The steps are the same even for a log4j.xml.

So here's what is required to get it working in a EAR file:

1) Create a log4j.properties and package it with your application and make it available in the classpath (i placed the log4j.properties file at the root of the EAR file).

2) Also package the appropriate version of log4j jar with your application (this step and the next step are important because you will have to ensure that log4j initializes separately for your application and picks up the log4j.properties file). Place this log4j jar file in the application package so that it is made available in the classpath (i placed it in a folder named lib of the EAR file - remember that any jars in the lib folder of the EAR are by default added to the classpath and made available to the entire application, starting JBoss-4.2.x version).

3) Enable classloader isolation for your application. This is necessary as explained in step#2. You will have to create a jboss-app.xml file and place it in the META-INF folder of the EAR. The jboss-app.xml looks like:


<jboss-app>
<loader-repository>
org.myapp:loader=MyClassLoader
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>

</jboss-app>






This is how the EAR file would look like:



myApp.ear
|
|--- log4j.properties
|
|--- META-INF
| |
| |--- application.xml
| |
| |--- jboss-app.xml
|
|--- lib
| |
| |--- log4jxxx.jar






That's it! Your application now will use it own version of log4j config file as well log4j jar.

Steps involved for a WAR file are similar (If the WAR file is part of an EAR file, then you don't have to follow the steps below. The steps mentioned above for an EAR file are sufficient for a WAR inside an EAR):

1) Create a log4j.properties and package it with your application and make it available in the classpath (i placed the log4j.properties file in the WEB-INF/classes folder of the WAR).

2) Also package the appropriate version of log4j jar with your application (this step and the next step are important because you will have to ensure that log4j initializes separately for your application and picks up the log4j.properties file). Place this log4j jar file in the application package so that it is made available in the classpath (i placed it in a WEB-INF/lib of the WAR file).

3) Enable classloader isolation for your application. This is necessary as explained in step#2. You will have to create a jboss-web.xml file and place it in the WEB-INF folder of the WAR. The jboss-web.xml looks like:



<jboss-web>
<class-loading java2ClassLoadingCompliance="false">
<loader-repository>
org.myapp:loader=MyClassLoader
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>





This is how the WAR file would look like:


myApp.war
|
|--- WEB-INF
| |
| |--- web.xml
| |
| |--- jboss-web.xml
| |
| |--- classes
| | |
| | |--- log4j.properties
|
|
|--- lib
| |
| |--- log4jxxx.jar




13 comments:

Anonymous said...

Excellent article! I have banged my head for a week until I found it.

You could amend it by saying that if the EAR contains both EJBs and a webappa WAR, then you don't have to enable classload isolation (using WEB-INF/jboss-web.xml).

/Per Lindberg

Jaikiran said...

Happy to know, you found it useful.

Per Lindberg said...

You could amend it by saying that if the EAR contains both EJBs and a webappa WAR, then you don't have to enable classload isolation (using WEB-INF/jboss-web.xml).


You are right. The section for configuring WAR file was for those WARs which are deployed outside an EAR. I have updated that part to be more clear. Thanks for your comments :)

Anonymous said...

Hi,
I did the same procedure as you told, but i use log4j.xml instead of log4j.properties. I get the following error if i place jboss-app.xml under META-INF folder.

java.lang.RuntimeException: An exception occurred initialising interceptors for class com.bally.mom.ejb.CustomerListener.onMessage
at org.jboss.ejb3.interceptor.EJB3InterceptorsFactory.createPerJoinpoint(EJB3InterceptorsFactory.java:108)
at org.jboss.aop.advice.AspectFactoryDelegator.createPerJoinpoint(AspectFactoryDelegator.java:119)
at org.jboss.aop.advice.ScopedInterceptorFactory.create(ScopedInterceptorFactory.java:113)
at org.jboss.aop.Advisor.createInterceptorChain(Advisor.java:618)
at org.jboss.aop.Advisor.pointcutResolved(Advisor.java:888)
at org.jboss.aop.Advisor.resolveMethodPointcut(Advisor.java:650)
at org.jboss.aop.ClassContainer.createInterceptorChains(ClassContainer.java:248)
at org.jboss.aop.ClassContainer.rebuildInterceptors(ClassContainer.java:115)
at org.jboss.aop.ClassContainer.initializeClassContainer(ClassContainer.java:58)
at org.jboss.ejb3.EJBContainer.create(EJBContainer.java:548)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.ejb3.ServiceDelegateWrapper.createService(ServiceDelegateWrapper.java:87)
at org.jboss.system.ServiceMBeanSupport.jbossInternalCreate(ServiceMBeanSupport.java:260)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:243)
at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.create(Unknown Source)
at org.jboss.system.ServiceController.create(ServiceController.java:330)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy55.create(Unknown Source)
at org.jboss.ejb3.JmxKernelAbstraction.install(JmxKernelAbstraction.java:119)
at org.jboss.ejb3.Ejb3Deployment.registerEJBContainer(Ejb3Deployment.java:301)
at org.jboss.ejb3.Ejb3Deployment.start(Ejb3Deployment.java:362)
at org.jboss.ejb3.Ejb3Module.startService(Ejb3Module.java:91)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.start(Unknown Source)
at org.jboss.system.ServiceController.start(ServiceController.java:417)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy33.start(Unknown Source)
at org.jboss.ejb3.EJB3Deployer.start(EJB3Deployer.java:512)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:97)
at org.jboss.system.InterceptorServiceMBeanSupport.invokeNext(InterceptorServiceMBeanSupport.java:238)
at org.jboss.wsf.container.jboss42.DeployerInterceptor.start(DeployerInterceptor.java:87)
at org.jboss.deployment.SubDeployerInterceptorSupport$XMBeanInterceptor.start(SubDeployerInterceptorSupport.java:188)
at org.jboss.deployment.SubDeployerInterceptor.invoke(SubDeployerInterceptor.java:95)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy34.start(Unknown Source)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1025)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1015)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:819)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:782)
at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy9.deploy(Unknown Source)
at org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymentScanner.java:421)
at org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentScanner.java:634)
at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.doScan(AbstractDeploymentScanner.java:263)
at org.jboss.deployment.scanner.AbstractDeploymentScanner.startService(AbstractDeploymentScanner.java:336)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.start(Unknown Source)
at org.jboss.system.ServiceController.start(ServiceController.java:417)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy4.start(Unknown Source)
at org.jboss.deployment.SARDeployer.start(SARDeployer.java:302)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1025)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:819)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:782)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:766)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy5.deploy(Unknown Source)
at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:482)
at org.jboss.system.server.ServerImpl.start(ServerImpl.java:362)
at org.jboss.Main.boot(Main.java:200)
at org.jboss.Main$1.run(Main.java:508)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.jboss.ejb3.mdb.MDB.getMessagingType(MDB.java:84)
at org.jboss.ejb3.interceptor.EJB3InterceptorsFactory.getBusinessInterfaces(EJB3InterceptorsFactory.java:167)
at org.jboss.ejb3.interceptor.EJB3InterceptorsFactory.isBusinessMethod(EJB3InterceptorsFactory.java:122)
at org.jboss.ejb3.interceptor.EJB3InterceptorsFactory.createPerJoinpoint(EJB3InterceptorsFactory.java:98)
... 153 more

Anonymous said...

Hi,
Could you please explain about MyClassLoader for EAR file. It was clear for war file. How to do the same for EAR file and load it.

Maty said...

Hi! i try to use log4j in a war file with my JBOSS 4.0.5 GA server but when i check in the jmx console it seems to load the log4j.jar of "server/default/lib" :(. Any idea?

I put the log4j.jar file in "WEB-INF/lib" of my war file

Regards

Jaikiran said...

Maty said...
Hi! i try to use log4j in a war file with my JBOSS 4.0.5 GA server but when i check in the jmx ....


Maty, have you enabled classloader scoping for your application through the jboss-web.xml? A detailed explanation can be found at Classloader Configuration in JBoss

Jaikiran said...

Anonymous said...

Hi,
I did the same procedure as you told, but i use log4j.xml instead of log4j.properties. I get the following error if i place jboss-app.xml under META-INF folder.

java.lang.RuntimeException: An exception occurred initialising interceptors for class com.bally.mom.ejb.CustomerListener.onMessage
...


This doesn't look specific to log4j related configuration. Maybe a classloader issue which arose when you configured the classloader scoping through the xmls.

Jaikiran said...

Anonymous said...

Hi,
Could you please explain about MyClassLoader for EAR file.


MyClassLoader is just any (unique) name that you can give to your classloader which will be configured and used for loading your application's classes.

Ashok said...

Hi,

I am following the same procedure as you said. But still my appllication is unable to find log4j.prop file in classpath.
My EAR structure is as follows
.EAR
|
|-log4j.properties
|-log4j.jar
|-myCustomJars.jar(Contains my
utils)
|-myWar.war
|-myEjbClient.jar(Contains only
interfaces)
|-META-INF
|-jboss-web.xml
|-application.xml

I am using jboss-5.0.0.CR1
Please suggest,
-Ashok

Unknown said...

After I amended log4j.properties file, I must restart JBoss application to effective the setting. Am I right ?

kar said...

I am using JBoss 5.0.1 and I am not able to load the log4j.properties file from my application. All the settings are correct and I am sure of this.

Regarding the classload isolation, the following properties are defined in "war-deployers-jboss-beans.xml"

false

false

javax.servlet,org.apache.commons.logging

I tried removing "org.apache.commons.logging" from filteredPackages property, however, that didn't help as well.

Any suggestions would be highly appreciated.

Thanks in advance.

Anonymous said...

Hi I have followed the article very well, it seems to work fine on war and on ear, it classes which are in jars in that ear are not loaded, works only for war inside the same ear.

I think classloader on ear is the problem. Can anyone help on how custom log4j.properties should be set in ear.

I am using Jboss AS 5.1

Anonymous said...

This article was published a long time ago... but still find it useful with jboss 5.1.X