Problem with el-api in Eclipse/Maven/Tomcat
javaRecently I have worked a lot on Java Web projects and today I got strange exceptions like this:
java.lang.LinkageError: loader constraint violation:
when resolving interface method "javax.servlet.jsp.JspApplicationContext.addELResolver(Ljavax/el/ELResolver;)V"
the class loader
(instance of org/apache/catalina/loader/WebappClassLoader)
of the current class, com/sun/faces/config/ConfigureListener,
and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class,
javax/servlet/jsp/JspApplicationContext, have different Class objects
for the type javax/el/ELResolver used in the signature
The origin was a little helper method that should lookup a String value in the expression language context:
private String getStringELValue(final String el) {
String result = "";
FacesContext fc = FacesContext.getCurrentInstance();
if (fc != null) {
String value = fc.getApplication().evaluateExpressionGet(fc, el, String.class);
if (value != null && !value.isEmpty()) {
result = value;
}
}
return result;
}
This methods depends on classes from the el-api.jar. This jar is provided by tomcat per default so you don't have to provide it with your application but to be able to compile (and test) the code with maven you have to specify the dependency in your project's pom.xml:
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
Line 5 (<scope>provided</scope>
) is important in this dependency definition because it tells maven to use the
el-api.jar to compile and test the application but not to put it in the WEB-INF/libs folder of the resulting
web-application because this jar is already provided by the server.
After a lot of investigation I found out that the maven-plugin of eclipse doesn't care about this scope declaration. The result is that there are 2 copies of some classes on the classpath which causes the exception mentioned above.
The solution was to install the m2e-wtp plugin. As the name suggests this plugin does some kind of integration between maven and the web tools platform (wtp). After installing this plugin you have to choose "Update Project Configuration" in the maven sub-menu of your project. After this, everything was working perfectly. Maven was able to build the application and run all tests and tomcat was able to deploy and run the application without any exceptions.
After installing the plugin I got some red crosses on my projects telling me that there are still some problems. The reason for this was a wrong compiler setting. It seems that the new maven plugin tells the projects that they are of java version 1.5 and not 1.6 as it should be. The solution was to explicitly configure the compiler setting in the pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>