(tomcat) branch main updated: Correct the Elvis (?:) operator and add null coalescing (??) operator

2025-04-24 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
 new b037fcfec5 Correct the Elvis (?:) operator and add null coalescing 
(??) operator
b037fcfec5 is described below

commit b037fcfec53dda465e280d221fd5b85e50078794
Author: Mark Thomas 
AuthorDate: Thu Apr 24 15:05:28 2025 +0100

Correct the Elvis (?:) operator and add null coalescing (??) operator
---
 java/org/apache/el/parser/AstElvis.java|   8 +-
 .../{AstElvis.java => AstNullCoalescing.java}  |   8 +-
 java/org/apache/el/parser/ELParser.java| 706 +++--
 java/org/apache/el/parser/ELParser.jjt |   5 +-
 .../apache/el/parser/ELParserTreeConstants.java|  85 +--
 test/org/apache/el/TestELEvaluation.java   |  30 +-
 webapps/docs/changelog.xml |   4 +-
 7 files changed, 474 insertions(+), 372 deletions(-)

diff --git a/java/org/apache/el/parser/AstElvis.java 
b/java/org/apache/el/parser/AstElvis.java
index ce34074616..4a5982b3f1 100644
--- a/java/org/apache/el/parser/AstElvis.java
+++ b/java/org/apache/el/parser/AstElvis.java
@@ -20,6 +20,7 @@ package org.apache.el.parser;
 
 import jakarta.el.ELException;
 
