You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Steve Storey <ss...@gmail.com> on 2021/05/23 21:40:00 UTC

tomcat-embed-el JAR appears to violate EL spec causing ClassNotFoundException's

Hi there,

I've run into a problem trying to deploy an web application on Wildfly that
includes the tomcat-embed-el JAR (which is now the default EL for Spring
Boot 2.5 applications). The spec at
https://docs.oracle.com/javaee/7/api/javax/el/ExpressionFactory.html#newInstance--
says:

> 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.

but the tomcat-embed-el.jar file (as of 9.0.31 - "Add a META-INF/services
entry to jasper-el.jar so that the Expression Language implementation can
be discovered via the services API. (markt)") has the following file
content:

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

org.apache.el.ExpressionFactoryImpl

and thus having the licence header violates the spec. When the class loader
situation means that a non-Tomcat javax.el.ExpressionFactory is resolving
which implementation to use (which happens in Wildfly but judging by
Google, also several other app servers), then it fails with a trace with
the following sort of root cause:

Caused by: java.lang.ClassNotFoundException: # Licensed to the Apache
Software Foundation (ASF) under one or more from [Module
"deployment.services-boot.war" from Service Module Loader]
        at
org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255)
        at
org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
        at
org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
        at
org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
        at javax.el.api@2.0.0.Final
//javax.el.FactoryFinder.newInstance(FactoryFinder.java:48)
        ... 30 common frames omitted

In this specific case, it's the JBoss spec implementation at
https://github.com/jboss/jboss-jakarta-el-api_spec/blob/master/api/src/main/java/org/jboss/el/cache/FactoryFinderCache.java#L99
which reads the first line only, but the RI also does the same:
https://github.com/javaee/el-spec/blob/master/api/src/main/java/javax/el/FactoryFinder.java#L154
so it's the Tomcat ExpressionFactory that appears to be more tolerant than
the specification allows rather than the others being buggy?

Assuming you agree that it's a spec violation, do I raise a bugzilla myself
or does one of the Tomcat developers? Would an acceptable solution be to
simply move the licence header to be _after_ the first line ?

regards,

Steve

-- 
Steve Storey

e: sstorey@gmail.com

Re: tomcat-embed-el JAR appears to violate EL spec causing ClassNotFoundException's

Posted by Mark Thomas <ma...@apache.org>.
On 23/05/2021 22:40, Steve Storey wrote:

<snip/>

> The spec at
> https://docs.oracle.com/javaee/7/api/javax/el/ExpressionFactory.html#newInstance--
> says:
> 
>> Use the Services API (as detailed in the JAR specification).

The above is the key part.

> 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.

The above is a (very) inaccurate summary of the Services API. I'll get 
that sentence removed from the API Javadoc shortly.

> but the tomcat-embed-el.jar file (as of 9.0.31 - "Add a META-INF/services
> entry to jasper-el.jar so that the Expression Language implementation can
> be discovered via the services API. (markt)") has the following file
> content:
> 
> # Licensed to the Apache Software Foundation (ASF) under one or more
> # contributor license agreements.  See the NOTICE file distributed with
> # this work for additional information regarding copyright ownership.
> # The ASF licenses this file to You under the Apache License, Version 2.0
> # (the "License"); you may not use this file except in compliance with
> # the License.  You may obtain a copy of the License at
> #
> #     http://www.apache.org/licenses/LICENSE-2.0
> #
> # Unless required by applicable law or agreed to in writing, software
> # distributed under the License is distributed on an "AS IS" BASIS,
> # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> # See the License for the specific language governing permissions and
> # limitations under the License.
> 
> org.apache.el.ExpressionFactoryImpl
> 
> and thus having the licence header violates the spec.

No it doesn't. Please read the Services API specification.

> When the class loader
> situation means that a non-Tomcat javax.el.ExpressionFactory is resolving
> which implementation to use (which happens in Wildfly but judging by
> Google, also several other app servers), then it fails with a trace with
> the following sort of root cause:
> 
> Caused by: java.lang.ClassNotFoundException: # Licensed to the Apache
> Software Foundation (ASF) under one or more from [Module
> "deployment.services-boot.war" from Service Module Loader]

Then you need to raise a bug for any application server that behaves 
this way as it is not following the Services API specification.

> In this specific case, it's the JBoss spec implementation at
> https://github.com/jboss/jboss-jakarta-el-api_spec/blob/master/api/src/main/java/org/jboss/el/cache/FactoryFinderCache.java#L99
> which reads the first line only,

Then you need to raise a bug with JBoss.

> but the RI also does the same:
> https://github.com/javaee/el-spec/blob/master/api/src/main/java/javax/el/FactoryFinder.java#L154

That is not the current reference implementation. The current reference 
implementation is:

https://github.com/eclipse-ee4j/el-ri/blob/master/api/src/main/java/jakarta/el/FactoryFinder.java#L93

If you review the history for that file you'll find this:

https://github.com/eclipse-ee4j/el-ri/issues/118

and this:

https://github.com/eclipse-ee4j/el-ri/commit/6075bc9


> so it's the Tomcat ExpressionFactory that appears to be more tolerant than
> the specification allows rather than the others being buggy?

Nope. Tomcat is specification compliant and the others are buggy.

> Assuming you agree that it's a spec violation,

I (speaking for the Tomcat developers on this point) do not agree.

> do I raise a bugzilla myself or does one of the Tomcat developers?

In this case, neither. You need to raise a bug with JBoss and any other 
app server where you have observed this behaviour.

> Would an acceptable solution be to
> simply move the licence header to be _after_ the first line ?

No. The acceptable solution is for the buggy app servers to fix their EL 
implementation.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org