2016-03-01 2 views
2

В настоящее время я создаю небольшую платформу плагинов для программы на Java. В основном GRPluginManager.loadPlugins() петли через все файлы jar в каталоге, затем читает имя основного класса этого плагина из определенного файла внутри jar и загружает его в путь к классам. После этого он вызывает метод enable() этого плагина-основного класса (который расширяет GRPlugin).Результаты загрузки класса Java в ClassNotFoundException для родительского класса

Однако, это не работает. Похоже, что загрузка плагина-Main-класса прекрасна, и только родительский класс (GRPlugin) не найден. Но это определенно существует.

GRPlugin.java

package io.github.grengine.core.plugins; 

public class GRPlugin { 

    public void enable(){ 

    } 

    public void disable(){ 

    } 
} 

GRPluginManager.java

package io.github.grengine.core.plugins; 

import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.reflect.Method; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.Map; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipFile; 

import org.bukkit.plugin.java.JavaPluginLoader; 
import org.yaml.snakeyaml.Yaml; 

import io.github.grengine.JarUtils; 
import io.github.grengine.Log; 
import io.github.grengine.Main; 

public class GRPluginManager { 

    private static final String PLUGIN_PATH = Main.main.getDataFolder()+File.separator+"storage"+File.separator+"plugins"; 
    private ArrayList<GRPlugin> plugins = new ArrayList<GRPlugin>(); 

    public ArrayList<GRPlugin> loadPlugins() throws Exception{ 

    File filePath = new File(PLUGIN_PATH); 
    File files [] = filePath.listFiles(); 

    //Iterate over files in the plugin directory 

    for(File file:files){ 
     if(file.isFile()){ 

      Log.Info("Reading "+file); 

      ZipFile zipFile = new ZipFile(file); 


      String fullyQualifiedName = null; 
      String plname = null; 
      String plversion = null; 

      Enumeration<? extends ZipEntry> entries = zipFile.entries(); 

      while (entries.hasMoreElements()) { 
       ZipEntry ze = (ZipEntry) entries.nextElement(); 
       if(ze.getName().equals("gre"+File.separator+"ext.yml")){ 
        Yaml yaml = new Yaml(); 
        InputStream is = zipFile.getInputStream(ze); 
        Map<?, ?> map = (Map<?, ?>) yaml.load(is); 

        fullyQualifiedName = (String) map.get("main"); 
        plname = (String) map.get("name"); 
        plversion = (String) map.get("version"); 
       } 
      } 


      zipFile.close(); 


      Log.Info("Enabling "+plname+" "+plversion+" ..."); 

      URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { new URL("file:"+file) }); 


      Class<?> clazz = classLoader.loadClass(fullyQualifiedName); 
      GRPlugin pl = (GRPlugin) clazz.newInstance(); 
      pl.enable(); 

Log.Info("Enabling "+plname+" "+plversion+" ..."); 

     }else { 
     //skip folders 
     continue; 
     } 
    } 
    return plugins; 
    } 

} 

И Основной класс плагина (класс расширения GRPlugin)/Main.java

package io.github.plutos; 

import io.github.grengine.Log; 
import io.github.grengine.core.plugins.GRPlugin; 

public class Main extends GRPlugin{ 

    @Override 
    public void enable() { 
     Log.Info("ENABLED"); 

    } 

    @Override 
    public void disable() { 
     Log.Info("DISABLED"); 

    } 

} 

Вот StackTrace:

java.lang.NoClassDefFoundError: io/github/grengine/core/plugins/GRPlugin 
     at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_05] 
     at java.lang.ClassLoader.defineClass(ClassLoader.java:760) ~[?:1.8.0_05] 
     at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_05] 
     at java.net.URLClassLoader.defineClass(URLClassLoader.java:455) ~[?:1.8.0_05] 
     at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[?:1.8.0_05] 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:367) ~[?:1.8.0_05] 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[?:1.8.0_05] 
     at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_05] 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:360) ~[?:1.8.0_05] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_05] 
     at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:798) ~[?:1.8.0_05] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_05] 
     at io.github.grengine.core.plugins.GRPluginManager.loadPlugins(GRPluginManager.java:82) ~[?:?] 
     at io.github.grengine.Main.onEnable(Main.java:56) ~[?:?] 
     at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:356) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:316) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at net.minecraft.server.v1_8_R3.MinecraftServer.s(MinecraftServer.java:418) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at net.minecraft.server.v1_8_R3.MinecraftServer.k(MinecraftServer.java:382) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at net.minecraft.server.v1_8_R3.MinecraftServer.a(MinecraftServer.java:337) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:256) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:528) [spigot-core.jar:git-Spigot-c5146ba-c637b93] 
     at java.lang.Thread.run(Thread.java:745) [?:1.8.0_05] 
Caused by: java.lang.ClassNotFoundException: io.github.grengine.core.plugins.GRPlugin 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:372) ~[?:1.8.0_05] 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[?:1.8.0_05] 
     at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_05] 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:360) ~[?:1.8.0_05] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_05] 
     at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:798) ~[?:1.8.0_05] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_05] 
     ... 25 more 

Я просто не могу найти решение этой проблемы, я уже пробовал разные загрузчики классов (ClassLoader.getSystemClassLoader() и GRPlugin.class.getClassLoader()) ...

Можете ли вы сказать, что я делать не так? Если вам нужна дополнительная информация, не стесняйтесь спрашивать!

Спасибо заранее, fusionlightcat

ответ

4

Если вы не установили родительский загрузчик классов для пользовательского загрузчика классов, система Загрузчик классов будет использоваться в качестве родителя по по умолчанию.

Кажется, что в вашей среде GRPlugin загружен потоком системного загрузчика классов и, следовательно, является ошибкой.

Используйте вместо этого:

URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { new URL("file:"+file) }, GRPlugin.class.getClassLoader()); 
+0

Это решило, +1 за хорошее объяснение! – fusionlightcat

+0

рад, что это помогло! – idelvall

1

Вы можете увидеть плагин внедрения системы в ipscan проекта с открытым исходным кодом. Вот стартовые точки для разведки:

  • Plugin интерфейс. Любой из плагинов в ipscan должен реализовать его.
  • PluginLoader класс - ваш GRPluginManager аналог. Он загружает плагины из разных мест (в банке проекта, внешних банках и т. Д.). Посмотрите здесь реализацию PluginClassLoader, которая расширяет URLClassLoader и загружает классы из файлов jar.
  • feeders папка с некоторыми встроенными плагинами, которые внедрили интерфейс Plugin.

UPDATE: также вы можете использовать для стандартной java.util.ServiceLoader системы плагинов или некоторые alternative solution

+0

Это было на самом деле очень полезно для меня, спасибо! – fusionlightcat

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