Klassen aus einem Package ermitteln und per Laufzeit laden

Christopher25

Bekanntes Mitglied
Hallo zusammen. Ich habe keine Frage an euch.
Ich habe hier eine Methode geschrieben, welche mir während der Laufzeit
zu einem bestimmten Package die Klassen als Class-Objekt ermittelt um dann
die classen einer Liste innerhalb eines Inviroments-Objektes hinzuzufügen.
Hier der bisherige Code:

Java:
public void registerMonster(String packageName, Enviroments env) {
        ArrayList<File> directories = new ArrayList<File>();
        try {
            ClassLoader cld = Thread.currentThread().getContextClassLoader();
            if (cld == null) {
                throw new ClassNotFoundException("Can't get class loader.");
            }
            Package pack = Package.getPackage(packageName);
            if (pack == null) return;
            packageName = pack.getName();
            String path = packageName.replace('.', '/');
            // Ask for all resources for the path
            Enumeration<URL> resources = cld.getResources(path);
            
            while (resources.hasMoreElements()) {
                directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8")));
            }
	        List<Class<?>> classes = new ArrayList<Class<?>>();
	        // For every directory identified capture all the .class files
	        for (File directory : directories) {
	            if (directory.exists()) {
	                // Get the list of the files contained in the package
	                String[] files = directory.list();
	                for (String file : files) {
	                    // we are only interested in .class files
	                    if (file.endsWith(".class")) {
	                        // removes the .class extension
	                            classes.add(Class.forName(packageName + '.'
	                                    + file.substring(0, file.length() - 6)));
	                    }
	                }
	            } else {
	                throw new ClassNotFoundException(packageName + " ("
	                        + directory.getPath()
	                        + ") does not appear to be a valid package");
	            }
	        }
	        for (Class m : classes) {
	        	 env.getMonsters().add(m);
	        }
        } catch (Exception e) {
			e.printStackTrace();
		}
	}

Der funktioniert in Eclipse super. Ich gebe dort die Package namen an und der lädt mir alle
Klassen innerhalb eines Package rein.
Wenn ich jedoch eine ausführbare .jar Datei erzeuge, kann er anscheinend nichts mehr richtig ermittelnt. Ich sehe nur die Auswirkungen, dass keine Monster mehr angezeigt werden,
wenn ich ein Enviroment betrete. Woran kann das liegen und wie kann ich das beheben?
 
Zuletzt bearbeitet von einem Moderator:

Gucky

Top Contributor
Das liegt vermutlich daran, dass ein JAR ZIP komprimiert ist. Du müsstest also irgendwie hinter den ZIP kommen. Z. B. mit einem ZipInputStream.

env.getMonsters().add(Class) ist ein etwas unglückliches Konstrukt. Implementiere lieber env.addMonsters()
 

Gucky

Top Contributor
File kann nur auf Dateien und Ordner zeigen, auch wenn sie (noch) nicht vorhanden sind. ZIP komprimierte Ordner werden aber als eine Datei behandelt.
Der ClassLoader kann zwar aus ZIP Dateien Klassen laden, allerdings kann File eben nicht darauf zeigen. Deshalb müsstest du anderweitig zu den geforderten Klassen navigieren. Vielleicht hilft dir diese Seite dabei weiter.
 

Christopher25

Bekanntes Mitglied
Ich habe das mit dem ZipInputStream versucht, jedoch bekomm ich einen "ZugriffVerweigert" - Error,
weil dich die jar ja in Benutzung vom Betriebssystems steckt und deshalb nicht eingelesen werden kann. (jedenfalls meine Erlärung)
 

Gucky

Top Contributor
Ja das wäre auch meine Erklärung.

Es liegt an der Klasse File. Da du die nicht verwenden kannst und der ZipInputStream anscheinend auch nicht funktioniert, kannst du nur noch versuchen mit Boardmitteln des ClassLoaders etwas zu werden oder du lagerst die zu ladenden Klassen in ein anderes JAR aus.
 

Christopher25

