How to fix the error:
java.lang.IllegalArgumentException: The main resource set specified [C:\temp\myApp.jar] is not valid
in an Embedded Tomcat application?
I believe I am doing something wrong with the context path but I couldn't figure out how to set it up. Starting the application throw Eclipse work as expected but when I try to run from command prompt I get the error below. I pasted below the two main ways I have tried, App3 and App4 (the error is the same via command prompt). I guess it is not showing error in Eclipse because there must be some pre-defined parameter related to Context that it is making the application run on Eclipse but crashing while triggered from Command Prompt. I have already checked and I am using exactly same JDK.
I believe the problem is with context because, even when it runs throw Eclipse with second tentative (App4), if I check C:\temp, there is no war at all over there.
One tentative (without setAppBase):
import java.io.File;
import java.net.URISyntaxException;
import javax.servlet.ServletException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
public class App3 {
public static void main(String[] args) throws ServletException,
LifecycleException, URISyntaxException {
String runningJarPath = App.class.getProtectionDomain().getCodeSource() .getLocation().toURI().getPath().replaceAll("\\\\", "/");
String contextPath = "/";
File rootF = new File(runningJarPath);
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(".");
tomcat.addWebapp(contextPath, rootF.getAbsolutePath());
tomcat.start();
tomcat.getServer().await();
}
}
Other tentative (with setAppBase to especific folder):
import java.io.File;
import java.net.URISyntaxException;
import javax.servlet.ServletException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
public class App4 {
public static void main(String[] args) throws URISyntaxException,
ServletException, LifecycleException {
String runningJarPath = App4.class.getProtectionDomain()
.getCodeSource().getLocation().toURI().getPath()
.replaceAll("\\\\", "/");
String contextPath = "/";
File rootF = new File(runningJarPath);
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir("C\\temp");
//the next line was added along with ***Edited 2
tomcat.addWebapp(tomcat.getHost(), "/App", "C:\\temp\\");
//the next two lines commented was commented along with ***Edited 2
//tomcat.addWebapp(contextPath, rootF.getAbsolutePath());
tomcat.getHost().setAppBase("C\\temp");
tomcat.start();
//tomcat.addWebapp(tomcat.getHost(), "/App", "C:\\temp\\");//
tomcat.getServer().await();
}
}
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app >
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>App</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>App</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Logs from Eclipse:
Mar 02, 2016 3:11:25 PM org.apache.catalina.core.StandardContext setPath
WARNING: A context path must either be an empty string or start with a '/' and do not end with a '/'. The path [/] does not meet these criteria and has been changed to []
Mar 02, 2016 3:11:26 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Mar 02, 2016 3:11:27 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Mar 02, 2016 3:11:27 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Mar 02, 2016 3:11:27 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Mar 02, 2016 3:11:27 PM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
INFO: No global web.xml found
Mar 02, 2016 3:11:38 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Mar 02, 2016 3:11:39 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Mar 02, 2016 3:11:39 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [203] milliseconds.
Mar 02, 2016 3:11:40 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'App'
Mar 02, 2016 3:11:40 PM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'App': initialization started
Mar 02, 2016 3:11:40 PM org.springframework.web.context.support.XmlWebApplicationContext prepareRefresh
INFO: Refreshing WebApplicationContext for namespace 'App-servlet': startup date [Wed Mar 02 15:11:40 CST 2016]; root of context hierarchy
Mar 02, 2016 3:11:40 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/App-servlet.xml]
Mar 02, 2016 3:11:41 PM org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping registerHandler
INFO: Mapped URL path [/upload] onto handler 'fileUploadController'
...
Mar 02, 2016 3:11:41 PM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'App': initialization completed in 1609 ms
Mar 02, 2016 3:11:41 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Mar 02, 2016 3:11:45 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Mar 02, 2016 3:11:45 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Error from command prompt:
C:\Program Files\Java\jdk1.8.0_45\jre>java -jar C:\temp\myApp.jar
Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
Picked up _JAVA_OPTIONS: -Xrunjvmhook -Xbootclasspath/a:C:\PROGRA~2\HP\QUICKT~1\
bin\JAVA_S~1\classes;C:\PROGRA~2\HP\QUICKT~1\bin\JAVA_S~1\classes\jasmine.jar
Mar 02, 2016 3:15:55 PM org.apache.catalina.core.StandardContext setPath
WARNING: A context path must either be an empty string or start with a '/' and d
o not end with a '/'. The path [/] does not meet these criteria and has been changed to []
Mar 02, 2016 3:15:56 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Mar 02, 2016 3:15:56 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Mar 02, 2016 3:15:56 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Mar 02, 2016 3:15:56 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Mar 02, 2016 3:15:57 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException:
Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
POM.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myCompany.myApp.batchs</groupId>
<artifactId>AuthFileUpload</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>AuthFileUpload</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>8.0.32</tomcat.version>
<java.version>1.8</java.version>
<maven.compiler.plugin.version>2.1</maven.compiler.plugin.version>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<finalName>embeddedApp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>com.myCompany.myApp.batchs.AuthFileUpload.App4</mainClass>
<name>App4</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
*** Edited 1 - the entire log relate to the tentative 1 (App3)
C:\Program Files\Java\jdk1.8.0_45\jre>java -jar C:\temp\myApp.jar
Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
Picked up _JAVA_OPTIONS: -Xrunjvmhook -Xbootclasspath/a:C:\PROGRA~2\HP\QUICKT~1\
bin\JAVA_S~1\classes;C:\PROGRA~2\HP\QUICKT~1\bin\JAVA_S~1\classes\jasmine.jar
Mar 02, 2016 7:53:13 PM org.apache.catalina.core.StandardContext setPath
WARNING: A context path must either be an empty string or start with a '/' and d
o not end with a '/'. The path [/] does not meet these criteria and has been cha
nged to []
Mar 02, 2016 7:53:14 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Mar 02, 2016 7:53:14 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSele
ctor
INFO: Using a shared selector for servlet write/read
Mar 02, 2016 7:53:14 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Mar 02, 2016 7:53:14 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Mar 02, 2016 7:53:15 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException:
Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].Stand
ardContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.ja
va:916)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java
:871)
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: org.apache.catalina.LifecycleException: Failed to start component [St
andardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
... 6 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [or
g.apache.catalina.webresources.StandardRoot@791d05e7]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
at org.apache.catalina.core.StandardContext.resourcesStart(StandardConte
xt.java:4928)
at org.apache.catalina.core.StandardContext.startInternal(StandardContex
t.java:5058)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 6 more
Caused by: java.lang.IllegalArgumentException: The main resource set specified [
C:\temp\myApp.jar] is not valid
at org.apache.catalina.webresources.StandardRoot.createMainResourceSet(S
tandardRoot.java:723)
at org.apache.catalina.webresources.StandardRoot.startInternal(StandardR
oot.java:684)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 9 more
Mar 02, 2016 7:53:15 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException:
Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.ja
va:916)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.
java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.StandardService.startInternal(StandardServic
e.java:441)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.
java:769)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:345)
at com.MyCompany.myApp.batchs.AuthFileUpload.App3.main(App3.java:28)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [St
andardEngine[Tomcat].StandardHost[localhost]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
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: org.apache.catalina.LifecycleException: A child container failed duri
ng start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.ja
va:924)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java
:871)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 6 more
Exception in thread "main" org.apache.catalina.LifecycleException: Failed to sta
rt component [StandardServer[-1]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:345)
at com.MyCompany.myApp.batchs.AuthFileUpload.App3.main(App3.java:28)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [St
andardService[Tomcat]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.
java:769)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 2 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [St
andardEngine[Tomcat]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
at org.apache.catalina.core.StandardService.startInternal(StandardServic
e.java:441)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 4 more
Caused by: org.apache.catalina.LifecycleException: A child container failed duri
ng start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.ja
va:924)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.
java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 6 more
C:\Program Files\Java\jdk1.8.0_45\jre>
*** edited 2 entire log relate to tentative 2 (App4)
C:\Program Files\Java\jdk1.8.0_45\jre>java -jar C:\temp\myApp.jar
Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
Picked up _JAVA_OPTIONS: -Xrunjvmhook -Xbootclasspath/a:C:\PROGRA~2\HP\QUICKT~1\
bin\JAVA_S~1\classes;C:\PROGRA~2\HP\QUICKT~1\bin\JAVA_S~1\classes\jasmine.jar
Mar 02, 2016 8:04:09 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Mar 02, 2016 8:04:09 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSele
ctor
INFO: Using a shared selector for servlet write/read
Mar 02, 2016 8:04:09 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Mar 02, 2016 8:04:09 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Mar 02, 2016 8:04:10 PM org.apache.catalina.core.StandardContext postWorkDirecto
ry
WARNING: Failed to create work directory [C:\Program Files\Java\jdk1.8.0_45\jre\
C\temp\work\Tomcat\localhost\App] for context [/App]
Mar 02, 2016 8:04:10 PM org.apache.catalina.startup.ContextConfig getDefaultWebX
mlFragment
INFO: No global web.xml found
Mar 02, 2016 8:04:18 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Mar 02, 2016 8:04:18 PM org.apache.catalina.util.SessionIdGeneratorBase createSe
cureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRN
G] took [187] milliseconds.
Mar 02, 2016 8:04:18 PM org.apache.jasper.EmbeddedServletOptions <init>
SEVERE: The scratchDir you specified: C:\Program Files\Java\jdk1.8.0_45\jre\C\te
mp\work\Tomcat\localhost\App is unusable.
Mar 02, 2016 8:04:18 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
*** Added in 2016/03/03 at 4:30PM (Brasilia Time UTC-03:00)
public static void main(String[] args) throws IOException,
ServletException, LifecycleException {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
String strBaseDIr = "C:\\temp\\"; // Files.createTempDirectory("tomcat-basedir").toString();
tomcat.setBaseDir(strBaseDIr);
// Option 1 - default-doc-base - doesn't work even in Eclipse
// String strWebApp =
// Files.createTempDirectory("default-doc-base").toString();
// strWebApp is C:\Users\myUser\AppData\Local\Temp
// tomcat.addWebapp("", strWebApp);
// Option 2 - it works in Eclipse but "HTTP Status 404 - /upload" when
// started from java -jar
// tomcat.addWebapp("",
// "C:\\STS\\wsRestTemplate\\AuthFileUpload\\target\\classes");
// Option 3 - passing empty path as you wrote
// "... the trick is to pass an empty folder ..."
// same issue - "HTTP Status 404 - /upload" when started from java -jar
// tomcat.addWebapp("", "");
// Option 4 - the executable jar was placed in C:\Temp
// same issue - "HTTP Status 404 - /upload" when started from java -jar
tomcat.addWebapp("/", "C:\\temp\\myApp.jar");
tomcat.start();
tomcat.getServer().await();
}
App-servlet.xml
<context:component-scan base-package="com.mycompany.myapp.batchs.AuthFileUpload" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
The doc base path must resolve to a folder and in your case is set to the current running jar.
Given that you are running a jar, and the API does not accept a null
docbase, the trick is to pass an empty folder (so no content is accessible from it):
public class App {
public static void main(String[] args) throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(Files.createTempDirectory("tomcat-basedir").toString());
tomcat.addWebapp("/", Files.createTempDirectory("yourwebapp-doc-base").toString());
tomcat.start();
tomcat.getServer().await();
}
}
You can see here a more complex example, allowing running over jar/war or source folder, and automatically opening the browser after startup.