2015-11-26 2 views
0

В настоящее время я создаю плагин для Bukkit-Server, но у меня проблема с использованием механизма сценариев Nashorn. Я оцениваю внешний файл javascript из своего Java-плагина. Я не могу получить мой JavaScript, чтобы импортировать классы из моего плагина, только стандартные классы Java работают (как var JavaBool = Java.type('java.lang.Boolean');, но не var Holder = Java.type('io.github.advtest1.js.JSHolder');)Java Nashorn - ClassNotFoundException - Java.type()

Всякий раз, когда я пытаюсь загрузить один из них я получаю следующее сообщение об ошибке:

Caused by: java.lang.ClassNotFoundException: io.github.advtest1.js.JSHolder 

После небольшого исследования я обнаружил, что он имеет какое-то отношение к моим плагиатам, находящимся в пути к классам, но как я могу добавить его в путь к классам, когда сам Bukkit загружает плагин, и я не хочу никаких других запусков для сервер затем java -jar bukkit.jar?

Не стесняйтесь спрашивать, если вам нужна дополнительная информация. Спасибо заранее!

+0

Это выглядит как только 'Java', а не' JavaScript' ... – Arg0n

+0

это поможет установить контекст загрузчика классов, прежде чем создавать ScriptEngine, как описано здесь HTTP: // StackOverflow .com/a/30251930/3215527 – wero

+0

@wero Я попробую это, один момент! И для Arg0n: да, приведенные выше примеры - все javascript, потому что это проблема javascript. если я не использую какие-либо другие классы, оценивающие скрипты из java-работ, отлично. – fusionlightcat

ответ

2
  • Nashorn использует контекстную нить загрузчик найден в момент создания двигателя, чтобы найти классы Java от Java.type API.

  • Nashorn также использует другой загрузчик, если вы используете опцию командной строки «-classpath» nashorn. Nashorn пытается загрузить классы, используя новый загрузчик, созданный при создании движка, инициализированный указанным классом. Обратите внимание, что параметры командной строки nashorn могут быть переданы через свойство Java System «nashorn.args». Итак, если вы определенно -Dnashorn.args = "- classpath your_path" в другом месте (скажем, в вашем конфиге), то Nashorn может получить доступ к классам из указанного вами_пакета.

Если не может передать параметры Насхорн двигателя через систему собственности [или с помощью командной строки в случае использования инструмента в «JJs»], вы можете установить контекст погрузчиком нити, чтобы соответствовать Загрузчик как это было предложено более ранний ответ.

Если это нежелательно из-за других зависимостей приложений, вы получаете объект java.lang.Class требуемого класса и выставляете то же самое, что и переменную скрипту (из вашего кода Java вы можете получить объект класса и вызвать ScriptEngine .put). Затем скрипт может получить доступ к «статическому» свойству, чтобы получить объект «type». С объектом типа обычные «новые», статические вызовы методов и т. Д. Работают, как ожидалось.

Пример:

import javax.script.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ScriptEngineManager m = new ScriptEngineManager(); 
     ScriptEngine e = m.getEngineByName("nashorn"); 
     e.put("Vec", java.util.Vector.class); // replace it with any Class object 
     e.eval("var T = Vec.static; var obj = new T()"); // create new Vector 
     e.eval("print(obj.getClass())"); 
    } 
} 
2

Как @wero упоминалось, что мне нужно, чтобы добавить

ClassLoader cl = plugin.getClass().getClassLoader(); 
Thread.currentThread().setContextClassLoader(cl); 

, прежде чем я вызвать JS-функцию от Явы.

plugin выступает за основной класс (класс, который простирается JavaPlugin)