Запустить код R из сервлета Java

Я пытаюсь запустить код R из сервлета Java, работающего в Eclipse, как IDE на TomCat 7.0.

Целью END является создание веб-сайта, работающего на TOMCAT или JETTY, для отображения графиков + данных, созданных с использованием существующего кода R, который функция R возвращает в виде кода Base 64 в сочетании с результатами обработки некоторых существующих функций Java и Python и создания расширенных файлов Excel для пример.

(Я не собираюсь использовать R Shiny Server по многим причинам, поэтому я хочу запустить R / Python из Java)

Чтобы получить базовую настройку, я создал динамический веб-проект с простым сервлетом и файлом test.java, который может выполнять код R.

test.java:

public class test {
      public static void main(String[] args) throws Exception {
          System.out.println(DoR.collectR());
      }
}

DoR.java:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class DoR {

  public static Object collectR() {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("Renjin");
    if(engine == null) {
        throw new RuntimeException("Renjin Script Engine not found on the classpath.");
    }
    Object catchR = "XX";
    try {
        catchR = engine.eval("df <- data.frame(x=1:10, y=(1:10)+rnorm(n=10));"
                + "print(df);"
                + "print(lm(y ~ x, df))");
    } catch (ScriptException e) {
        e.printStackTrace();
    }
    return catchR;
   }
}

StartTestServlet.java:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/StartTestServlet")
public class StartTestServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public StartTestServlet() {
    super();
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //response.getWriter().append("Served at: ").append(request.getContextPath()).append((CharSequence) DoR.collectR());
    response.getWriter().append("Served at: ").append(request.getContextPath());
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }
}

У меня установлены библиотеки:

renjin-script-engine-0.7.0-RC2.jar
renjin-studio-0.8.1915-jar-with-dependencies.jar
slf4j-api-1.7.19.jar
slf4j-simple-1.7.19.jar

Если я запускаю test.java как Java-приложение, оно работает нормально.

Если я запускаю сервлет на сервере TomCat 7.0, он работает нормально (без.append((CharSequence) DoR.collectR()))

Если я запускаю код с помощью.append ((CharSequence) DoR.collectR ()), я получаю исключение:

java.lang.RuntimeException: Renjin Script Engine not found on the classpath.
    ......DoR.collectR(DoR.java:16)
    ......StartTestServlet.doGet(StartTestServlet.java:19)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

DoR.java:16 это строка с:

try {

StartTestServlet.doGet (StartTestServlet.java:19) - это строка с:

response.getWriter().append("Served at: ").append(request.getContextPath()).append((CharSequence) DoR.collectR());

Я пробовал все виды вещей, чтобы заставить это работать в Eclipse Version: Mars.1 Release (4.5.1), и скачал файлы примеров из Renjin / поиск в Интернете и т. Д., Но безуспешно до сих пор, чтобы запустить код R из сервлета.

Я пропускаю что-то простое или мне нужно сделать это совсем по-другому?

1 ответ

Решение

Смотрите (недавно добавленный) eclipse-dynamic-web-project в Renjin Примеры. Подводя итог README:

  1. Загрузите автономный файл renjin-script-engine-0.8.1931-jar-with-dependencies.jar со страницы загрузок Renjin. Похоже, вы комбинируете старую версию renjin-script-engine с графическим флягой GUI.
  2. Скопируйте этот JAR-файл в WebContent/WEB-INF/lib, чтобы он был развернут вместе с вашим приложением.

Также посмотрите на ваш метод "DoR": вы звоните print() который отправляет свой вывод на стандартный вывод и возвращает NULL, На веб-сервере это может быть отправлено в журналы, но, безусловно, не будет в ответе клиенту.

Если вы хотите отправить результаты lm() Функция для клиента, вы можете сериализовать его, например, с помощью rjson::toJSON().

Другие вопросы по тегам