2014-12-22 3 views
0

В настоящее время я пытаюсь скомпилировать класс во время выполнения, но по какой-то причине он работает только в одной системе. Обе системы используют один и тот же код и имеют одну и ту же версию java, но в одной системе мой .java-файл компилируется в .class, а в другой системе я получаю исключения, потому что некоторые классы, которые являются или должны быть в classpath не найден.Компиляция класса во время выполнения с помощью пути к классам

код я использую, чтобы скомпилировать его заключается в следующем:

private static File compile(File file) { 
    try { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     List<String> optionList = new ArrayList<>(); 
     File jar = getJar(RuntimeCompiler.class); 
     File pluginDirectory = new File(jar.getAbsolutePath().substring(0, jar.getAbsolutePath().length() - jar.getName().length())); 
     String classes = buildClassPath(getJar(Bukkit.class).getAbsolutePath(), pluginDirectory.getAbsolutePath() + "/*"); 
     optionList.addAll(Arrays.asList("-classpath",classes)); 
     boolean success; 
     try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) { 
      Iterable<? extends JavaFileObject> units; 
      units = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(file)); 
      JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, optionList, null, units); 
      success = task.call(); 
     } 
     if(success) { 
      return new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 5) + ".class"); 
     } 
     else { 
      return null; 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(RuntimeCompiler.class.getName()).log(Level.SEVERE, null, ex); 
     return null; 
    } 
} 
private static String buildClassPath(String... paths) { 
    StringBuilder sb = new StringBuilder(); 
    for (String path : paths) { 
     if (path.endsWith("*")) { 
      path = path.substring(0, path.length() - 1); 
      File pathFile = new File(path); 
      for (File file : pathFile.listFiles()) { 
       if (file.isFile() && file.getName().endsWith(".jar")) { 
        sb.append(path); 
        sb.append(file.getName()); 
        sb.append(System.getProperty("path.separator")); 
       } 
      } 
     } else { 
      sb.append(path); 
      sb.append(System.getProperty("path.separator")); 
     } 
    } 
    String s = sb.toString(); 
    s = s.substring(0,s.length() - 1); 
    return s; 
} 

классам (optionList.toString()) с Core-1,0-SNAPSHOT.jar, содержащий необходимые файлы.

[-classpath, /usr/local/gpx/users/user/127.0.0.1:25702/spigot.jar:25702/plugins/Core-1.0-SNAPSHOT.jar] 

StackTrace

/usr/local/gpx/users/user/127.0.0.1:25702/plugins/debug/DebugClass.java:1: error: package  net.nowcraft.core does not exist 
[14:04:10] [Server thread/WARN]: import net.nowcraft.core.core; 
[14:04:10] [Server thread/WARN]:      ^
[14:04:10] [Server thread/WARN]:  /usr/local/gpx/users/user/127.0.0.1:25702/plugins/debug/DebugClass.java:2: error: package net.nowcraft.core.RuntimeCompiler does not exist 
[14:04:10] [Server thread/WARN]: import net.nowcraft.core.RuntimeCompiler.Debugger 
[14:04:10] [Server thread/WARN]:           
[14:04:10] [Server thread/WARN]: /usr/local/gpx/users/user/127.0.0.1:25702/plugins/debug/DebugClass.java:7: error: method does not override or implement a method from a supertype 
[14:04:10] [Server thread/WARN]:  @Override 
[14:04:10] [Server thread/WARN]: ^
[14:04:10] [Server thread/WARN]: 3 errors 
[14:04:10] [Server thread/ERROR]: null 
org.bukkit.command.CommandException: Unhandled exception executing command 'rd' in plugin NowCraftCore v1.0 
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot.jar:git-Spigot-330d66b-fe41b01] 
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot.jar:git-Spigot-330d66b-fe41b01] 
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServer.java:642) ~[spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.PlayerConnection.handleCommand(PlayerConnection.java:1115) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:950) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(PacketPlayInChat.java:26) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(PacketPlayInChat.java:53) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_25] 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_25] 
at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:683) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:316) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:623) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:526) [spigot.jar:git-Spigot-330d66b-fe41b01] 
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_25] 

