Okay, after further digging, here's where I'm at:

According to the specification (
https://download.oracle.com/javaee-archive/el-spec.java.net/users/att-0034/EL3.0.PFD.RC1.pdf),
section 1.22 suggests that if we have an import (which it seems we do --
legacy scriptlets code), that an expression containing a class name will be
resolved against the static members of the class.

So, as to why it is different between the two environments, maybe it's as
Rob S suggested (a classpath issue of some sort) -- I will continue looking
in this direction....

On Mon, Feb 7, 2022 at 5:07 PM Robert Turner <rtur...@e-djuster.ca> wrote:

> Yep -- I can use the same WAR in both cases, and it's a .class file in the
> WAR.
>
> I've also just figured out that if I rename the attribute from "class1" to
> "cl1", it works -- so it's something to do with the attribute name matching
> the class name.
>
> On Mon, Feb 7, 2022 at 5:05 PM Rob Sargent <rsarg...@xmission.com> wrote:
>
>>
>>
>> On 2/7/22 14:50, Robert Turner wrote:
>> > All
>> >
>> > I'm hoping that someone can point me in the right direction as this
>> issue
>> > has been baffling me all day, and I'm starting to run out of ideas of
>> what
>> > to look at next.
>> >
>> > The logic below is working without issue until I move our test
>> environment
>> > into a Docker container. I'm using the same Tomcat version, and the same
>> > JDK in both the container and the non-container environments.
>> >
>> >
>> > I've got some EL in a JSP page, for example (simplified):
>> >
>> >   <p>${class1.field}</p>
>> >
>> >
>> > And an attribute is set on the page context as follows:
>> >
>> > final package1.Class1 objectValue = ...; // either value object of
>> Class1
>> > or null
>> > pageContext.setAttribute("class1", objectValue);
>> >
>> >
>> > Now, when objectValue is pointing to a valid object, everything is okay.
>> > But when objectValue is null, this is where things get peculiar (and I
>> get
>> > both a working and non-working behaviour in the different environments).
>> >
>> > I can easily work around the issue by changing the EL to:
>> >
>> >    <p>${not empty class1 ? class1.field : ''$}</p>
>> >
>> > But it is my understanding that EL should handle nulls on it's own, and
>> > this shouldn't be necessary.
>> >
>> >
>> > In the failure situation in the docker container, I'm seeing a
>> > NoClassDefFoundError exception for "package1/Class1" below [1] during
>> the
>> > JSP page "rendering". Things work fine outside the docker container.
>> >
>> >
>> > It might be worth noting that in my case, the attribute name is of the
>> same
>> > name as the actual class (with the first letter being lowercase for the
>> > attribute instead of uppercase in the class).
>> >
>> > Note that I've also replaced my actual package name and class names with
>> > "package1" and "Class1", and the attribute name with "class", but they
>> > translate 1-to-1 as in what I've provided here and do not use reserved
>> > names.
>> >
>> >
>> > I've done a bit of digging into the EL scope resolution code in Tomcat,
>> and
>> > I'm suspecting it might be related to how it chooses the scope of the
>> > object. Possibly related to maybe looking for static aspects of the
>> class,
>> > or something like that. After reviewing the Servlet / JSP / EL
>> > documentation, I also haven't found anything obvious that would suggest
>> > what the problem might be.
>> >
>> > Hopefully someone has encountered this before and can nudge me in the
>> right
>> > direction.
>> >
>> > Thanks in advance,
>> >
>> > Robert
>> >
>> >
>> >
>> > [1]
>> > Caused by: java.lang.NoClassDefFoundError: package1/Class1 (wrong name:
>> > package1/class1)
>> > at java.base/java.lang.ClassLoader.defineClass1(Native Method)
>> > at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
>> > at
>> >
>> java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
>> > at
>> >
>> org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2478)
>> > at
>> >
>> org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:870)
>> > at
>> >
>> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1371)
>> > at
>> >
>> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1215)
>> > at javax.el.ImportHandler.findClass(ImportHandler.java:477)
>> > at javax.el.ImportHandler.resolveClass(ImportHandler.java:421)
>> > at
>> >
>> javax.servlet.jsp.el.ScopedAttributeELResolver.getValue(ScopedAttributeELResolver.java:85)
>> > at
>> org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:124)
>> > at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:93)
>> > at org.apache.el.parser.AstValue.getValue(AstValue.java:136)
>> > at org.apache.el.parser.AstFunction.getValue(AstFunction.java:188)
>> > at
>> org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
>> > at
>> >
>> org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:692)
>> > at
>> >
>> And you're sure package1 is on the classpath of the docker version?
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
>> For additional commands, e-mail: users-h...@tomcat.apache.org
>>
>>

Reply via email to