14

I want to deploy my application to a tomcat in version 7 and I get the following Exception java.lang.NoClassDefFoundError: javax/el/ELManager But if I try to deploy this application to tomcat version 8 it works fine.

Do you have any ideas how to fix this?

Why do i switch from tomcat 8 to 7? In the test environment was tomcat 8 in the repo and on the server it is tomcat7.

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>certplatform</groupId>
<artifactId>certplatform</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
      <source>1.8</source>
      <target>1.8</target>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
      <warSourceDirectory>WebContent</warSourceDirectory>
    </configuration>
  </plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring- 
core -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring- 
context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring- 
context-support -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring- 
webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web 
-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<!--https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/javax.servlet.jsp.jstl-api -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.5.0-b01</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.8.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.15.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.2.15.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.59</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.59</version>
</dependency>   

<!-- https://mvnrepository.com/artifact/javax.el/javax.el-api -->
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.el/el-api -->
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>el-api</artifactId>
    <version>2.2</version>
</dependency>   

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">

<display-name>spring-mvc-demo</display-name>

<!-- Spring MVC Configs -->

<!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-mvc-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Mister Lamp
  • 345
  • 1
  • 4
  • 13
  • 2
    The issue is caused by the fact that this class javax/el/ELManager is introduced in javax.el-api version 3.0. Tomcat 7 is coming with pre-bundled el-api 2.2 (which is missing the class) and it's picking that at runtime, instead of you el-api jar. Do you have access to the Tomcat? Can you upgrade it? – hovanessyan Mar 20 '18 at 13:20
  • Thanks for the information. It is possible to upgrade but then I loose the comfort that also tomcat will be updated at the next os update cycle. And yes I have access to the tomcat. – Mister Lamp Mar 20 '18 at 13:27
  • It's best if you can sync your dev/test/prod environments as close as possible. It makes much more sense to develop against Tomcat 8 in dev, when your test environment has Tomcat 8. As you found out Tomcat 7 and 8 servers comes with different set of libraries, so your code can behave differently against those different set of libraries. – hovanessyan Mar 20 '18 at 13:31
  • I totally agree to you. I naively assumed that the repos contain the same rpms, but I was wrong. Is there no possibility to solve this issue? – Mister Lamp Mar 20 '18 at 13:33
  • I've summarized the comments in an answer. – hovanessyan Mar 20 '18 at 13:36

2 Answers2

14

The issue is caused by the fact that this class javax/el/ELManager is introduced in el-api version 3.0.

Tomcat 7 is coming with pre-bundled el-api 2.2 (which is missing the class) and it's picking that at runtime, instead of your el-api jar.

Tomcat 8 has the el-api 3.0 and hence the javax/el/ELManager class is present.

It's best if you can sync your dev/test/prod environments as close as possible.

It makes much more sense to develop against Tomcat 8 in dev, when your test environment has Tomcat 8. As you found out Tomcat 7 and 8 servers comes with different set of libraries, so your code can behave differently against those different set of libraries.

hovanessyan
  • 30,580
  • 6
  • 55
  • 83
4

If you want to run your webapp on Tomcat 7 in production, then you should be using Tomcat 7 in your test environment.

What has happened is that you have accidentally introduced a dependency on the EL 3.0 APIs ... and included it in your POM file. It is working find on Tomcat 8. But on Tomcat 7, the platform supports EL 2.1. So when your app attempts to load the classfile for javax.el.ELManager ... it fails.

Solutions:

  • Upgrade your production platform to Tomcat 8
  • Downgrade your dev and test platforms to Tomcat 7, and eliminate any dependencies on the newer APIs from your codebase .

The Apache Tomcat Versions page lists the various spec versions for each of the major versions of Tomcat.


Is there no possibility to solve this issue?

If you were prepared to "butcher" the Tomcat 7 server, you might be able to replace the EL implementation with a newer one. But I would not try that, because 1) it may not work at all, and 2) the result is liable to be difficult to maintain. And you are liable to give your operations, quality assurance and/or security teams an apoplexy!

Is there no possibility to solve this issue with changes in the application?

AFAIK, there is no possibility.

I thought you could try replacing the EL dependency with this:

<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>

But it doesn't work. According to a comment from Alex:

"Adding the JAR to the application POM does not solve anything. Here its the message printed out by Tomcat bootstrap: "validateJarFile(C:\Software\apache-tomcat-7.0.99\webapps\leonardo-flows-services\WEB-INF\lib\javax.el-api-3.0.0.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class". It conflicts with its lib jar."

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    Adding the JAR to the application POM does not solve anything. Here its the message printed out by Tomcat bootstrap: "validateJarFile(C:\Software\apache-tomcat-7.0.99\webapps\leonardo-flows-services\WEB-INF\lib\javax.el-api-3.0.0.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class". It conflicts with its lib jar. – Alex Jan 22 '20 at 15:34
  • what is the solution apart from upgrade ? – sitakant Feb 18 '20 at 19:03
  • @sitakant - downgrade the test platform. – Stephen C Feb 18 '20 at 22:59