Bekanntes Mitglied
Habs jetzt mal versucht die Klassen einfach in einem Nebenordner zu extrahieren und von dort aus zu laden.
Aber bekomm das irgendwie nicht hin. Der Classloader kann die irgendwie nicht erkennen.
Hat denn niemand sowas mal versucht Dynamisch alle Klassen aus einem Package zu laden??
 

keddelzz

Mitglied
Die Idee wäre durch alle Einträge in allen jars zu iterieren die, sich in dem Pfad
Java:
   File path = new File(System.getProperty("java.home"), "lib");
und alle Bibliotheken, die sich auf dem ClassPath befinden (da bin ich mir nicht mehr sicher, wie man an die kommt, ist aber auch leichter als gedacht) zu iterieren.

Das Iterieren durch die Einträge der jars geht mit der Klasse JarFile ganz einfach!

Der Name der Einträge haben z.B. die Form "java/util/ArrayList.class", welche du dann mit Stringmanipulationen mit deinem gesuchten Package vergleichen kannst.

Um die Klassen dann zu laden müsstest du dir evtl einen eigenen ClassLoader schreiben, der mit Hilfe eines InputStreams und einem kompletten Klassennamen (z.B. "java.util.ArrayList") eine Klasse definiert.
Den Stream bekommst du von den Einträgen des JarFiles.

mfg keddelzz
 

keddelzz

Mitglied
Es könnte auch Klappen mit
Java:
   Class.forName(<klassenname>);
dazu müssen die Klassen auf dem ClassPath liegen.

Nur wenn sie das nicht tun, musst du sie mit einem ClassLoader nachladen.
 

keddelzz

Mitglied
Willst du nur selbstgeschriebene Klassen mit deiner Methode bekommen, oder auch Bibliotheksklassen?

Bei selbstgeschriebenen Klassen würde
Java:
    StringTokenizer cps = new StringTokenizer(System.getProperty("java.class.path"), ";");
    while (cps.hasMoreElements()) {
     	    String classPath = cps.nextToken();
            System.out.println(classPath);
    }
alle bekannten ClassPaths ausgeben. - Da sollte der Pfad deiner exportierten Jar dabei sein.
Die könntest du wie bereits beschrieben mit Hilfe der Klasse JarFile durchsuchen.

mfg keddelzz
 

Christopher25

Bekanntes Mitglied
Also ich bekomme das echt nicht hin.
Ich habe die Klassen als eigenständige Jar exportiert und lese die ein.
Aber der SystemClassLoader sagt ständig, dass er diese Klasse nicht finden kann
und gibt eine ClassNotFoundException aus.
 

Christopher25

Bekanntes Mitglied
Also ich bekomme das echt nicht hin.
Ich habe die Klassen als eigenständige Jar exportiert und lese die ein.
Aber der SystemClassLoader sagt ständig, dass er diese Klasse nicht finden kann
und gibt eine ClassNotFoundException aus.

PS: Bei diesem Tokenizer bekomm ich das JRE7 Verzeichnis in meinem Windows Verzeichnis raus.
Das ist Correkt so?? Wüsste nicht was das bringen soll, da die Jar doch nicht dort liegt.
 

keddelzz

Mitglied
Die Tokenizer-Methode funktioniert nur, wenn die jar-Datei "richtig" aufgerufen wird.
Mit dem Aufruf
Code:
java -jar <jardatei.jar>
kennt Java den ClassPath nicht.
stattdessen solltest du die jar mit
Code:
java -cp "<jardatei.jar>" package.MainClass
ausführen. So taucht dann auch der Pfad zu deiner Jar-Datei auf, anstatt nur der zu dem Pfad der JRE Installation.

Ich glaube, wenn Java deine Klassen kennt (wenn sie auf dem ClassPath liegen), dann solltest du mit
Java:
Class.forName(...);
die Klasse laden sollen.

Ansonsten müsstest du einen eigenen ClassLoader schreiben.

mfg keddelzz
 
Zuletzt bearbeitet:

Christopher25

Bekanntes Mitglied
So hallo zusammen.

