问题
I didn't manage to use the Jersey linking support with Google App Engine, I'm getting these exceptions when trying to access the application :
Caused by: javax.el.ELException: Could not find expression factory class
...
Caused by: java.lang.ClassNotFoundException: de.odysseus.el.ExpressionFactoryImpl
As specified in the documentation, I put this in the Jersey servlet section of the web.xml :
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.server.linking.LinkFilter</param-value>
</init-param>
I also add the jersey-server-linking-1.13.jar to the WEB-INF/lib directory of my project.
I tried to add el-api.jar first, then juel-2.1.0.jar to the WEB-INF/lib directory but I'm still getting these errors.
I'd like to know if someone could give me some hints about the way to deal with this. When I don't use the Jersey linking jar, everything is working as expected.
回答1:
I had a similar problem with my GAE app. It was working fine with el-api and el-impl but started asking for de.odysseus.el.ExpressionFactoryImpl as development progressed. I made the switch but when I added JUEL to my pom.xml, I got the same error as John Prince (java.security.AccessControlException).
The solution for GAE users is to use JUEL 2.2.7.
At the time of this writing, 2.2.7 is not available in maven central. However, you can find it on
<repository>
<id>repo-id</id>
<name>repo-name</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
and link with whatever you need from
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-api</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-impl</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-spi</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependen
Source: https://github.com/beckchr/juel/issues/73
回答2:
The issue is due to de.odysseus.el.ExpressionFactoryImpl class not being found. I will assume that you have added the jars as you have mentioned to the WEB-INF\lib folder.
I would suggest that you view the JAR files via theProject Explorer , simple expand them in Eclipse and see if you can find the de.odysseus.el.ExpressionFactoryImpl class in ny of the JAR files that you have added.
回答3:
I "solved" the problem by adding "juel" and "juel-impl" as dependencies of my project (we're using Maven; if you're doing it manually, you might have to figure out exactly what those projects contain).
However, as soon as I did that, I started getting a different exception:
java.security.AccessControlException: access denied (java.io.FilePermission C:\Program Files (x86)\Java\jdk1.6.0_33\jre\lib\el.properties read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:289)
...
I'm pretty sure that's because it's running afoul of GAE restrictions.
I noticed in the original ClassNotFound exception it was trying to use the URLClassLoader; I'm also wondering if that problem was ultimately a GAE issue as well.
At this point, it seems like Jersey linking support isn't compatible with GAE.
回答4:
This issue is (or rather was) due to a missing implementation of the Unified Expression Language. The EL API defines a static method that looks up an implementation of the ExpressionFactory
class. There are various ways to define which implementation is to be used:
- Use the Services API (as detailed in the JAR specification). If a resource with the name of META-INF/services/javax.el.ExpressionFactory exists, then its first line, if present, is used as the UTF-8 encoded name of the implementation class.
- Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the java.util.Properties.load(InputStream) method, and it contains an entry whose key is "javax.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class.
- Use the javax.el.ExpressionFactory system property. If a system property with this name is defined, then its value is used as the name of the implementation class.
- Use a platform default implementation.
(Source: http://docs.oracle.com/javaee/7/api/javax/el/ExpressionFactory.html#newInstance())
App Engine appears to have defined JUEL as default implementation but does not provide the respective packages.
In order to solve this, you need to (1) provide EL API and implementation packages and (2) use one of the above ways to link it. See https://stackoverflow.com/a/19814199/2099217 for details.
来源:https://stackoverflow.com/questions/12393589/jersey-linking-support-with-google-app-engine-issue