You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2013/11/18 14:42:42 UTC
[Bug 55792] New: Collection literals not recognized within stream
lambda expression, result in syntax error
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
Bug ID: 55792
Summary: Collection literals not recognized within stream
lambda expression, result in syntax error
Product: Tomcat 8
Version: 8.0.0-RC5
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P2
Component: EL
Assignee: dev@tomcat.apache.org
Reporter: nicholas@nicholaswilliams.net
I have the following EL expression in a JSP. The expression evaluates and
executes correctly without error:
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.toList()}
I want to apply the map operation to this as well. Section 2.3.6.4 of the JUEL
3.0 specification uses the following example, where a list-literal is used as
the right-hand side of the mapping lambda expression:
products.stream().filter(p->p.unitPrice >= 10)
.map(p->[p.name, p.unitPrice])
.toList()
So I tried applying the exact same pattern to my map operation (the new map
operation is the only change to the expression):
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> [u.username, u.firstName, u.lastName])
.toList()}
I also tried using a map-literal:
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> {'username':u.username, 'first':u.firstName,
'last':u.lastName})
.toList()}
However, using the list-literal in my map lambda expression results in this
error, indicating that it doesn't recognize the list-literal as a list-literal:
javax.el.ELException: java.lang.NumberFormatException: For input string:
"lastName"
javax.el.BeanELResolver.invoke(BeanELResolver.java:185)
org.apache.jasper.el.JasperELResolver.invoke(JasperELResolver.java:147)
org.apache.el.parser.AstValue.getValue(AstValue.java:158)
...
And using the map-literal results in this error, indicating that it doesn't
recognize the map-literal as a map-literal (instead, it thinks the closing
brace of the map-literal is the end of the EL expression:
javax.el.ELException: Failed to parse the expression [${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> {'username':u.username, 'first':u.firstName,
'last':u.lastName}]
...
<root cause>
org.apache.el.parser.ParseException: Encountered "<EOF>" at line 6, column 38.
Was expecting one of:
"." ...
")" ...
etc...
Putting parentheses around the list- and map-literals does not work, but the
Section 2.3.6.4 example doesn't use parentheses. Section 1.20 also indicates
that collection literals as bodies of lambda expressions are legal:
customers.select(c->[c.name, c.orders.sum(o->o.total)])
Collection literals are described in more detail in Section 2.2.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] EL expression containing a map is not parsed correctly.
'}' is interpreted as closing brace of the EL expression.
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
--- Comment #4 from Konstantin Kolinko <kn...@gmail.com> ---
Created attachment 31054
--> https://issues.apache.org/bugzilla/attachment.cgi?id=31054&action=edit
2013-11-19_55792_tc8_tests.patch
Amendment to the tests. This is currently failing.
Notes:
1. This issue affects not only maps, but sets as well. In my reproducer
"{1,2,3,4}" is a set, not a map.
2. I am using sorted() so that the result of evaluation were not affected by
the order of items in a HashSet.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] EL expression containing a map is not parsed correctly.
'}' is interpreted as closing brace of the EL expression.
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
Konstantin Kolinko <kn...@gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Summary|Collection literals not |EL expression containing a
|recognized within stream |map is not parsed
|lambda expression, result |correctly. '}' is
|in syntax error |interpreted as closing
| |brace of the EL expression.
--- Comment #2 from Konstantin Kolinko <kn...@gmail.com> ---
(For reference - discussion on users@ before filing this issue
http://tomcat.markmail.org/thread/mohw6qhaauez27h5
The only issue here is that '}' in declaration of a map is interpreted as
closing brace of EL expression. I am changing TITLE accordingly.
Searching through Tomcat 8 sources, we have a similar test:
/test/webapp/el-misc.jsp
The code there is
<tags:echo echo='19-${{1,2,3,4}.stream().max().orElse(-1)}' />
The above works when EL is used in an attribute of a tag.
But when I move the EL expression into the body of the document, it starts to
fail. The following simple JSP fails
[[[
<%@page contentType="text/plain; charset=UTF-8"%>
${{1,2,3,4}.stream().max().orElse(-1)}
]]]
javax.el.ELException: Failed to parse the expression [${{1,2,3,4}]
For completeness, '}' in string literals is parsed correctly.
The following JSP does work
[[[
<%@page contentType="text/plain; charset=UTF-8"%>
${'}A'}B
${"}C"}D
]]]
It prints
}AB
}CD
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] EL expression containing a map is not parsed correctly.
'}' is interpreted as closing brace of the EL expression.
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
Mark Thomas <ma...@apache.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution|--- |FIXED
--- Comment #5 from Mark Thomas <ma...@apache.org> ---
Nick, thanks for the report.
Konstantin, thanks for the test case.
Thsi has been fixed in trunk and will be in 8.0.0-RC6 onwards.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] Collection literals not recognized within stream lambda
expression, result in syntax error
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
--- Comment #1 from Nick Williams <ni...@nicholaswilliams.net> ---
Please note the following revision to this bug:
It's only the map-literal that isn't working. The list-literal is working fine.
When I used the list-literal originally, I mapped before sorting, like so:
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.map(u -> [u.username, u.firstName, u.lastName])
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.toList()}
This caused the NumberFormatException, which makes sense. When mapping happens
after sorting:
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> [u.username, u.firstName, u.lastName])
.toList()}
The expression works correctly. So the ONLY expression that isn't working uses
the map-literal for the mapping:
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> {'username':u.username, 'first':u.firstName,
'last':u.lastName})
.toList()}
This is definitely broken, as the } ending the map-literal makes the EL engine
think the expression has ended prematurely.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] EL expression containing a map is not parsed correctly.
'}' is interpreted as closing brace of the EL expression.
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
--- Comment #3 from Konstantin Kolinko <kn...@gmail.com> ---
Created attachment 31053
--> https://issues.apache.org/bugzilla/attachment.cgi?id=31053&action=edit
test_55792.jsp - Sample JSP page
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[Bug 55792] EL expression containing a map is not parsed correctly.
'}' is interpreted as closing brace of the EL expression.
Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=55792
--- Comment #6 from Nick Williams <ni...@nicholaswilliams.net> ---
I can confirm that this is fixed. Thanks!
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org