Class-files zur Laufzeit zu Reflection-Zwecken laden

tbar0711

Mitglied
Hallo,

folgender Sachverhalt:
Ich bekomme immer wieder verschiedene ear-files, die wiederum ein bestimmtes jar-file enthalten, welches wiederum unter bestimmten packages verschiedene Java class-files enthält. Einige dieser class-files sind session beans.

Nun möchte ich ein Java-Programm schreiben, welches diese class-files zur Laufzeit per Classloader läd und über Reflection die Annotationen ausliest und entsprechend durch Erkennen einer @Stateful oder @Stateless -Annotation eine Session Bean identifiziert. Diese Session Bean möchte ich dann per Reflection nach weiteren Dingen durchsuchen (z.B. Annotationen von Methoden usw.).

Der Sinn dahinter ist, dass die Session Beans bestimmte Konventionen erfüllen müssen und erst, wenn alle Session Beans diese erfüllen, dürfen sie auf den JBoss deployed werden. Daher soll die Prüfung außerhalb eines Applikationsserver erfolgen.

Nun ist meine Frage:
Geht denn das überhaupt?
Wenn ja, wie kann ich die class-files als Class-Objekte zur Laufzeit laden, damit ich Reflections durchführen kann?

Ich vermute, ich muss zunächst das ear-file und danach das jar-file entpacken und dann die Ordnerstruktur nach class-files durchsuchen. Die gefundenen class-files müssen dann mit einem Classloader geladen werden.

Ich wäre euch sehr dankbar, wenn ihr mir Code-Vorschläge diesbezüglich geben könntet.

Grüße
Tom
 

tbar0711

Mitglied
Danke, ich habe bin nun soweit, dass ich die komplette jar nach .class Dateien durchsuchen kann.
Dann hole ich mir per Class.forName(Package und Klassenname) die Klassen.

Das Problem ist nun, dass ich nicht alle Klassen bekomme. Manche Klassen importieren wohl Klassen, die ich nicht verfügbar habe, woraufhin mein Class.forName mit der Exception in thread "main" java.lang.NoClassDefFoundError abfliegt.

Gibt es nun eine Möglichkeit, dieses Problem zu umgehen? Die Imports interessieren mich an dieser Stelle nämlich nicht. Ich möchte nur per Reflection herausfinden, welche Annotations die jeweilige Klasse hat. Die eigentliche Lauffähigkeit der Klasse ist in dem Moment nicht wichtig.

Deshalb meine Frage: Gibt es eine Möglichkeit, die jeweilige Klasse doch per Class.forName ohne Fehler zu bekommen, ohne sämtliche von ihr importierten jars verfügbar zu haben?

Grüße
Tom
 

FArt

Top Contributor
Du kannst die Klasse nur laden, wenn auch alle davon abhängigen Klassen geladen werden können. Somit müssen auch diese Ressourcen im Klassenpfad sein.
 

tbar0711

