You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Garret Wilson (Jira)" <ji...@apache.org> on 2022/11/29 00:25:00 UTC

[jira] [Updated] (JEXL-388) v3.3-SNAPSHOT doesn't find public getter as property

     [ https://issues.apache.org/jira/browse/JEXL-388?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Garret Wilson updated JEXL-388:
-------------------------------
    Description: 
In my [Guise Mummy|https://github.com/globalmentor/guise-mummy] static site generator I'm using JEXL to interpret the built-in [Mesh Expression Language|https://github.com/globalmentor/guise-mummy/tree/main/mesh] (MEXL). Everything was working fine with JEXL 3.1. In fact the entire [Guise Mummy web site|https://guise.io/mummy/] itself was produced using Guise Mummy with MEXL on top of JEXL. But when I upgrade to JEXL 3.3-SNAPSHOT, a couple of unit tests break. In particular, the new version doesn't seem to find a public getter method on a custom public class as a property.

In the Mesh templating, we have an {{mx:each}} attribute (similar to JSP or Thymeleaf) which loops through and replicates some HTML element (e.g. an {{<li>}} inside an {{<ul>}}) for each value in a list. It assigns each value, one at a time, to a variable {{it}} in the context. That is working fine. But on each iteration it also assigns {{iter}} in the context, with the value being an instance of [{{MeshIterator}}|https://github.com/globalmentor/guise-mummy/blob/main/mesh/src/main/java/io/guise/mesh/MeshIterator.java]. That object has, among other things, {{getCurrent()}}:

{code:java}
/**
 * Returns the current item. This will be the result of the last successful call to {@link #next()}.
 * @throws NoSuchElementException if iteration has not yet started.
 * @return The current item.
 */
public Object getCurrent() { ... }
{code}

To make a long story short, the MEXL expression should be able to use {{iter.current}} to get the value, but it's not finding it. I traced through the new code, and it's finding the {{MeshIterator}} instance just fine and assigning it to {{iter}}. The problem is that JEXL's {{ClassMap}} (probably inside {{create()}}) is not finding and caching {{getCurrent()}} mapped to the {{current}} property.

It looks like {{Permissions.allow()}} for method {{MeshIterator.getCurrent()}}, is falling through to the end and returning {{explicit[0]}}, which happens to be {{false}}. It looks like this comes from {{wildcardAllow(Class<?> clazz)}}, which eventually calls {{wildcardAllow(Set<String> allowed, String name)}}. There's what I presume to be a set of allowed packages. Is that new? Do we have to explicitly provide a list of allowed packages for property discovery via reflection now?

To reproduce this:

# Clone [Guise Mummy 0.5.3|https://github.com/globalmentor/guise-mummy/releases/tag/v0.5.3].
# In the overall project {{pom.xml}}, change the version of {{org.apache.commons:commons-jexl3}} from {{<version>3.1</version>}} to {{<version>3.3-SNAPSHOT</version>}}. (You'll also need to add the {{https://repository.apache.org/content/repositories/snapshots/}} repository in the POM.)
# Run {{mvn clean verify}}.

You'll see that {{io.guise.mesh.GuiseMeshTest.testMxEachWithIterVar()}} will fail because {{iter.current}} can't be found.

  was:
In my [Guise Mummy|https://github.com/globalmentor/guise-mummy] static site generator I'm using JEXL to interpret the built-in [Mesh Expression Language|https://github.com/globalmentor/guise-mummy/tree/main/mesh] (MEXL). Everything was working fine with JEXL 3.1. In fact the entire [Guise Mummy web site|https://guise.io/mummy/] itself was produced using Guise Mummy with MEXL on top of JEXL. But when I upgrade to JEXL 3.3-SNAPSHOT, a couple of unit tests break. In particular, the new version doesn't seem to find a public getter method on a custom public class as a property.

In the Mesh templating, we have an {{mx:each}} attribute (similar to JSP or Thymeleaf) which loops through and replicates some HTML element (e.g. an {{<li>}} inside an {{<ul>}}) for each value in a list. It assigns each value, one at a time, to a variable {{it}} in the context. That is working fine. But on each iteration it also assigns {{iter}} in the context, with the value being an instance of [{{MeshIterator}}|https://github.com/globalmentor/guise-mummy/blob/main/mesh/src/main/java/io/guise/mesh/MeshIterator.java]. That object has, among other things, {{getCurrent()}}:

{code:java}
/**
 * Returns the current item. This will be the result of the last successful call to {@link #next()}.
 * @throws NoSuchElementException if iteration has not yet started.
 * @return The current item.
 */
public Object getCurrent() { ... }
{code}

To make a long story short, the MEXL expression should be able to use {{iter.current}} to get the value, but it's not finding it. I traced through the new code, and it's finding the {{MeshIterator}} instance just fine and assigning it to {{iter}}. The problem is that JEXL's {{ClassMap}} (probably inside {{create()}}) is not finding and caching {{getCurrent()}} mapped to the {{current}} property.

It looks like {{Permissions.allow()}} for method {{MeshIterator.getCurrent()}}, is falling through to the end and returning {{explicit[0]}}, which happens to be {{false}}. It looks like this comes from {{wildcardAllow(Class<?> clazz)}}, which eventually calls {{wildcardAllow(Set<String> allowed, String name)}}. There's what I presume to be a set of allowed packages. Is that new? Do we have to explicitly provide a list of allowed packages for property discovery via reflection now?

To reproduce this:

# Clone [Guise Mummy 0.5.3|https://github.com/globalmentor/guise-mummy/releases/tag/v0.5.3].
# In the overall project {{pom.xml}}, change the version of {{org.apache.commons:commons-jexl3}} from {{<version>3.1</version>}} to {{<version>3.3-SNAPSHOT</version>}}. (You'll also need to add the {{https://repository.apache.org/content/repositories/snapshots/}} repository in the POM.}
# Run {{mvn clean verify}}.

You'll see that {{io.guise.mesh.GuiseMeshTest.testMxEachWithIterVar()}} will fail because {{iter.current}} can't be found.


> v3.3-SNAPSHOT doesn't find public getter as property
> ----------------------------------------------------
>
>                 Key: JEXL-388
>                 URL: https://issues.apache.org/jira/browse/JEXL-388
>             Project: Commons JEXL
>          Issue Type: Bug
>    Affects Versions: 3.3
>         Environment: Java 17; Windows 10
>            Reporter: Garret Wilson
>            Priority: Major
>
> In my [Guise Mummy|https://github.com/globalmentor/guise-mummy] static site generator I'm using JEXL to interpret the built-in [Mesh Expression Language|https://github.com/globalmentor/guise-mummy/tree/main/mesh] (MEXL). Everything was working fine with JEXL 3.1. In fact the entire [Guise Mummy web site|https://guise.io/mummy/] itself was produced using Guise Mummy with MEXL on top of JEXL. But when I upgrade to JEXL 3.3-SNAPSHOT, a couple of unit tests break. In particular, the new version doesn't seem to find a public getter method on a custom public class as a property.
> In the Mesh templating, we have an {{mx:each}} attribute (similar to JSP or Thymeleaf) which loops through and replicates some HTML element (e.g. an {{<li>}} inside an {{<ul>}}) for each value in a list. It assigns each value, one at a time, to a variable {{it}} in the context. That is working fine. But on each iteration it also assigns {{iter}} in the context, with the value being an instance of [{{MeshIterator}}|https://github.com/globalmentor/guise-mummy/blob/main/mesh/src/main/java/io/guise/mesh/MeshIterator.java]. That object has, among other things, {{getCurrent()}}:
> {code:java}
> /**
>  * Returns the current item. This will be the result of the last successful call to {@link #next()}.
>  * @throws NoSuchElementException if iteration has not yet started.
>  * @return The current item.
>  */
> public Object getCurrent() { ... }
> {code}
> To make a long story short, the MEXL expression should be able to use {{iter.current}} to get the value, but it's not finding it. I traced through the new code, and it's finding the {{MeshIterator}} instance just fine and assigning it to {{iter}}. The problem is that JEXL's {{ClassMap}} (probably inside {{create()}}) is not finding and caching {{getCurrent()}} mapped to the {{current}} property.
> It looks like {{Permissions.allow()}} for method {{MeshIterator.getCurrent()}}, is falling through to the end and returning {{explicit[0]}}, which happens to be {{false}}. It looks like this comes from {{wildcardAllow(Class<?> clazz)}}, which eventually calls {{wildcardAllow(Set<String> allowed, String name)}}. There's what I presume to be a set of allowed packages. Is that new? Do we have to explicitly provide a list of allowed packages for property discovery via reflection now?
> To reproduce this:
> # Clone [Guise Mummy 0.5.3|https://github.com/globalmentor/guise-mummy/releases/tag/v0.5.3].
> # In the overall project {{pom.xml}}, change the version of {{org.apache.commons:commons-jexl3}} from {{<version>3.1</version>}} to {{<version>3.3-SNAPSHOT</version>}}. (You'll also need to add the {{https://repository.apache.org/content/repositories/snapshots/}} repository in the POM.)
> # Run {{mvn clean verify}}.
> You'll see that {{io.guise.mesh.GuiseMeshTest.testMxEachWithIterVar()}} will fail because {{iter.current}} can't be found.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)