gradle-tomcat-plugin icon indicating copy to clipboard operation
gradle-tomcat-plugin copied to clipboard

RFE: Support web apps with custom ClassLoaders

Open vyazelenko opened this issue 8 years ago • 0 comments

Currently gradle-tomcat-plugin always uses org.apache.catalina.loader.WebappLoader as ClassLoader for the web app (see BaseTomcat7xPlusImpl.groovy#L48 for Tomcat 7/8 and Tomcat6xServer.groovy#L56 for Tomcat 6). This does not work if web app specifies custom ClassLoader to be used as part of its context.xml, e.g.:

<Context>
    <Loader loaderClass="test.CustomClassLoader" delegate="false" />
</Context>

I've create sample project to reproduce this issue https://github.com/vyazelenko/gradle-tomcat-plugin-custom-classloader. When I run ./gradlew tomcatRun in this project I get the following error:

./gradlew tomcatRun
:compileJava
:processResources UP-TO-DATE
:classes
:custom-classloader:compileJava
:custom-classloader:processResources UP-TO-DATE
:custom-classloader:classes
:custom-classloader:jar
:tomcatRunEnd event threw exception
java.lang.ClassNotFoundException: org.apache.tomcat.util.descriptor.web.ServletDef
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
        at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:355)
        at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:145)
        at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:956)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1783)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2970)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1451)
        at org.apache.tomcat.util.descriptor.web.WebXmlParser.parseWebXml(WebXmlParser.java:120)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1116)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:780)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:305)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Parse error in application web.xml file at file:/P:/Projects/oss/gradle-tomcat-plugin-custom-classloader/src/main/webapp/WEB-INF/web.xml
org.xml.sax.SAXParseException; systemId: file:/P:/Projects/oss/gradle-tomcat-plugin-custom-classloader/src/main/webapp/WEB-INF/web.xml; lineNumber: 9; columnNumber: 15; Error at (9, 15) : org.apache.tomcat.util.descriptor.web.ServletDef
        at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:1908)
        at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:1940)
        at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:959)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1783)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2970)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1451)
        at org.apache.tomcat.util.descriptor.web.WebXmlParser.parseWebXml(WebXmlParser.java:120)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1116)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:780)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:305)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.util.descriptor.web.ServletDef
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
        at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:355)
        at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:145)
        at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:956)
        ... 25 more
Occurred at line 9 column 15
Marking this application unavailable due to previous error(s)
One or more components marked the context as not correctly configured
Context [/gradle-tomcat-plugin-custom-classloader] startup failed due to previous errors

JDBC driver de-registration failed for web application [gradle-tomcat-plugin-custom-classloader]
java.lang.NullPointerException
        at org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc(WebappClassLoaderBase.java:1609)
        at org.apache.catalina.loader.WebappClassLoaderBase.clearReferences(WebappClassLoaderBase.java:1544)
        at org.apache.catalina.loader.WebappClassLoaderBase.stop(WebappClassLoaderBase.java:1496)
        at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:446)
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:224)
        at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5517)
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:224)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:159)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Started Tomcat Server
The Server is running at http://localhost:8080/gradle-tomcat-plugin-custom-classloader

However if I comment out context.xml#L3 I can start web app without error. But of course it will not run properly as it expects test.CustomClassLoader to be used, i.e. the java.lang.IllegalStateException: Invalid ClassLoader used: WebappClassLoader will be thrown: errorduetowrongclassloader

If proper ClassLoader will be used then servlet should print the following message: okmessage

vyazelenko avatar Feb 29 '16 15:02 vyazelenko