Неизвестная ошибка операции при запуске программы Jolie с использованием Interpreter в Spring Boot - PullRequest
1 голос
/ 07 июля 2019

Недавно я получил ответ на этот вопрос о том, как объединить функции Jolie и Spring Boot.Я попытался реализовать предложенное решение, используя класс LocalCommChannel и локальный inputPort в Jolie, но, к сожалению, операция, которую я передаю в запросе, не распознается.Ниже мое Spring Boot Application, простой контроллер, который пытается запустить Интерпретатор и программу 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 проходит моя программа, и заметил, что при вызове getLocalCommChannel () он создает новый LocalListenerкоторый создает совершенно новый и пустой интерфейс InputPort, поэтому я не знаю, как будет видна операция дважды .Я подозреваю, что мне, возможно, придется использовать addLocalInputPort () в CommCore или mergeInterface () в LocalListener и настроить вещи самостоятельно, но я надеялся, что Джоли может позаботиться об этом без моих действий.

PS: есть ли онлайн-документациядля тех базовых классов Java Джоли или лучший и единственный вариант - прочитать код на github?

1 Ответ

1 голос
/ 08 июля 2019

В коде Java:

  • Вы не используете replaceAll и не экранируете $, как я делал в своем исходном сообщении: http://fmontesi.github.io/2015/01/30/running-jolie-inside-of-java.html
  • Вы незапуск переводчика.На самом деле, с тех пор, как я написал свое первоначальное сообщение в блоге, появился новый необычный интерфейс: вы можете вызватьinterter.start (), который возвращает будущее, в котором вы можете ждать, пока интерпретатор не будет готов к приему сообщений.

В коде Джоли:

  • Вам не нужно вызывать Runtime для использования локального местоположения.
  • Вы помещаете вычисления для операции запрос-ответ 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
    }]
}

Надеюсь, это поможет!

...