2010-11-23 4 views
4

У меня возникли некоторые проблемы, обертывающие мою голову вокруг концепции загрузки классов, я программировал на некоторое время, но я относительно знал, как работает классная загрузка, я мы прошли через несколько примеров и прочитали о деталях, лежащих в основе загрузки классов и самих классов, в то время как я понимаю это в определенной степени, это концепция, которая ускользает от меня и кажется довольно сложной для поиска в удобных для пользователя условиях.Classloading плагин для пользовательского приложения создает NoClassDefFoundError

По существу, я пытаюсь создать «гильдии» для игрового режима, который я разрабатывал для Minecraft, эти гильдии лежат в их собственных классах и загружаются с игрой при запуске или всякий раз, когда метод reloadGuildFiles() ' выпущен. Я разрабатываю эти классы, сначала экспортируя основное приложение и добавляя его к пути к классам создаваемой гильдии, а также к зависимостям основных приложений.

Это метод reloadGuildFiles.

public void reloadGuildFiles() { 
    unloadGuildFiles(); 

    synchronized (_sync) { 
    System.out.println("Loading guild class files."); 

    File guildDataSourceDirectory = new File("Prospect/Guilds/"); 

    URLClassLoader urlcl = null; 

    try { 
    urlcl = URLClassLoader.newInstance(new URL[] { guildDataSourceDirectory.toURI().toURL() }, Thread.currentThread().getContextClassLoader()); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    return; 
    } 

    if (urlcl == null) 
    return; 

    for (File guildDataFile : guildDataSourceDirectory.listFiles()) { 
    if (!guildDataFile.getName().endsWith(".class")) { 
    System.out.println("Skipping " + guildDataFile.getName()); 
    continue; 
    } 

    try { 
    String className = guildDataFile.getName().substring(0, guildDataFile.getName().lastIndexOf(".")); 

    System.out.println("Loading: " + className + "\n" + 
     "\tfrom: " + guildDataFile.getPath()); 

    Class<?> clazz = urlcl.loadClass(className); 

    Object object = clazz.newInstance(); 

    if (object instanceof Guild == false) { 
     System.out.println("Object loaded is not an instance of Guild."); 
     continue; 
    } 

    Guild guild = (Guild) object; 

    if (_guildMap.containsKey(guild.getName())) { 
     System.out.println("Duplicate guild names in guild map: " + guild.getName()); 
     continue; 
    } 

    _guildMap.put(guild.getName(), guild); 
    guild.onGuildLoaded(); 
    } catch (Exception e) { 
    System.out.println(e.getMessage()); 
    e.printStackTrace(); 
    continue; 
    } 
    } 
    } 
} 
} 

Вот класс Гильдия, содержащаяся в главном приложении.

public abstract class Guild { 
public abstract String getName(); 

public void onGuildLoaded() { 
    System.out.println("Loaded: " + getName()); 
} 
} 

Вот класс Я пытаюсь classload

public class Warrior extends Guild { 
public String getName() { 
    returns "Warrior"; 
} 
} 

Здесь ошибка это дает мне:

java.lang.NoClassDefFoundError: Guild 
     at java.lang.ClassLoader.defineClass1(Native Method) 
     at java.lang.ClassLoader.defineClassCond(Unknown Source) 
     at java.lang.ClassLoader.defineClass(Unknown Source) 
     at java.security.SecureClassLoader.defineClass(Unknown Source) 
     at java.net.URLClassLoader.defineClass(Unknown Source) 
     at java.net.URLClassLoader.access$000(Unknown Source) 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at java.net.FactoryURLClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at GuildManager.reloadGuildFiles(GuildManager.java:53) 
     at Prospect.enable(Prospect.java:64) 
     at PluginLoader.load(PluginLoader.java:205) 
     at PluginLoader.reloadPlugin(PluginLoader.java:189) 
     at je.d(je.java:1196) 
     at je.a(je.java:430) 
     at bg.a(SourceFile:24) 
     at bh.a(SourceFile:218) 
     at je.a(je.java:56) 
     at dp.a(SourceFile:85) 
     at net.minecraft.server.MinecraftServer.h(SourceFile:267) 
     at net.minecraft.server.MinecraftServer.run(SourceFile:208) 
     at bw.run(SourceFile:482) 
Caused by: java.lang.ClassNotFoundException: Guild 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at java.net.FactoryURLClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     ... 25 more 

Из того, что я могу собрать и из того, что я понимаю, хотя основное приложение находится на пути сборки класса, чтобы быть lo aded, classloader не распознает класс Guild. Я думаю, мне нужно попробовать, чтобы classloader распознал класс Гильдии, содержащийся в главном приложении, есть ли все равно сделать это или есть что-то, что я явно делаю неправильно?

+0

Является ли 'Гильдия' свой собственный класс или класс MineCraft? Если это ваше, попробуйте добавить конструктор по умолчанию. – javamonkey79 2010-11-24 02:01:17

ответ

1

Единственная возможная проблема, которую я вижу здесь, состоит в том, что Thread.currentThread().getContextClassLoader() по какой-то причине создает загрузчик классов, который не может использоваться для доступа к классу Guild.

Попробуйте вместо этого:

urlcl = URLClassLoader.newInstance(new URL[] { guildDataSourceDirectory.toURI().toURL() }, Guild.class.getClassLoader()); 
Смежные вопросы