2010-09-15 23 views
0

J'ai une question: J'ai écrit un programme Java qui implémente un service STAF (juste un framework pour tester, http://staf.sourceforge.net/). Pour STAF, toutes mes classes doivent être dans un répertoire STAF-INF/classes. Alors je fis mon programme à un MyProg.jar fichier JAR, qui ressemble à ceci:Comment charger une classe à partir d'une archive JAR qui implémente mon interface? (java)

MyProg.jar

--> STAF-INF/

-------> classes/

------------> com/

----------------->/MyClass.class

----------------->/IInterface.class

---> META-INF/

Alors, mon JAR-Archiv a deux répertoires, l'un appelé META-INF et appelé STAF-INF. Dans STAF-INF, il y a un autre répertoire appelé classes, et dans les classes il y a mon paquet "com" qui contient ma classe et mon interface. c'est la situation. cette chose fonctionne très bien, et la structure du répertoire est requise par le framework STAF que j'utilise.

Maintenant, voici le problème: Je veux que les autres utilisateurs puissent prendre mon fichier JAR (MyProg.jar) et l'inclure dans son propre projet pour écrire des classes qui implémente mon interface IInterface.

Problème 1) Lorsque j'ajoute le fichier MyProg.jar à un projet Eclipse-Java, il ne trouve pas IInterface. Si même ne trouve aucun paquet dans le fichier JAR. Je pense que ça a quelque chose à voir avec les répertoires (STAF-INF/classes) ???

Problème 2) Lorsque je connecte mon nouveau projet dans Eclipse, avec mon vieux MONPROG projet, Eclipse trouve la IInterface et je peux le mettre en œuvre (cela pourrait être une solution pour le problème 1, mais :). Ensuite, j'exporte ma nouvelle classe sous la forme d'un fichier JAR, appelons-le NewClassForMyProg.jar. Mais quand je charge la nouvelle classe de la NewClassForMyProg.jar dans mon MONPROG-programme, je suis une exception:

NoClassDefFoundError: com.IInterface

Je pense que cela a quelque chose à voir avec mes répertoires aussi . mais je ne suis pas sûr. Je pense qu'il pourrait être un problème avec le URLClassLoader ou le ClassPath, aussi ... mais je n'ai aucune idée ...

aidez s'il vous plaît. merci.

modifier:

est ici le code de la méthode qui doit charger les classes:

public static ArrayList<IInterface> getExternalWorkloads(String jarName, String packageName) 
{ 
    jarName = "c:/STAF/services/NewClassForMyProg.jar"; 
    packageName = "com"; 

    packageName = packageName.replaceAll("\\." , "/"); 

    ArrayList<IInterface> myClasses = new ArrayList<IInterface>(); 

    JarInputStream jarFile = null; 
    JarEntry jarEntry = null; 

    try 
    { 
     jarFile = new JarInputStream(new FileInputStream (jarName)); 

     while(true) 
     { 
      jarEntry=jarFile.getNextJarEntry(); 

      if(jarEntry == null) 
       break; 

      if((jarEntry.getName().startsWith (packageName)) && 
       (jarEntry.getName().endsWith (".class"))) 
      { 
       String classname = jarEntry.getName().replaceAll("/", "\\."); 

       classname = classname.substring(0, classname.length() - 6); 

       if(classname.contains("$") == false) 
       { 
        ClassLoader.getSystemClassLoader(); 
        URL url = new URL("jar:file:" + jarName + "!/"); 

        URLClassLoader ucl = new URLClassLoader(new URL[] { url }); 

         try 
         { 
          Class<IInterface> myLoadedClass = (Class<IInterface>) ucl.loadClass(classname); 

          IInterface myClass = (IInterface) myLoadedClass.newInstance(); 
          myClasses.add(myClass); 
         } 
         catch(Exception e){} 
       } 
      } 
     } 

     jarFile.close(); 
    } 
    catch(Exception e){} 

    return myClasses; 
} 

Oh, et si je charge avec cette méthode une classe, qui se trouve dans mon propre JAR (MONPROG. jar) cela fonctionne parfaitement. Mais par un autre JAR (comme NewClassForMyProg.jar ") je reçois une erreur, mais la méthode fonde les classes, le problème est de créer une nouvelle instance et de la convertir en IInterface ...

Répondre

0

problème résolu! t utilisé le classloader correct.

      ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader(); 

          URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader); 

          Class iInterfaceClass = Class.forName(classname, true, URLLoader); 

la première ligne a résolu le problème.