运行 Jolie 程序在 Spring Boot 中使用 Interpreter 时出现未知运行错误
Unknown operation error when running Jolie program using Interpreter in Spring Boot
不久前,我得到了关于如何结合 Jolie 和 Spring 引导功能的 问题的答案。我已尝试在 Jolie 中使用 LocalCommChannel class 和本地 inputPort 来实施建议的解决方案,但不幸的是,无法识别我在请求中传递的操作。下面是我的 Spring 启动应用程序,一个尝试 运行 解释器和 Jolie 程序的简单控制器。
App.java
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
HelloController.java
@RestController
public class HelloController {
@RequestMapping("/")
String hello() {
String jh = System.getenv( "JOLIE_HOME" );
String arg[] = new String[]{
"-l",
".\lib\*;$JOLIE_HOME\lib;$JOLIE_HOME\javaServices\*;$JOLIE_HOME\extensions\*".replace("$JOLIE_HOME", jh),
"-i",
"$JOLIE_HOME\include".replace("$JOLIE_HOME", jh),
"main.ol"
};
try {
final Interpreter interpreter = new Interpreter(arg, HelloController.class.getClassLoader(), null);
Value v = Value.create();
v.setFirstChild( "number", 5 );
CommMessage request = CommMessage.createRequest( "twice", "/", v );
LocalCommChannel c = interpreter.commCore().getLocalCommChannel();
c.send( request );
CommMessage response = c.recvResponseFor( request );
if ( response.isFault() ) {
System.out.println("thrown response.fault()");
throw response.fault();
}
return response.value().toString();
} catch (Exception e) {
e.printStackTrace();
}
return "Bad result";
}
}
main.ol
include "console.iol"
include "runtime.iol"
execution { concurrent }
type TwiceRequest: void {
.number: int
}
type TwiceResponse: void {
.result: int
}
interface LocalInterface {
RequestResponse:
twice(TwiceRequest)(TwiceResponse)
}
inputPort TwiceIP {
Location: "local"
Interfaces: LocalInterface
}
init
{
getLocalLocation@Runtime()( TwiceIP.location )
}
main {
[twice( request )( response )] {
println@Console("Hello World")();
response.result = request.number * 2
}
}
输出
2019-07-07 18:20:53.315 WARN 19236 --- [ Thread-3] Jolie : [main.ol] Received
a message for operation twice, not specified in the input port LocalInputPort
at the receiving service. Sending IOException to the caller.
thrown response.fault()
jolie.runtime.FaultException: IOException: Invalid operation: twice
at jolie.net.CommCore$CommChannelHandlerRunnable.handleMessage(CommCore.java:594)
at jolie.net.CommCore$CommChannelHandlerRunnable.run(CommCore.java:620)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我试图跟踪我的程序经过了哪些 Jolie classes 和函数,我注意到当调用 getLocalCommChannel() 时,它创建了新的 LocalListener,它创建了全新的空接口 InputPort,所以我不知道 twice 操作如何可见。我怀疑我可能不得不在 CommCore 中使用 addLocalInputPort() 或在 LocalListener 中使用 mergeInterface() 并自己进行配置,但我希望 Jolie 可以在我不采取行动的情况下解决这个问题。
PS:是否有任何有关 Jolie 核心 Java class 的在线文档,或者最好且唯一的选择是阅读 github 上的代码?
在Java代码中:
- 您没有使用 replaceAll,也没有像我原来的那样转义 $ post:http://fmontesi.github.io/2015/01/30/running-jolie-inside-of-java.html
- 您没有启动解释器。自从我写了我的原始博客 post 以来,实际上有一个新的更漂亮的界面:你可以调用 interpreter.start(),这 returns 你可以等待直到解释器准备好接收消息.
在朱莉代码中:
- 您不需要调用运行时来使用本地位置。
- 您在发送响应后为 request-response 操作
twice
进行了计算(注意放置方括号的位置)。
这是一个对我有用的例子。请注意,我使用的是 : 而不是 ;作为参数中的路径分隔符(我正在 Linux 上进行测试),您可能需要更改它。
Example.java
public class Example
{
public static void main( String[] args )
{
String jh = System.getenv( "JOLIE_HOME" );
String arg[] = {
"-l",
"./lib/*:$JOLIE_HOME/lib:$JOLIE_HOME/javaServices/*:$JOLIE_HOME/extensions/*".replaceAll("\$JOLIE_HOME", jh),
"-i",
"$JOLIE_HOME/include".replaceAll("\$JOLIE_HOME", jh),
"main.ol"
};
try {
final Interpreter interpreter = new Interpreter(arg, Example.class.getClassLoader(), null);
Exception e = interpreter.start().get();
if ( e != null )
throw e;
Value v = Value.create();
v.setFirstChild( "number", 5 );
CommMessage request = CommMessage.createRequest( "twice", "/", v );
LocalCommChannel c = interpreter.commCore().getLocalCommChannel();
c.send( request );
CommMessage response = c.recvResponseFor( request ).get();
if ( response.isFault() ) {
System.out.println("thrown response.fault()");
throw response.fault();
}
System.out.println( response.value().getFirstChild( "result" ).strValue() );
} catch (Exception e) {
e.printStackTrace();
}
}
}
main.ol
include "console.iol"
execution { concurrent }
type TwiceRequest: void {
.number: int
}
type TwiceResponse: void {
.result: int
}
interface LocalInterface {
RequestResponse:
twice(TwiceRequest)(TwiceResponse)
}
inputPort TwiceIP {
Location: "local"
Interfaces: LocalInterface
}
main {
[twice( request )( response ) {
println@Console("Hello World")();
response.result = request.number * 2
}]
}
希望对您有所帮助!
不久前,我得到了关于如何结合 Jolie 和 Spring 引导功能的
App.java
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
HelloController.java
@RestController
public class HelloController {
@RequestMapping("/")
String hello() {
String jh = System.getenv( "JOLIE_HOME" );
String arg[] = new String[]{
"-l",
".\lib\*;$JOLIE_HOME\lib;$JOLIE_HOME\javaServices\*;$JOLIE_HOME\extensions\*".replace("$JOLIE_HOME", jh),
"-i",
"$JOLIE_HOME\include".replace("$JOLIE_HOME", jh),
"main.ol"
};
try {
final Interpreter interpreter = new Interpreter(arg, HelloController.class.getClassLoader(), null);
Value v = Value.create();
v.setFirstChild( "number", 5 );
CommMessage request = CommMessage.createRequest( "twice", "/", v );
LocalCommChannel c = interpreter.commCore().getLocalCommChannel();
c.send( request );
CommMessage response = c.recvResponseFor( request );
if ( response.isFault() ) {
System.out.println("thrown response.fault()");
throw response.fault();
}
return response.value().toString();
} catch (Exception e) {
e.printStackTrace();
}
return "Bad result";
}
}
main.ol
include "console.iol"
include "runtime.iol"
execution { concurrent }
type TwiceRequest: void {
.number: int
}
type TwiceResponse: void {
.result: int
}
interface LocalInterface {
RequestResponse:
twice(TwiceRequest)(TwiceResponse)
}
inputPort TwiceIP {
Location: "local"
Interfaces: LocalInterface
}
init
{
getLocalLocation@Runtime()( TwiceIP.location )
}
main {
[twice( request )( response )] {
println@Console("Hello World")();
response.result = request.number * 2
}
}
输出
2019-07-07 18:20:53.315 WARN 19236 --- [ Thread-3] Jolie : [main.ol] Received
a message for operation twice, not specified in the input port LocalInputPort
at the receiving service. Sending IOException to the caller.
thrown response.fault()
jolie.runtime.FaultException: IOException: Invalid operation: twice
at jolie.net.CommCore$CommChannelHandlerRunnable.handleMessage(CommCore.java:594)
at jolie.net.CommCore$CommChannelHandlerRunnable.run(CommCore.java:620)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我试图跟踪我的程序经过了哪些 Jolie classes 和函数,我注意到当调用 getLocalCommChannel() 时,它创建了新的 LocalListener,它创建了全新的空接口 InputPort,所以我不知道 twice 操作如何可见。我怀疑我可能不得不在 CommCore 中使用 addLocalInputPort() 或在 LocalListener 中使用 mergeInterface() 并自己进行配置,但我希望 Jolie 可以在我不采取行动的情况下解决这个问题。
PS:是否有任何有关 Jolie 核心 Java class 的在线文档,或者最好且唯一的选择是阅读 github 上的代码?
在Java代码中:
- 您没有使用 replaceAll,也没有像我原来的那样转义 $ post:http://fmontesi.github.io/2015/01/30/running-jolie-inside-of-java.html
- 您没有启动解释器。自从我写了我的原始博客 post 以来,实际上有一个新的更漂亮的界面:你可以调用 interpreter.start(),这 returns 你可以等待直到解释器准备好接收消息.
在朱莉代码中:
- 您不需要调用运行时来使用本地位置。
- 您在发送响应后为 request-response 操作
twice
进行了计算(注意放置方括号的位置)。
这是一个对我有用的例子。请注意,我使用的是 : 而不是 ;作为参数中的路径分隔符(我正在 Linux 上进行测试),您可能需要更改它。
Example.java
public class Example
{
public static void main( String[] args )
{
String jh = System.getenv( "JOLIE_HOME" );
String arg[] = {
"-l",
"./lib/*:$JOLIE_HOME/lib:$JOLIE_HOME/javaServices/*:$JOLIE_HOME/extensions/*".replaceAll("\$JOLIE_HOME", jh),
"-i",
"$JOLIE_HOME/include".replaceAll("\$JOLIE_HOME", jh),
"main.ol"
};
try {
final Interpreter interpreter = new Interpreter(arg, Example.class.getClassLoader(), null);
Exception e = interpreter.start().get();
if ( e != null )
throw e;
Value v = Value.create();
v.setFirstChild( "number", 5 );
CommMessage request = CommMessage.createRequest( "twice", "/", v );
LocalCommChannel c = interpreter.commCore().getLocalCommChannel();
c.send( request );
CommMessage response = c.recvResponseFor( request ).get();
if ( response.isFault() ) {
System.out.println("thrown response.fault()");
throw response.fault();
}
System.out.println( response.value().getFirstChild( "result" ).strValue() );
} catch (Exception e) {
e.printStackTrace();
}
}
}
main.ol
include "console.iol"
execution { concurrent }
type TwiceRequest: void {
.number: int
}
type TwiceResponse: void {
.result: int
}
interface LocalInterface {
RequestResponse:
twice(TwiceRequest)(TwiceResponse)
}
inputPort TwiceIP {
Location: "local"
Interfaces: LocalInterface
}
main {
[twice( request )( response ) {
println@Console("Hello World")();
response.result = request.number * 2
}]
}
希望对您有所帮助!