diff --git a/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java b/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java
index 68ac6ddb5..6736c55c0 100644
--- a/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java
+++ b/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java
@@ -85,6 +85,6 @@ public class JavaExecutor extends ScriptExecutor {
return "import com.yomahub.liteflow.script.body.JaninoCommonScriptBody;\n" +
script1 + "\n" +
StrUtil.format("{} item = new {}();\n", className, className) +
- "if (item instanceof JaninoCommonScriptBody){item.body(_meta);return null;}else{return item.body(_meta);}";
+ "if (JaninoCommonScriptBody.class.isInstance(item)){item.body(_meta);return null;}else{return item.body(_meta);}";
}
}
diff --git a/liteflow-script-plugin/liteflow-script-javax/pom.xml b/liteflow-script-plugin/liteflow-script-javax/pom.xml
new file mode 100644
index 000000000..446bea89d
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/pom.xml
@@ -0,0 +1,28 @@
+
+
+ 4.0.0
+
+ com.yomahub
+ liteflow-script-plugin
+ ${revision}
+ ../pom.xml
+
+
+ liteflow-script-javax
+
+
+
+ com.yomahub
+ liteflow-core
+ ${revision}
+ true
+ provided
+
+
+ org.noear
+ liquor-eval
+
+
+
\ No newline at end of file
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/BooleanScriptBody.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/BooleanScriptBody.java
new file mode 100644
index 000000000..c6be4e421
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/BooleanScriptBody.java
@@ -0,0 +1,6 @@
+package com.yomahub.liteflow.script.body;
+
+
+public interface BooleanScriptBody extends ScriptBody {
+
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/CommonScriptBody.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/CommonScriptBody.java
new file mode 100644
index 000000000..90d4ef7d4
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/CommonScriptBody.java
@@ -0,0 +1,5 @@
+package com.yomahub.liteflow.script.body;
+
+public interface CommonScriptBody extends ScriptBody {
+
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ForScriptBody.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ForScriptBody.java
new file mode 100644
index 000000000..92a47274e
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ForScriptBody.java
@@ -0,0 +1,6 @@
+package com.yomahub.liteflow.script.body;
+
+
+public interface ForScriptBody extends ScriptBody {
+
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ScriptBody.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ScriptBody.java
new file mode 100644
index 000000000..2d3414098
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/ScriptBody.java
@@ -0,0 +1,7 @@
+package com.yomahub.liteflow.script.body;
+
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
+
+public interface ScriptBody {
+ T body(ScriptExecuteWrap wrap);
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/SwitchScriptBody.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/SwitchScriptBody.java
new file mode 100644
index 000000000..854d42307
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/body/SwitchScriptBody.java
@@ -0,0 +1,6 @@
+package com.yomahub.liteflow.script.body;
+
+
+public interface SwitchScriptBody extends ScriptBody {
+
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/javax/JavaxExecutor.java b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/javax/JavaxExecutor.java
new file mode 100644
index 000000000..b26ad4144
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/java/com/yomahub/liteflow/script/javax/JavaxExecutor.java
@@ -0,0 +1,97 @@
+package com.yomahub.liteflow.script.javax;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.enums.ScriptTypeEnum;
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
+import com.yomahub.liteflow.script.ScriptExecutor;
+import com.yomahub.liteflow.script.exception.ScriptLoadException;
+import com.yomahub.liteflow.util.CopyOnWriteHashMap;
+import org.noear.liquor.eval.CodeSpec;
+import org.noear.liquor.eval.ScriptEvaluator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class JavaxExecutor extends ScriptExecutor {
+ private final Map compiledScriptMap = new CopyOnWriteHashMap<>();
+
+ private ScriptEvaluator scriptEvaluator;
+
+ @Override
+ public ScriptExecutor init() {
+ scriptEvaluator = new ScriptEvaluator();
+ scriptEvaluator.setPrintable(true);
+ return this;
+ }
+
+ @Override
+ public void load(String nodeId, String script) {
+ try{
+ compiledScriptMap.put(nodeId, (CodeSpec) compile(script));
+ }catch (Exception e){
+ String errorMsg = StrUtil.format("script loading error for node[{}],error msg:{}", nodeId, e.getMessage());
+ throw new ScriptLoadException(errorMsg);
+ }
+
+ }
+
+ @Override
+ public void unLoad(String nodeId) {
+ compiledScriptMap.remove(nodeId);
+ }
+
+ @Override
+ public List getNodeIds() {
+ return new ArrayList<>(compiledScriptMap.keySet());
+ }
+
+ @Override
+ public Object executeScript(ScriptExecuteWrap wrap) throws Exception {
+ if (!compiledScriptMap.containsKey(wrap.getNodeId())) {
+ String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
+ throw new ScriptLoadException(errorMsg);
+ }
+ CodeSpec codeSpec = compiledScriptMap.get(wrap.getNodeId());
+ return scriptEvaluator.eval(codeSpec, wrap);
+ }
+
+ @Override
+ public void cleanCache() {
+ compiledScriptMap.clear();
+ }
+
+ @Override
+ public ScriptTypeEnum scriptType() {
+ return ScriptTypeEnum.JAVA;
+ }
+
+ @Override
+ public Object compile(String script) throws Exception {
+ CodeSpec codeSpec = new CodeSpec(convertScript(script))
+ .returnType(Object.class)
+ .parameters(new String[] {"_meta"}, new Class[] {ScriptExecuteWrap.class});
+ scriptEvaluator.getClazz(codeSpec);
+ return codeSpec;
+ }
+
+ private String convertScript(String script){
+ //替换掉public,private,protected等修饰词
+ String script1 = script.replaceAll("public class", "class")
+ .replaceAll("private class", "class")
+ .replaceAll("protected class", "class");
+
+ //分析出class的具体名称
+ String className = ReUtil.getGroup1("class\\s+(\\w+)\\s+implements", script1);
+
+ if (StrUtil.isBlank(className)){
+ throw new RuntimeException("cannot find class defined");
+ }
+
+ return "import com.yomahub.liteflow.script.body.CommonScriptBody;\n" +
+ script1 + "\n" +
+ StrUtil.format("{} item = new {}();\n", className, className) +
+ "if (CommonScriptBody.class.isInstance(item)){item.body(_meta);return null;}else{return item.body(_meta);}";
+ }
+}
diff --git a/liteflow-script-plugin/liteflow-script-javax/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor b/liteflow-script-plugin/liteflow-script-javax/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor
new file mode 100644
index 000000000..2449bbec8
--- /dev/null
+++ b/liteflow-script-plugin/liteflow-script-javax/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor
@@ -0,0 +1,2 @@
+# Java的实现
+com.yomahub.liteflow.script.javax.JavaxExecutor
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/pom.xml b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/pom.xml
new file mode 100644
index 000000000..4636f0fd2
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ liteflow-testcase-el
+ com.yomahub
+ ${revision}
+ ../pom.xml
+
+
+ liteflow-testcase-el-script-javax-springboot
+
+
+
+ com.yomahub
+ liteflow-spring-boot-starter
+ ${revision}
+
+
+ com.yomahub
+ liteflow-script-javax
+ ${revision}
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.39
+
+
+
+
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java
new file mode 100644
index 000000000..14f3bdf59
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java
@@ -0,0 +1,24 @@
+package com.yomahub.liteflow.test;
+
+import com.yomahub.liteflow.core.FlowInitHook;
+import com.yomahub.liteflow.flow.FlowBus;
+import com.yomahub.liteflow.property.LiteflowConfigGetter;
+import com.yomahub.liteflow.spi.holder.SpiFactoryInitializing;
+import com.yomahub.liteflow.spring.ComponentScanner;
+import com.yomahub.liteflow.thread.ExecutorHelper;
+import org.junit.jupiter.api.AfterAll;
+
+public class BaseTest {
+
+ @AfterAll
+ public static void cleanScanCache() {
+ ComponentScanner.cleanCache();
+ FlowBus.cleanCache();
+ ExecutorHelper.loadInstance().clearExecutorServiceMap();
+ SpiFactoryInitializing.clean();
+ LiteflowConfigGetter.clean();
+ FlowInitHook.cleanHook();
+ FlowBus.clearStat();
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/ScriptJavaxCommonELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/ScriptJavaxCommonELTest.java
new file mode 100644
index 000000000..77cf4f457
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/ScriptJavaxCommonELTest.java
@@ -0,0 +1,38 @@
+package com.yomahub.liteflow.test.script.javax.common;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.annotation.Resource;
+
+@ExtendWith(SpringExtension.class)
+@TestPropertySource(value = "classpath:/common/application.properties")
+@SpringBootTest(classes = ScriptJavaxCommonELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({ "com.yomahub.liteflow.test.script.javax.common.cmp" })
+public class ScriptJavaxCommonELTest extends BaseTest {
+
+ @Resource
+ private FlowExecutor flowExecutor;
+
+ // 测试普通脚本节点
+ @Test
+ public void testCommon1() {
+ LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+ DefaultContext context = response.getFirstContextBean();
+ Assertions.assertTrue(response.isSuccess());
+ Assertions.assertEquals(6, (int)context.getData("s1"));
+ Assertions.assertEquals("hello,jack", context.getData("hi"));
+ Assertions.assertEquals(47100, (Integer) context.getData("salary"));
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/ACmp.java
new file mode 100644
index 000000000..ae83cd47c
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/ACmp.java
@@ -0,0 +1,21 @@
+/**
+ * Title: liteflow
+ * Description: 轻量级的组件式流程框架
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowComponent;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowComponent("a")
+public class ACmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ System.out.println("ACmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/BCmp.java
new file mode 100644
index 000000000..3592855be
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/BCmp.java
@@ -0,0 +1,21 @@
+/**
+ * Title: liteflow
+ * Description: 轻量级的组件式流程框架
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowComponent;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowComponent("b")
+public class BCmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ System.out.println("BCmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/CCmp.java
new file mode 100644
index 000000000..ed6122528
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/CCmp.java
@@ -0,0 +1,21 @@
+/**
+ * Title: liteflow
+ * Description: 轻量级的组件式流程框架
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowComponent;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowComponent("c")
+public class CCmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ System.out.println("CCmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/DCmp.java
new file mode 100644
index 000000000..e7d139b20
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/DCmp.java
@@ -0,0 +1,24 @@
+/**
+ * Title: liteflow
+ * Description: 轻量级的组件式流程框架
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowComponent;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+@LiteflowComponent("d")
+public class DCmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ DefaultContext context = this.getFirstContextBean();
+ context.setData("count", 198);
+ System.out.println("DCmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/Person.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/Person.java
new file mode 100644
index 000000000..6f7349ddd
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/Person.java
@@ -0,0 +1,28 @@
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+public class Person {
+ private String name;
+
+ private Integer salary;
+
+ public Person(String name, Integer salary) {
+ this.name = name;
+ this.salary = salary;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getSalary() {
+ return salary;
+ }
+
+ public void setSalary(Integer salary) {
+ this.salary = salary;
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/TestDomain.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/TestDomain.java
new file mode 100644
index 000000000..7f4852831
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/common/cmp/TestDomain.java
@@ -0,0 +1,26 @@
+package com.yomahub.liteflow.test.script.javax.common.cmp;
+
+import cn.hutool.core.collection.ListUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.function.ToIntFunction;
+
+@Component
+public class TestDomain {
+
+ public String sayHello(String name){
+ return "hello," + name;
+ }
+
+ public static void main(String[] args) {
+ List personList = ListUtil.toList(
+ new Person("jack", 15000),
+ new Person("tom", 13500),
+ new Person("peter", 18600)
+ );
+
+ int totalSalary = personList.stream().mapToInt(Person::getSalary).sum();
+ System.out.println(totalSalary);
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/remove/LiteFlowJavaxScriptRemoveELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/remove/LiteFlowJavaxScriptRemoveELTest.java
new file mode 100644
index 000000000..09f423adb
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/remove/LiteFlowJavaxScriptRemoveELTest.java
@@ -0,0 +1,124 @@
+package com.yomahub.liteflow.test.script.javax.remove;
+
+import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.enums.ScriptTypeEnum;
+import com.yomahub.liteflow.exception.ELParseException;
+import com.yomahub.liteflow.flow.FlowBus;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.script.ScriptExecutor;
+import com.yomahub.liteflow.script.ScriptExecutorFactory;
+import com.yomahub.liteflow.script.exception.ScriptLoadException;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 测试脚本的卸载和重载功能
+ *
+ * @author DaleLee
+ */
+@ExtendWith(SpringExtension.class)
+@TestPropertySource(value = "classpath:/remove/application.properties")
+@SpringBootTest(classes = LiteFlowJavaxScriptRemoveELTest.class)
+@EnableAutoConfiguration
+public class LiteFlowJavaxScriptRemoveELTest extends BaseTest {
+
+ @Resource
+ private FlowExecutor flowExecutor;
+
+ private ScriptExecutor scriptExecutor = ScriptExecutorFactory.loadInstance()
+ .getScriptExecutor(ScriptTypeEnum.JAVA.getDisplayName());
+
+ // 仅卸载脚本
+ @Test
+ public void testUnload() {
+ flowExecutor.reloadRule();
+
+ // 获取节点id
+ List nodeIds = scriptExecutor.getNodeIds();
+ Assertions.assertEquals(2, nodeIds.size());
+ Assertions.assertTrue(nodeIds.contains("s1"));
+ Assertions.assertTrue(nodeIds.contains("s2"));
+
+ // 保证脚本可以正常运行
+ LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+ Assertions.assertTrue(response.isSuccess());
+ DefaultContext context = response.getFirstContextBean();
+ Assertions.assertEquals(Integer.valueOf(6), context.getData("s1"));
+
+ // 卸载脚本
+ scriptExecutor.unLoad("s1");
+ response = flowExecutor.execute2Resp("chain1", "arg");
+ Assertions.assertFalse(response.isSuccess());
+ Assertions.assertEquals(ScriptLoadException.class, response.getCause().getClass());
+ Assertions.assertEquals("script for node[s1] is not loaded", response.getMessage());
+
+ // 脚本已卸载
+ Assertions.assertFalse(scriptExecutor.getNodeIds().contains("s1"));
+ }
+
+ // 卸载节点和脚本
+ @Test
+ public void testRemove() {
+ flowExecutor.reloadRule();
+
+ // 保证脚本可以正常运行
+ LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+ Assertions.assertTrue(response.isSuccess());
+ DefaultContext context = response.getFirstContextBean();
+ Assertions.assertEquals(Integer.valueOf(5), context.getData("s2"));
+
+ // 卸载节点
+ FlowBus.unloadScriptNode("s2");
+
+ // 旧 chain 报脚本加载错误
+ response = flowExecutor.execute2Resp("chain2", "arg");
+ Assertions.assertEquals(ScriptLoadException.class, response.getCause().getClass());
+
+ // 新 chian 会找不到节点
+ Assertions.assertThrows(ELParseException.class,
+ () -> LiteFlowChainELBuilder.createChain()
+ .setChainId("chain3")
+ .setEL("THEN(s2)")
+ .build());
+
+ // 节点已卸载
+ Assertions.assertFalse(FlowBus.containNode("s2"));
+ // 脚本已卸载
+ Assertions.assertFalse(scriptExecutor.getNodeIds().contains("s2"));
+ }
+
+ // 重载脚本
+ @Test
+ public void testReloadScript() {
+ flowExecutor.reloadRule();
+ String script = " import com.yomahub.liteflow.slot.DefaultContext;\n" +
+ " import com.yomahub.liteflow.script.body.CommonScriptBody;\n" +
+ " import com.yomahub.liteflow.script.ScriptExecuteWrap;\n" +
+ "\n" +
+ " public class Demo implements CommonScriptBody {\n" +
+ " public Void body(ScriptExecuteWrap wrap) {\n" +
+ " DefaultContext ctx = wrap.getCmp().getFirstContextBean();\n" +
+ " ctx.setData(\"s1\", \"abc\");\n" +
+ " return null;\n" +
+ " }\n" +
+ " }";
+ FlowBus.reloadScript("s1", script);
+ LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+ DefaultContext context = response.getFirstContextBean();
+ // 执行结果变更
+ Assertions.assertEquals("abc", context.getData("s1"));
+ // 脚本变更
+ Assertions.assertEquals(FlowBus.getNode("s1").getScript(), script);
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/validate/ValidateJavaxScriptComponentTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/validate/ValidateJavaxScriptComponentTest.java
new file mode 100644
index 000000000..11c443e05
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/java/com/yomahub/liteflow/test/script/javax/validate/ValidateJavaxScriptComponentTest.java
@@ -0,0 +1,66 @@
+package com.yomahub.liteflow.test.script.javax.validate;
+
+import com.yomahub.liteflow.enums.ScriptTypeEnum;
+import com.yomahub.liteflow.script.validator.ScriptValidator;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = ValidateJavaxScriptComponentTest.class)
+@EnableAutoConfiguration
+public class ValidateJavaxScriptComponentTest {
+ @Test
+ public void testJavaScriptComponentValidateFunction(){
+ String correctScript = "import com.alibaba.fastjson2.JSON;\n" +
+ " import com.yomahub.liteflow.slot.DefaultContext;\n" +
+ " import com.yomahub.liteflow.spi.holder.ContextAwareHolder;\n" +
+ " import com.yomahub.liteflow.test.script.java.common.cmp.TestDomain;\n" +
+ " import com.yomahub.liteflow.script.body.CommonScriptBody;\n" +
+ " import com.yomahub.liteflow.script.ScriptExecuteWrap;\n" +
+ "\n" +
+ " public class Demo implements CommonScriptBody {\n" +
+ " public Void body(ScriptExecuteWrap wrap) {\n" +
+ " int v1 = 2;\n" +
+ " int v2 = 3;\n" +
+ " DefaultContext ctx = wrap.getCmp().getFirstContextBean();\n" +
+ " ctx.setData(\"s1\", v1 * v2);\n" +
+ "\n" +
+ " TestDomain domain = ContextAwareHolder.loadContextAware().getBean(TestDomain.class);\n" +
+ " System.out.println(JSON.toJSONString(domain));\n" +
+ " String str = domain.sayHello(\"jack\");\n" +
+ " ctx.setData(\"hi\", str);\n" +
+ "\n" +
+ " return null;\n" +
+ " }\n" +
+ " }";
+ // 未指定类型名错误
+ String wrongScript = "import com.alibaba.fastjson2.JSON;\n" +
+ " import com.yomahub.liteflow.slot.DefaultContext;\n" +
+ " import com.yomahub.liteflow.spi.holder.ContextAwareHolder;\n" +
+ " import com.yomahub.liteflow.test.script.java.common.cmp.TestDomain;\n" +
+ " import com.yomahub.liteflow.script.body.CommonScriptBody;\n" +
+ " import com.yomahub.liteflow.script.ScriptExecuteWrap;\n" +
+ "\n" +
+ " public class Demo implements CommonScriptBody {\n" +
+ " public Void body(ScriptExecuteWrap wrap) {\n" +
+ " v1 = 2;\n" +
+ " int v2 = 3;\n" +
+ " DefaultContext ctx = wrap.getCmp().getFirstContextBean();\n" +
+ " ctx.setData(\"s1\", v1 * v2);\n" +
+ "\n" +
+ " TestDomain domain = ContextAwareHolder.loadContextAware().getBean(TestDomain.class);\n" +
+ " System.out.println(JSON.toJSONString(domain));\n" +
+ " String str = domain.sayHello(\"jack\");\n" +
+ " ctx.setData(\"hi\", str);\n" +
+ "\n" +
+ " return null;\n" +
+ " }\n" +
+ " }";
+ Assertions.assertTrue(ScriptValidator.validate(correctScript));
+ Assertions.assertFalse(ScriptValidator.validate(wrongScript));
+
+ Assertions.assertTrue(ScriptValidator.validate(correctScript, ScriptTypeEnum.JAVA));
+ Assertions.assertFalse(ScriptValidator.validate(correctScript, ScriptTypeEnum.GROOVY));
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/application.properties b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/application.properties
new file mode 100644
index 000000000..4c9c216b6
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/application.properties
@@ -0,0 +1 @@
+liteflow.rule-source=common/flow.xml
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/flow.xml
new file mode 100644
index 000000000..57f52a9d5
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/common/flow.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+ personList = ListUtil.toList(
+ new Person("jack", 15000),
+ new Person("tom", 13500),
+ new Person("peter", 18600)
+ );
+
+ int totalSalary = personList.stream().mapToInt(Person::getSalary).sum();
+
+ System.out.println(totalSalary);
+ ctx.setData("salary", 47100);
+
+ return null;
+ }
+ }
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+ THEN(FOR(s2).DO(THEN(a, b, c, s1)), SWITCH(s3).TO(a,b));
+
+
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/application.properties b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/application.properties
new file mode 100644
index 000000000..21b596255
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/application.properties
@@ -0,0 +1 @@
+liteflow.rule-source=remove/flow.xml
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/flow.xml
new file mode 100644
index 000000000..e80b964fc
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javax-springboot/src/test/resources/remove/flow.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ THEN(s1);
+
+
+
+ THEN(s2);
+
+
\ No newline at end of file
diff --git a/liteflow-testcase-el/pom.xml b/liteflow-testcase-el/pom.xml
index c7f23ce38..a1407eefc 100644
--- a/liteflow-testcase-el/pom.xml
+++ b/liteflow-testcase-el/pom.xml
@@ -42,6 +42,7 @@
liteflow-testcase-el-routechain
liteflow-testcase-el-script-kotlin-springboot
liteflow-testcase-el-sql-solon
+ liteflow-testcase-el-script-javax-springboot
diff --git a/pom.xml b/pom.xml
index 53919555e..eea9cb820 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,6 +77,7 @@
3.21.0
3.1.12
1.9.23
+ 1.2.7-SNAPSHOT
@@ -320,6 +321,11 @@
kotlin-scripting-jsr223
${kotlin.version}
+
+ org.noear
+ liquor-eval
+ ${liquor.version}
+
@@ -442,6 +448,7 @@
liteflow-solon-plugin
liteflow-testcase-el
liteflow-el-builder
+ liteflow-script-plugin/liteflow-script-javax