java.lang.NoClassDefFoundError: javax/el/ELManager



我正在使用Spring Tool Suite在Spring中开发Web应用程序。如果我使用 IDE 在那里构建应用程序并将其部署到提供的 Pivotal tc 服务器上,它可以正常工作。但是,如果我进行手动"mvn 干净包"构建并尝试将其部署到独立的 Tomcat 服务器(使用最新的 Tomcat 7(,它会引发以下异常:

2017-08-23 15:24:13 WARN  AnnotationConfigWebApplicationContext:551 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerAdapter' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Factory method 'requestMappingHandlerAdapter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcValidator' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/el/ELManager
2017-08-23 15:24:13 ERROR DispatcherServlet:502 - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerAdapter' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Factory method 'requestMappingHandlerAdapter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcValidator' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/el/ELManager

经过进一步检查,它确实抱怨上面几行没有装载罐子:

sie 23, 2017 3:24:12 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive D:Apache-Tomcat-7.0webappsTestApp-0.0.1-SNAPSHOT.war
sie 23, 2017 3:24:12 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(D:Apache-Tomcat-7.0webappsTestApp-0.0.1-SNAPSHOTWEB-INFlibel-api-2.2.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
sie 23, 2017 3:24:12 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(D:Apache-Tomcat-7.0webappsTestApp-0.0.1-SNAPSHOTWEB-INFlibjavax.servlet-api-3.1.0.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
sie 23, 2017 3:24:12 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(D:Apache-Tomcat-7.0webappsTestApp-0.0.1-SNAPSHOTWEB-INFlibtomcat-el-api-8.0.21.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
2017-08-23 15:24:13 INFO  ContextLoader:304 - Root WebApplicationContext: initialization started

我的绒球.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.exmaple.mvc</groupId>
<artifactId>TestApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<exclusions>
<exclusion>
<artifactId>jms</artifactId>
<groupId>javax.jms</groupId>
</exclusion>
<exclusion>
<artifactId>jmxri</artifactId>
<groupId>com.sun.jmx</groupId>
</exclusion>
<exclusion>
<artifactId>jmxtools</artifactId>
<groupId>com.sun.jdmk</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.1.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

此行为的原因是什么,我该如何解决此问题?

编辑更多信息:

javax.servlet-api添加<scope>provided</scope>似乎可以修复有关开始时未加载javax.servlet-api的警告。el-api的问题仍然存在。

我已经检查了 tomcat/lib 目录,它已经包含el-api.jar,这可能就是为什么它告诉我它不会加载我在 pom.xml 中列出的目录。问题是,添加<scope>provided</scope>也不能解决它。无论我做什么,它仍然抱怨给了我同样的java.lang.NoClassDefFoundError: javax/el/ELManager错误。

溶液

除了上面编辑中关于javax.servlet-api的部分之外,el-api的问题在于我在 7 版中运行了 Tomcat 7el-apijar 2.2。缺少的类是在el-api 3.0中引入的。在Tomcat 8(使用el-api 3.0 jar(中运行相同的Web应用程序可以正常工作。

你错过了作为依赖关系的javax.el-api。加:

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

到你的绒球.xml

Hibernate Validator 6.x -> Bean Validation 2.0 (JSR 380( -> EL3.0

Hibernate Validator 5.x -> Bean Validation 1.1 (JSR 349( -> EL2.2

Bean Validation 1.0 (JSR 303( -> (我不确定(

所以,它也会影响其他版本(Tomcat,JDK,JSP,servlet(

比如tomcat7,如果要使用Hibernate验证器,应该使用Hibernate验证器5.x、el 2.2(以及servlet 3.0、jsp 2.2和JDK 6+(

将休眠验证器降级到版本5,它将在Tomcat 7中正常工作。 就我而言,我将下一个依赖项添加到我的pom中:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.3.Final</version>
</dependency>

或者您可以将较新的 el-api.jat 添加到 tomcat lib 文件夹中。

請參閱 Hibernate 驗證 "無法初始化 javax.el.ExpressionFactory" 錯誤

<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b08</version>
</dependency>

我正在使用Tomcat 7.0.9,由于我的公司官僚主义而无法更改为任何较新的版本。将EL作为依赖项导入也没有解决它。

在Tomcat的根文件夹->lib中,我用新的3.0(来自本地.m2repositoryjavaxeljavax.el-api3.0.0(替换了旧的el-api(它的2.2版本(。然后,正确隔离 tomcat 的依赖项(如此处所示(使我的 WAR 在 Tomcat 7.0.9 中正确部署

为那些拥有 Tomcat 7 并尝试应用所选答案的人添加我的答案。

如果添加依赖项对您没有帮助,并且您继续获得

java.lang.NoClassDefFoundError: javax/el/ELManager

这是因为 Tomcat 7 不允许你用包中的对象加载更现代javax.*罐子。它将打印到日志中:

Jakarta.el-3.0.3.jar - 罐子未加载。请参阅 Servlet 规范 3.0 的第 10.7.2 节。违规类:javax/el/Expression.class

解决方案是升级您的Tomcat或将hibernate-validator降级到最新的5.x版本。另一个(从我的 POV 中不太喜欢(选项是尝试替换 tomcat7/lib 文件夹中的 jar。

就我而言, 注释掉了这种依赖关系,

<!-- <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.8.Final</version>
</dependency> -->

并添加

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

这解决了我的问题

尝试以下操作:

  • 添加javax.eljavax.el-api到pom中.xml正如其他人提到的那样
  • 如果你有不同的类加载器(就像使用 OSGi 时经常出现的情况一样(,你需要暂时将上下文设置为保存实现的上下文。结束通话方式:

    ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
    try {
    Class<?> currentClass = this.getClass(); // or any class that is in a bundle with the dependency 
    Thread.currentThread().setContextClassLoader(currentClass.getClassLoader());
    // execute library call
    } finally {
    Thread.currentThread().setContextClassLoader(originalClassLoader); // back to original context
    }
    
  • 将服务添加到 META-INF/services/

  • 将属性添加到 $java.home/lib/el.properties
  • 将系统属性与工厂 ID 一起使用

当库通过>ELManager.newInstance(..)>FactoryFinder.find(..)实例化ExpressionFactory时,它有几种策略来查找实现。调用按如下方式硬编码:

public static ExpressionFactory newInstance(Properties properties) {
return (ExpressionFactory) FactoryFinder.find(
"javax.el.ExpressionFactory", "com.sun.el.ExpressionFactoryImpl", properties);
}

有关更多信息,请参阅javax.el.FactoryFinder.find(..)来源

最新更新