Mitglied
Gibt es nicht noch eine andere Möglichkeit? Ich weiss nämlich nicht im Voraus, welche Abhängigkeiten das jeweilige von meinem Programm zu prüfende jar hat. ;(
 

tbar0711

Mitglied
Hi,

ok, nun mal angenommen, ich bekomme in einer Schleife nacheinander alle jars, die ich brauche, mit deren absolutem Pfad (z.B. /home/meinName/scheduler-plugin.jar).

Wie kann ich diese jars zur Laufzeit meinem Classpath hinzufügen?
Dabei möchte ich nicht nur bestimmte Klassen der jeweiligen Jar, sondern alle (also jeweils das komplette jar).

Grüße
Tom
 
T

tuxedo

Gast
Es gibt ne Lib namens Scannotation. Der gibst du einfach die JAR URLs und kannst dann nach Annotations in den JARs suchen ohne auch nur eine davon Instantiieren zu müssen oder von allen .class Files kenntniss zu haben... Intern wird Javassist benutzt und auf ByteCode ebene gesucht...

- Alex
 

tbar0711

Mitglied
Das hört sich ja super an.

Hab jetzt mal mit dem Scannotation herumgespielt. Leider bekomme ich aber immer Source not found, wenn ich der scanArchives-Methode die url übergebe. Ich weiss nur den Pfad zum jar-File als String.
Das ganze läuft auf Linux.

Die url habe ich versucht, so zu übergeben:

Java:
		URLClassLoader classLoader = new URLClassLoader(new URL[]{SecurityMain.class.getResource("/home/meinName/jar-test/myApplication.jar")}, SecurityMain.class.getClassLoader());

		AnnotationDB adb = new AnnotationDB();
		try {
			adb.scanArchives(classLoader.getURLs());
			// Just scan Class Annotations
			adb.setScanFieldAnnotations(false);
			adb.setScanMethodAnnotations(false);
			adb.setScanParameterAnnotations(false);
			
			Map<String, Set<String>> annotationIndex = adb.getAnnotationIndex();
			
			// Classes with stateless annotation
			Set<String> entities = annotationIndex.get("javax.ejb.Stateless");

			// Classes with statful annotation
			Set<String> entities2 = annotationIndex.get("javax.ejb.Stateful");
			
			

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

Habt ihr eine Idee, was da falsch läuft?

Grüße
Tom
 
T

tuxedo

Gast
Ich hab das so gemacht:

Java:
/**
     * Returns a list of class-names which contain the <code>MarvinModule</code> annotation
     *
     * @param file the archive to check
     * @param myAnnotationClass the annotation to check for
     * @return a list of class-names. The list can be zero sized if no annotated class is found
     * @throws ArchiveLoadException
     */
    private static List<String> getAnnotatedClasses(File file, Class<?> myAnnotationClass) throws ArchiveLoadException {
        AnnotationDB adb = new AnnotationDB();
        List<String> annotationList = new ArrayList<String>();
        try {
            URL[] urls = new URL[]{file.toURI().toURL()};
            adb.scanArchives(urls);
            Map<String, Set<String>> annotationIndex = adb.getAnnotationIndex();
            Iterator<String> iterator = annotationIndex.keySet().iterator();
            while (iterator.hasNext()) {
                String annotationKey = iterator.next();
                Set<String> classSet = annotationIndex.get(annotationKey);
                Iterator<String> classSetIterator = classSet.iterator();
                while (classSetIterator.hasNext()) {
                    String annotatedClass = classSetIterator.next();
                    logger.debug("Annotation found: {} in {}", annotationKey, annotatedClass);
                    if (annotationKey.equals(myAnnotationClass.getClass().getName())) {
                        logger.debug("Adding class {} to modules list", annotatedClass);
                        annotationList.add(annotatedClass);
                    }
                }
            }
        } catch (IOException ex) {
            throw new ArchiveLoadException("could not load file [" + file.getAbsolutePath() + "] for inspecting annotations ...");
        }
        return annotationList;
    }

Vielleicht kannst du's ja in teilen weiterverwenden ....
 

tbar0711

Mitglied
Hallo,

danke nochmal für die Hilfe. Ich habe nun mein Problem gelöst und konnte mit Scannotation die Annotations auslesen.

Allerdings reicht mir das leider noch nicht, da ich aufgrund einer Session Bean nicht das zugehörige Interface, sowie dessen Methoden ermitteln kann. Auch kann ich nicht die Methoden der Session Bean ermitteln. Das mit crossReferenceImplementedInterfaces() funktioniert leider nicht.

Daher würde ich das ganze doch lieber über Reflection lösen. Wie gesagt, momentan bekomme ich alle jars, die ich brauche, über eine Schleife als String (kompletter Pfad und jarname).

Wie kann ich nun diese einzelnen jars zur Laufzeit innerhalb meiner Schleife zum Classpath hinzufügen? Hierbei möchte ich mir nicht einzelne Klassen aus den jars holen, sondern jeweils die komplette jar.

Grüße
Tom
 

tbar0711

Mitglied
Hi,

ich hab das jetzt so ungefähr gemacht:
Java:
			URL p2 = new URL("file:/home/Temp/firstjar.jar");
			URL p = new URL("file:/home/Temp/secondjar.jar");
			
			java.net.URLClassLoader loader = new java.net.URLClassLoader(new URL[]{p,p2}, ClassLoader.getSystemClassLoader());
		
foundClass = Class.forName(className,true,loader);

Danke für die Tips

Grüße
Tom
 

iholta

Mitglied
Hey!

So, erster post =)
Ich habe folgendes Problem: Wenn ich Files aus dem gleichen Verzeichnis lade, also mit Class.forName(..) kann ich ohne Probleme alle Annotations auslesen. LAde ich das ganze über den URLClassLoader aus einem anderen Verzeichnis, finde ich keine Annotations mehr. Wie ist das möglich?

Wäre super wenn mir jemand helfen kann:)
 

iholta

Mitglied
Also, ich möchte aus meinen class files annotations wie:

@Path("/test")
public class SimpleService {...}
oder
public String hallo(@QueryParam("name") String name, @QueryParam("num") int i){..}
auslesen.

Wenn ich folgenden (verienfachten) code verwende:
private void scan(String filename) {
Class clazz= Class.forName(filename);
for (Annotation ann:clazz.getAnnotations()){
System.out.println(ann.toString());
}
}
gibt er mir korrekt @javax.ws.rs.Path(value=/test) aus. Da das aber nur mit klassen im selben verzeichnis funktioniert habe ich es umgeändert auf:
File fJar = new File(path);
URL url = null;
try
{
url = fJar.toURI().toURL();
URLClassLoader urlcl = new URLClassLoader(new URL[] {url});
String strPackage = file;
clazz = Class.forName(strPackage, true, urlcl);
}
catch(Exception ex)
{ex.printStackTrace();}