Ich habe jetzt einige Zeit wenig gemacht aber mich heute wieder dran gesetzt bin nochmal alles durch gegangen und zu einem Ergebnis gekommen.
Eure Ansätze haben mir gut geholfen, besonders mit diesem JarFile etc. Ich poste hier nun mein Ergebnis und hoffe ich kann damit jemanden behilflich sein.
Java:
       /**
	 * Registriert die Monster in dem Package an das Enviroment
	 * @param packageName
	 */
	@SuppressWarnings("unchecked")
	public void registerMonster(String packageName, Enviroments env) {
		try {
			List<Class<?>> clazzez = getClasses(packageName);
			for (Class clazz : clazzez) {
				env.addMonsters(clazz);
			}
		} catch (ClassNotFoundException | IOException | URISyntaxException e) {
			JOptionPane.showMessageDialog(new JFrame(), "Spiel konnte wichtige Ressourcen nicht finden! \n" + e.getMessage(), "Fehlende Ressourcen", JOptionPane.OK_OPTION);
			System.exit(-1);
		}
	}
	
	@SuppressWarnings("static-access")
    public static List<Class<?>> getClasses(String packageName) throws IOException, URISyntaxException, ClassNotFoundException {
        List<String> names = getClassNamesFromPackage(packageName);
        List<Class<?>> classes = new ArrayList<Class<?>>();
        for (String name : names) {
            classes.add(GameController.class.forName(name));
        }
        
        return classes;
    }
	
	private static ArrayList<String>getClassNamesFromPackage(String packageName) throws IOException, URISyntaxException{
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL packageURL;
        ArrayList<String> names = new ArrayList<String>();;

        packageName = packageName.replace(".", "/");
        packageURL = classLoader.getResource(packageName);

        if(packageURL.getProtocol().equals("jar")){
            String jarFileName;
            JarFile jf ;
            Enumeration<JarEntry> jarEntries;
            String entryName;
            
            jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
            jarFileName = jarFileName.substring(5,jarFileName.indexOf("!"));
            jf = new JarFile(jarFileName);
            jarEntries = jf.entries();
            while(jarEntries.hasMoreElements()){
                entryName = jarEntries.nextElement().getName();
                if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){
                    entryName = entryName.substring(packageName.length(),entryName.lastIndexOf('.'));
                    String[] s = entryName.split("/");
                    names.add(packageName +s[0] + "."+ s[1]);
                }
            }
        } else{
        URI uri = new URI(packageURL.toString());
        File folder = new File(uri.getPath());
            File[] contenuti = folder.listFiles();
            String entryName;
            for(File actual: contenuti){
                entryName = actual.getName();
                entryName = entryName.substring(0, entryName.lastIndexOf('.'));
                names.add(packageName + "." + entryName);
            }
        }
        return names;
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Klassen von einem package laden, Statisches Feld auslesen und Objekt erstellen Java Basics - Anfänger-Themen 8
V Unbekannte Klassen aus einem Package laden? Java Basics - Anfänger-Themen 4
I @Entity Klassen, Service Beans etc. aus einem Share Projekt beziehen? Java Basics - Anfänger-Themen 26
algebraiker Nur Klassen aus einem bestimmten Jar laden Java Basics - Anfänger-Themen 16
L Liste aller Klassen die in einem Paket sind Java Basics - Anfänger-Themen 7
C Zwei Klassen in einem Fenster darstellen Java Basics - Anfänger-Themen 32
N Aufrufen von .java Klassen in einem Projekt Java Basics - Anfänger-Themen 2
D Eingabe bei einem Klassen-Attribu auf Richtigkeit überprüfen Java Basics - Anfänger-Themen 6
S Mehrere klassen in einem GUI ausführen Java Basics - Anfänger-Themen 3
J Methodenaufrufe abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 17
M Abstrakte Klassen - Notation Java Basics - Anfänger-Themen 9
Detlef Bosau Nachladen von Klassen zur Laufzeit Java Basics - Anfänger-Themen 24
M Anonyme Klassen - Warum wird in der Konsole nichts ausgegeben? Java Basics - Anfänger-Themen 1
MoxMorris Einige Methoden aus verschiedenen Klassen nacheinander auszuführen läuft seltsam Java Basics - Anfänger-Themen 2
I 2 verschiedene Klassen mit gleichen Property vergleichen Java Basics - Anfänger-Themen 13
C Array von Klassen Java Basics - Anfänger-Themen 2
monsterherz 2 Klassen daher Probs mit dem Dateinamen Java Basics - Anfänger-Themen 9
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 9
I JPA Query für mehrere Klassen Java Basics - Anfänger-Themen 3
S IntelliJ geht alle Klassen durch Java Basics - Anfänger-Themen 9
I Gleiche Klassen und Methoden in unterschiedlichen Projekten nutzen Java Basics - Anfänger-Themen 2
T variablen klassen übergreifend Java Basics - Anfänger-Themen 12
N Klassen Methoden anderer Klassen aufrufen Java Basics - Anfänger-Themen 4
D Klassen Klassen Kommunikation Java Basics - Anfänger-Themen 12
Encera Auf Objekte aus anderer Klassen zugreifen Java Basics - Anfänger-Themen 20
berserkerdq2 Zwei Klassen Erben von der Klasse A, die eine Klasse kann ich an Methoden übergeben, die als Parameter A haben, die andere nicht? Java Basics - Anfänger-Themen 3
M Andere Methoden in anderen Klassen aufrufen Java Basics - Anfänger-Themen 11
L Methoden in anderen Klassen nutzen Java Basics - Anfänger-Themen 6
D Klassen und Vererbung Java Basics - Anfänger-Themen 2
L Best Practice Annotierte Klassen im Classpath herausfinden Java Basics - Anfänger-Themen 1
P Mit dem Scanner Klassen aufrufen Java Basics - Anfänger-Themen 3
O Klassen Zusammenspiel zwischen 2 Klassen Java Basics - Anfänger-Themen 1
K Zweite Ausgabe von vererbten Klassen Java Basics - Anfänger-Themen 3
M Wie können Klassen nicht-materialisierte Attribute haben, die nur über get/ set-Mehoden simuliert sind? Java Basics - Anfänger-Themen 6
Speedrunner klassen aufrufen Java Basics - Anfänger-Themen 41
M Log4J (v2) nachträglich in allen Klassen hinzufügen Java Basics - Anfänger-Themen 9
D importieren eigener Klassen Java Basics - Anfänger-Themen 12
W Wo ist der Wurm in meinem Grundverständnis von Klassen? Java Basics - Anfänger-Themen 22
S Daten/Klassen/Packages richtig updaten!? Java Basics - Anfänger-Themen 2
alice98 Erste Schritte Liste erstellen ohne vorgefertigte Klassen Java Basics - Anfänger-Themen 1
C Archiv für eigene Klassen Java Basics - Anfänger-Themen 9
S Objekte von zwei klassen in zwei verschiedene Textdateien schreiben Java Basics - Anfänger-Themen 5
elsaaaaaa Wochentag als String ausgeben mit JDK Klassen Java Basics - Anfänger-Themen 6
CptK Generics: Klassen die Interface implementieren, aber selbst nicht das Interface sind Java Basics - Anfänger-Themen 8
Z Mehtode bei Start des Programms ausführen (Klassen übergreifend) Java Basics - Anfänger-Themen 12
J Allgemeines Problem mit Klassen Java Basics - Anfänger-Themen 5
TimoN11 Java Klassen Global einbinden Java Basics - Anfänger-Themen 1
B Inventar als einzelne Klassen anlegen? Java Basics - Anfänger-Themen 12
G Java Klassen und Instanzmethoden Java Basics - Anfänger-Themen 15
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 3
T Vererbung Verschiedene Attribute für vererbte Klassen Java Basics - Anfänger-Themen 4
S Klassen instanziieren und verwenden von Getter und Setter Java Basics - Anfänger-Themen 4
B Variablen Variablen übertragen ohne Klassen Java Basics - Anfänger-Themen 5
C Fernseher-Aufgabe (Methoden, Klassen und Objekte) Java Basics - Anfänger-Themen 63
H Methoden in großen Klassen gruppieren oder auslagern? Java Basics - Anfänger-Themen 10
G Abstrakte Klassen Java Basics - Anfänger-Themen 11
Y Klassen Klassen und Objekte Java Basics - Anfänger-Themen 3
Y Klassen Klassen und Objekte mit set und get Java Basics - Anfänger-Themen 0
A Generischen Klassen Java Basics - Anfänger-Themen 8
A Vererbung Klassen im Bezug auf Auto´s Java Basics - Anfänger-Themen 18
A Generische Klassen/Interface Java Basics - Anfänger-Themen 1
A Klassen Vererbung und zusätzliche Unterklassen Java Basics - Anfänger-Themen 23
J 2 klassen benutzen Java Basics - Anfänger-Themen 5
A Klassen und methoden Java Basics - Anfänger-Themen 15
A Bankweverwaltung mit Klassen und Methoden Java Basics - Anfänger-Themen 14
J Klassen Problem Java Basics - Anfänger-Themen 8
I Java Klassen "Graphics" und "MouseEvent" kombinieren Java Basics - Anfänger-Themen 7
I Klassen als Datentyp nutzen? Java Basics - Anfänger-Themen 11
M Aufsplitten von Methoden in andere Klassen Java Basics - Anfänger-Themen 2
M (Sehr großes Problem) Listen als static in anderen Klassen verwendet Java Basics - Anfänger-Themen 12
C Klassen objektorientiert aufteilen Java Basics - Anfänger-Themen 6
hello_autumn Klassen Anzahl sowie die Anzahl der Junit Tests ermitteln? Java Basics - Anfänger-Themen 8
A Auf Eigenschaften von Objekten anderer Klassen zugreifen Java Basics - Anfänger-Themen 5
F Klassen und Pakete Projektübergreifend (Eclipse) Java Basics - Anfänger-Themen 6
V_Fynn03 Klassen Überweisungen tätigen und einzahlen mit 2 Klassen Java Basics - Anfänger-Themen 1
W Abarbeitungsreihenfolge Anonyme Klassen Java Basics - Anfänger-Themen 2
V_Fynn03 Bruchrechner programmieren (2 Klassen) Java Basics - Anfänger-Themen 9
D OOP- Eine Klasse in mehrere Klassen aufteilen Java Basics - Anfänger-Themen 7
J Problem mit Array: 2 Klassen Java Basics - Anfänger-Themen 2
W Frage zu anonymen Klassen Java Basics - Anfänger-Themen 4
Curtis_MC Parameter-Übergabe bei Klassen und Methoden Java Basics - Anfänger-Themen 12
E Klassen implementieren Java Basics - Anfänger-Themen 94
T Interfaces in erbenden Klassen Java Basics - Anfänger-Themen 2
C Methoden/Klassen Übergabewerte Java Basics - Anfänger-Themen 8
C Java Klassen/Methoden/Übergabeparameter Java Basics - Anfänger-Themen 4
L Wie geht man bei mehreren Action Klassen vor? Java Basics - Anfänger-Themen 0
P Datentypen, Klassen, Operatoren, Wrapperklassen Java Basics - Anfänger-Themen 2
L Wie teilt man ein Programm in vernünftige Klassen ein? Java Basics - Anfänger-Themen 10
T Klassen Denkfehler im Klassen "dynamisch" instanzieren? Java Basics - Anfänger-Themen 4
P Zugriff auf Variablen anderer Klassen in Greenfoot Java Basics - Anfänger-Themen 1
A Methode, Klassen Java Basics - Anfänger-Themen 3
B UML Klassen Diagramm zu Java Code Programmieren und ausführen Java Basics - Anfänger-Themen 21
J Zwei Klassen die sich gegenseitig referenzieren - Bad practice? Java Basics - Anfänger-Themen 4
G Klassen und Objekte Java Basics - Anfänger-Themen 2
Java The Hutt SetWerte über verschiedene Klassen Java Basics - Anfänger-Themen 16
D Klassen ausgeben Java Basics - Anfänger-Themen 2
H linkedlist generische klassen Java Basics - Anfänger-Themen 169
B CSS Klassen in eine Liste schreiben Java Basics - Anfänger-Themen 4
Queiser Nicht statische Klassen Java Basics - Anfänger-Themen 6
neerual Klassen Wie rufe ich Klassen, die andere Klassen extenden in einer Test Unit auf? Java Basics - Anfänger-Themen 10

Ähnliche Java Themen

Neue Themen


Oben