Specify whether evaluating `ValueExpression`s mapped in `VariableMapper` or created via `createValueExpression(Object, Class)` triggers `EvaluationListener`
Maintainers usually reply within 7 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 46/100
- Issue type
- Documentation
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- java
- Domain
- documentation, testing
Research direction
Start by reading Section 3.7 of the specification, the ExpressionFactory#createValueExpression(Object, Class<?>) and EvaluationListener Javadocs, and the existing TCK tests for evaluation listeners. The issue identifies divergent behavior but leaves the expected notifications undecided, so first trace how the specification and TCK cover these APIs. Done means the expected behavior is clarified in the specification and Javadoc and a TCK test validates it.
Written by the indexing model from the issue text.
Description
Section 3.7 ("Variables") of the Jakarta Expression Language 6.1 specification states:
An EL variable does not directly refer to a model object that can then be resolved by an
ELResolver. Instead, an EL variable refers to an EL expression. The evaluation of that EL expression yields the value associated with the EL variable.
When a variable is registered in VariableMapper using ExpressionFactory#createValueExpression(Object instance, Class<?> expectedType) and referenced inside another expression (e.g. ${person.name}), implementations diverge on whether evaluating the mapped ValueExpression fires EvaluationListener#beforeEvaluation and afterEvaluation:
- Eclipse Expressly: Fires
beforeEvaluationandafterEvaluationonly once for the outer expression${person.name}. Evaluating theValueExpressionLiteralcreated bycreateValueExpression(Object, Class)does not notifyEvaluationListener. - Apache Tomcat Jasper EL: Fires
beforeEvaluation("${person.name}"), then firesbeforeEvaluation(person.toString())andafterEvaluation(person.toString())whenValueExpressionLiteral#getValueis called, and finally firesafterEvaluation("${person.name}").
Steps to Reproduce
import jakarta.el.*;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
public class VariableMapperListenerTest {
public record Person(String name) {}
@Test
void testListenerWithVariableMapper() {
ExpressionFactory factory = ExpressionFactory.newInstance();
StandardELContext context = new StandardELContext(factory);
List<String> events = new ArrayList<>();
context.addEvaluationListener(new EvaluationListener() {
@Override
public void beforeEvaluation(ELContext ctx, String expr) {
events.add("before:" + expr);
}
@Override
public void afterEvaluation(ELContext ctx, String expr) {
events.add("after:" + expr);
}
@Override
public void propertyResolved(ELContext ctx, Object base, Object property) {
events.add("resolved:" + property);
}
});
Person person = new Person("Alice");
context.getVariableMapper().setVariable(
"person",
factory.createValueExpression(person, Person.class)
);
ValueExpression ve = factory.createValueExpression(context, "${person.name}", String.class);
ve.getValue(context);
// Expressly (3 events): [before:${person.name}, resolved:name, after:${person.name}]
// Jasper EL (5 events): [before:${person.name}, before:Person[name=Alice], after:Person[name=Alice], resolved:name, after:${person.name}]
System.out.println(events);
}
}
Request
Please clarify in the specification and Javadoc:
- Should
ValueExpressions created viaExpressionFactory#createValueExpression(Object, Class)notifyEvaluationListener#beforeEvaluationandafterEvaluationwhengetValue(ELContext)is called? - When resolving an identifier mapped via
VariableMapper, shouldbeforeEvaluation/afterEvaluationbe fired for the mappedValueExpression, or only for the top-level expression being evaluated? - Please add a TCK test validating the expected listener notifications.
- Dominant language
- Java
- Stars
- 86
- Forks
- 54
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 11
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from jakartaee/expression-language
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
jakartaee/expression-language#501 ·
Maintainers usually reply within 7 days
-
ELProcessor.defineFunction() fails for valid method signaturesPossibly taken @RaphaelFakhri claimed this 7 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
jakartaee/expression-language#492 ·
Maintainers usually reply within 7 days
-
Difficulty 4/5 3-5 days Newbie friendliness 57/100
jakartaee/expression-language#502 ·
Maintainers usually reply within 7 days
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
jakartaee/expression-language#500 ·
Maintainers usually reply within 7 days
-
certification
Difficulty 1/5 Under an hour Newbie friendliness 20/100
jakartaee/expression-language#494 · 2 reactions ·
Maintainers usually reply within 7 days
All issues in jakartaee/expression-language
Similar issues
-
desktop edt not responding
Difficulty 1/5 1-3 hours Newbie friendliness 86/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
physical
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
antonyrag/ragleap-core#1339 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
rezelyn/Wathe-Extended#116 ·