Alex R
Alex R

Reputation: 926

How to create javax.el.ExpressionFactory in Google App Engine to use Hibernate Validator

I'm trying to upgrade to hibernate validator version 6 on my Google App Engine app, which needs javax.el, so I added org.glassfish:javax.el:jar:3.0.1-b10 to my dependencies.

However, this is not used:

In the local dev environment, I can create a new ExpressionFactory with ExpressionFactory.newInstance(). The ExpressionFactory is from the local Jetty installation jetty93/jetty-distribution/lib/apache-jsp/org.mortbay.jasper.apache-el-8.0.33.jar and it returns the implementation org.apache.el.ExpressionFactoryImpl from the same jar.

In the deployed GAE environment, the ExpressionFactory is from java8_runtime/runtime-shared.jar!/javax/el/ExpressionFactory.class but ExpressionFactory.newInstance() still tries to get a org.apache.el.ExpressionFactoryImpl, even though com.sun.el.ExpressionFactoryImpl is present.

In both environments, I can manually load a com.sun.el.ExpressionFactoryImpl from WEB-INF/lib/javax.el-3.0.1-b10.jar, so it is present in the classpath:

final Constructor<ExpressionFactoryImpl> constructor = com.sun.el.ExpressionFactoryImpl.class.getConstructor();
final ExpressionFactoryImpl expressionFactory = constructor.newInstance();

Upvotes: 1

Views: 521

Answers (1)

Alex R
Alex R

Reputation: 926

I finally solved it by adding a system property to appengine-web.xml:

<system-properties>
    <property name="javax.el.ExpressionFactory" value="com.sun.el.ExpressionFactoryImpl" />
</system-properties>

An other possibility could be to add the file 'META-INF/services/javax.el.ExpressionFactory' with the contents:

com.sun.el.ExpressionFactoryImpl

See also this answer

I didn't test the second method, but it has the highest priority in the source of apache-el ExpressionFactory, while the system property is only the third try.

Upvotes: 2

Related Questions