Caused by: java.lang.NullPointerException 
at net.nowcraft.core.RuntimeCompiler.RuntimeCompiler.load(RuntimeCompiler.java:127) ~[?:?] 
at net.nowcraft.core.RuntimeCompiler.RuntimeCompiler.loadHastebin(RuntimeCompiler.java:88) ~[?:?] 
at net.nowcraft.core.RuntimeCompiler.RuntimeCompiler.debugFromHastebin(RuntimeCompiler.java:170) ~[?:?] 
at net.nowcraft.core.commands.RuntimeDebug.onCommand(RuntimeDebug.java:35) ~[?:?] 
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-330d66b-fe41b01] 
... 14 more 

EDIT: Я также проверил его в другой каталог, не работает. Когда я использую код на моем локальном ноутбуке Windows, он работает.

EDIT 2: Как представляется, проблема с CentOS, поскольку она не работает на системе 2 CentOS.

+0

Можете ли вы опубликовать stacktrace? – avgvstvs

+0

Вы подтвердили, что зависимые классы, на самом деле, можно найти в пути к классам в системе, где происходит сбой компиляции? Кроме того, вы подтвердили, что «проблемная» система имеет ту же самую версию java, что и у успешного экземпляра? – him

+0

@avgvstvs Да, они имеют одну и ту же версию Java (1.8), и я редактировал главный пост с помощью stacktrace. – Joba

ответ

1

Stacktrace очень помог, и окружающий контекст.

Проблема здесь Linux. Таким образом, каталог, который вы пытаетесь попасть:

/usr/local/gpx/users/user/127.0.0.1:25702/plugins/debug/DebugClass.java

буквально ищет каталог с именем 127.0.0.1:25702 (хотя : придется спасаться, потому что большинство оболочек используют : в качестве синтаксиса символа

. Ваш сетевой адрес будет отображаться в определенном каталоге. Вам нужно будет создать общий сетевой ресурс (не знакомый с CentOS, но обычно довольно простой), чтобы исключить сетевую ссылку на физическое место. Если вы можете cd к нему из командной строки, тогда ваше время выполнения java должно быть ab le, чтобы на самом деле ссылаться на него.

Here is a reference для установки удаленных файловых систем на CentOS. Да, я знаю, что 127.0.0.1:25702 технически «localhost», но ни командная оболочка, ни время выполнения java не узнают, как разрешить сетевой адрес так, как вы хотите сделать это здесь. Он работает на Windows, потому что Windows API более просты.

0

Я предполагаю, что вы используете локальные окна и unix для удаленного сервера? разделитель classpath для java на машине unix - «:», и у вас есть каталог с именем «:» в имени, компилятор unix может разделять имя каталога на «:». Пробовали ли вы использовать путь к классам на нерабочем компьютере, который не содержит «:» в именах файлов/каталогов?

+0

Хорошо, это немного помогло. Я компилирую и выполняю классы, которым не нужны внешние библиотеки (они реализуют интерфейс Debugger из моего приложения). Я попытался использовать внешнюю библиотеку, но я получаю новую ошибку: «Исключение в потоке» main «java.lang.NoClassDefFoundError: com/mongodb/MongoClient ' My classpath: '/home/user/DebugTester.jar:/home/user/mongo-java-driver-2.11.2.jar' – Joba

+0

Пара вещей ... 1) попробуйте поставить инструкцию debug в buildclasspath, чтобы узнать, что ее возвращает. 2) глядя на код (не уверен, что не тестировал), но pluginDirectory может иметь «/» в конце уже .. поэтому добавление «/ *» может добавить дополнительный «/». – cmparish

+0

Было, наверное, недостаточно ясно, извините. Проверьте мой первый ответ: «My classpath:» - это то, что возвращал метод. – Joba

Смежные вопросы