java.lang.NoClassDefFoundError:javax / el / ELManager

我正在使用Spring Tool Suite在Spring上开发一个webapp。 如果我使用IDE在提供的Pivotal tc服务器上构建和部署应用程序,它就可以正常工作。 但是,如果我执行手动“mvn clean package”构建并尝试将其部署到独立的Tomcat服务器(使用最新的Tomcat 7),则会引发以下exception:

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 

经过进一步检查,它确实抱怨几条线高于未加载jar子:

 sie 23, 2017 3:24:12 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive D:\Apache-Tomcat-7.0\webapps\TestApp-0.0.1-SNAPSHOT.war sie 23, 2017 3:24:12 PM org.apache.catalina.loader.WebappClassLoader validateJarFile INFO: validateJarFile(D:\Apache-Tomcat-7.0\webapps\TestApp-0.0.1-SNAPSHOT\WEB-INF\lib\el-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.0\webapps\TestApp-0.0.1-SNAPSHOT\WEB-INF\lib\javax.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.0\webapps\TestApp-0.0.1-SNAPSHOT\WEB-INF\lib\tomcat-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 

我的pom.xml:

  4.0.0 com.exmaple.mvc TestApp 0.0.1-SNAPSHOT war   org.springframework spring-core 4.3.10.RELEASE   org.springframework spring-webmvc 4.3.10.RELEASE   org.springframework spring-web 4.3.10.RELEASE   org.springframework spring-test 4.3.10.RELEASE   org.slf4j slf4j-log4j12 1.6.6   log4j log4j 1.2.17   jms javax.jms   jmxri com.sun.jmx   jmxtools com.sun.jdmk     jstl jstl 1.2   junit junit 4.12 test    org.mockito mockito-all 1.9.5 test    commons-lang commons-lang 2.3    org.hibernate hibernate-validator 6.0.1.Final   javax.servlet javax.servlet-api 3.1.0      org.apache.maven.plugins maven-compiler-plugin 3.1  1.8 1.8      

这种行为的原因是什么?我该如何解决这个问题?

编辑更多信息:

providedjavax.servlet-api似乎修复了关于javax.servlet-api未在开始时加载的警告。 el-api问题仍然存在。

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

除了上面关于javax.servlet-api的编辑部分之外, el-api javax.servlet-api的问题在于我在2.2版本中运行了一个带有el-api jar的Tomcat 7。 缺少的类在el-api 3.0中引入。 在Tomcat 8中运行相同的webapp(使用el-api 3.0 jar)可以正常运行。

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

  javax.el javax.el-api 3.0.0  

到你的pom.xml

请参阅Hibernatevalidation“无法初始化javax.el.E​​xpressionFactory”错误

使用

  org.glassfish javax.el 3.0.1-b08  

在我的情况下,注释掉这种依赖,

  

并补充说

   javax.el javax.el-api 3.0.0 provided  

这解决了我的问题

请尝试以下方法:

  • 像其他人提到的那样,将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
  • 将system属性与factoryId一起使用

当库通过> ELManager.newInstance(..) > ELManager.newInstance(..)实例化ExpressionFactory ,它有几种策略来查找实现。 这个电话硬编码如下:

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

有关详细信息,请参阅javax.el.FactoryFinder.find(..)源代码

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

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