I have a Tomcat Embedded
project that I want to run using a fat jar
with Shadow Plugin
My Gradle in build.gradle.kts
configuration looks like this for the parts related to Shadow:
plugins {
...
id("com.github.johnrengelman.shadow") version "7.1.2"
}
...
tasks {
"build" {
dependsOn(shadowJar)
}
shadowJar {
mergeServiceFiles()
manifest.inheritFrom(jar.get().manifest) // This makes the shadowJar (produced by jar task) runnable..
// This allows java to run the generated .jar file recognizing the Main class for this project.
manifest.attributes["Main-Class"] = "some.project.package.Main"
manifest.attributes["Implementation-Version"] = version
}
}
My Main.main
method for Tomcat embedded looks like this:
public static void main(String[] args) throws Exception {
// Application context path
String contextPath = "/";
String webappDirLocation = "src/main/webapp/";
Tomcat tomcat = new Tomcat();
tomcat.setPort(PORT);
Context context = tomcat.addWebapp(
contextPath, new File(webappDirLocation).getAbsolutePath()
);
// Define and bind web.xml file location.
File configFile = new File(webappDirLocation + "WEB-INF/web.xml");
context.setConfigFile(configFile.toURI().toURL());
tomcat.start();
System.out.println("Server");
System.out.println("listening on");
System.out.println("http://" + tomcat.getHost().getName() + ":" + tomcat.getConnector().getPort() + "/" );
tomcat.getServer().await();
}
gradle build
now generates a fat jar
in the /build/libs
folder. However, when I run it using java -jar project_name-version-all.jar
, it then tries to run some.project.package.Main
and fails with this error:
SEVERE: Missing context.xml: [file:/home/user/repo/build/libs/src/main/webapp/WEB-INF/web.xml]
java.io.FileNotFoundException: /home/user/repo/build/libs/src/main/webapp/WEB-INF/web.xml (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111)
at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86)
at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189)
at org.apache.catalina.startup.ContextConfig.processContextConfig(ContextConfig.java:631)
at org.apache.catalina.startup.ContextConfig.contextConfig(ContextConfig.java:606)
at org.apache.catalina.startup.ContextConfig.init(ContextConfig.java:849)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:400)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:137)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:173)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Sep 25, 2022 5:35:22 PM org.apache.catalina.startup.ContextConfig processContextConfig
SEVERE: Parse error in context.xml for []
java.io.FileNotFoundException: /home/user/repo/build/libs/src/main/webapp/WEB-INF/web.xml (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111)
at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86)
at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:150)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:861)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1525)
at org.apache.catalina.startup.ContextConfig.processContextConfig(ContextConfig.java:649)
at org.apache.catalina.startup.ContextConfig.contextConfig(ContextConfig.java:606)
at org.apache.catalina.startup.ContextConfig.init(ContextConfig.java:849)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:400)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:137)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:173)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Sep 25, 2022 5:35:22 PM org.apache.catalina.core.StandardContext resourcesStart
SEVERE: Error starting static Resources
java.lang.IllegalArgumentException: Document base [/home/user/repo/build/libs/src/main/webapp] does not exist or is not a readable directory
at org.apache.naming.resources.FileDirContext.setDocBase(FileDirContext.java:136)
at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:5256)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5448)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Sep 25, 2022 5:35:22 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Error in resourceStart()
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1227)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:804)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.apache.catalina.LifecycleException: Error in resourceStart()
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5449)
... 7 more
Sep 25, 2022 5:35:22 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: A child container failed during start
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1227)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:300)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:444)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:744)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:469)
at some.project.package.Main.main(Main.java:29)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1238)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:804)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Error in resourceStart()
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1227)
... 8 more
Caused by: org.apache.catalina.LifecycleException: Error in resourceStart()
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5449)
... 7 more
Exception in thread "main" org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1238)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:300)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:444)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:744)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:469)
at some.project.package.Main.main(Main.java:29)
Caused by: java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: A child container failed during start
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1227)
... 8 more
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1238)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:804)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1689)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1679)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Error in resourceStart()
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1227)
... 8 more
Caused by: org.apache.catalina.LifecycleException: Error in resourceStart()
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5449)
... 7 more
This error does not happen when I do gradle run
. In that case the code runs normally.
From the error I can clearly see that it is looking for the file in my local machine's file system when it should be looking for it in the packaged fat jar
.
When I opened the fat jar I couldn't find the webapp folder, neither could I find my project's web.xml
or context.xml
files.
Is there something I am missing to configure the Shadow plugin to export these locations into the fat jar
and to load them properly on the Main.main
method for Tomcat embedded
?