tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
10
ZUGRIFFE
337
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    bnr bnr ist offline Mitglied
    Registriert seit
    Jun 2006
    Beiträge
    21
    Hallo @ all,

    ich schlage mich im Moment mit einem ClassLoader rum. Mein Ziel ist es, aus ein Paar jar Dateien mittels Reflection und Anntotation Informationen aus einer bestimmten Klasse auszulesen. Der Code an sich funktioniert ohne Probleme in meinem Projekt (Projekt A). Jedoch verwendet mein Projekt ein eclipse.plugin Projekt (Projekt B) und dann knallt es.

    Erst mal ein Paar Code-Schnipsel aus dem Projekt A

    Klasse A1
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        Method m = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
        m.setAccessible(true);
        
        for (String title : jarsToBeLoaded.keySet()) {
            File jarFile = new File(jarsToBeLoaded.get(title));
            m.invoke(cl, new Object[] { jarFile.toURL() });
        ...
        }
    ...

    Aus Klasse B1
    Code :
    1
    
    Class instandeDataClass = Class.forName(pluginDS.getInstanceDataClass());

    Wenn der Code aus meinem Projekt ausgeführt wird, so ist der ClassLoader cl ein "sun.misc.Launcher$AppClassLoader"
    Dieser erbt von URLClassLoader und man kann daher die Methode addURL verwenden.

    Wenn jedoch Projekt B den Code in Projekt A verwendet, so handelt es sich um folgenden ClassLoader
    "org.eclipse.core.runtime.internal.adaptor.ContextFinder". Die Folge ist, dass es in Zeile m.invoke(cl, new Object[] { jarFile.toURL() }); knallt.

    Daher habe ich versucht den ParentLoader von "org.eclipse.core.runtime.internal.adaptor.ContextFinder" zu verwenden (cl=cl.getParent()). Dies ist der "sun.misc.Launcher$AppClassLoader".
    Danach läuft der Code in Klasse A1 durch, jedoch kann der Code in Klasse B1 (Class.forName) die Klasse nicht finden (java.lang.ClassNotFoundException).


    Ich stehe auf dem Schlauch und habe keinen Ansatz, wie ich dies lösen könnte.
     

  2. #2
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi,
    das gleiche Problem hat ich auch schon mal, ich habe dafür auch noch keine Lösung gefunden. Aber ich kann dir sagen, dass du mit dem ClassLoader nicht Projektübergreifend Dateien laden kannst.
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  3. #3
    SE Tutorials.de Gastzugang
    Ähm ... WHAT THE ...
    Also sowas seh ich ja zum ersten Mal.
    Was ich nicht verstehe is warum du extra über Reflections mit dem ClassLoader rumspielst. Die viel einfachere Methode wäre hier einfach einen neuen URLClassLoader mit dem absoluten Pfad auf das zweite Projekt und dann ganz normal über
    Code java:
    1
    2
    
    Class clazz=urlClassLoader.loadClass("Klasse");
    Object o=clazz.newInstance();
    die Klasse laden und ein Objekt erzeugen.

    Auch sollte der Compiler bei
    Code java:
    1
    
    File.toURL();
    meckern da dies deprecated ist. Statt dessen sollte man
    Code java:
    1
    
    File.toURI().toURL();
    verwenden.
     

  4. #4
    bnr bnr ist offline Mitglied
    Registriert seit
    Jun 2006
    Beiträge
    21
    So, ich habe jetzt eine Woche versucht den Classloader an den Start zu bekommen, leider ohne Erfolg. Das Problem liegt darin, das Projekt B ein OSGI-Projekt ist. Nun habe ich auch den Code aus Projekt A in Projekt B gelegt, damit ich nur noch ein Projekt habe, ein OSGI-Projekt. Leider ist es mir aber nicht möglich die externen JARS(keine OSGI) zum ClassPath hinzuzufügen, um dann entsprechenden Klassen zu Laden. Hat da jemand eine Idee?
     

  5. #5
    SE Tutorials.de Gastzugang
    Hat du es schon mal mit dem von mir angesprochenen URLClassLoader versucht ?
     

  6. #6
    bnr bnr ist offline Mitglied
    Registriert seit
    Jun 2006
    Beiträge
    21
    Geht auch nicht

    URL[] urls = new URL[3];
    urls[0] = new URL("...PluginA.jar");
    urls[1] = new URL("...PluginB.jar");
    urls[2] = new URL("...PluginC.jar");
    URLClassLoader cl = new URLClassLoader(urls);
    Class instandeDataClass = cl.loadClass("Klasse");

    Es hängt mit OSGI zusammen. Die ClassLoader die dort verwendet werden sind OSGI-Classloader vom Framework.
     

  7. #7
    SE Tutorials.de Gastzugang
    Nunja ... wenn du Projekt B als OSGI-Projekt gestaltet hast dann solltest du dies auch über den OSGI-Loader laden.
     

  8. #8
    bnr bnr ist offline Mitglied
    Registriert seit
    Jun 2006
    Beiträge
    21
    Die Jars sind keine OSGI Bundles. Daher dürfte es mit dem OSGI-BundleLoader nicht funktionieren, oder bin ich falsch Informiert?
     

  9. #9
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    wo liegen denn die jars, aus denen du die Klassen laden möchtest? Direkt im Filesystem oder innerhalb eines OSGI-Bundles?

    Externe jars kannst du auch (wie Spikee) schon angedeutet hat via: URLClassLoader laden
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ...
    public class Activator implements BundleActivator {
    ...
        public void start(BundleContext bundleContext) throws Exception {
            Activator.context = bundleContext;
            System.out.println(bundleContext);
            URLClassLoader cl = new URLClassLoader(new URL[]{new File("C:/development/java/libs/guava-r07/guava-r07.jar").toURI().toURL()},Thread.currentThread().getContextClassLoader());
            System.out.println(cl.loadClass("com.google.common.annotations.Beta"));
    ...

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  10. #10
    bnr bnr ist offline Mitglied
    Registriert seit
    Jun 2006
    Beiträge
    21
    Hallo,

    genau dies funktioniert nicht (java.lang.ClassNotFoundException). Die URL zu der Jar stimmt und die Klasse, die geladen werden soll, ist auch in dem Package bzw. Jar. Wie gesagt, der Loader funktioniert wenn es kein OSGI XTEXT Projekt ist.
     

  11. #11
    SE Tutorials.de Gastzugang
    Also wenn du über einen URLClassLoader welcher mit URL auf ein JAR erstellt wurde eine ClassNotFoundException bekommst ist entweder der Aufruf falsch oder die Struktur innerhalb des JAR stimmt nicht. Bitte überprüfe beides noch einmal auf Tippfehler.

    ! Achtung ! Die meisten IDE's nehmen einem nicht alle Arbeiten ab. So ist es z.B. bekannt das wenn du innerhalb des Projektes Klassen , Pakete oder die main()-Methode verschiebst dies nicht automatisch übernommen wird. Hier muss man dann immer noch mal selbst Hand anlegen.
     

Ähnliche Themen

  1. einzelne form funktioniert funktioniert nicht
    Von JBJHJM im Forum HTML & XHTML
    Antworten: 0
    Letzter Beitrag: 05.04.11, 16:54
  2. Antworten: 1
    Letzter Beitrag: 24.09.07, 22:51
  3. Classloader funktioniert im JBoss aber nicht im Glassfish
    Von dr_d00m im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 0
    Letzter Beitrag: 20.09.07, 15:33
  4. Antworten: 1
    Letzter Beitrag: 15.01.07, 15:58
  5. Funktion IE/Firefox - funktioniert/funktioniert nicht
    Von SixDark im Forum Javascript & Ajax
    Antworten: 3
    Letzter Beitrag: 02.03.06, 00:26