2010-11-23 54 views
4

Je rencontre des problèmes avec le concept de la classe de charge, j'ai programmé depuis un petit moment mais je suis relativement conscient de la façon dont la classe fonctionne, je J'ai lu quelques exemples et j'ai lu les détails de la classe et des classes, alors que je comprends dans une certaine mesure un concept qui m'échappe et me semble plutôt difficile à mettre en mots. Essentiellement, j'essaie de créer des 'guildes' pour un gamemode que j'ai développé pour Minecraft, ces guildes se trouvent dans leurs propres classes et sont chargées avec le jeu au démarrage ou chaque fois que la méthode 'reloadGuildFiles() 'est émis. Je développe ces classes en exportant d'abord l'application principale et en l'ajoutant au classpath de la guilde en cours de création ainsi qu'aux principales dépendances des applications.Classloading un plugin pour une application personnalisée produit un NoClassDefFoundError

Voici la méthode '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; 
    } 
    } 
    } 
} 
} 

Voici la classe Guilde contenu dans l'application principale.

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

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

Voici la classe que je suis en train de classload

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

Voici l'erreur, il me donne:

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 

D'après ce que je peux recueillir et à partir de ce que je comprends, même si l'application principale est sur le chemin de construction de la classe à lo aded, le classloader ne reconnaît pas la classe Guild. Je pense que je dois essayer de faire reconnaître la classe de guilde contenue dans l'application principale par le classloader, y a-t-il un moyen de le faire ou y a-t-il quelque chose que je fais de mal?

+0

est votre propre classe 'Guild' ou une classe MineCraft? Si c'est le vôtre, essayez d'ajouter un constructeur par défaut. – javamonkey79

Répondre

1

Le seul problème possible que je peux voir ici est que Thread.currentThread().getContextClassLoader() produit pour une raison quelconque un classloader qui ne peut pas être utilisé pour accéder à la classe Guild.

Essayez ceci:

urlcl = URLClassLoader.newInstance(new URL[] { guildDataSourceDirectory.toURI().toURL() }, Guild.class.getClassLoader());