Можно ли вызвать Java из Node.js через JNI и как?
Я могу вызвать Java из Node.js через JNI? Есть ли примеры?
6 ответов
Это выглядит сложно. Node.JS работает на движке Google Chrome JavaScript V8. Вам нужно будет создать привязку V8 C++ (пример C8h C8), которая запускает JVM и выполняет всю обработку JNI.
Я думаю, что вам может быть лучше позволить JavaServer и Node.js взаимодействовать через сеть (кто-то написал пример использования RabbitMQ для обмена сообщениями на основе сообщений Java/Node.js). Здесь, JSON будет отличным форматом обмена данными (если вы доверяете, что ваш Java-сервер производит правильный JSON, вы можете просто выполнить eval() в Node).
Вы должны попробовать модуль node-java npm, который является хорошо написанной оболочкой над JNI.
кажется, что у node-jave (пока) нет широкого распространения, но, играя с ним, я был впечатлен тем, насколько он прост и надежен.
Это так просто, как:
var list = java.newInstanceSync("java.util.ArrayList");
list.addSync("item1");
list.addSync("item2");
console.log(list.getSync(1)); // prints "item2"
Со встроенной JVM вы можете делать практически все - создавать объекты, вызывать методы, поля доступа и т. Д.
Существует небольшое несоответствие импеданса между Node и Java, поэтому, если вы собираетесь взаимодействовать с чем-то сложным, я бы порекомендовал написать большую часть ваших взаимодействий в Java и показать более простой интерфейс через барьер Node/Java. Это просто облегчает отладку таким способом.
--- Дэйв
ps, RealWorldUseCase(tm): я работал в месте, где был довольно сложный (и кодированный спагетти) протокол между несколькими клиентами браузера и службой на основе Java. Я написал довольно приятную тестовую программу, которая использовала jsdom для размещения N имитированных браузеров и использовала node-java в качестве оболочки для кода сервиса Java. Было тривиально урезать транспортные интерфейсы, как в JS для клиентов, так и в Java для сервиса, поэтому, когда какая-либо из этих вещей отправляет сообщение, я записываю его и помещаю в очередь для вероятностной доставки намеченной цели. (т.е. я виртуализировал сеть). Таким образом, я мог бы выполнить полное моделирование нескольких клиентов, взаимодействующих с Java-сервисом и через него, и запустить все это в одном процессе без какой-либо проводной связи. А потом я мог делать забавные вещи, такие как преднамеренное изменение порядка доставки сообщений, чтобы убедиться, что код устойчив к ошибкам синхронизации. И когда была обнаружена ошибка, я зарегистрировал порядок сообщений и смог воспроизвести их, чтобы воспроизвести ошибку. О, и все это подготовило и запустило довольно сложный сценарий с несколькими тысячами строк регистрации и завершился менее чем за 1 секунду за цикл. 2 недели хорошо провели. Прикольные вещи.
Вариант использования RealWorld # 2: selenium-inproc - модуль, который упаковывает JAR-файл SeleniumRC, предоставляя интерфейс узла для тестирования автоматизации браузера с Selenium без необходимости запуска еще одной службы localhost.
Связь может быть сделана child_process.
породить новый процесс и выполнить класс Main. Этот основной класс возвращает вывод на консоль. поэтому данные доступны для узла stdout data
событие.
var cmd = require('child_process').spawn('java', ['Main']);
cmd.stdout.on('data', function (data) {
console.log('stdout: ' + data); // This will print string returned by Main class.
});
Я думаю, что вы ищете родное расширение для использования в качестве моста. Хотя у меня нет примера того, что вы говорите, у меня есть пример того, как вызвать расширение C++ с помощью Node.JS
Интересно, возможно ли это вообще? но даже если это возможно, я думаю, что это трудно реализовать, и я уверен, что никто еще не сделал этого.
как насчет использования именованного канала для связи между процессами (java и node.js)?
Я думаю, что утвержденный ответ немного стар. Возможно, стоит попробовать: https://github.com/joeferner/node-java
Я не знаю всех деталей Node.js, но я предполагаю, что ваше упоминание JNI на самом деле является Java Native Interface. Можно использовать только JNI из Java, поэтому imho не имеет смысла обращаться к Java из JNI, если вы еще не в Java.
Может показаться, что это неправильный подход, и вам нужно поискать документацию по интеграции Node.js.