for (Annotation ann:clazz.getAnnotations()){
System.out.println(ann.toString());
}
Jetz bekomme ich keine Annotations mehr, die klasser wird aber richtig geladen, denn ich bekomme immer noch die richtigen Methoden heraus. hoff es ist jetz verständlicher..
 

tbar0711

Mitglied
Hi,

hat die Klasse, die du jetzt geladen hast, überhaupt eine Annotation? So wie Deine Klasse SimpleService die Annotation @Path("/test") hat?

Oder willst Du die Annotations auf Methodenebene auslesen? Dann müsstest Du Dir die Methoden über clazz.getDeclaredMethods() holen und diese in einen Array vom Typ java.lang.reflect.Method stecken und anschließend Dir für jede Methode mit getAnnotations() die Annotationen holen.

Kannst auch mal im Debug-Modus schauen, was dein Class-Objekt alles so mitbringt.

Grüße
Tom
 

iholta

Mitglied
Ja, sie hat annotations. Ich lade beim zweiten mal genau die gleiche Klasse (also SimpleService), nur aus einem anderen Verzeichnis. Habe jetzt bemerkt, wenn ich das Programm mit dem URLClassLoader auch im selben Verzeichnis ausführe funktioniert es auch.

Das mit den MEthoden ist mir klar, die muss ich später auch noch holen, hoffe aber dass das kein problem ist wenn die class- annotations mal funktionieren.

und..mir ist nich ganz klar was ich im debug-modus machen soll..?

