How to use Log4J in ejb module in Jboss7.1

JBoss 7.1 already ships with Log4J, but the config is somehow different from previous versions of the server.
The same Log4J architecture applies, you have appenders and categories, but the config files are different, so I’ll explain how to configure a new category and appender for this.

When developing your EJB you need to:

  1. import the Logger class: import org.apache.log4j.Logger;
  2. If the import does not resolve, add this jar to the path: %JBOSS_HOME%\modules\org\apache\log4j\main\log4j-1.2.16.jar
  3. create a field with the logger: private static Logger logger = Logger.getLogger(YourEJBClass.class);
  4. use the logger in any method: logger.info("my log");

JBoss already comes with a configuration file under %JBOSS_FOLDER%/standalone/configuration/standalone.xml. By default, your logger will output to server.log and console, but you can add some appender to output your app logs to another file.

Here is an example, edit that file and add the following snippets (following the definition of the file):

  • This one is to add an appender to the file myappfile.log inside the logs folder (add this right after the already defined under name=”FILE”):
     <periodic-rotating-file-handler name="FILETWO">
       <formatter>
         <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
       </formatter>
       <file relative-to="jboss.server.log.dir" path="myappfile.log"/>
       <suffix value=".yyyy-MM-dd"/>
       <append value="true"/>
     </periodic-rotating-file-handler>
  • Add this snippet tells log4j to send all logs from “com.mypackage” category to the previously created appender (copy this right after other defined logger in the file, but before the root-logger):
     <logger category="com.mypackage">
         <level name="DEBUG"/>
         <handlers>
             <handler name="CONSOLE"/>
             <handler name="FILETWO"/>
         </handlers>
     </logger>

Restart the server and you should see the new myappfile.log in the folder. Make sure your app logs something, for example, adding logger.info(“my servlet info log”) in some servlet and call it from the browser. You’ll also see this log in the console

If you need further customization, have a look at log4j help.

Advertisements

JBOSS EAP 5.0 – JAX-WS – Excessive logging when soap faults are thrown

Developing web services with JAX-WS is very quick and versatile, becoming very easy to create a simple web service and quickly adding complexity like more methods, complex datatypes, validation, custom application faults, etc. In this example I am using JBOSS EAP 5.0.
This said, sometimes you stumble onto an awkward moment when you need to start digging to fix some issue. In this case this was not really an issue, but a bugging log that started filling our log files.
In our web services we throw specific application faults which are defined automatically in the generated wsdls. The problem is that every time an application fault is thrown, the server logs an error, even if the fault is expected to be thrown to the client. Also, as the client (a JAX-WS client) receives the fault, the JAX-WS framework logs an error, even if the client catches the application fault and manages it. This logs may mask any other important issue or some other important information reported by the log file.
These are the logs that can be seen in the server / client:

	SERVER
14:10:15,758 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
com.myapp.ws.MyAppFault
	at com.myapp.ws.MyWebService(MyWebService.java:59)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.jboss.wsf.container.jboss50.invocation.InvocationHandlerJSE.invoke(InvocationHandlerJSE.java:108)
	at org.jboss.ws.core.server.ServiceEndpointInvoker.invoke(ServiceEndpointInvoker.java:221)
	at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:468)
	at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleRequest(RequestHandlerImpl.java:293)
	at org.jboss.wsf.stack.jbws.RequestHandlerImpl.doPost(RequestHandlerImpl.java:203)
	at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:129)
	at org.jboss.wsf.common.servlet.AbstractEndpointServlet.service(AbstractEndpointServlet.java:85)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
	at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
	at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)
	CLIENT
14:10:15,789 ERROR [CommonClient] Exception caught while (preparing for) performing the invocation: 
javax.xml.ws.soap.SOAPFaultException: com.myapp.ws.MyAppFault
	at org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS.getSOAPFaultException(SOAPFaultHelperJAXWS.java:84)
	at org.jboss.ws.core.jaxws.binding.SOAP11BindingJAXWS.throwFaultException(SOAP11BindingJAXWS.java:107)
	at org.jboss.ws.core.CommonSOAPBinding.unbindResponseMessage(CommonSOAPBinding.java:558)
	at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:373)
	at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:231)
	at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:162)
	at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:148)
	at $Proxy209.getContrato(Unknown Source)
	...

According to https://issues.jboss.org/browse/JBWS-3299, the log created by the server was reported as a bug, and was fixed in the next release of JBOSS.
For the second, I couldn’t find any reported issue, but I assumed it is a similar issue as the reported for SOAPFaultHelperJAXWS.

After all this analysis, the workaround that did the job for me was a quick patch to the log4j configuration of the JBOSS server:

  1. Open the file /jboss-as/server//conf/jboss-log4j.xml
  2. Add the following lines inside the tag. For example: before opening the tag.
  3. 	<category name="org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS" additivity="false">
    	</category>   
    	<category name="org.jboss.ws.core.CommonClient" additivity="false">
    	</category>   
    

    This code will remove the appenders for the categories generating the unwanted logs.

  4. Restart the server

That’s it! Now the logs will look much cleaner, and these logs won’t mask any other log that may be important.