+import org.apache.el.lang.ELSupport;
 import org.apache.el.lang.EvaluationContext;
 
 public class AstElvis extends SimpleNode {
@@ -36,10 +37,11 @@ public class AstElvis extends SimpleNode {
 @Override
 public Object getValue(EvaluationContext ctx) throws ELException {
 Object obj0 = this.children[0].getValue(ctx);
-if (obj0 == null) {
-return this.children[1].getValue(ctx);
-} else {
+Boolean b = ELSupport.coerceToBoolean(ctx, obj0, true);
+if (b.booleanValue()) {
 return obj0;
+} else {
+return this.children[1].getValue(ctx);
 }
 }
 }
diff --git a/java/org/apache/el/parser/AstElvis.java 
b/java/org/apache/el/parser/AstNullCoalescing.java
similarity index 86%
copy from java/org/apache/el/parser/AstElvis.java
copy to java/org/apache/el/parser/AstNullCoalescing.java
index ce34074616..98a010e32a 100644
--- a/java/org/apache/el/parser/AstElvis.java
+++ b/java/org/apache/el/parser/AstNullCoalescing.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Generated By:JJTree: Do not edit this line. AstElvis.java Version 7.0 */
+/* Generated By:JJTree: Do not edit this line. AstNullCoalescing.java Version 
7.0 */
 /* 
JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=Ast,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true
 */
 package org.apache.el.parser;
 
@@ -22,8 +22,8 @@ import jakarta.el.ELException;
 
 import org.apache.el.lang.EvaluationContext;
 
-public class AstElvis extends SimpleNode {
-public AstElvis(int id) {
+public class AstNullCoalescing extends SimpleNode {
+public AstNullCoalescing(int id) {
 super(id);
 }
 
@@ -43,4 +43,4 @@ public class AstElvis extends SimpleNode {
 }
 }
 }
-/* JavaCC - OriginalChecksum=e0633cc57b29ec4931c19e4a07e0611e (do not edit 
this line) */
+/* JavaCC - OriginalChecksum=7f7cabdfdef87abc6e6a22ac32db0871 (do not edit 
this line) */
diff --git a/java/org/apache/el/parser/ELParser.java 
b/java/org/apache/el/parser/ELParser.java
index 963e234aec..60e2729a36 100644
--- a/java/org/apache/el/parser/ELParser.java
+++ b/java/org/apache/el/parser/ELParser.java
@@ -594,10 +594,10 @@ public class ELParser/* @bgen(jjtree) */ implements 
ELParserTreeConstants, ELPar
 jj_la1[10] = jj_gen;
 break label_6;
 }
-if (jj_2_5(3)) {
+if (jj_2_5(2)) {
 jj_consume_token(QUESTIONMARK);
-jj_consume_token(COLON);
-AstElvis jjtn001 = new AstElvis(JJTELVIS);
+jj_consume_token(QUESTIONMARK);
+AstNullCoalescing jjtn001 = new 
AstNullCoalescing(JJTNULLCOALESCING);
 boolean jjtc001 = true;
 jjtree.openNodeScope(jjtn001);
 try {
@@ -633,46 +633,85 @@ public class ELParser/* @bgen(jjtree) */ implements 
ELParserTreeConstants, ELPar
 jjtree.closeNodeScope(jjtn001, 2);
 }
 }
+} else if (jj_2_6(2)) {
+jj_consume_token(QUESTIONMARK);
+jj_consume_token(COLON);
+AstElvis jjtn002 = new AstElvis(JJTELVIS);
+boolean jjtc002 = true;
+jjtree.openNodeScope(jjtn002);
+try {
+Ternary();
+} catch (Throwable jjte002) {
+if (jjtc002) {
+jjtree.clearNodeScope(jjtn002);
+  

[Bug 69659] New: Automatic JSP EL optimization

2025-04-24 Thread bugzilla
https://bz.apache.org/bugzilla/show_bug.cgi?id=69659

Bug ID: 69659
   Summary: Automatic JSP EL optimization
   Product: Tomcat 9
   Version: 9.0.98
  Hardware: All
OS: All
Status: NEW
  Severity: enhancement
  Priority: P2
 Component: Jasper
  Assignee: dev@tomcat.apache.org
  Reporter: jeng...@apache.org
  Target Milestone: -

The majority of my application's EL statements contain wasteful empty checks,
added by well-intended engineers who wanted to prevent NPEs.  Example:

${not empty availability && not availability.hasError && not empty
availability.primary && availability.primary.type == 'Whatever'}

Since EL inherently handles nulls, those checks are unnecessary, and the
example above could instead be:

${not availability.hasError && availability.primary.type == 'Whatever'}

I modified the existing benchmark TestELParserPerformance to support these two
queries and found the shorter one performs 40% faster.  The gains come from
fewer nodes and less reflection, as demonstrated in #69338 and #69381.

Educating our engineers and modifying our entire codebase is impractical, so
I'd like to modify Tomcat to automatically optimize the statements during JSP
code generation.  The statements are functionally equivalent so this could be
an always-on feature.

Specifically, I'd create ELOptimizer.optimize(statement) or similar, to be
called by Generator; however I'm unsure of the best way to build that logic.  A
single rule like we have here could be implemented a dozen different ways, but
we may want to add more in the future.  Is a simple implementation enough for
now or should we invest in an optimizing compiler of some sort?

-- 
You are receiving this mail because:
You are the assignee for the bug.
-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[Bug 69631] java.nio.channels.WritePendingException when using https-openssl-nio2 and virtual threads

2025-04-24 Thread bugzilla
https://bz.apache.org/bugzilla/show_bug.cgi?id=69631

--- Comment #18 from Mark Thomas  ---
NIO is poller based.
NIO2 is callback based.

Performance wise they should be pretty much identical.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[Bug 69631] java.nio.channels.WritePendingException when using https-openssl-nio2 and virtual threads

2025-04-24 Thread bugzilla
https://bz.apache.org/bugzilla/show_bug.cgi?id=69631

--- Comment #17 from Ronny Perinke  ---
We have cross-checked with HTTP and NIO to see if they are also affected.
http-nio2 and https-openssl-nio are _not_ affected, only https-openssl-nio2.

What are the effective differences between NIO and NIO2? We have been using
NIO2 for many years without virtual threads and have not noticed any
NIO2-related problems. The comparison table
(https://tomcat.apache.org/tomcat-11.0-doc/config/http.html#Connector_Comparison)
is not very helpful as it does not show any significant differences.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[Bug 69631] java.nio.channels.WritePendingException when using https-openssl-nio2 and virtual threads

2025-04-24 Thread bugzilla
https://bz.apache.org/bugzilla/show_bug.cgi?id=69631

--- Comment #19 from Remy Maucherat  ---
NIO2 is very clean, so initially when it was released it was better than NIO,
which felt abandoned.

Since then, roughly staring with Java 11, the following happened:
- NIO got fixes and significant refactorings.
- NIO got new features.
- NIO2 did not get the new features.

I don't see the trend reversing, so as a result, it might not be useful anymore
to keep NIO2 in Tomcat 12. I'm not 100% sure yet though.

Note: even if removed, it is important to keep things abstracted as if NIO is
not the only endpoint implementation.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org