[jira] [Comment Edited] (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:comment-tabpanel=17641437#comment-17641437 ] Garret Wilson edited comment on JEXL-388 at 11/30/22 4:35 PM: -- {quote}… to restrict what JEXL can see using permissions …{quote} On the face of it that sounds reasonable. Where can I find the documentation for this, since this is a breaking change? {quote}Btw, any comment on JEXL-342?{quote} I'm not sure what comment you want. That was a feature request that is still open, even though a third party indicated they had added something to a modified fork of the library. In any case JEXL is pretty much stuck at the same place it was years ago, since v3.2.1 is completely broken because of JEXL-387, v3.3 is not released, and [there will be no v3.2.2 to fix the bug|https://issues.apache.org/jira/browse/JEXL-387?focusedCommentId=17640302=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17640302]. was (Author: garretwilson): {quote}… to restrict what JEXL can see using permissions …{quote} On the face of it that sounds reasonable. Where can I find the documentation for this, since this is a breaking change? {quote}Btw, any comment on JEXL-342?{quote} I'm not sure what comment you want. That was a feature request that is still open, even though a third party indicated they had added something to a modified fork of the library. > 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 > {{}} inside an {{}}) 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 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 {{3.1}} to > {{3.3-SNAPSHOT}}. (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)
[jira] [Commented] (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:comment-tabpanel=17641437#comment-17641437 ] Garret Wilson commented on JEXL-388: {quote}… to restrict what JEXL can see using permissions …{quote} On the face of it that sounds reasonable. Where can I find the documentation for this, since this is a breaking change? {quote}Btw, any comment on JEXL-342?{quote} I'm not sure what comment you want. That was a feature request that is still open, even though a third party indicated they had added something to a modified fork of the library. > 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 > {{}} inside an {{}}) 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 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 {{3.1}} to > {{3.3-SNAPSHOT}}. (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)
[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 {{}} inside an {{}}) 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 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 {{3.1}} to {{3.3-SNAPSHOT}}. (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 {{}} inside an {{}}) 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
[jira] [Created] (JEXL-388) v3.3-SNAPSHOT doesn't find public getter as property
Garret Wilson created JEXL-388: -- Summary: 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 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 {{}} inside an {{}}) 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 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 {{3.1}} to {{3.3-SNAPSHOT}}. (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)
[jira] [Commented] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17640295#comment-17640295 ] Garret Wilson commented on JEXL-387: 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 I'll have to back and trace through, which is a real pain. Maybe you would know offhand why {{wildcardAllow(Class clazz)}} is returning an array starting with {{false}} for permissions for a public class with a public getter? Oh, I see that in {{wildcardAllow(Set allowed, String name)}} there's what I presume to be a set of allowed packages. Is that new? Where can I find more information about that? Coming back to this current ticket, I guess v3.2.1 is just completely broken, huh? Can you release a hotfix? Or will we have to wait until some other version in the future to get off v3.1? > v3.2.1 breaks with logger-related NullPointerException > -- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:java} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) > at > org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) > at > org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) > at > org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) > at > org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) > at > org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) > at > org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) > at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) > at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) > ... 72 more > {noformat} > Here's the line in question inside {{ClassMap.populateWithClass(ClassMap > cache, Permissions permissions, Class clazz, Log log)}}: > {code:java} > if (pmi != null && pmi != CACHE_MISS && log.isDebugEnabled() && > !key.equals(new MethodKey(pmi))) { > {code} > For some reason your internal {{ClassMap}} class is being passed a {{Log}} > that is {{null}}. Looking up the stack trace,
[jira] [Commented] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17640291#comment-17640291 ] Garret Wilson commented on JEXL-387: [~ggregory], switching to the latest v3.3-SNAPSHOT stops the log-related {{NullPointerException}}. Most of the unit tests pass now. However a couple of other unit tests are now breaking. (Let me know if I should file a separate ticket.) 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 {{}} inside an {{}}) 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. This worked fine in earlier versions. You can reproduce it exactly as explained in the description, except using the {{-SNAPSHOT}} version you mentioned and running the {{GuiseMeshTest.testMxEachWithIterVar()}}. Did something change in the {{-SNAPSHOT}} version that would make it no longer recognize a public {{getCurrent()}} method as representing a readable {{current}} property? > v3.2.1 breaks with logger-related NullPointerException > -- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:java} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) > at > org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) > at > org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) > at >
[jira] [Updated] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-387: --- 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if you look in the stack trace, you'll see that the problem seems to be a deeper {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches and effectively ignores, making it look like the problem was a missing variable. {code:java} } catch (final Exception xany) { xcause = xany; } {code} Here's the real problem: {noformat} Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) at org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) at org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) at org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) at org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) at org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) at org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) ... 72 more {noformat} Here's the line in question inside {{ClassMap.populateWithClass(ClassMap cache, Permissions permissions, Class clazz, Log log)}}: {code:java} if (pmi != null && pmi != CACHE_MISS && log.isDebugEnabled() && !key.equals(new MethodKey(pmi))) { {code} For some reason your internal {{ClassMap}} class is being passed a {{Log}} that is {{null}}. Looking up the stack trace, it would appear this is coming from your {{Introspector}}. (There is a similar [error on Stack Overflow|https://stackoverflow.com/q/64927054] with no answers; I don't know if they are using JAXL.) * First, passing the {{Log}} around as a parameter is an antipattern. Logging is a cross-cutting concern; passing it around as a parameter is a bad idea. * I wish you were using {{SLF4J}} like practically everyone else instead of {{org.apache.commons.logging}}. * You shouldn't catch {{NullPointerException}} and turn it into a "normal" error condition, trying to say that a variable wasn't defined when really this was an internal error with the library. In any case, for some reason JEXL 3.2.1 isn't initializing its internal logging support. 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 {{3.1}} to {{3.2.1}}. # Run {{mvn clean verify}}. 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
[jira] [Updated] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-387: --- 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if you look in the stack trace, you'll see that the problem seems to be a deeper {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches and effectively ignores, making it look like the problem was a missing variable. {code:java} } catch (final Exception xany) { xcause = xany; } {code} Here's the real problem: {noformat} Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) at org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) at org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) at org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) at org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) at org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) at org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) ... 72 more {noformat} Here's the line in question inside {{ClassMap.populateWithClass(final ClassMap cache, final Permissions permissions, final Class clazz, final Log log)}}: {code:java} if (pmi != null && pmi != CACHE_MISS && log.isDebugEnabled() && !key.equals(new MethodKey(pmi))) { {code} For some reason your internal {{ClassMap}} class is being passed a {{Log}} that is {{null}}. Looking up the stack trace, it would appear this is coming from your {{Introspector}}. (There is a similar [error on Stack Overflow|https://stackoverflow.com/q/64927054] with no answers; I don't know if they are using JAXL.) * First, passing the {{Log}} around as a parameter is an antipattern. Logging is a cross-cutting concern; passing it around as a parameter is a bad idea. * I wish you were using {{SLF4J}} like practically everyone else instead of {{org.apache.commons.logging}}. * You shouldn't catch {{NullPointerException}} and turn it into a "normal" error condition, trying to say that a variable wasn't defined when really this was an internal error with the library. In any case, for some reason JEXL 3.2.1 isn't initializing its internal logging support. 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 {{3.1}} to {{3.2.1}}. # Run {{mvn clean verify}}. 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
[jira] [Comment Edited] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17640159#comment-17640159 ] Garret Wilson edited comment on JEXL-387 at 11/28/22 5:52 PM: -- To guide you through the project unit test, look in {{io.guise.mesh.JexlMexlEvaluatorTest}}. The "MEXL" interfaces are a very thin wrapper around JEXL, just in case Mesh wants to switch to a different expression engine in the future. An example unit test looks like this: {code:java} @Test public void shouldRetrieveMapValue() { final MeshContext context = new DefaultMeshContext(); context.setVariable("foo", Map.of("bar", 123)); assertThat(JexlMexlEvaluator.INSTANCE.evaluate(context, "foo.bar"), is(123)); } {code} You can't get much simpler than that. It works fine in JEXL 3.1, but breaks as described in JEXL 3.2.1. In {{JexlMexlEvaluator}} you'll see we create an instance of {{JexlEngine}} using {{new JexlBuilder().strategy(RESOLVER_STRATEGY).create()}}, where {{RESOLVER_STRATEGY}} is a {{JexlUberspect.PropertyResolver}} that knows how to get properties from [URF|https://urf.io/]. That's about all there is. Even those are irrelevant details, as the problem here stems from some internal logger not getting initialized. The question is: what did you change with your internal logger that suddenly makes me go through extra steps (as of yet unknown) in order to get it initialized? was (Author: garretwilson): To guide you through the project unit test, look in {{io.guise.mesh.JexlMexlEvaluatorTest}}. The "MEXL" interfaces are a very thin wrapper around JEXL, just in case Mesh wants to switch to a different expression engine in the future. An example unit test looks like this: {code:java} @Test public void shouldRetrieveMapValue() { final MeshContext context = new DefaultMeshContext(); context.setVariable("foo", Map.of("bar", 123)); assertThat(JexlMexlEvaluator.INSTANCE.evaluate(context, "foo.bar"), is(123)); } {code} You can't get much simpler than that. It works fine in JEXL 3.1, but breaks as described in JEXL 3.2.1. In {{JexlMexlEvaluator}} you'll see we create an instance of {{JexlEngine}} using {{new JexlBuilder().strategy(RESOLVER_STRATEGY).create()}}, where {{RESOLVER_STRATEGY}} is a {{JexlUberspect.PropertyResolver}} that knows how to get properties from [URF|https://urf.io/]. That's about all there is. Even those are irrelevant details, as the problem here stems from some internal logger not getting initialized. The question is: what did you change with your internal logger that suddenly makes me go through extra steps in order to get it initialized? > v3.2.1 breaks with logger-related NullPointerException > -- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:java} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at >
[jira] [Updated] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-387: --- 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if you look in the stack trace, you'll see that the problem seems to be a deeper {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches and effectively ignores, making it look like the problem was a missing variable. {code:java} } catch (final Exception xany) { xcause = xany; } {code} Here's the real problem: {noformat} Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) at org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) at org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) at org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) at org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) at org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) at org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) ... 72 more {noformat} For some reason your internal {{ClassMap}} class is being passed a {{Log}} that is {{null}}. Looking up the stack trace, it would appear this is coming from your {{Introspector}}. (There is a similar [error on Stack Overflow|https://stackoverflow.com/q/64927054] with no answers; I don't know if they are using JAXL.) * First, passing the {{Log}} around as a parameter is an antipattern. Logging is a cross-cutting concern; passing it around as a parameter is a bad idea. * I wish you were using {{SLF4J}} like practically everyone else instead of {{org.apache.commons.logging}}. * You shouldn't catch {{NullPointerException}} and turn it into a "normal" error condition, trying to say that a variable wasn't defined when really this was an internal error with the library. In any case, for some reason JEXL 3.2.1 isn't initializing its internal logging support. 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 {{3.1}} to {{3.2.1}}. # Run {{mvn clean verify}}. 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93
[jira] [Updated] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-387: --- 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if you look in the stack trace, you'll see that the problem seems to be a deeper {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches and effectively ignores, making it look like the problem was a missing variable. {code:java} } catch (final Exception xany) { xcause = xany; } {code} Here's the real problem: {noformat} Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) at org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) at org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) at org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) at org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) at org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) at org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) ... 72 more {noformat} For some reason your internal {{ClassMap}} class is being passed a {{Log}} that is {{null}}. Looking up the stack trace, it would appear this is coming from your {{Introspector}}. (There is a similar [error on Stack Overflowhttps://stackoverflow.com/q/64927054] with no answers; I don't know if they are using JAXL.) * First, passing the {{Log}} around as a parameter is an antipattern. Logging is a cross-cutting concern; passing it around as a parameter is a bad idea. * I wish you were using {{SLF4J}} like practically everyone else instead of {{org.apache.commons.logging}}. * You shouldn't catch {{NullPointerException}} and turn it into a "normal" error condition, trying to say that a variable wasn't defined when really this was an internal error with the library. In any case, for some reason JEXL 3.2.1 isn't initializing its internal logging support. 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 {{3.1}} to {{3.2.1}}. # Run {{mvn clean verify}}. 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93
[jira] [Updated] (JEXL-387) v3.2.1 breaks with logger-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-387: --- Summary: v3.2.1 breaks with logger-related NullPointerException (was: v3.2.1 breaks with log-related NullPointerException) > v3.2.1 breaks with logger-related NullPointerException > -- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:xml} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) > at > org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) > at > org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) > at > org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) > at > org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) > at > org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) > at > org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) > at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) > at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) > ... 72 more > {noformat} > For some reason your internal {{ClassMap}} class is being passed a {{Log}} > that is {{null}}. Looking up the stack trace, it would appear this is coming > from your {{Introspector}}. (There is a similar [error on Stack > Overflowhttps://stackoverflow.com/q/64927054] with no answers; I don't know > if they are using JAXL.) > * First, passing the {{Log}} around as a parameter is an antipattern. Logging > is a cross-cutting concern; passing it around as a parameter is a bad idea. > * I wish you were using {{SLF4J}} like practically everyone else instead of > {{org.apache.commons.logging}}. > * You shouldn't catch {{NullPointerException}} and turn it into a "normal" > error condition, trying to say that a variable wasn't defined when really > this was an internal error with the library. > In any case, for some reason JEXL 3.2.1 isn't initializing its internal > logging support. > 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 {{3.1}} to >
[jira] [Comment Edited] (JEXL-387) v3.2.1 breaks with log-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17640159#comment-17640159 ] Garret Wilson edited comment on JEXL-387 at 11/28/22 5:47 PM: -- To guide you through the project unit test, look in {{io.guise.mesh.JexlMexlEvaluatorTest}}. The "MEXL" interfaces are a very thin wrapper around JEXL, just in case Mesh wants to switch to a different expression engine in the future. An example unit test looks like this: {code:java} @Test public void shouldRetrieveMapValue() { final MeshContext context = new DefaultMeshContext(); context.setVariable("foo", Map.of("bar", 123)); assertThat(JexlMexlEvaluator.INSTANCE.evaluate(context, "foo.bar"), is(123)); } {code} You can't get much simpler than that. It works fine in JEXL 3.1, but breaks as described in JEXL 3.2.1. In {{JexlMexlEvaluator}} you'll see we create an instance of {{JexlEngine}} using {{new JexlBuilder().strategy(RESOLVER_STRATEGY).create()}}, where {{RESOLVER_STRATEGY}} is a {{JexlUberspect.PropertyResolver}} that knows how to get properties from [URF|https://urf.io/]. That's about all there is. Even those are irrelevant details, as the problem here stems from some internal logger not getting initialized. The question is: what did you change with your internal logger that suddenly makes me go through extra steps in order to get it initialized? was (Author: garretwilson): To guide you through the project unit test, look in {{io.guise.mesh.JexlMexlEvaluatorTest}}. The "MEXL" interfaces are a very thin wrapper around JEXL, just in case Mesh wants to switch to a different expression engine in the future. An example unit test looks like this: {code:java} @Test public void shouldRetrieveMapValue() { final MeshContext context = new DefaultMeshContext(); context.setVariable("foo", Map.of("bar", 123)); assertThat(JexlMexlEvaluator.INSTANCE.evaluate(context, "foo.bar"), is(123)); } {code} You can't get much simpler than that. It works fine in JEXL 3.1, but breaks as described in JEXL 3.2.1. > v3.2.1 breaks with log-related NullPointerException > --- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:xml} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) > at > org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) > at > org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) > at >
[jira] [Commented] (JEXL-387) v3.2.1 breaks with log-related NullPointerException
[ https://issues.apache.org/jira/browse/JEXL-387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17640159#comment-17640159 ] Garret Wilson commented on JEXL-387: To guide you through the project unit test, look in {{io.guise.mesh.JexlMexlEvaluatorTest}}. The "MEXL" interfaces are a very thin wrapper around JEXL, just in case Mesh wants to switch to a different expression engine in the future. An example unit test looks like this: {code:java} @Test public void shouldRetrieveMapValue() { final MeshContext context = new DefaultMeshContext(); context.setVariable("foo", Map.of("bar", 123)); assertThat(JexlMexlEvaluator.INSTANCE.evaluate(context, "foo.bar"), is(123)); } {code} You can't get much simpler than that. It works fine in JEXL 3.1, but breaks as described in JEXL 3.2.1. > v3.2.1 breaks with log-related NullPointerException > --- > > Key: JEXL-387 > URL: https://issues.apache.org/jira/browse/JEXL-387 > Project: Commons JEXL > Issue Type: Bug > 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.2.1, the unit tests break. The MEX+JEXL error > message says "Error in MEXL expression `foo.bar`: > io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if > you look in the stack trace, you'll see that the problem seems to be a deeper > {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches > and effectively ignores, making it look like the problem was a missing > variable. > {code:xml} > } catch (final Exception xany) { > xcause = xany; > } > {code} > Here's the real problem: > {noformat} > Caused by: java.lang.NullPointerException: Cannot invoke > "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) > at > org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) > at > org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) > at > org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) > at > org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) > at > org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) > at > org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) > at > org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) > at > org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) > at > org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) > at > org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) > at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) > at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) > ... 72 more > {noformat} > For some reason your internal {{ClassMap}} class is being passed a {{Log}} > that is {{null}}. Looking up the stack trace, it would appear this is coming > from your {{Introspector}}. (There is a similar [error on Stack > Overflowhttps://stackoverflow.com/q/64927054] with no answers; I don't know > if they are using JAXL.) > * First, passing the {{Log}} around as a parameter is an antipattern. Logging > is a cross-cutting concern; passing it around as a parameter is a bad idea. > * I wish you were using {{SLF4J}} like practically everyone else instead of > {{org.apache.commons.logging}}.
[jira] [Created] (JEXL-387) v3.2.1 breaks with log-related NullPointerException
Garret Wilson created JEXL-387: -- Summary: v3.2.1 breaks with log-related NullPointerException Key: JEXL-387 URL: https://issues.apache.org/jira/browse/JEXL-387 Project: Commons JEXL Issue Type: Bug Environment: Java 17; Windows 10 Reporter: Garret Wilson 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.2.1, the unit tests break. The MEX+JEXL error message says "Error in MEXL expression `foo.bar`: io.guise.mesh.JexlMexlEvaluator.evaluate:93 undefined property 'bar'", but if you look in the stack trace, you'll see that the problem seems to be a deeper {{NullPointerException}} which {{InterpreterBase.getAttribute(…)}} catches and effectively ignores, making it look like the problem was a missing variable. {code:xml} } catch (final Exception xany) { xcause = xany; } {code} Here's the real problem: {noformat} Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "log" is null at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithClass(ClassMap.java:296) at org.apache.commons.jexl3.internal.introspection.ClassMap.populateWithInterface(ClassMap.java:270) at org.apache.commons.jexl3.internal.introspection.ClassMap.create(ClassMap.java:229) at org.apache.commons.jexl3.internal.introspection.ClassMap.(ClassMap.java:100) at org.apache.commons.jexl3.internal.introspection.Introspector.getMap(Introspector.java:315) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:146) at org.apache.commons.jexl3.internal.introspection.Introspector.getMethod(Introspector.java:133) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discoverGet(PropertyGetExecutor.java:107) at org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor.discover(PropertyGetExecutor.java:42) at org.apache.commons.jexl3.internal.introspection.Uberspect.getPropertyGet(Uberspect.java:263) at org.apache.commons.jexl3.internal.InterpreterBase.getAttribute(InterpreterBase.java:971) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1108) at org.apache.commons.jexl3.parser.ASTIdentifierAccess.jjtAccept(ASTIdentifierAccess.java:104) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1156) at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:19) at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1029) at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:58) at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:193) at org.apache.commons.jexl3.internal.Script.execute(Script.java:188) at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:180) ... 72 more {noformat} For some reason your internal {{ClassMap}} class is being passed a {{Log}} that is {{null}}. Looking up the stack trace, it would appear this is coming from your {{Introspector}}. (There is a similar [error on Stack Overflowhttps://stackoverflow.com/q/64927054] with no answers; I don't know if they are using JAXL.) * First, passing the {{Log}} around as a parameter is an antipattern. Logging is a cross-cutting concern; passing it around as a parameter is a bad idea. * I wish you were using {{SLF4J}} like practically everyone else instead of {{org.apache.commons.logging}}. * You shouldn't catch {{NullPointerException}} and turn it into a "normal" error condition, trying to say that a variable wasn't defined when really this was an internal error with the library. In any case, for some reason JEXL 3.2.1 isn't initializing its internal logging support. 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 {{3.1}} to {{3.2.1}}. # Run {{mvn clean verify}}. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (JEXL-341) Errors needs to provide more information on caught exceptions.
[ https://issues.apache.org/jira/browse/JEXL-341?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17358123#comment-17358123 ] Garret Wilson commented on JEXL-341: I haven't worked with this part of the code in a while, but I think my point is that having a general exception type {{JexlException}}, I would expect its message to be a little more explanatory. Saying just {{"bar"}} doesn't help hardly anything at all. If there was an error evaluating the expression, I would expect an error explaining what sort of problem there was. Let me give an example: if you have a specific {{FileNotFoundException}}, it might be reasonable to include only {{"bar.txt"}} in the message, indicating which file was missing. (I still think this is not ideal; I would prefer a separate variable indicating the file that was missing.) But imagine that instead of a {{FileNotFoundException}} a general {{IOException}} was thrown, and it merely contained {{"bar.txt"}} as the message. That would not be helpful at all. I would expect it to say something like: "File not found: bar.txt". It could be constructed by {{new IOException("File not found: "+fnfe.getMessage(), fnfexception}}. I'm not asking for new methods to be exposed. I'm just asking for more insight to be given into expression evaluation errors, rather than the developer having to rewrite the parsing logic or try to backtrack into what was happening in the expression evaluation by drilling down into the stack trace. Just a simple message about what happened would be useful. In JEXL-340 in fact the message was nice: {{"undefined variable foobar"}}. That was perfect! Imagine if it would have said simply {{"foobar"}}. That would have been like this ticket. The problem in JEXL-340 is that it added a lot of non-error-message implementation detail cruft {{io.guise.mesh.JexlMexlEvaluator.evaluate}} to the error message. So in JEXL-340 extra implementation detail cruft was added. In this ticket JEXL-341 the error message was inadequate. Each exception needs a way to get just an error message such as {{"undefined variable foobar"}}. Not {{"foobar"}}. not {{"io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable foobar"}}. To me the distinction is clear and obvious. Maybe it's not so clear and obvious to everyone else, sorry. Anyway you've made your decision and closed the ticket. I was just responding to your question and explaining the request. The bigger problem is getting v3.2 released. Are you any closer to that? If not, all these other tickets are meaningless if they never make it into a release. > Errors needs to provide more information on caught exceptions. > -- > > Key: JEXL-341 > URL: https://issues.apache.org/jira/browse/JEXL-341 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Assignee: Henri Biestro >Priority: Trivial > Fix For: 3.2 > > > I have a method {{bar()}} that happens to throw a {{NullPointerException}}. A > bug, of course. But when I use the following expression in JEXL: > {noformat}foo.bar(){noformat} > The {{JexlException.getMessage()}} result is: > {noformat}io.guise.mesh.JexlMexlEvaluator.evaluate@1:… bar{noformat} > This is too little information to be helpful (and too much irrelevant > information— see JEXL-340). If a {{NullPointerException}} occurred during > invocation of the method, it would be nice to know that. Otherwise the > developer has no idea if JEXL couldn't find {{bar()}} or what exactly the > problem was. > Obviously this is is a low priority bug that is in no way blocking anything. > But it sure would be helpful if it could be improved one day. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17358118#comment-17358118 ] Garret Wilson commented on JEXL-340: {quote}Garret, is the proposed solution (per previous commit) something you can work with? Have you been able to check the JexlInfo provided features, etc ?{quote} [~henrib], sorry for the delay in responding. The commit has a few changes, and I haven't had time to go through them extensively. But if this change provides access to a {{getDetail()}} method that in the circumstances explained in the ticket description would provide simply "undefined variable foobar", then yes, this is a welcome and usable change, thanks! > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Assignee: Henri Biestro >Priority: Trivial > Fix For: 3.2 > > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable > foobar{quote} > This is not a pretty error message. It has lots of things a user doesn't care > about. I just want the real error message: > {quote}undefined variable foobar{quote} > But there is no way to get just that simple error message from > {{JexlException}}. If you look at the source code for > {{JexlException.getMessage()}}, you'll see that the "simple" message comes > from {{JexlException.detailedMessage()}}. > Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is > no way to access it from outside. Moreover the semantics of "message" and > "detailed message" are reversed! The "message" should provide fewer details > than the "detailed message". > Here is what should be done: > * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} > provides now. (You'll note that {{detailedMessage()}} already calls > {{super.getMessage()}}; this criss-cross overriding is not the best practice. > My suggestion would therefore improve and even reduce the code.) > * A new {{JexlException.getDetailedMessage()}} should provide what > {{getMessage()}} provides now. > That would be simpler and more correct. And it would give me the simpler > error message I need. If you absolutely must leave > {{JexlException.getMessage()}} the way it is for backwards compatibility, at > least provide a {{getSimpleMessage()}} that returns what > {{detailedMessage()}} returns now. (That way you can leave > {{detailedMessage()}} hidden, because it returns the _opposite_ of a detailed > message.) > I would guess that this issue of {{detailedMessage()}} returning the opposite > of a "detailed message" arose out of confusion of the API docs of > {{Throwable}} and {{Exception}} referring to a "detail message". But "detail > message" and "detailed message" mean different things. The API docs of > {{Throwable}} et. al. are referring to the message providing a detail about > the {{Throwable}}. The message itself is the "detail". But when you change > "detail message" to "detailed message", the "detailed" now means that the > message provides additional details than a normal message. So by adding the > "ed" to "detail" it changed the sense of what "detail message" originally > meant (the message providing detail). -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (IMAGING-280) Length specifier for ByteSourceArray.
[ https://issues.apache.org/jira/browse/IMAGING-280?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17289604#comment-17289604 ] Garret Wilson commented on IMAGING-280: --- {quote}Taking a very quick look through the commons imaging source code, I didn't find anyplace obvious where the alternate constructor could be applied.{quote} Your library doesn't necessarily have cases where it needs that constructor to provide a {{ByteSource}}, because it's the developer who will normally be supplying the bytes. {quote}Are you thinking of using this in applications outside the Commons Imaging package itself?{quote} Exactly. Your library _requests_ a {{ByteSource}}; that is, you request the _caller_ to provide one when they process images (e.g. {{ExifRewriter.updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet)}}). You want to make it flexible for the developer to supply the bytes in whatever form they have them. You don't want to force the developer to copy huge arrays just to because your {{ByteSourceArray}} doesn't provide a way to specify a portion of an existing buffer. See the internal {{BufByteSource}} class inside [{{BaseImageMummifier}}|https://bitbucket.org/globalmentor/guise/src/master/mummy/src/main/java/io/guise/mummy/mummify/image/BaseImageMummifier.java] as an example. Note the class API comment referring to this ticket. > Length specifier for ByteSourceArray. > - > > Key: IMAGING-280 > URL: https://issues.apache.org/jira/browse/IMAGING-280 > Project: Commons Imaging > Issue Type: Improvement >Reporter: Garret Wilson >Priority: Major > > Many of the library processing methods take a {{ByteSource}}. The > {{ByteSourceArray}} allows a byte source from an array of bytes, but > unfortunately it does not allow specification of the number of bytes, > assuming that the entire byte array is used; e.g.: > {code:java} > public ByteSourceArray(final byte[] bytes) { > this(null, bytes); > } > {code} > This severely impedes the use of the class if the code using > {{ByteSourceArray}} has a byte array partially filled. The obvious case is > processing data in a pipeline, when the producer has written to a > {{ByteArrayOutputStream}}. Although {{ByteArrayOutputStream.toByteArray()}} > provides a copy of the internal data, it is possible to subclass > {{ByteArrayOutputStream}} to get access to the underlying bytes to prevent > copying. Because {{ByteArrayOutputStream}} grows dynamically, the internal > byte array may not be full. > Thus {{ByteSourceArray}} needs a separate constructor to indicate the length > (and even the offset), just like {{ByteArrayInputStream}} does: > {code:java} > public ByteArrayInputStream(byte buf[], int offset, int length) {…} > {code} > Moreover this is extremely trivial to add. Without it, however, the developer > is forced to basically reimplement the entire class. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Closed] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson closed IMAGING-281. - > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image the > metadata of which cannot be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Resolved] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson resolved IMAGING-281. --- Resolution: Not A Problem Good news: I found the source of the problem. It seems that Microsoft stores the XP tags, including {{XPTitle}}, not as UTF-8 but as UCS-2. (See [ExifTool FAQ on charsets|https://exiftool.org/faq.html#Q10].) Thus in Apache Commons Imaging I should have been using {{TagInfoXpString}} instead of {{TagInfoAscii}}, like this: {code:java} TagInfoXpString EXIF_TAG_XP_TITLE = new TagInfoXpString("XPTitle", 0x9C9B, TiffDirectoryType.EXIF_DIRECTORY_IFD0); {code} The other libraries, which knew about the XP tag encoding, had been been trying to read the UTF-8 value as a two-byte Unicode encoding, which is what resulted in the corrupted string. (I'm not sure why Irfan view managed to read it. Maybe it went out of its way to detect UTF-8 before trying UCS-2 or UTF-16LE, or maybe it is just written incorrectly and was making the same mistaken assumption I made.) I'll close this ticket as not a problem. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image the > metadata of which cannot be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17280594#comment-17280594 ] Garret Wilson commented on IMAGING-281: --- Note also that, when creating the TIFF output set from scratch, if I use the following I cannot pick up the values in [metadata-extractor|https://github.com/drewnoakes/metadata-extractor]: {code:java} TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateExifDirectory() {code} Instead I have to use this: {code:java} TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory() {code} Again this doesn't fix the problem. It's some counter-intuitive call I have to make to get [metadata-extractor|https://github.com/drewnoakes/metadata-extractor] to see any values at all. Apache Commons Imaging is corrupting my image metadata, and its documentation is incomplete. I'm stuck. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image the > metadata of which cannot be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17280590#comment-17280590 ] Garret Wilson edited comment on IMAGING-281 at 2/7/21, 3:43 PM: If I use the same code with the {{ImageDescription}} field, it seems to work in that I can read the value in ExifTool: {code:java} TagInfoAscii EXIF_IMAGE_DESCRIPTION_TAG_INFO = new TagInfoAscii("ImageDescription", 0x010E, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //ImageDescription (270, 0x010E) {code} Note that this doesn't fix the problem. I want to write the {{XPTitle}} field. Moreover not knowing what the problem is, I don't know if Apache Common Imaging is going to arbitrarily corrupt some of my Exif fields, and when. was (Author: garretwilson): If I use the same code with the {{ImageDescription}} field, it seems to work: {code:java} TagInfoAscii EXIF_IMAGE_DESCRIPTION_TAG_INFO = new TagInfoAscii("ImageDescription", 0x010E, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //ImageDescription (270, 0x010E) {code} Note that this doesn't fix the problem. I want to write the {{XPTitle}} field. Moreover not knowing what the problem is, I don't know if Apache Common Imaging is going to arbitrarily corrupt some of my Exif fields, and when. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image the > metadata of which cannot be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17280590#comment-17280590 ] Garret Wilson commented on IMAGING-281: --- If I use the same code with the {{ImageDescription}} field, it seems to work: {code:java} TagInfoAscii EXIF_IMAGE_DESCRIPTION_TAG_INFO = new TagInfoAscii("ImageDescription", 0x010E, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //ImageDescription (270, 0x010E) {code} Note that this doesn't fix the problem. I want to write the {{XPTitle}} field. Moreover not knowing what the problem is, I don't know if Apache Common Imaging is going to arbitrarily corrupt some of my Exif fields, and when. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image the > metadata of which cannot be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated IMAGING-281: -- Description: I have a small input JPEG image containing _no metadata sections whatsoever_. I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} properties using [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" Here is a simplified excerpt of the code: {code:java} TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) … TiffOutputSet tiffOutputSet = new TiffOutputSet(); TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); … new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet); {code} Using [ExifTool|https://exiftool.org/] 12.16 (via [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows the same corrupted value. This is disheartening, as this is nearly the most simple test case possible. (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image metadata reading, and is confirmed by Metadata++. Having an image the metadata of which cannot be read in ExifTool is a show-stopper.) I'm will attach the test case image to this ticket. was: I have a small input JPEG image containing _no metadata sections whatsoever_. I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} properties using [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" Here is a simplified excerpt of the code: {code:java} TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) … TiffOutputSet tiffOutputSet = new TiffOutputSet(); TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); … new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet); {code} Using [ExifTool|https://exiftool.org/] 12.16 (via [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows the same corrupted value. This is disheartening, as this is nearly the most simple test case possible. (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image metadata reading, and is confirmed by Metadata++. Having an image that cannot be read in ExifTool is a show-stopper.) I'm will attach the test case image to this ticket. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using >
[jira] [Updated] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated IMAGING-281: -- Description: I have a small input JPEG image containing _no metadata sections whatsoever_. I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} properties using [{{ExifRewriter().updateExifMetadataLossy()}}|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" Here is a simplified excerpt of the code: {code:java} TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) … TiffOutputSet tiffOutputSet = new TiffOutputSet(); TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); … new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet); {code} Using [ExifTool|https://exiftool.org/] 12.16 (via [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows the same corrupted value. This is disheartening, as this is nearly the most simple test case possible. (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image metadata reading, and is confirmed by Metadata++. Having an image that cannot be read in ExifTool is a show-stopper.) I'm will attach the test case image to this ticket. was: I have a small input JPEG image containing _no metadata sections whatsoever_. I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} properties using [`ExifRewriter().updateExifMetadataLossy()`|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" Here is a simplified excerpt of the code: {code:java} TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) … TiffOutputSet tiffOutputSet = new TiffOutputSet(); TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); … new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet); {code} Using [ExifTool|https://exiftool.org/] 12.16 (via [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows the same corrupted value. This is disheartening, as this is nearly the most simple test case possible. (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image metadata reading, and is confirmed by Metadata++. Having an image that cannot be read in ExifTool is a show-stopper.) I'm will attach the test case image to this ticket. > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using >
[jira] [Updated] (IMAGING-281) Simple Exif XPTitle corrupted.
[ https://issues.apache.org/jira/browse/IMAGING-281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated IMAGING-281: -- Attachment: gate-turret-exif-bad-title.jpg > Simple Exif XPTitle corrupted. > -- > > Key: IMAGING-281 > URL: https://issues.apache.org/jira/browse/IMAGING-281 > Project: Commons Imaging > Issue Type: Bug >Affects Versions: 1.0-alpha2 >Reporter: Garret Wilson >Priority: Blocker > Attachments: gate-turret-exif-bad-title.jpg > > > I have a small input JPEG image containing _no metadata sections whatsoever_. > I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} > properties using > [`ExifRewriter().updateExifMetadataLossy()`|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. > * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" > * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" > Here is a simplified excerpt of the code: > {code:java} > TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, > TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) > TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, > -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) > … > TiffOutputSet tiffOutputSet = new TiffOutputSet(); > TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); > exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); > exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); > … > new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, > tiffOutputSet); > {code} > Using [ExifTool|https://exiftool.org/] 12.16 (via > [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is > stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". > [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows > the same corrupted value. > This is disheartening, as this is nearly the most simple test case possible. > (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the > {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image > metadata reading, and is confirmed by Metadata++. Having an image that cannot > be read in ExifTool is a show-stopper.) > I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Created] (IMAGING-281) Simple Exif XPTitle corrupted.
Garret Wilson created IMAGING-281: - Summary: Simple Exif XPTitle corrupted. Key: IMAGING-281 URL: https://issues.apache.org/jira/browse/IMAGING-281 Project: Commons Imaging Issue Type: Bug Affects Versions: 1.0-alpha2 Reporter: Garret Wilson I have a small input JPEG image containing _no metadata sections whatsoever_. I use Apache Commons Imaging 1.0-alpha2 to add two simple Exif {{IFD0}} properties using [`ExifRewriter().updateExifMetadataLossy()`|https://commons.apache.org/proper/commons-imaging/apidocs/org/apache/commons/imaging/formats/jpeg/exif/ExifRewriter.html#updateExifMetadataLossy-org.apache.commons.imaging.common.bytesource.ByteSource-java.io.OutputStream-org.apache.commons.imaging.formats.tiff.write.TiffOutputSet-]. * {{XPTitle}} ({{0x9C9B}}): "Gate and Turret" * {{Copyright}} ({{33432}}, {{0x8298}}): "Copyright © 2009 Garret Wilson" Here is a simplified excerpt of the code: {code:java} TagInfoAscii EXIF_XP_TITLE_TAG_INFO = new TagInfoAscii("XPTitle", 0x9C9B, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //XPTitle (0x9C9B) TagInfoAscii EXIF_COPYRIGHT_TAG_INFO = new TagInfoAscii("Copyright", 0x8298, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); //Copyright (33432, 0x8298) … TiffOutputSet tiffOutputSet = new TiffOutputSet(); TiffOutputDirectory exifDirectory = tiffOutputSet.getOrCreateRootDirectory(); exifDirectory.add(EXIF_XP_TITLE_TAG_INFO, "Gate and Turret"); exifDirectory.add(EXIF_COPYRIGHT_TAG_INFO, "Copyright © 2009 Garret Wilson"); … new ExifRewriter().updateExifMetadataLossy(byteSource, outputStream, tiffOutputSet); {code} Using [ExifTool|https://exiftool.org/] 12.16 (via [ExifToolGUI|https://exiftool.org/gui/) 5.16.0.0], the {{Copyright}} value is stored correctly but the {{XPTitle}} is stored as "慇整愠摮吠牵敲t". [Metadata++|https://www.logipole.com/metadata++-en.htm] 1.22.14 also shows the same corrupted value. This is disheartening, as this is nearly the most simple test case possible. (Note that [IrfanView|https://www.irfanview.com/] 4.54 can read the {{XPTitle}} just fine! Nevertheless ExifTool is the gold standard for image metadata reading, and is confirmed by Metadata++. Having an image that cannot be read in ExifTool is a show-stopper.) I'm will attach the test case image to this ticket. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Created] (IMAGING-280) Length specifier for ByteSourceArray.
Garret Wilson created IMAGING-280: - Summary: Length specifier for ByteSourceArray. Key: IMAGING-280 URL: https://issues.apache.org/jira/browse/IMAGING-280 Project: Commons Imaging Issue Type: Improvement Reporter: Garret Wilson Many of the library processing methods take a {{ByteSource}}. The {{ByteSourceArray}} allows a byte source from an array of bytes, but unfortunately it does not allow specification of the number of bytes, assuming that the entire byte array is used; e.g.: {code:java} public ByteSourceArray(final byte[] bytes) { this(null, bytes); } {code} This severely impedes the use of the class if the code using {{ByteSourceArray}} has a byte array partially filled. The obvious case is processing data in a pipeline, when the producer has written to a {{ByteArrayOutputStream}}. Although {{ByteArrayOutputStream.toByteArray()}} provides a copy of the internal data, it is possible to subclass {{ByteArrayOutputStream}} to get access to the underlying bytes to prevent copying. Because {{ByteArrayOutputStream}} grows dynamically, the internal byte array may not be full. Thus {{ByteSourceArray}} needs a separate constructor to indicate the length (and even the offset), just like {{ByteArrayInputStream}} does: {code:java} public ByteArrayInputStream(byte buf[], int offset, int length) {…} {code} Moreover this is extremely trivial to add. Without it, however, the developer is forced to basically reimplement the entire class. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-342: --- Description: Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can this this easily be added as some sort of plugin, or better yet can it be added to the library? h3. {{Optional}} Traversal I need to create an API that works well for application developers as for those using templates with JEXL expressions. Let's say that the {{Bar}} class has a {{Bar.getName()}}. And the {{Foo}} class has this method: {code:java} Optional getBar(String barId); {code} In code getting the "test" foo-bar name would be like this: {code:java} String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); {code} I want the navigation across {{Optional<>}} to work just as if it were a nullable variable. That is, I want the following JEXL expression to give the same result as {{fooBarName}} above: {code} foo.bar("test").name {code} If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, I think JEXL would work for this already. but the whole point of {{Optional<>}} is that I keep nullables out of my code, so I don't want to create inferior APIs inconsistent with the rest of my project just to work with JEXL. h3. {{Optional}} Getter Name As icing on the cake, I would like to have {{Optional<>}} returning getter discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. I've been using this pattern for several years, and I really like it. Thus to indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: {code:java} Optional findBar(String barId); {code} I would thus want the exact same JEXL expression above to still work: {code} foo.bar("test").name {code} Otherwise I'll have to forego use of modern Java constructs and make an outdated style and less safe API just to get JEXL to work. was: Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can this this easily be added as some sort of plugin, or better yet can it be added to the library? h3. {{Optional}} Traversal I need to create an API that works well for application developers as for those using templates with JEXL expressions. Let's say that the {{Bar}} class has a {{Bar.getName()}}. And the {{Foo}} class has this method: {code:java} Optional getBar(String barId); {code} In code getting the "test" foo-bar name would be like this: {code:java} String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); {code} I want the navigation across {{Optional<>}} to work just as if it were a nullable variable. That is, I want the following JEXL expression to give the same result as {{fooBarName}} above: {code} foo.bar("test").name {code} If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, I think JEXL would work for this already. but the whole point of {{Optional<>}} is that I keep nullables out of my code, so I don't want to create inferior APIs inconsistent with the rest of my project just to work with JEXL. h3. {{Optional}} Getter Name As icing on the cake, I would like to have {{Optional<>}} returning getter discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. I've been using this pattern for several years, and I really like it. Thus to indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: {code:java} Optional getBar(String barId); {code} I would thus want the exact same JEXL expression above to still work: {code} foo.bar("test").name {code} Otherwise I'll have to forego use of modern Java constructs and make an outdated style and less safe API just to get JEXL to work. > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String
[jira] [Comment Edited] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17270914#comment-17270914 ] Garret Wilson edited comment on JEXL-342 at 1/24/21, 4:02 PM: -- To get really wil To get really wild, we could get the Elvis operator working, too. Using the API in the description, I would want to have the following JEXL expression work equivalent to the Java code {{foo.findBar("test").map(Bar::getName).orElse("unavailable")}}: {code} foo.bar("test").name ?: "unavailable" {code} I realize that under the hood this could get pretty complicated and that the current design of JEXL may not be amenable to this, so I didn't place it in the main feature request description. But it does show the sort of native support that would be nice. In the least, recognizing the {{findXXX()}} getter pattern and turning {{Optional<>}} to a nullable by calling {{orElse(null)}} during instance tree traversal (and treating as you normally would treat a {{null}} return value to short-circuit expression evaluation) should be completely doable and likely not too much trouble. was (Author: garretwilson): To get really wil To get really wild, we could get the Elvis operator working, too. Using the API in the description, I would want to have the following JEXL expression work equivalent to the Java code {{foo.findBar("test").map(Bar::getName).orElse("no such bar")}}: {code} foo.bar("test").name ?: "no such bar" {code} I realize that under the hood this could get pretty complicated and that the current design of JEXL may not be amenable to this, so I didn't place it in the main feature request description. But it does show the sort of native support that would be nice. In the least, recognizing the {{findXXX()}} getter pattern and turning {{Optional<>}} to a nullable by calling {{orElse(null)}} during instance tree traversal (and treating as you normally would treat a {{null}} return value to short-circuit expression evaluation) should be completely doable and likely not too much trouble. > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); > {code} > I want the navigation across {{Optional<>}} to work just as if it were a > nullable variable. That is, I want the following JEXL expression to give the > same result as {{fooBarName}} above: > {code} > foo.bar("test").name > {code} > If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, > I think JEXL would work for this already. but the whole point of > {{Optional<>}} is that I keep nullables out of my code, so I don't want to > create inferior APIs inconsistent with the rest of my project just to work > with JEXL. > h3. {{Optional}} Getter Name > As icing on the cake, I would like to have {{Optional<>}} returning getter > discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne > suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. > I've been using this pattern for several years, and I really like it. Thus to > indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable > but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: > {code:java} > Optional getBar(String barId); > {code} > I would thus want the exact same JEXL expression above to still work: > {code} > foo.bar("test").name > {code} > Otherwise I'll have to forego use of modern Java constructs and make an > outdated style and less safe API just to get JEXL to work. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17270914#comment-17270914 ] Garret Wilson commented on JEXL-342: To get really wil To get really wild, we could get the Elvis operator working, too. Using the API in the description, I would want to have the following JEXL expression work equivalent to the Java code {{foo.findBar("test").map(Bar::getName).orElse("no such bar")}}: {code} foo.bar("test").name ?: "no such bar" {code} I realize that under the hood this could get pretty complicated and that the current design of JEXL may not be amenable to this, so I didn't place it in the main feature request description. But it does show the sort of native support that would be nice. In the least, recognizing the {{findXXX()}} getter pattern and turning {{Optional<>}} to a nullable by calling {{orElse(null)}} during instance tree traversal (and treating as you normally would treat a {{null}} return value to short-circuit expression evaluation) should be completely doable and likely not too much trouble. > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); > {code} > I want the navigation across {{Optional<>}} to work just as if it were a > nullable variable. That is, I want the following JEXL expression to give the > same result as {{fooBarName}} above: > {code} > foo.bar("test").name > {code} > If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, > I think JEXL would work for this already. but the whole point of > {{Optional<>}} is that I keep nullables out of my code, so I don't want to > create inferior APIs inconsistent with the rest of my project just to work > with JEXL. > h3. {{Optional}} Getter Name > As icing on the cake, I would like to have {{Optional<>}} returning getter > discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne > suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. > I've been using this pattern for several years, and I really like it. Thus to > indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable > but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: > {code:java} > Optional getBar(String barId); > {code} > I would thus want the exact same JEXL expression above to still work: > {code} > foo.bar("test").name > {code} > Otherwise I'll have to forego use of modern Java constructs and make an > outdated style and less safe API just to get JEXL to work. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (JEXL-342) Support for Java Optional.
[ https://issues.apache.org/jira/browse/JEXL-342?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-342: --- Description: Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can this this easily be added as some sort of plugin, or better yet can it be added to the library? h3. {{Optional}} Traversal I need to create an API that works well for application developers as for those using templates with JEXL expressions. Let's say that the {{Bar}} class has a {{Bar.getName()}}. And the {{Foo}} class has this method: {code:java} Optional getBar(String barId); {code} In code getting the "test" foo-bar name would be like this: {code:java} String fooBarName=foo.getBar("test").map(Bar::getName).orElse(null); {code} I want the navigation across {{Optional<>}} to work just as if it were a nullable variable. That is, I want the following JEXL expression to give the same result as {{fooBarName}} above: {code} foo.bar("test").name {code} If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, I think JEXL would work for this already. but the whole point of {{Optional<>}} is that I keep nullables out of my code, so I don't want to create inferior APIs inconsistent with the rest of my project just to work with JEXL. h3. {{Optional}} Getter Name As icing on the cake, I would like to have {{Optional<>}} returning getter discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. I've been using this pattern for several years, and I really like it. Thus to indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: {code:java} Optional getBar(String barId); {code} I would thus want the exact same JEXL expression above to still work: {code} foo.bar("test").name {code} Otherwise I'll have to forego use of modern Java constructs and make an outdated style and less safe API just to get JEXL to work. was: Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can this this easily be added as some sort of plugin, or better yet can it be added to the library? h3. {{Optional}} Traversal I need to create an API that works well for application developers as for those using templates with JEXL expressions. Let's say that the {{Bar}} class has a {{Bar.getName()}}. And the {{Foo}} class has this method: {code:java} Optional getBar(String barId); {code} In code getting the "test" foo-bar name would be like this: {code:java} String fooBarName=foo.getBar("test").getName().orElse(null); {code} I want the navigation across {{Optional<>}} to work just as if it were a nullable variable. That is, I want the following JEXL expression to give the same result as {{fooBarName}} above: {code} foo.bar("test").name {code} If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, I think JEXL would work for this already. but the whole point of {{Optional<>}} is that I keep nullables out of my code, so I don't want to create inferior APIs inconsistent with the rest of my project just to work with JEXL. h3. {{Optional}} Getter Name As icing on the cake, I would like to have {{Optional<>}} returning getter discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. I've been using this pattern for several years, and I really like it. Thus to indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: {code:java} Optional getBar(String barId); {code} I would thus want the exact same JEXL expression above to still work: {code} foo.bar("test").name {code} Otherwise I'll have to forego use of modern Java constructs and make an outdated style and less safe API just to get JEXL to work. > Support for Java Optional. > -- > > Key: JEXL-342 > URL: https://issues.apache.org/jira/browse/JEXL-342 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Major > > Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can > this this easily be added as some sort of plugin, or better yet can it be > added to the library? > h3. {{Optional}} Traversal > I need to create an API that works well for application developers as for > those using templates with JEXL expressions. Let's say that the {{Bar}} class > has a {{Bar.getName()}}. And the {{Foo}} class has this method: > {code:java} > Optional getBar(String barId); > {code} > In code getting the "test" foo-bar name would be like this: > {code:java} > String
[jira] [Created] (JEXL-342) Support for Java Optional.
Garret Wilson created JEXL-342: -- Summary: Support for Java Optional. Key: JEXL-342 URL: https://issues.apache.org/jira/browse/JEXL-342 Project: Commons JEXL Issue Type: New Feature Affects Versions: 3.1 Reporter: Garret Wilson Does JEXL provide any native support for Java 8+ {{Optional<>}}? If not can this this easily be added as some sort of plugin, or better yet can it be added to the library? h3. {{Optional}} Traversal I need to create an API that works well for application developers as for those using templates with JEXL expressions. Let's say that the {{Bar}} class has a {{Bar.getName()}}. And the {{Foo}} class has this method: {code:java} Optional getBar(String barId); {code} In code getting the "test" foo-bar name would be like this: {code:java} String fooBarName=foo.getBar("test").getName().orElse(null); {code} I want the navigation across {{Optional<>}} to work just as if it were a nullable variable. That is, I want the following JEXL expression to give the same result as {{fooBarName}} above: {code} foo.bar("test").name {code} If {{Foo.getBar(String)}} returned a nullable rather than an {{Optional<>}}, I think JEXL would work for this already. but the whole point of {{Optional<>}} is that I keep nullables out of my code, so I don't want to create inferior APIs inconsistent with the rest of my project just to work with JEXL. h3. {{Optional}} Getter Name As icing on the cake, I would like to have {{Optional<>}} returning getter discovery to recognize the {{findXXX}} pattern, as [Stephen Colebourne suggested|https://blog.joda.org/2015/09/naming-optional-query-methods.html]. I've been using this pattern for several years, and I really like it. Thus to indicate that the {{Foo.getBar(String)}} "getter" doesn't return a nullable but an {{Optional<>}}, I would name it {{Foo.findBar(String)}}, like this: {code:java} Optional getBar(String barId); {code} I would thus want the exact same JEXL expression above to still work: {code} foo.bar("test").name {code} Otherwise I'll have to forego use of modern Java constructs and make an outdated style and less safe API just to get JEXL to work. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-341) Errors needs to provide more information on caught exceptions.
[ https://issues.apache.org/jira/browse/JEXL-341?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17259353#comment-17259353 ] Garret Wilson commented on JEXL-341: The point of all this (and JEXL-340) is that I'm creating an entire templating framework from the ground up in [GUISE-170|https://globalmentor.atlassian.net/browse/GUISE-170], currently using embedded JEXL as the foundation of the expression language. Users (who may be web savvy but not necessarily Java savvy) will add their own expressions in the HTML. I need a way to nicely tell the user when something went wrong with their expression. Even if the problem in the method invocation happened not to be their fault (in the case of a {{NullPointerException}} it would have been my fault, that of the developer), it would be helpful to give them some sort of useful error message, be it "Null reference error in bar()" or even "unexpected error in bar()". If they just see "bar", they will be very confused. > Errors needs to provide more information on caught exceptions. > -- > > Key: JEXL-341 > URL: https://issues.apache.org/jira/browse/JEXL-341 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Assignee: Henri Biestro >Priority: Trivial > > I have a method {{bar()}} that happens to throw a {{NullPointerException}}. A > bug, of course. But when I use the following expression in JEXL: > {noformat}foo.bar(){noformat} > The {{JexlException.getMessage()}} result is: > {noformat}io.guise.mesh.JexlMexlEvaluator.evaluate@1:… bar{noformat} > This is too little information to be helpful (and too much irrelevant > information— see JEXL-340). If a {{NullPointerException}} occurred during > invocation of the method, it would be nice to know that. Otherwise the > developer has no idea if JEXL couldn't find {{bar()}} or what exactly the > problem was. > Obviously this is is a low priority bug that is in no way blocking anything. > But it sure would be helpful if it could be improved one day. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-341) Errors needs to provide more information on caught exceptions.
[ https://issues.apache.org/jira/browse/JEXL-341?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17259351#comment-17259351 ] Garret Wilson commented on JEXL-341: What I'm getting at is that somewhere the JEXL code (I haven't investigated; I'm guessing from experience) is wrapping the method invocation with some sort of {{try\{…\} catch(Throwable t)}} just so it can be sure that the whole thing doesn't blow up when the method implementation (in this case, my code) has a bad bug. That's reasonable; I'm just suggesting that it would be helpful if the detail message at least gave some indication of what went wrong. Just saying "bar" isn't really helpful. Ideally you would do something like this: {code:java} try { invokeBar(); } catch(JexlException je) { throw je; } catch(NullPointerExeption npe) { throw new JexlException("Null reference when invoking `bar`", npe); } catch(Throwable t) { throw new JexlException("Unexpected error when invoking `bar`: "+t.getMessage(), t); //I would guess you are doing this currently: throw new JexlException("`bar`", t); } {code} Even just adding the "unexpected error" part would be helpful, because later Java versions are going to add more information to the {{NullPointerException}} message anyway: {code:java} } catch(Throwable t) { throw new JexlException("Unexpected error when invoking `bar`: "+t.getMessage(), t); } {code} We don't need the whole {{Throwable.toString()}} in the message. Just the {{Throwable.message()}} (if it isn't {{null}}). In fact any little message saying "unexpected error invoking bar()" would be really more helpful than simply "bar". It should be an extremely simple change that will bring loads of help. Again, this is a tiny, trivial suggestion, but it would be helpful. > Errors needs to provide more information on caught exceptions. > -- > > Key: JEXL-341 > URL: https://issues.apache.org/jira/browse/JEXL-341 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Assignee: Henri Biestro >Priority: Trivial > > I have a method {{bar()}} that happens to throw a {{NullPointerException}}. A > bug, of course. But when I use the following expression in JEXL: > {noformat}foo.bar(){noformat} > The {{JexlException.getMessage()}} result is: > {noformat}io.guise.mesh.JexlMexlEvaluator.evaluate@1:… bar{noformat} > This is too little information to be helpful (and too much irrelevant > information— see JEXL-340). If a {{NullPointerException}} occurred during > invocation of the method, it would be nice to know that. Otherwise the > developer has no idea if JEXL couldn't find {{bar()}} or what exactly the > problem was. > Obviously this is is a low priority bug that is in no way blocking anything. > But it sure would be helpful if it could be improved one day. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17259345#comment-17259345 ] Garret Wilson commented on JEXL-340: A {{getDetail()}} method that provides a simple message such as "undefined variable foobar" would be very helpful, thanks. > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Assignee: Henri Biestro >Priority: Trivial > Fix For: 3.2 > > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable > foobar{quote} > This is not a pretty error message. It has lots of things a user doesn't care > about. I just want the real error message: > {quote}undefined variable foobar{quote} > But there is no way to get just that simple error message from > {{JexlException}}. If you look at the source code for > {{JexlException.getMessage()}}, you'll see that the "simple" message comes > from {{JexlException.detailedMessage()}}. > Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is > no way to access it from outside. Moreover the semantics of "message" and > "detailed message" are reversed! The "message" should provide fewer details > than the "detailed message". > Here is what should be done: > * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} > provides now. (You'll note that {{detailedMessage()}} already calls > {{super.getMessage()}}; this criss-cross overriding is not the best practice. > My suggestion would therefore improve and even reduce the code.) > * A new {{JexlException.getDetailedMessage()}} should provide what > {{getMessage()}} provides now. > That would be simpler and more correct. And it would give me the simpler > error message I need. If you absolutely must leave > {{JexlException.getMessage()}} the way it is for backwards compatibility, at > least provide a {{getSimpleMessage()}} that returns what > {{detailedMessage()}} returns now. (That way you can leave > {{detailedMessage()}} hidden, because it returns the _opposite_ of a detailed > message.) > I would guess that this issue of {{detailedMessage()}} returning the opposite > of a "detailed message" arose out of confusion of the API docs of > {{Throwable}} and {{Exception}} referring to a "detail message". But "detail > message" and "detailed message" mean different things. The API docs of > {{Throwable}} et. al. are referring to the message providing a detail about > the {{Throwable}}. The message itself is the "detail". But when you change > "detail message" to "detailed message", the "detailed" now means that the > message provides additional details than a normal message. So by adding the > "ed" to "detail" it changed the sense of what "detail message" originally > meant (the message providing detail). -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Created] (JEXL-341) Errors needs to provide more information on caught exceptions.
Garret Wilson created JEXL-341: -- Summary: Errors needs to provide more information on caught exceptions. Key: JEXL-341 URL: https://issues.apache.org/jira/browse/JEXL-341 Project: Commons JEXL Issue Type: Improvement Affects Versions: 3.1 Reporter: Garret Wilson I have a method {{bar()}} that happens to throw a {{NullPointerException}}. A bug, of course. But when I use the following expression in JEXL: {noformat}foo.bar(){noformat} The {{JexlException.getMessage()}} result is: {noformat}io.guise.mesh.JexlMexlEvaluator.evaluate@1:… bar{noformat} This is too little information to be helpful (and too much irrelevant information— see JEXL-340). If a {{NullPointerException}} occurred during invocation of the method, it would be nice to know that. Otherwise the developer has no idea if JEXL couldn't find {{bar()}} or what exactly the problem was. Obviously this is is a low priority bug that is in no way blocking anything. But it sure would be helpful if it could be improved one day. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17257477#comment-17257477 ] Garret Wilson commented on JEXL-338: I'm still waiting to hear back on what the release process is and what the next steps are to get a release out. I've found this [Apache Commons – Preparations for a Release|https://commons.apache.org/releases/prepare.html] page. Is that the most up-to-date documentation? It seems still to refer to Subversion. Surely you're releasing from a Git repository now (I would hope)? And who managed the last release? It would be nice to at least touch base with them to see what the major pain points are. > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17257476#comment-17257476 ] Garret Wilson commented on JEXL-340: Thanks for responding, [~ggregory]. I would be happy to provide a pull request, but I'm hesitant to do any work if it is still unclear whether and when there will even be any new releases, as we've been discussing in JEXL-338. I have said in that ticket that I would be interested in serving as Release Manager, but I still have some questions in JEXL-338 that are unanswered, and no one has told me what the next steps would be. > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Trivial > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable > foobar{quote} > This is not a pretty error message. It has lots of things a user doesn't care > about. I just want the real error message: > {quote}undefined variable foobar{quote} > But there is no way to get just that simple error message from > {{JexlException}}. If you look at the source code for > {{JexlException.getMessage()}}, you'll see that the "simple" message comes > from {{JexlException.detailedMessage()}}. > Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is > no way to access it from outside. Moreover the semantics of "message" and > "detailed message" are reversed! The "message" should provide fewer details > than the "detailed message". > Here is what should be done: > * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} > provides now. (You'll note that {{detailedMessage()}} already calls > {{super.getMessage()}}; this criss-cross overriding is not the best practice. > My suggestion would therefore improve and even reduce the code.) > * A new {{JexlException.getDetailedMessage()}} should provide what > {{getMessage()}} provides now. > That would be simpler and more correct. And it would give me the simpler > error message I need. If you absolutely must leave > {{JexlException.getMessage()}} the way it is for backwards compatibility, at > least provide a {{getSimpleMessage()}} that returns what > {{detailedMessage()}} returns now. (That way you can leave > {{detailedMessage()}} hidden, because it returns the _opposite_ of a detailed > message.) > I would guess that this issue of {{detailedMessage()}} returning the opposite > of a "detailed message" arose out of confusion of the API docs of > {{Throwable}} and {{Exception}} referring to a "detail message". But "detail > message" and "detailed message" mean different things. The API docs of > {{Throwable}} et. al. are referring to the message providing a detail about > the {{Throwable}}. The message itself is the "detail". But when you change > "detail message" to "detailed message", the "detailed" now means that the > message provides additional details than a normal message. So by adding the > "ed" to "detail" it changed the sense of what "detail message" originally > meant (the message providing detail). -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-340: --- Description: I need to wrap {{JexlException}} and provide a nice error message to the user. If I have an expression using a variable {{foobar}} not present in the context, here is what {{JexlException.getMessage()}} returns: {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable foobar{quote} This is not a pretty error message. It has lots of things a user doesn't care about. I just want the real error message: {quote}undefined variable foobar{quote} But there is no way to get just that simple error message from {{JexlException}}. If you look at the source code for {{JexlException.getMessage()}}, you'll see that the "simple" message comes from {{JexlException.detailedMessage()}}. Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is no way to access it from outside. Moreover the semantics of "message" and "detailed message" are reversed! The "message" should provide fewer details than the "detailed message". Here is what should be done: * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} provides now. (You'll note that {{detailedMessage()}} already calls {{super.getMessage()}}; this criss-cross overriding is not the best practice. My suggestion would therefore improve and even reduce the code.) * A new {{JexlException.getDetailedMessage()}} should provide what {{getMessage()}} provides now. That would be simpler and more correct. And it would give me the simpler error message I need. If you absolutely must leave {{JexlException.getMessage()}} the way it is for backwards compatibility, at least provide a {{getSimpleMessage()}} that returns what {{detailedMessage()}} returns now. (That way you can leave {{detailedMessage()}} hidden, because it returns the _opposite_ of a detailed message.) I would guess that this issue of {{detailedMessage()}} returning the opposite of a "detailed message" arose out of confusion of the API docs of {{Throwable}} and {{Exception}} referring to a "detail message". But "detail message" and "detailed message" mean different things. The API docs of {{Throwable}} et. al. are referring to the message providing a detail about the {{Throwable}}. The message itself is the "detail". But when you change "detail message" to "detailed message", the "detailed" now means that the message provides additional details than a normal message. So by adding the "ed" to "detail" it changed the sense of what "detail message" originally meant (the message providing detail). was: I need to wrap {{JexlException}} and provide a nice error message to the user. If I have an expression using a variable {{foobar}} not present in the context, here is what {{JexlException.getMessage()}} returns: {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable foobar{quote} This is not a pretty error message. It has lots of things a user doesn't care about. I just want the real error message: {quote}undefined variable foobar{quote} But there is no way to get just that simple error message from {{JexlException}}. If you look at the source code for {{JexlException.getMessage()}}, you'll see that the "simple" message comes from {{JexlException.detailedMessage()}}. Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is no way to access it from outside. Moreover the semantics of "message" and "detailed message" are reversed! The "message" should provide fewer details than the "detailed message". Here is what should be done: * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} provides now. (You'll note that {{detailedMessage()}} already calls {{super.getMessage()}}; this criss-cross overriding is not the best practice. My suggestion would therefore improve and even reduce the code.) * A new {{JexlException.getDetailedMessage()}} should provide what {{getMessage()}} provides now. That would be simpler and more correct. And it would give me the simpler error message I need. It's not apparent to me why the current roundabout implementation was used to begin with, or what benefit it brings. > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Trivial > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined
[jira] [Updated] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-340: --- Priority: Trivial (was: Minor) > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Trivial > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable > foobar{quote} > This is not a pretty error message. It has lots of things a user doesn't care > about. I just want the real error message: > {quote}undefined variable foobar{quote} > But there is no way to get just that simple error message from > {{JexlException}}. If you look at the source code for > {{JexlException.getMessage()}}, you'll see that the "simple" message comes > from {{JexlException.detailedMessage()}}. > Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is > no way to access it from outside. Moreover the semantics of "message" and > "detailed message" are reversed! The "message" should provide fewer details > than the "detailed message". > Here is what should be done: > * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} > provides now. (You'll note that {{detailedMessage()}} already calls > {{super.getMessage()}}; this criss-cross overriding is not the best practice. > My suggestion would therefore improve and even reduce the code.) > * A new {{JexlException.getDetailedMessage()}} should provide what > {{getMessage()}} provides now. > That would be simpler and more correct. And it would give me the simpler > error message I need. > It's not apparent to me why the current roundabout implementation was used to > begin with, or what benefit it brings. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (JEXL-340) JexlException message access is incomplete and reversed
[ https://issues.apache.org/jira/browse/JEXL-340?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Garret Wilson updated JEXL-340: --- Priority: Minor (was: Major) > JexlException message access is incomplete and reversed > --- > > Key: JEXL-340 > URL: https://issues.apache.org/jira/browse/JEXL-340 > Project: Commons JEXL > Issue Type: Improvement >Affects Versions: 3.1 >Reporter: Garret Wilson >Priority: Minor > > I need to wrap {{JexlException}} and provide a nice error message to the > user. If I have an expression using a variable {{foobar}} not present in the > context, here is what {{JexlException.getMessage()}} returns: > {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable > foobar{quote} > This is not a pretty error message. It has lots of things a user doesn't care > about. I just want the real error message: > {quote}undefined variable foobar{quote} > But there is no way to get just that simple error message from > {{JexlException}}. If you look at the source code for > {{JexlException.getMessage()}}, you'll see that the "simple" message comes > from {{JexlException.detailedMessage()}}. > Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is > no way to access it from outside. Moreover the semantics of "message" and > "detailed message" are reversed! The "message" should provide fewer details > than the "detailed message". > Here is what should be done: > * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} > provides now. (You'll note that {{detailedMessage()}} already calls > {{super.getMessage()}}; this criss-cross overriding is not the best practice. > My suggestion would therefore improve and even reduce the code.) > * A new {{JexlException.getDetailedMessage()}} should provide what > {{getMessage()}} provides now. > That would be simpler and more correct. And it would give me the simpler > error message I need. > It's not apparent to me why the current roundabout implementation was used to > begin with, or what benefit it brings. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Created] (JEXL-340) JexlException message access is incomplete and reversed
Garret Wilson created JEXL-340: -- Summary: JexlException message access is incomplete and reversed Key: JEXL-340 URL: https://issues.apache.org/jira/browse/JEXL-340 Project: Commons JEXL Issue Type: Improvement Affects Versions: 3.1 Reporter: Garret Wilson I need to wrap {{JexlException}} and provide a nice error message to the user. If I have an expression using a variable {{foobar}} not present in the context, here is what {{JexlException.getMessage()}} returns: {quote}io.guise.mesh.JexlMexlEvaluator.evaluate@1:1 undefined variable foobar{quote} This is not a pretty error message. It has lots of things a user doesn't care about. I just want the real error message: {quote}undefined variable foobar{quote} But there is no way to get just that simple error message from {{JexlException}}. If you look at the source code for {{JexlException.getMessage()}}, you'll see that the "simple" message comes from {{JexlException.detailedMessage()}}. Unfortunately {{JexlException.detailedMessage()}} is {{protected}}—there is no way to access it from outside. Moreover the semantics of "message" and "detailed message" are reversed! The "message" should provide fewer details than the "detailed message". Here is what should be done: * {{JexlException.getMessage()}} should provide what {{detailedMessage()}} provides now. (You'll note that {{detailedMessage()}} already calls {{super.getMessage()}}; this criss-cross overriding is not the best practice. My suggestion would therefore improve and even reduce the code.) * A new {{JexlException.getDetailedMessage()}} should provide what {{getMessage()}} provides now. That would be simpler and more correct. And it would give me the simpler error message I need. It's not apparent to me why the current roundabout implementation was used to begin with, or what benefit it brings. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17255128#comment-17255128 ] Garret Wilson edited comment on JEXL-338 at 12/26/20, 9:42 PM: --- {quote}Not sure what new features you want to see integrated that need functionality/code changes …{quote} I'm not sure, either; I was just making a guess from experience. (For example, [Thymeleaf still doesn't support {{Optional<>}}|https://github.com/thymeleaf/thymeleaf/issues/672] in a natural way.) {quote}… describing them as JIRA enhancements would be the (kinda) standard way.{quote} For sure! I mentioned this as another general reason why I'd be interested in helping make sure JEXL is kept current. If I think of something in particular I'll definitely file a Jira ticket. {quote}If you havent participated in releasing Apache (Commons?) projects before though, it might be a longer and windier road than you think it is.{quote} I have not participated in releasing any Apache projects before, no. Is there documentation on what I can expect so I can research what I might be getting into? was (Author: garretwilson): {quote}Not sure what new features you want to see integrated that need functionality/code changes …{quote} I'm not sure, either; I was just making a guess from experience. (For example, [Thymeleaf still doesn't support {{Optional<>}}|https://github.com/thymeleaf/thymeleaf/issues/672] in a natural way.) {quote}… describing them as JIRA enhancements would be the (kinda) standard way.{quote} For sure! I mentioned this as another reason why I'd be interested in helping make sure JEXL is kept current. {quote}If you havent participated in releasing Apache (Commons?) projects before though, it might be a longer and windier road than you think it is.{quote} I have not participated in releasing any Apache projects before, no. Is there documentation on what I can expect so I can research what I might be getting into? > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17255128#comment-17255128 ] Garret Wilson commented on JEXL-338: {quote}Not sure what new features you want to see integrated that need functionality/code changes …{quote} I'm not sure, either; I was just making a guess from experience. (For example, [Thymeleaf still doesn't support {{Optional<>}}|https://github.com/thymeleaf/thymeleaf/issues/672] in a natural way.) {quote}… describing them as JIRA enhancements would be the (kinda) standard way.{quote} For sure! I mentioned this as another reason why I'd be interested in helping make sure JEXL is kept current. {quote}If you havent participated in releasing Apache (Commons?) projects before though, it might be a longer and windier road than you think it is.{quote} I have not participated in releasing any Apache projects before, no. Is there documentation on what I can expect so I can research what I might be getting into? > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17255105#comment-17255105 ] Garret Wilson commented on JEXL-338: It works!! I was able to plug in my own resolver and access properties from my own object type, which has specialized property access methods. JEXL may work as-is for my _initial_ needs, but I'd hate to see the project go stale, and eventually I'll probably need support for newer Java features (e.g. streams and {{Optional}}) if they aren't supported already. So if you still need a Release Manager, I would be willing to step forward. If the project has some specialized, complicated build requirements (such as installing a C++ build subsystem or something) I probably wouldn't have the time, but if this is just a straightforward Maven Java project, I'd love to help. I can make sure the POM is tidied up, make sure the dependencies are up-to-date, go through the checklist, and get a new version up on Maven Central. If everything goes well, I should be able to continue in the role for the near future for other releases. How would you like to proceed? {quote}There one user's mailing list for all of Apache Commons and one developer's mailing list for all of Apache Commons.{quote} I just saw that there is a new [GitHub Discussions|https://docs.github.com/en/free-pro-team@latest/discussions] feature for the GitHub repository, and it seems ideal for discussions such as these. Have you looked into turning on something like that? If absolutely necessary I can subscribe to the Apache Commons mailing lists, but being bombarded with irrelevant emails from unrelated projects is not ideal. > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17255060#comment-17255060 ] Garret Wilson commented on JEXL-338: I'm almost there on my own. My resolver must return a {{JexlPropertyGet}}. If I use {{MapGetExecutor}} as an example, I don't fully understand the purpose of the {{MAP_GET}}, that is, the whole {{initMarker()}} business. Maybe I can get by without it. In any case, I can't really extend {{AbstractExecutor.Get}} because it isn't visible, so I'll implement {{JexlPropertyGet}} directly and hope the {{initMarker()}} wasn't important. I should know today if it works, but it has a few extra layers of indirection than I would have expected. Is there a better place to discuss this? Are you on the Apache list? (It appears I have to sign up the main Apache Commons list and be flooded with all sorts of unrelated emails; is there a better discussion forum?) > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17253626#comment-17253626 ] Garret Wilson edited comment on JEXL-338 at 12/22/20, 4:59 PM: --- That's exciting to hear. Thanks for the reply, [~henrib]. I might be interested in volunteering, depending on of the project meets my needs. I'd also want to push for support of newer Java features (e.g. iteration on streams and lambas, if not supported). The biggest thing I need to know first of all is if JEXL will allow for the expression {{foo.bar}} not only looking up an object in a context (e.g. {{context.getObject("foo")}}) but also using the context or some strategy to look up the property (e.g. {{context.getProperty(foo, "bar")}}). That's because my object {{foo}} is not a map and has a different way to get properties than simple reflection of getter methods. If you know the answer that let me know; otherwise I'll have to try it out. If it works let's talk more about this Release Manager. was (Author: garretwilson): That's exciting to hear. Thanks for the reply, [~henrib]. I might be interested in volunteering, depending on of the project meets my needs. I'd also want to push for support of newer Java features (e.g. iteration on streams and lambas, if not supported). The biggest thing I need to know first of all is if JEXL will allow for the expression {{foo.bar}} not only looking up an object in a context (e.g. {{context.getObject("foo")}}) but also using the context or some strategy to look up the property (e.g. {{context.getProperty(foo, "bar")}}). That's because my object {{foo}} is not a map and has a different way to get properties than simple reflection of getters. If you know the answer that let me know; otherwise I'll have to try it out. If it works let's talk more about this Release Manager. > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17253626#comment-17253626 ] Garret Wilson commented on JEXL-338: That's exciting to hear. Thanks for the reply, [~henrib]. I might be interested in volunteering, depending on of the project meets my needs. I'd also want to push for support of newer Java features (e.g. iteration on streams and lambas, if not supported). The biggest thing I need to know first of all is if JEXL will allow for the expression {{foo.bar}} not only looking up an object in a context (e.g. {{context.getObject("foo")}}) but also using the context or some strategy to look up the property (e.g. {{context.getProperty(foo, "bar")}}). That's because my object {{foo}} is not a map and has a different way to get properties than simple reflection of getters. If you know the answer that let me know; otherwise I'll have to try it out. If it works let's talk more about this Release Manager. > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Commented] (JEXL-338) Release 3.2 to Maven Central
[ https://issues.apache.org/jira/browse/JEXL-338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17253167#comment-17253167 ] Garret Wilson commented on JEXL-338: I just found this project. I need a lightweight expression language processor for my static site generator. Is this project still active? Are there plans to put out a new version? > Release 3.2 to Maven Central > > > Key: JEXL-338 > URL: https://issues.apache.org/jira/browse/JEXL-338 > Project: Commons JEXL > Issue Type: Wish > Environment: Maven, Eclipse-GIT, Maven Central. >Reporter: Sylke Soong >Priority: Critical > Labels: maven > > Similar to JEXL-220. > JEXL github homepage [https://github.com/apache/commons-jexl] recommends > {noformat} > > org.apache.commons > commons-jexl3 > 3.2 > {noformat} > But Maven central does not have it.. EGIT croaks artefact jar not foundr, > when jexl 3.2 dependency is in the pom. > -- This message was sent by Atlassian Jira (v8.3.4#803005)