0

All,

I built a sample app using spring-boot, maven and it worked fine in my IDE using mvn spring-boot:run. But, when I attempt to deploy the app as a WAR(mvn clean install) in Tomcat 7 I get the following error. Please help me find the reason for the issue.

**INFO: validateJarFile(C:\_tools\apache-tomcat-7.0.96\webapps\spring-server-2.1.8.RELEASE\WEB-INF\lib\tomcat-embed-el-9.0.24.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class Oct 16, 2019 2:31:57 PM org.apache.catalina.core.ContainerBase addChildInternal
SEVERE: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-server-2.1.8.RELEASE]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1018)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:994)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2020)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)**

Here's my POM file.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.service.data</groupId>
    <artifactId>spring-server</artifactId>
    <packaging>war</packaging>
    <name>dev-tools-server</name>
    <description>Spring Backend to access Tandem SQL/MX</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>       
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

And this is my class file

@SpringBootApplication
public class SpringServerApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringServerApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringServerApplication.class, args);
    }
}
Thulasi
  • 126
  • 3
  • 19
  • Within this pom.xml, mvn clean install can not deploy the WAR into Tomcat7 – Yugerten Oct 16 '19 at 19:33
  • Well, it looks like the embedded Tomcat hasn't been removed from the classpath, even with you overriding the default scope with 'provided' in your POM.. Have you tried to run `mvn clean install` again? – Matheus Oct 16 '19 at 20:09
  • @Yugerten Sorry for not describing it properly. I ran **mvn clean install** to generate the WAR under target directory, which I manually dropped it under tomcat's webapps folder. And, I get stuck at this error when trying to run the startup.bat – Thulasi Oct 16 '19 at 20:26
  • Hi @MatheusCirillo, yes I have been using mvn clean install but I still see the error while deploying the WAR on tomcat. – Thulasi Oct 16 '19 at 20:28
  • @Thulasi_G Can you add some log untile "Caused by: java.....". First, i suggest to use another maven building plugin instead spring-boot-maven-plugin; Next, if you use Servlet.3.x. add this javax.servlet javax.servlet-api 3.0.1 provided – Yugerten Oct 16 '19 at 21:20
  • Spring Boot 2.1 requires at least tomcat 8. As it depends on Spring 5.x which has a mimimal servlet api 3.1 dependency. Tomcat 8.0 is the first to provide that. Running it on tomcat 7 wont't work. So either upgrade tomcat or downgrade Spring Boot to 1.5 (the 2.x range depends on Spring 5.x which depends on Servlet API 3.1+). – M. Deinum Oct 17 '19 at 06:12

2 Answers2

1

Please, in your pom.xml, try to remove this:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>  

And replace this:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

by this:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

And try again.

This makes sure that you're excluding the embedded Tomcat from the dependency tree in your project.

UPDATE

Add the Servet API as provided to your classpath. The error in the coments happens because the tomcat (which has the servlet API implementation and specification as transitive dependency) has been removed, so there's no Servlet API available on your classpath

Add the 3.0.1 Servlet API specification as you're using Tomcat 7

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
Matheus
  • 3,058
  • 7
  • 16
  • 37
  • I tried this but I got another reference problem. Received **Error:(9, 8) java: cannot access javax.servlet.ServletException class file for javax.servlet.ServletException not found** And my SpringBoot code with imports looks like this `import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class SpringServerApplication extends SpringBootServletInitializer { ........... }` Please let me know if you know why this fails.. – Thulasi Oct 16 '19 at 21:45
  • @Thulasi_G, try to add javax.servlet javax.servlet-api 3.0.1 provided – Yugerten Oct 16 '19 at 21:54
  • Answer updated. Add the 3.0.1 version, as its Tomcat 7. (My mistake on saying 4.0.1.. Tomcat 7 doesn't support Servlet 4.0.1) – Matheus Oct 16 '19 at 21:59
  • The servlet-api is already provided byu the tomcat starter, and because that is provided it won't be added. – M. Deinum Oct 17 '19 at 06:08
0

You cannot run a Spring Boot 2.x application on Tomcat 7. Due to the simple fact that Spring Boot 2.x depends on Spring Framework 5.x which has a minimal Servlet API requirement for version 3.1 (see the Whats New In Spring 5).

You need at least Tomact 8.5 to run it (8.0 in theory but that has been superseded by 8.5).

To fix use Tomcat 8.5 or downgrade to the Spring Boot 1.5 line.

See also: Using Spring Boot 2.0 with Tomcat 7.0.82

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Thanks for your help! I moved to Tomcat 8.5.47 and set jre_home then I am able to deploy the war file. Also, I didn't exclude the tomcat dependency rather used it as a dependency with scope = provided – Thulasi Oct 17 '19 at 20:16