tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <jimi.hulleg...@svensktnaringsliv.se>
Subject RE: Intermittent ClassNotFoundException in Jasper EL evaluation
Date Thu, 10 Mar 2016 21:16:31 GMT
On Thursday, March 10, 2016 11:20 AM, markt@apache.org wrote:
> 
> > 3. Why is the problem not limited to the first request for a jsp page? 
> 
> Because EL imports may be dynamic so the EL has to be evaluated on execution.

I'm not really sure I follow you now. Can you explain what you mean with dynamic imports in
this regard? I can't see any mentioning of it in the specs (http://download.oracle.com/otn-pub/jcp/el-3_0-fr-eval-spec/EL3.0.FR.pdf).

Can you give a concrete example, where an EL expression element would need to be evaluated
as a potential class, again and again for each request?

Because the way I see it, "foo" in ${foo.bar} in some jsp page only needs to be evaluated
once. If "foo" corresponded to a class, matching one of the imports in the jsp, then this
lookup will not change unless the jsp code changes. And the same is true if the lookup failes
with a ClassNotFoundException. What am I missing?


> > 4. Why isn't the ClassNotFoundException logged by the ImportHandler?
> 
> Because it is expected and logging it provides no value to the user.

Well, I happen to disagree. :)
In our case, if we could see all these stacktraces in the log, by enabling DEBUG/TRACE log
level on the ImportHandler class for example, then we would quickly see just how big this
problem is (ie how often this happens), on what jsp pages it happens, and what EL expressions
cause it.

On my local machine, I was able to "catch" the ClassNotFoundException using a debug breakpoint
in my IDE, and using the breakpoint hit count I could see that this exception is thrown and
handled (ie ignored) by the ImportHandler 2700 times for a single request to the start page.



> The JavaEE specs are very big on backwards compatibility. 
> Therefore, the chances of changing the spec syntax to fix this are zero.

OK. Fair enough. I agree with you that backwards compatibility is important. But there are
ways to fix this while still keeping the backwards compatibility. For example by making it
possible to turn off this feature (globally, per webapp, or per jsp), where the default is
"on". Wouldn't you agree that such a change would be 100% backwards compatible? And at the
same time it would more or less solve this problem completely. Because people who experience
the mentioned problems could turn of this setting globally, and then only enable it for those
specific jsp pages where it is needed (and these pages would then be cleaned up, so that no
EL-references exist without specific scope unless they are known to never be null. Tada, problem
solved! =)

Actually... this wouldn't even need to be in the specifications... I can't see any harm in
a EL implementation introducing such settings on its own, before the specifications can "catch
up". That way you could basically introduce this fix in trunk right now, and have it tested
and out in a stable release in no time =)



On Thursday, March 10, 2016 1:24 PM, markt@apache.org wrote:
> 
> The issue is in ScopedAttributeELResolver.
> 
> ScopedAttributeELResolver checks the page/request/session/application context
> first and only if it doesn't find the attribute there does it try loading the class.

When debugging this in my IDE, I could see this in action. I also noticed that the ImportHandler
that performs the class lookup is fetched from the ELContext object. So if I could wrap that
object, I could simply return null in the method getImportHandler(), thus disabling this functionallity
and therefore solving the performance problem for us. But I couldn't find any way to wrap
the ELContext, for some reason. Can it be done, using standard code or config? Or can this
"import logic" be disabled some other way?

There really should be a way for users to disable this, if the functionallity is not used
and it just is causing problems. And, like I said above, that could be done without breaking
the specs. And an alternative way to the way above, could be like I mentioned before, to add
a configuration option that forces the class name to begin with a capital letter. That way
${Boolean.TRUE}, ${Integer.MAX_VALUE} and ${MyClass.myStaticField} would still work, while
${foo.bar} etc would simply be ignored. As long as the configuration option would default
to false (ie lower case first letter is allowed, as per the specification) it wouldn't break
the specification unless the user deliberately told it to (which is fine, right?).

It would be really nice to get your input on these suggestions. And if you don't like them,
could you explain why? If your opinion is "We need to stick 100% to the specification, and
never ever give even the expert user any way to override this, ever", then I would say that
such a view causes more harm than good. :)

Regards
/Jimi

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


Mime
View raw message