com.ql.util.express.ExpressUtil#replaceString 方法存在空指针异常
- Dominant language
- Java
- Stars
- 5.6k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
现象描述:
1. 设置了compareNullLessMoreAsFalse = true
2. 为==操作符设置了errorInfo(这里只是拿==操作符进行举例说明,其他操作符是一样的)
3. ==操作符左边使用实例方法调用(对比静态方法调用)
4. ==操作符左边操作数传的是null,右边操作数不为null
5. 调用ExpressRunner.execute方法,errorInfoList参数不为空
结果说明:
1. ==操作符左边使用的是实例方法调用时,封装errorInfo结果会报空指针异常
2. ==操作符左边使用的是静态方法调用时,运行结果正常,封装errorInfo结果正常
pom依赖:
```
com.alibaba
QLExpress
3.3.4
```
测试主类:
```package org.example;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.config.QLExpressRunStrategy;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
// testClassFunction();
testServiceFunction();
}
private static void testClassFunction() throws Exception {
QLExpressRunStrategy.setCompareNullLessMoreAsFalse(true);
ExpressRunner runner = new ExpressRunner();
DefaultContext context = new DefaultContext();
context.put("a", null);
context.put("b", 2);
context.put("c", 3);
runner.addFunctionOfClassMethod("取绝对值", Math.class.getName(), "abs", new String[] {"double"}, null);
runner.addFunctionOfClassMethod("转换为大写", BeanExample.class.getName(), "upper", new String[] {"String"}, null);
runner.addFunctionOfClassMethod("转换为小写", BeanExample.class.getName(), "lower", new String[] {"String"}, null);
String express = "转换为小写(转换为大写(a)) == c;";
List errorList = new ArrayList<>();
runner.getOperatorFactory().getOperator("==").setErrorInfo("$1等于$2");
Object r = runner.execute(express, context, errorList, true, false);
System.out.println(r);
}
private static void testServiceFunction() throws Exception {
QLExpressRunStrategy.setCompareNullLessMoreAsFalse(true);
ExpressRunner runner = new ExpressRunner();
DefaultContext context = new DefaultContext();
context.put("a", null);
context.put("b", 2);
context.put("c", 3);
BeanServiceExample beanServiceExample = new BeanServiceExample();
runner.addFunctionOfServiceMethod("upper", beanServiceExample, "upper", new String[] {"String"}, null);
runner.addFunctionOfServiceMethod("lower", beanServiceExample, "lower", new String[] {"String"}, null);
String express = "beanServiceExample = new org.example.BeanServiceExample(); return beanServiceExample.lower(beanServiceExample.upper(a)) == c;";
List errorList = new ArrayList<>();
runner.getOperatorFactory().getOperator("==").setErrorInfo("$1等于$2");
Object r = runner.execute(express, context, errorList, true, false);
System.out.println(r);
}
}
```
testServiceFunction方法报错空指针异常:
```
Exception in thread "main" com.ql.util.express.exception.QLBizException: run QlExpress Exception at line 1 :
at com.ql.util.express.instruction.detail.InstructionOperator.execute(InstructionOperator.java:38)
at com.ql.util.express.InstructionSet.executeInnerOriginalInstruction(InstructionSet.java:200)
at com.ql.util.express.InstructionSet.execute(InstructionSet.java:164)
at com.ql.util.express.InstructionSetRunner.execute(InstructionSetRunner.java:64)
at com.ql.util.express.InstructionSetRunner.execute(InstructionSetRunner.java:55)
at com.ql.util.express.InstructionSetRunner.executeOuter(InstructionSetRunner.java:19)
at com.ql.util.express.ExpressRunner.executeReentrant(ExpressRunner.java:655)
at com.ql.util.express.ExpressRunner.executeInner(ExpressRunner.java:641)
at com.ql.util.express.ExpressRunner.execute(ExpressRunner.java:629)
at org.example.Main.testServiceFunction(Main.java:48)
at org.example.Main.main(Main.java:13)
Caused by: java.lang.NullPointerException: Cannot invoke "Object.toString()" because "parameters[index]" is null
at com.ql.util.express.ExpressUtil.replaceString(ExpressUtil.java:597)
at com.ql.util.express.instruction.op.OperatorBase.execute(OperatorBase.java:61)
at com.ql.util.express.instruction.detail.InstructionOperator.execute(InstructionOperator.java:32)
... 10 more
```
BeanServiceExample:
```
package org.example;
public class BeanServiceExample {
public String upper(String abc) {
if (null == abc) {
return null;
}
return abc.toUpperCase();
}
public String lower(String abc) {
if (null == abc) {
return null;
}
return abc.toLowerCase();
}
public boolean anyContains(String str, String searchStr) {
char[] s = str.toCharArray();
for (char c : s) {
if (searchStr.contains(c+"")) {
return true;
}
}
return false;
}
}
```
BeanExample:
```package org.example;
public class BeanExample {
public static String upper(String abc) {
if (null == abc) {
return null;
}
return abc.toUpperCase();
}
public static String lower(String abc) {
if (null == abc) {
return null;
}
return abc.toLowerCase();
}
public boolean anyContains(String str, String searchStr) {
char[] s = str.toCharArray();
for (char c : s) {
if (searchStr.contains(c+"")) {
return true;
}
}
return false;
}
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with ExpressUtil.java at replaceString and trace the call from OperatorBase.java while reproducing the service-method case in ExpressRunner.execute. Compare it with the static-method example using compareNullLessMoreAsFalse and operator errorInfo. Done means the service-method expression completes without a NullPointerException and errorList receives the expected formatted error information.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100