-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Thymeleaf to check for allowed method access of Java supertypes #474
Conversation
Thanks a lot for contributing, @jkuipers! |
Happy to add some tests. Note that this code is only exercised by the framework when you use Spring or OGNL expressions, but the required changes have to go in the core project. @fniephaus is it sufficient to simply add some tests that invoke the |
No need to pull in addition dependencies if you can invoke the code somehow directly, that is without accessing any private APIs reflectively or so. |
add5166
to
318fc39
Compare
I added tests. Note that I had to update the existing date-based test, because it failed on my local machine (which uses a Dutch locale) without an explicit format. |
e901560
to
960bf9a
Compare
Hey, is anything still missing that's causing this to stay open? I was hoping that this could get merged in its current state. |
960bf9a
to
cf575c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I order to approve or not, I need to understand a bit better why this is needed. This adds reflection metadata for all public methods of types from the JDK (guarded by the ExpressionUtils
access), which can be quite expensive. Is this really needed or can we narrow more the methods which would be accessed reflectively?
Hey, thanks for getting back to me. The Thymeleaf ExpressionUtils class is used when a template uses an expression (via Spring expression language or OGNL) to check whether that's an allowed call. It contains a hardcoded list of Java types for which it allows calls by reflectively iterating over all their declared methods and comparing the resulting names to the memberName that's being passed to the method.
Of course I cannot predict what declared methods of those types would be used in practice by all possible Thymeleaf users, so my PR is based on wanting the ExpressionUtils to simply behave the same as when running on a JVM. |
@melix Hey, did you manage to have a look at my explanation and the Thymeleaf code that this PR allows to work in a native image? Without this, most real-world applications using Thymeleaf will not work correctly, which is extra confusing since this repo does already contain reachability metadata for it (I had assumed that this would've worked out the box when I started to use this). In general I think that for a templating solution that relies on reflection it seems reasonable that some additional metadata is included, since you cannot predict what access templates will require, but in this particular case Thymeleaf even actively denies calls to common Java operations (esp. calls to collections, which are used all over the place in templates) without this metadata: it took me some time to figure this out and implement a fix in my own applications, it seems better to have this work out of the box and perhaps file an issue with the Thymeleaf team to optimize this for GraalVM in future releases so that the overhead can be reduced then. |
@jkuipers sorry for the late answer, I'm back from a break. The explanation makes sense to me. |
cf575c2
to
fd0b20f
Compare
To prevent Thymeleaf templates from accessing methods on built-in Java types that are not allowed, it ships with a list of allowed supertypes. Its org.thymeleaf.util.ExpressionUtils type has an isMemberAllowed method that calls getDeclaredMethods() on those types, so that needs to work for all these types in a native image. Without this addition neither Spring support (using SpEL expressions) nor OGNL-based expressions work correctly. Recent versions of Thymeleaf have expanded the list with two additional types, which is why the M2 version has 7 new entries while the RC1 / latest has 9. Obviously the tests don't cover these. For details, check out https://github.com/thymeleaf/thymeleaf/blob/3.1-master/lib/thymeleaf/src/main/java/org/thymeleaf/util/ExpressionUtils.java
fd0b20f
to
1b7af01
Compare
I'm a bit confused: I was assuming that that means that this can be merged, but the issue stays open and has been for two months now. Is anything else expected from my side? |
Thanks for your patience, I just merged it. |
What does this PR do?
To prevent Thymeleaf templates from accessing methods on built-in Java types that are not allowed, it ships with a list of allowed supertypes. Its
org.thymeleaf.util.ExpressionUtils
type has anisMemberAllowed
method that callsgetDeclaredMethods()
on those types, so that needs to work for all these types in a native image. This PR ensures that.Recent versions of Thymeleaf have expanded the list with two additional types, which is why the M2 version has 7 new entries while the RC1 / latest has 9. For details, check out
the source code.
Code sections where the PR accesses files, network, docker or some external service
None.
Checklist before merging