eclipse-ee4j / eclipse-ee4j/expressly
Support of static functions with varargs
- Dominant language
- Java
- Stars
- 15
- Forks
- 10
- PR merge metrics
- No merged PRs in 30d
Description
Expression Language API allows one to use a [FunctionMapper ](https://jakarta.ee/specifications/platform/10/apidocs/jakarta/el/functionmapper) to register a static function mapped to a [Method](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Method.html). For example, `${str:format(...)}` could be mapped to [String.format()](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#format(java.lang.String,java.lang.Object...)) function.
However, this does not work for methods with varargs. Thus, evaluation of `${str:format('%s%s', 'a', 'b')}` fails with:
```
jakarta.el.ELException: Function 'str:format' specifies 2 params, but 3 were supplied
at org.glassfish.expressly.lang.ExpressionBuilder.visit(ExpressionBuilder.java:244)
at org.glassfish.expressly.parser.SimpleNode.accept(SimpleNode.java:157)
at org.glassfish.expressly.lang.ExpressionBuilder.prepare(ExpressionBuilder.java:195)
at org.glassfish.expressly.lang.ExpressionBuilder.build(ExpressionBuilder.java:206)
at org.glassfish.expressly.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:255)
at org.glassfish.expressly.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:95)
```
By contrast, varargs methods are supported for Java Beans. If "str" was registered as a [String ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html) bean, then the following expression would work (note the '.' instead of the ':'): `${str.format('%s%s', 'a', 'b')}`.
There are two issues in expressly code:
1. `org.glassfish.expressly.parser.AstFunction.getValue()` contains a loop that coerces function arguments to the proper method parameter data types. This loop does not handle varargs. Instead, you may consider using `jakarta.el.ELUtil.buildParameters()` which does support varargs.
2. `org.glassfish.expressly.lang.ExpressionBuilder.visit()` compares the number of provided function arguments to the number of parameters of the method implementing this function. This logic does not consider variable number of arguments for varargs methods.
Contributor guide
Assessment
This issue has not been assessed yet.