Danke :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M *.class Files ausführen Allgemeine Java-Themen 2
L Class Files , Methode .delete() Allgemeine Java-Themen 13
A Versionierung von Class-Files Allgemeine Java-Themen 10
G Probleme mit Class Files Allgemeine Java-Themen 16
G class files zu java files Allgemeine Java-Themen 3
D NoClassDefFoundError: Could not initialize class Allgemeine Java-Themen 0
J Class to link Java Allgemeine Java-Themen 4
C Was passt hier nicht bei der Calendar-Class Allgemeine Java-Themen 2
E Class.getResourceAsStream() gibt null zurück Allgemeine Java-Themen 2
Erwin82a Object cannot be converted to Custom Class in Lampda Expression Allgemeine Java-Themen 2
T Java Robot Class - Bot Allgemeine Java-Themen 3
S Class File Editor -> Source not found Allgemeine Java-Themen 4
G javafx "class path" exception Allgemeine Java-Themen 5
S Java class direved from inner class Allgemeine Java-Themen 6
S Inner Class Allgemeine Java-Themen 11
K Wildcard und class type Allgemeine Java-Themen 9
M Java model class ? Allgemeine Java-Themen 9
Thallius Ist meine static Helper Class Thread save? Allgemeine Java-Themen 9
S class path resource [config.properties}] cannot be opened because it does not exist Allgemeine Java-Themen 4
J Reflection Aufruf: .class durch .dll ersetzen Allgemeine Java-Themen 4
T Compiler-Fehler NoClassDefFoundError beim Laden einer Class Allgemeine Java-Themen 11
J Class Decompile als String (Procyon) Allgemeine Java-Themen 2
H Class 'java.io.BuferedReader' is not present in JRE Emulation Libary | GWT Fehler?! Allgemeine Java-Themen 0
I Datentypen String in class sicher verwahren Allgemeine Java-Themen 17
R Dynimc Class Loading Allgemeine Java-Themen 5
J Inner class + Leer-Konstruktor Allgemeine Java-Themen 1
Neumi5694 Methoden Generic: Rückgabetyp als Class-Parameter übergeben Allgemeine Java-Themen 3
D Collections.sort funktioniert nicht in exportierten .class Dateien Allgemeine Java-Themen 10
V Eclipse .class Dateien Allgemeine Java-Themen 9
KeexZDeveoper Von .class zu .java Allgemeine Java-Themen 7
N Wo ist Object.class ? Allgemeine Java-Themen 0
K Nicht alle class-Dateien im JRE? Allgemeine Java-Themen 2
L Klassen Nested Class In Nested Class Allgemeine Java-Themen 3
perlenfischer1984 Dialect class not found exception Allgemeine Java-Themen 15
Tort-E Manifest Main-Class Allgemeine Java-Themen 8
I JSoup Class auslesen Allgemeine Java-Themen 1
K Generic class und Reflection Allgemeine Java-Themen 2
R .class Datei in .jar austauschen Allgemeine Java-Themen 2
R Java .class-File-Konstrunkt mit Programm visualisieren Allgemeine Java-Themen 18
A main-class Not found Allgemeine Java-Themen 3
T Java Class Intrumentation mit Annotations in Laufzeit Allgemeine Java-Themen 1
N Per Reflection auf (method) local inner class zugreifen? Allgemeine Java-Themen 3
P JDK installieren Error: Could not find or load main class HelloWorld.java Allgemeine Java-Themen 3
B public class JarFilter extends FileFilter « Falsch? Allgemeine Java-Themen 4
D Object nach Vererbung mit Class Object überprüfen Allgemeine Java-Themen 4
T Hash von *.class-Datein überprüfen Allgemeine Java-Themen 1
F java.lang.ClassNotFoundException: .class Allgemeine Java-Themen 5
T InvalidClassException - Read null attempting to read class descriptor for object Allgemeine Java-Themen 8
Phash Can't find Main Class Allgemeine Java-Themen 4
B Erste Schritte Plugin erkennen und Class Dateien anzeigen lassen Allgemeine Java-Themen 3
B json zu java class Allgemeine Java-Themen 2
antonbracke Aus Jar eine Class laden und damit arbeiten! Allgemeine Java-Themen 5
D Class<CAP#1> statt Class<...> Allgemeine Java-Themen 5
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
A Class Datei aus Verzeichnis über URLClassLoader laden Allgemeine Java-Themen 2
E NetBeans warning: [options] bootstrap class path not set in conjunction with -source 1.6 Allgemeine Java-Themen 4
X Could not find the main class programm will exit (textdokument) Allgemeine Java-Themen 3
S Could not find the main class Allgemeine Java-Themen 7
B Mal wieder "Could not find the main class" Allgemeine Java-Themen 3
B Variable class in java.lang.Object Allgemeine Java-Themen 11
C Could not find the main class. Allgemeine Java-Themen 15
S Klassen .jar - eine .class datei ändern? Allgemeine Java-Themen 23
A Could not find main class: start Allgemeine Java-Themen 5
S main() class finden Allgemeine Java-Themen 7
hdi Could not find main class? Allgemeine Java-Themen 8
R Warum Class.forName(); Allgemeine Java-Themen 7
C class.class angefordert ? Allgemeine Java-Themen 2
S Methoden Class.forName() >> Methoden - Reihenfolge Allgemeine Java-Themen 5
B Test$1.class mit dem javac compiler Allgemeine Java-Themen 7
G jar Datei findet Main Class nicht... Allgemeine Java-Themen 2
P Java Editor Could not find the main class GUI. Programm will exit. Allgemeine Java-Themen 3
D class Datei einlesen Allgemeine Java-Themen 4
T Interface > Abstract > Class Allgemeine Java-Themen 11
TheDarkRose Subversion .class Dateien auch commiten? Allgemeine Java-Themen 3
D API - Beispiel + static member in inner (non static) class Allgemeine Java-Themen 2
E String name in class convertieren Allgemeine Java-Themen 4
F Änderung in .jar bzw. .class vornehmen ? Allgemeine Java-Themen 18
H2SO3- bestimmte class immer mit 1.4 compilieren Allgemeine Java-Themen 5
B class dateien "einlesen" und objekte erzeugen Allgemeine Java-Themen 6
G Unterschied MyClass.class vs this Allgemeine Java-Themen 2
S mit Class eine Klasse nur einmal instantiieren Allgemeine Java-Themen 4
Sonecc Zugriff auf Class File einer anderen Jar während der Laufzeit Allgemeine Java-Themen 2
M Klasse aus xyz.class Datei laden / package entfernen? Allgemeine Java-Themen 4
BattleMaster246 Could not find the Main class Allgemeine Java-Themen 30
N class Task extends TimerTask ohne Blockieren Allgemeine Java-Themen 15
H .class in .java umwandeln Allgemeine Java-Themen 3
T class.newinstance + try/catch-konstruktor Allgemeine Java-Themen 6
X Cannot refer to a non-final variable settings inside an inner class defined in a different method Allgemeine Java-Themen 4
J Class.forName und CLASSPATH -Problem Allgemeine Java-Themen 5
G Thread in Methode oder in inner class Allgemeine Java-Themen 3
woezelmann referenz der outer class aus static nested class heraus Allgemeine Java-Themen 7
reibi Main-Class in Jarfile Allgemeine Java-Themen 3
E Timer class macht einfach garnichts :/ Allgemeine Java-Themen 6
D Class.forName Allgemeine Java-Themen 2
S Class RGB Farbe Allgemeine Java-Themen 2
S JavaDoc aus .class Datei extrahieren Allgemeine Java-Themen 5
mongole Class.class.getResource(...) Allgemeine Java-Themen 10
N Probleme mit .jar 'Could not find main class' Allgemeine Java-Themen 3
T Class Not Found Exception beim import von Paket Allgemeine Java-Themen 2
G Abstract class Stillfrage Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben