I am having problems with configuration of AmqpAppender related to use in two web apps that run on the same tomcat 7.0.x instance. If I remove AmqpAppender and use the standard log4j appenders, there are no problems. They both work on my development instance as is because app A happens to start first. When app B starts first (as on our QA instances) I get the following:
Apr 16, 2012 10:11:41 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class net.sf.navigator.menu.MenuContextListener
java.lang.NoClassDefFoundError: org/springframework/util/Assert
at org.springframework.amqp.rabbit.connection.Abstrac tConnectionFactory.<init>(AbstractConnectionFactor y.java:44)
at org.springframework.amqp.rabbit.connection.Caching ConnectionFactory.<init>(CachingConnectionFactory. java:77)
at org.springframework.amqp.rabbit.connection.Caching ConnectionFactory.<init>(CachingConnectionFactory. java:100)
at org.springframework.amqp.rabbit.connection.Caching ConnectionFactory.<init>(CachingConnectionFactory. java:68)
at org.springframework.amqp.rabbit.log4j.AmqpAppender .append(AmqpAppender.java:380)
at org.apache.log4j.AppenderSkeleton.doAppend(Appende rSkeleton.java:251)
at org.apache.log4j.helpers.AppenderAttachableImpl.ap pendLoopOnAppenders(AppenderAttachableImpl.java:66 )
at org.apache.log4j.Category.callAppenders(Category.j ava:206)
at org.apache.log4j.Category.forcedLog(Category.java: 391)
at org.apache.log4j.Category.log(Category.java:856)
at org.apache.commons.logging.impl.Log4JLogger.error( Log4JLogger.java:257)
at org.apache.commons.digester.Digester.endElement(Di gester.java:1132)
at com.sun.org.apache.xerces.internal.parsers.Abstrac tSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.parsers.Abstrac tXMLDocumentParser.emptyElement(AbstractXMLDocumen tParser.java:180)
at com.sun.org.apache.xerces.internal.impl.XMLDocumen tFragmentScannerImpl.scanStartElement(XMLDocumentF ragmentScannerImpl.java:1343)
at com.sun.org.apache.xerces.internal.impl.XMLDocumen tFragmentScannerImpl$FragmentContentDriver.next(XM LDocumentFragmentScannerImpl.java:2756)
at com.sun.org.apache.xerces.internal.impl.XMLDocumen tScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLDocumen tFragmentScannerImpl.scanDocument(XMLDocumentFragm entScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Co nfiguration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Co nfiguration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLPars er.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.Abstrac tSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserI mpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at org.apache.commons.digester.Digester.parse(Digeste r.java:1666)
at net.sf.navigator.menu.MenuRepository.load(MenuRepo sitory.java:202)
at net.sf.navigator.menu.MenuContextListener.contextI nitialized(MenuContextListener.java:62)
at org.apache.catalina.core.StandardContext.listenerS tart(StandardContext.java:4723)
at org.apache.catalina.core.StandardContext$1.call(St andardContext.java:5226)
at org.apache.catalina.core.StandardContext$1.call(St andardContext.java:5221)
at java.util.concurrent.FutureTask$Sync.innerRun(Futu reTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.jav a:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.run Task(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
App A is a Spring 3.1 / Spring Integration 2.1.1 webapp
App B is a Spring 2.5.6 webapp (which I intend to convert eventually to the same framework as A, but will involve a fair amount of effort)
When App B attempts to start first, the above error occurs and App B ends in a stopped state. If I then click the 'start' button on the tomcat manager it works fine from that point. I can simulate this on my development setup by simply removing App A. App B attempts to start, the error occurs, I click the start button and it continues successfully.
I know from many posts there is not a supported way to enforce web app start order.
As far as I can tell it appears to be related to when the log4j initializes, if the required jars are not already loaded by the class loader, I get the error. Originally, the log4j.properties file was in the $CATALINA_HOME/lib directory, but because the differing spring version I don't want potentially conflicting jars at the tomcat level. So, I pulled the log4j configuration into the respective web apps. Now that the log4j configuration is in the web app, why do I still have the error if all the dependent jars are available? If I go back to a regular log4j appender configuration I do not have this problem, but I need to have the AmqpAppender as I am using the spring-integration web app (App A) for aggregating logs from App A, App B, and many other applications including Erlang applications, Grails applications, all of which are using RabbitMQ (App A is doing many other things as well). And everything is working great except this one glitch with the startup.
I have tried various incantations in App B of delaying the ThreadPoolTaskExecutor (because I am guessing that is where the log events are occurring during startup), but that doesn't seem that should be required as the AmqpAppender should have the necessary jars on hand in the WEB-INF/lib. And, my incantations are not working anyway. The frustrating part is once I manually force the start of App B, everything works wonderfully.
I am worried that part of the problem is maybe dependencies of AmqpAppender on Spring 3.1, but if that is the case why does it work at all even if I force the start, or even if App A is there and started first? Upgrading App B to Spring 3.1 / spring-integration 2.1.1 is not an option in the short term.
I have looked all around for more examples of how to use AmqpAppender properly, and have not found anything yet that helps me identify the errors of my ways.
Any constructive suggestions welcome.


Reply With Quote
