Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 定义和重用MVEL函数_Java_Function_Embedding_Evaluation_Mvel - Fatal编程技术网

Java 定义和重用MVEL函数

Java 定义和重用MVEL函数,java,function,embedding,evaluation,mvel,Java,Function,Embedding,Evaluation,Mvel,是否可以使用MVEL定义一些自定义预编译函数,并在另一个编译表达式中使用它们? 如果我尝试以下方法: MVEL.compileExpression("function hello() { System.out.println(\"Hello!\"); hello(); return x * y;"); 当我第二次尝试执行它时,线程“main”[错误:复制函数:hello]中出现异常 看起来我不应该在表达式本身声明函数,而是在某种上下文中声明函数。我使用ParsedContext玩了一段时间,但

是否可以使用MVEL定义一些自定义预编译函数,并在另一个编译表达式中使用它们? 如果我尝试以下方法:

MVEL.compileExpression("function hello() { System.out.println(\"Hello!\"); hello(); return x * y;");
当我第二次尝试执行它时,线程“main”[错误:复制函数:hello]中出现异常

看起来我不应该在表达式本身声明函数,而是在某种上下文中声明函数。我使用ParsedContext玩了一段时间,但线程“main”中总是出现
异常[错误:无法访问属性(空父级):hello]

互联网上有很多教程,涵盖了不同的MVEL语言使用主题,但这些嵌入主题的文档记录非常少。你能告诉我我做错了什么吗


另外,我不想从Java执行某些函数。我需要用MVEL动态地定义它们。

这比一些常见的用例要复杂一些,尽管这是可能的

基本上,您需要做的是创建一个定义函数的脚本,如下所示:

VariableResolverFactory functionFactory = new MapVariableResolverFactory();
MVEL.eval("def foo() { System.out.println("foo"); }; def bar() { System.out.println("bar") };", functionFactory);
然后,您要做的是将此工厂反向链接到您运行的任何表达式:

VariableResolverFactory myVarFactory = new MapVariableResolverFactory();
myVarFactory.setNextFactory(functionFactory);

Serializable s = MVEL.compileExpression("foo(); bar();");

MVEL.executeExpression(s, myVarFactory);
函数作为引用记录在变量表中,因此可以使用常规变量工厂反向链接在MVEL中共享它们


注意:您不应该重新共享“myVarFactory”。您希望每次都创建一个新的。您只需要回收“functionFactory”并将其反向链接到每次运行的工厂,如上图所示。否则,您将在执行之间共享本地var状态——这不是线程安全的

这比一些常见的用例要复杂一些,尽管这是可能的

基本上,您需要做的是创建一个定义函数的脚本,如下所示:

VariableResolverFactory functionFactory = new MapVariableResolverFactory();
MVEL.eval("def foo() { System.out.println("foo"); }; def bar() { System.out.println("bar") };", functionFactory);
然后,您要做的是将此工厂反向链接到您运行的任何表达式:

VariableResolverFactory myVarFactory = new MapVariableResolverFactory();
myVarFactory.setNextFactory(functionFactory);

Serializable s = MVEL.compileExpression("foo(); bar();");

MVEL.executeExpression(s, myVarFactory);
函数作为引用记录在变量表中,因此可以使用常规变量工厂反向链接在MVEL中共享它们


注意:您不应该重新共享“myVarFactory”。您希望每次都创建一个新的。您只需要回收“functionFactory”并将其反向链接到每次运行的工厂,如上图所示。否则,您将在执行之间共享本地var状态——这不是线程安全的

您提供的示例在第二行给出了NullPointerException。原因可能是什么?我有MVEL2.0.19,并在clean main()方法中运行您的示例。所有这些都已修复。我还添加了一个附加的免责声明。我的意思是NPE在
MVEL.eval(“def foo(){System.out.println(\'foo\”;};def bar(){System.out.println(\'bar\”)};”,functionFactory)。节目的第二行!我已经切换到MVEL2.1.0.drools16,现在这个示例运行正常。非常感谢@MikeBrock感谢您花时间在这里发布您的解决方案,这为我节省了很多API侦察时间。尽管我想指出,当在赋值表达式中使用时,如果表达式以分号结尾,则函数只能在第一次调用之后成功执行。这是合理的,但值得注意的是,以防有人碰到它。您提供的示例在第二行给出了NullPointerException。原因可能是什么?我有MVEL2.0.19,并在clean main()方法中运行您的示例。所有这些都已修复。我还添加了一个附加的免责声明。我的意思是NPE在
MVEL.eval(“def foo(){System.out.println(\'foo\”;};def bar(){System.out.println(\'bar\”)};”,functionFactory)。节目的第二行!我已经切换到MVEL2.1.0.drools16,现在这个示例运行正常。非常感谢@MikeBrock感谢您花时间在这里发布您的解决方案,这为我节省了很多API侦察时间。尽管我想指出,当在赋值表达式中使用时,如果表达式以分号结尾,则函数只能在第一次调用之后成功执行。这是合理的,但值得注意的是,万一有人碰到它。