Klassen dynamisch aus jar-datei laden

angus

Mitglied
Hallo,
mal wieder das leidige Thema und Probleme mit dem URLClassloader.
Könnte bitte jemand auf den code schauen und den/die Fehler finden? danke :)

Problemstellung:
Für einen FH-Kurs soll jede Gruppe ein Komponentenmodel ala OSGI und Konsorten entwickelt und programmiert werden. Natürlich nicht der komplette Funktionsumfang nur ein proof of concept.
Dabei soll es eine RuntimeEnviroment geben, die Komponenten auf wunsch des Users laden, entladen, starten, stoppen, ... etc. kann.

Unser Entwurf sieht so aus:
2 Java Bibliotheken: libComponent, libRuntime
Die libComponent beinhaltet nur ein Interface ComponentInterface.
Der User muss nur um eine Komponente zu erstellen die libComponent einbinden und seine Komponentenklasse muss das Interface implementieren.
Die Runtime baut auf der libCompnent auf und beinhaltet 2 Klassen zum verwalten der Komponenten (Runtime und ComponentContainer). Die Runtime-Klasse besitzt ein public Interface damit eine Anwendung, die die libRuntime einbindet diese steuern kann.

ComponentInterface:
Java:
package component;

public interface ComponentInterface {

    public String getStatus();

    public String getDescription();

    public String[] getDependencies();

    public String[] provides();

    public boolean start();

    public boolean stop();

}

nun die Klasse Runtime:
Java:
package runtime;

import component.ComponentInterface;
import java.util.List;

public class RunTime{  

    private ComponentContainer cc;

    // singleton pattern
    private RunTime(){

        cc = new ComponentContainer();
    }

    private static RunTime rt = new RunTime();

    public static RunTime getRuntime(){
        return rt;
    }

    public List<String> loadComponent(String compPath) throws Exception{
        return cc.loadClass(compPath);
    }

    public void startComponent(String compName)throws Exception{
        cc.startComponent(compName);
    }

    public void stopComponent(String compName)throws Exception{
        cc.stopComponent(compName);
    }

    public String unloadComponent(String compName) throws Exception{
        return cc.unloadComponent(compName);
    }

    private void unloadDependencies(){

    }

    public boolean isComponentRunning(String compName){

        return cc.isRunning(compName);
    }

    public ComponentInterface getComponent(String compName) {
        return cc.getComponent(compName);
    }

    public Object getInterface(String interfaceName) {
        return cc.getInterface(interfaceName);
    }

    public String getDescription(String compName) {
        return cc.getComponent(compName).getDescription();
    }

    public String getStatus(String compName) {
        return cc.getStatus(compName);
    }

    public String getStatus() {
        return cc.getStatus();
    }
}

Die CopmponentContainer-Klasse (wo die eigentliche Arbeit verrichtet wird -- Und wo es die Probleme hagelt)
Java:
package runtime;

import component.ComponentInterface;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

class ComponentContainer {

    private static enum status {

        deployed, started, stopped
    };
    // speichert Instanzen geladener Komponenten
    private Map<String, ComponentInterface> compMap;
	// speichert den Status zu den geladenen Komponenten
    private Map<String, status> compStatus;
	// brauche ich später für den Classloader
    private static final Class[] parameters = new Class[]{URL.class};
    
	// soll später verwendung finden, damit man weiss welche Komponenten welche Funktionalität bereitstellen
	private Map<String, Object> compByInterface;

    
    ComponentContainer() {
       
        compMap = new HashMap<String, ComponentInterface>();
        compStatus = new HashMap<String, status>();
        compByInterface = new HashMap<String, Object>();
    }

    void startComponent(String compName) {
        if (isLoaded(compName) && !isRunning(compName)) {
            compStatus.put(compName, status.started);

            compMap.get(compName).start();
        }
    }

    void stopComponent(String compName) {
        if (isLoaded(compName)) {
            compMap.get(compName).stop();
            compStatus.put(compName, status.stopped);
        }
    }

    boolean isLoaded(String compName) {

        if (compMap.containsKey(compName)) {
            return true;
        }

        return false;
    }

    boolean isRunning(String compName) {

        if (compStatus.get(compName).equals(status.started)) {
            return true;
        }

        return false;
    }

    String getStatus(String compName) {
        return compStatus.get(compName).toString();
    }

    public String getStatus() {
        String retVal = "";

        retVal += "Loaded Components: " + String.valueOf(compMap.size()) + "\n";

        return retVal;
    }

    String unloadComponent(String compName) {
        if (isLoaded(compName)) {

            if (isRunning(compName)) {
                stopComponent(compName);
            }

            compMap.remove(compName);
            compStatus.remove(compName);
            return compName;
        }

        return null;
    }

    ComponentInterface getComponent(String compName) {

        if (isLoaded(compName)) {
            return compMap.get(compName);
        }

        return null;
    }

    Object getInterface(String intName) {
        if (compByInterface.containsKey(intName)) {
            return compByInterface.get(intName);
        }

        return null;
    }

	// hier fängt der Aerger an!!!
    List<String> loadClass(String compPath) throws Exception {

        File jar = new File(compPath);
        if (!(jar.isFile() && jar.getName().endsWith(".jar"))) {
            return null;
        }

        boolean isComp = false;

		// hole mit der hilfsmethode Alle klassen aus der jar
        List<String> classNames = getClassNames(jar.getAbsolutePath());
        List<String> compNames = new ArrayList<String>();
		
		// iteriere über alle KLasse
        for (String className : classNames) {
            // Remove the ".class" at the back
            String name = className.substring(0, className.length() - 6);
           // System.out.println(name);
		   
		   // Lade die klassen FEHLER IN DIESER METHODE
            Class clazz = getClass(jar, name);
			
			// Hole alle interfaces der klasse
            Class[] interfaces = clazz.getInterfaces();
            for (Class c : interfaces) {
                // Implement the ComponentInterface
				// Wenn die Klasse das KomponentenInterface implementiert speicher eine Instanz der Klasse
                if (c.getName().equals("component.ComponentInterface")) {
                    compMap.put(clazz.getName(), ((ComponentInterface) clazz.newInstance()));
                    isComp = true;
                }
            }

            // when it is a component then add it's interfaces to the compByInterfaceMap
            if (isComp) {

                compNames.add(name);

                for (Class c : interfaces) {
                    // get the interface of the class
                    if (!c.getName().equals("component.ComponentInterface")) {
                        compByInterface.put(c.getName(), c.cast(clazz));
                    }
                }

            }
        }

		// gebe der Aufrufenden Methode eine Liste der KLassennamen zurück
		// damit z.b. in einer GUI-Anwendung diese in eine Liste gepackt werden können
        return compNames;
    }

    private List<String> getClassNames(String jarName) throws IOException {
        ArrayList<String> classes = new ArrayList<String>(10);
        JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName));
        JarEntry jarEntry;
        while (true) {
            jarEntry = jarFile.getNextJarEntry();
            if (jarEntry == null) {
                break;
            }
            if (jarEntry.getName().endsWith(".class")) {
                //System.out.println(jarEntry.getName());
                classes.add(jarEntry.getName().replaceAll("/", "\\."));
            }
        }

        return classes;
    }
	
	// Diese Methode funzt einfach nicht ...hilfe
    private Class getClass(File file, String name) throws Exception {
       // addURL(file.toURI().toURL());
        URLClassLoader clazzLoader;
        Class clazz;
        String filePath = file.getAbsolutePath();
        //filePath = "jar:file://" + filePath + "!/";
        //URL url = new File(filePath).toURI().toURL();
        URL url = new URL("jar", "", "file:" + filePath + "!/");		
        clazzLoader = new URLClassLoader(new URL[]{url}, this.getClass().getClassLoader());
        clazzLoader.loadClass(ComponentInterface.class.getName());
       // Class.forName(name, false, clazzLoader);
        clazz = clazzLoader.loadClass(name); // <---- throws exceptions like lucky luke
        return clazz;
    }
	
	// Methode um eine Jar (eine URL) zum systemklassenpfad hinzuzufügen
	// wird nciht verwendet (hilft auch nicht), da sonst eine klasse nicht mehr "vergessen" wird
    private void addURL(URL u) throws IOException {

        URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        URL urls[] = sysLoader.getURLs();
        for (int i = 0; i < urls.length; i++) {
            if (urls[i].toString().equalsIgnoreCase(u.toString())) {
                return;
            }
        }
        Class sysclass = URLClassLoader.class;
        try {
            Method method = sysclass.getDeclaredMethod("addURL", parameters);
            method.setAccessible(true);
            method.invoke(sysLoader, new Object[]{u});
        } catch (Throwable t) {
            throw new IOException("Error, could not add URL to system classloader");
        }
    }
}

Den Code zum laden der Klassen aus einer Jar stammt nicht von mir, google sei dank ... Dachte ihn genug verstanden zu haben damit er funktioniert.
Tja so irrt man sich ... Die vielen anderen Beispiele hier aus dem Forum und von Google sahen jetzt nicht viel anders aus, als dass ich Denken würde,
dass konzeptionell etwas nicht stimmt.

Jedenfalls mit einer kleinen Testanwendung (RTManager - Code im folgenden Post, da sonst zu lang):
kommt es immer wieder zu exceptions.
Immer wenn ich versuche eine kleine TestKomponente zu laden
Java:
import component.ComponentInterface;

public class HWComp implements ComponentInterface{

    public String getStatus() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getDescription() {
        return "a simple hello world example component";
    }

    public String[] getDependencies() {
        return null;
    }

    public String[] provides() {
        return null;
    }

    public boolean start() {
        System.out.println("Hello World");
        return true;
    }

    public boolean stop() {
        System.out.println("component stoppped");
        return true;
    }
}
kommt es zu folgender exceptions:

Java:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: component/ComponentInterface
        at runtime.ComponentContainer.getClass(ComponentContainer.java:197)
        at runtime.ComponentContainer.loadClass(ComponentContainer.java:137)
        at runtime.RunTime.loadComponent(RunTime.java:35)
  ...

Es besagt, dass er das CompnentInterface nicht finden kann, was ja eigentlich nicht sein darf, da die KLasse ComponentContainser selber dieses Interface einbindet.
Weiter fällt auf, dass die Exception component/ComponentInterface anstelle von component.ComponentInterface schreibt ?!?!

Ich weiss nicht mehr weiter ...
Wenn Jemand bitte sich dass mal anschauen würde und mir mal einen Wink mit dem Zaun geben würde wo es hakt ...

Zum Testen fogendens machen:
Java-Bibliothek erstellen mit dem ComponentInterface
Java Bibliothek erstellen mit den Klassen RunTime und ComponentContainer (nicht vergessen die fertige libComponent einbinden).
Komponente (Java Bibliothek) HelloWorldComponent erstellen (auch hier die libComponent einbinden)
Die Gui Anwendung RTManager mit den Klassen RTManager und CListModel erstellen und die libRuntime einbinden.
Beim Start der RTManager-Anwendung auf load klicken und im FileChooser das Jar-File der HelloWorldComponent raussuchen und sich über die Exception freuen.

Vielen Dank
Angus
 

angus

Mitglied
Hier noch der Code für die Gui-Anwendung zum steuern der Runtime:

Java:
package view;

import java.io.File;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;
import runtime.RunTime;

public class RTManager extends javax.swing.JFrame {

    /** Creates new form View */
    public RTManager() {

         try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ex) {
            Logger.getLogger(RTManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        initComponents();

        componentList.setModel(new CListModel());

        rt = RunTime.getRuntime();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        componentList = new javax.swing.JList();
        unloadButton = new javax.swing.JButton();
        loadButton = new javax.swing.JButton();
        startStopButton = new javax.swing.JButton();
        statusButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        statusArea = new javax.swing.JTextArea();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        componentList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(componentList);

        unloadButton.setText("Unload");
        unloadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unloadButtonActionPerformed(evt);
            }
        });

        loadButton.setText("Load");
        loadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadButtonActionPerformed(evt);
            }
        });

        startStopButton.setText("Start / Stop");
        startStopButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startStopButtonActionPerformed(evt);
            }
        });

        statusButton.setText("Status");
        statusButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                statusButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("Loaded Components");

        jLabel2.setText("Status");

        statusArea.setColumns(20);
        statusArea.setRows(5);
        jScrollPane2.setViewportView(statusArea);

        jButton1.setText("Description");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 351, Short.MAX_VALUE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel1)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(loadButton)
                            .addComponent(unloadButton)
                            .addComponent(startStopButton)
                            .addComponent(statusButton)
                            .addComponent(jButton1))))
                .addContainerGap())
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jButton1, loadButton, startStopButton, statusButton, unloadButton});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 256, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel2))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(loadButton)
                        .addGap(18, 18, 18)
                        .addComponent(unloadButton)
                        .addGap(18, 18, 18)
                        .addComponent(startStopButton)
                        .addGap(18, 18, 18)
                        .addComponent(statusButton)
                        .addGap(18, 18, 18)
                        .addComponent(jButton1)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 185, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
        JFileChooser jfc = new JFileChooser();

        jfc.setFileFilter(new FileFilter() {

            @Override
            public boolean accept(File f) {
                if (f.isDirectory() || f.getName().toLowerCase().endsWith(".jar")) {
                    return true;
                }

                return false;
            }

            @Override
            public String getDescription() {
                return "Ordner oder Jar-Files (*.jar)";
            }
        });


        int retVal = jfc.showOpenDialog(this);

        if (retVal == JFileChooser.APPROVE_OPTION) {

            File f = jfc.getSelectedFile();
            try {
               List<String> compList =  rt.loadComponent(f.getAbsolutePath());

               if(compList != null && !compList.isEmpty())
                   for(String s: compList)
                        ((CListModel)componentList.getModel()).add(s);
            } catch (Exception ex) {
                Logger.getLogger(RTManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }                                          

    private void unloadButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        try {
           String cName =  rt.unloadComponent(componentList.getSelectedValue().toString());
           ((CListModel)componentList.getModel()).remove(cName);
        } catch (Exception ex) {
            Logger.getLogger(RTManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }                                            

    private void startStopButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                
        
        String cName = componentList.getSelectedValue().toString();       
        
        if(rt.isComponentRunning(cName)){
            try {
                rt.stopComponent(cName);
            } catch (Exception ex) {
                Logger.getLogger(RTManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }else{
            try {
                rt.stopComponent(cName);
            } catch (Exception ex) {
                Logger.getLogger(RTManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }                                               

    private void statusButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             

        String status;
        
        if(componentList.isSelectionEmpty())
            status = rt.getStatus();

        else
            status = rt.getStatus(componentList.getSelectedValue().toString());

        statusArea.append(status);
        statusArea.append("\n");
    }                                            

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        if(componentList.isSelectionEmpty())
            return;

        String des = rt.getDescription(componentList.getSelectedValue().toString());

        statusArea.append(des);
        statusArea.append("\n");
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new RTManager().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JList componentList;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton loadButton;
    private javax.swing.JButton startStopButton;
    private javax.swing.JTextArea statusArea;
    private javax.swing.JButton statusButton;
    private javax.swing.JButton unloadButton;
    // End of variables declaration                   
    private RunTime rt;
}

Java:
package view;

import java.util.LinkedList;
import java.util.List;
import javax.swing.AbstractListModel;

public class CListModel extends AbstractListModel {

    private List<Object> data;

    public CListModel() {
        data = new LinkedList<Object>();
    }

    public int getSize() {
        return data.size();
    }

    public Object getElementAt(int index) {
        return data.get(index);
    }

    public void add(Object k) {
        data.add(k);
    }

    public void set(Object k, int index) {
        if (index < getSize()) {
            data.set(index, k);
        }
    }

    public void remove(int index) {
        if (index < getSize()) {
            data.remove(index);
        }
    }

    public void remove(Object k) {
        data.remove(k);
    }
}
 

kay73

Bekanntes Mitglied
Wie weit läuft Dein Tool denn? Bei mir funktioniert zumindest das Laden. Auch kein Problem mit
Code:
clazz = clazzLoader.loadClass(name); // <---- throws exceptions like lucky luke

Code:
java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)

P.s.: Füge mal in CListModel.add()
Code:
fireContentsChanged(this, 0, data.size());
ein.
P.p.s.: JCL - Jar Class Loader
 
Zuletzt bearbeitet:

angus

Mitglied
Hallo!
Also ich starte das Programm, klicke auf laden
und wähle mit dem Filechooser die zu ladene Jar aus.
Dann raised die im 1. Post beschriebene Exception.

Meine Kollegen konnten die auch reproduzieren ... (mac java)
Natürlich der Vorführeffekt, dass das Laden der Komponente bei Dir klappt :-(

Meine JVM/JDK:
Code:
java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

Danke für den fix mit der Liste ... im Eifer des Gefechts übersehen.
Die JCL-Bibliothek schau im mir mal an, Danke!
Leider können wir die für die gegeben Aufgabe wohl nicht benutzen.

Wenn Dir an dem Code nochwas auffallen sollte immer nur raus damit :)

Viele Grüße
Angus
 

kay73

Bekanntes Mitglied
Mir scheint, daß der URLClassLoader keinen Fehler wirft, wenn man ihm eine URL gibt, die er nicht finden kann. Vielleicht liegt es nur daran. Instantiiert mal einen URLClassLoader mit der JAR Url, ruft darauf getResourceAsStream("HWComp.class") auf und versucht die Klassenbytes zu lesen.
 
G

<GUEST>SPiKEe

Gast
Wieder mal JAVA und Plug-In's @ tutorials.de: Tutorials, Forum & Hilfe

da hab ich das thema schon mal lang und breit auseinander genommen ...
es ist zwar nicht vollständig das nach dem du suchst aber es funktioniert ohne problem

ACHTUNG

was dort noch nicht steht *weil es erst später dazu kam* ist das ENTLADEN von plug-in's ...
sämtliche klassen die von ClassLoader abgeleitet sind haben das problem das scheinbar referrenzlose und entladene JAR-files weiterhin gelockt bleiben
seit Java7 hat URLClassLoader die methode close()
für frühere versionen als 7 musst du einen CustomURLClassLoader ableiten und dort die das Closeable interface selbst implementieren ...
weitere infos dazu hier

Applikation updaten @ tutorials.de: Tutorials, Forum & Hilfe

ebenfalls ein von mir losgetrender thread in dem das "hacken" des URLClassLoaders beschrieben ist

ich denke diese beiden threads sollte dir genug infos zu deinem problem liefern

ich selber habe mitlerweile mein voll funktionsfähiges Pluginsystem
es bietet neben der von dir gewünscht HOT-PLUG-fähigkeit *plug-in's wieder vollständig entladen* auch noch weitere möglichkeiten die aber spezifisch für meine verwendung sind und nicht in ein allgemeines plug-in-system gehören

ich kann dir gerne das gesamte system zur verfügung stellen wenn du möchtest da ich wie du an den threads und der zeitspanne erkennen kannst LANGE meine probleme damit hatte ...
sowas kann man halt nicht in 2 wochen programmieren ... dafür braucht man schon einige zeit
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Classpath Klassen dynamisch erstellen Allgemeine Java-Themen 4
D Klassen dynamisch laden Allgemeine Java-Themen 5
T Klassen dynamisch ausführen Allgemeine Java-Themen 3
Reeny Dynamisch Klassen kompilieren Allgemeine Java-Themen 5
I Mehrere Klassen mit den selben Daten Allgemeine Java-Themen 5
Zrebna Wie ermittelt man alle testbaren (zu testenden) Klassen in seinem Maven-Projekt? Allgemeine Java-Themen 23
8u3631984 Jacoco Testcoverage bei Abstracten Klassen in verschachtelten Modulen Allgemeine Java-Themen 6
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
P9cman java.Lang Klassen fehlen in JRE System Library Allgemeine Java-Themen 1
B Wie kann ich mein 8 Klassen Gebilde objektorientierter schreiben? Allgemeine Java-Themen 114
N abstracte klassen methoden Allgemeine Java-Themen 32
W Klassen Zugriff auf ein Textfile aus allen Klassen. Allgemeine Java-Themen 2
M Klasse durch Klassen Aufteilung verbessern, aber wo? Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
M Kann man Annotationen auf Klassen einschränken die ein Interface implementieren? Allgemeine Java-Themen 1
nonickatall Methoden Kann man Klassen/Methoden aus Variablen heraus aufrufen? Allgemeine Java-Themen 6
H Interface PluginSystem ClassNotFound exception für library Klassen Allgemeine Java-Themen 10
L Classpath Zur Laufzeit bestimmte Klassen in Classloader hinzufügen? Allgemeine Java-Themen 4
P Abstrakte Klassen vs. Interface Allgemeine Java-Themen 4
I Klassen aus Jar-Dateien aus anderem Ordner laden Allgemeine Java-Themen 3
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
B Problem mit meinen Klassen Allgemeine Java-Themen 6
I Array Parameter mit 2 Klassen - NullPointerException Allgemeine Java-Themen 3
F ArrayList`s in Klassen mit Getter/Setter Allgemeine Java-Themen 8
F Code in Klassen bringen Allgemeine Java-Themen 4
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
F Klassen Verwendung abstrakter Klassen Allgemeine Java-Themen 9
W Variablenübergabe über mehrere Klassen Allgemeine Java-Themen 4
B Vererbung Interface und implementierende Klassen Allgemeine Java-Themen 8
D Klassen JLabels in anderen Klassen verwenden. Allgemeine Java-Themen 7
H Klassen LibGDX - Verschiedene Klassen als Value in einer Map Allgemeine Java-Themen 8
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
A Anonyme Klassen - Interface Allgemeine Java-Themen 5
ReinerCoder auf Klassen innerhalb eines package zugreifen Allgemeine Java-Themen 22
J Tetris Probleme bei Klassen Allgemeine Java-Themen 14
cool_brivk24 Klassen Klassen Aufruf Fehlgeschlagen Allgemeine Java-Themen 14
S Parametrisierte jUnit 5-Tests mit eigenen Datentypen/Klassen-Objekten als Test-Parameter Allgemeine Java-Themen 0
rentasad Design-Frage - Interfaces, Klassen, statische Methoden Allgemeine Java-Themen 3
S Klassen Abstrakte Klassen Allgemeine Java-Themen 5
T Log4J - Deaktivierung für einzelne Klassen Allgemeine Java-Themen 7
Tommy Nightmare Klassen Globale Klassen erstellen Allgemeine Java-Themen 7
X Klassen aus jar in jar Laden Allgemeine Java-Themen 1
S Klassen Klassen "virtuell" erstellen Allgemeine Java-Themen 5
J Aus mehreren Klassen ein Datei ausführbare machen Allgemeine Java-Themen 6
S equals-Methode bestimmer Klassen abfangen Allgemeine Java-Themen 2
M Klassen Eine Klasse in mehreren Klassen einbinden Allgemeine Java-Themen 11
Sin137 Struktur der Klassen & Package Allgemeine Java-Themen 2
G Klassen und interne Klassen Allgemeine Java-Themen 1
S Klassen übergeben Allgemeine Java-Themen 13
C Klassen und Konstruktor Allgemeine Java-Themen 2
S Classpath Wie kann ich Java-Library Klassen "verstecken"..? Allgemeine Java-Themen 4
A Java speech - 2 Klassen Allgemeine Java-Themen 1
V Wie kann ich die Fragen mit den anderen Klassen verbinden? Allgemeine Java-Themen 1
T Schlüsselworte mehrere public-Klassen in einem Paket Allgemeine Java-Themen 7
V Klassenname von allen Klassen mit einer bestimmten Eigenschaft bekommen Allgemeine Java-Themen 2
B Classpath Eclipse findet importierte Klassen nicht Allgemeine Java-Themen 1
C DBConnection als Methode in mehreren Klassen Allgemeine Java-Themen 4
C Arten von Klassen Allgemeine Java-Themen 3
7 Verbinden von Mehreren Klassen Allgemeine Java-Themen 29
A Klassen ein Interface aufzwingen Allgemeine Java-Themen 4
O Java-Obfuscator, welcher einzelne Methoden, Klassen und Ordnerstrukturen ausnehmen kann. Allgemeine Java-Themen 1
A also definition von klassen und string methoden und algorithmik Allgemeine Java-Themen 13
D Problem bei Vererbung abstrakter Klassen Allgemeine Java-Themen 6
M Interface Generische Klassen mit mehreren Typen überschreiben Allgemeine Java-Themen 0
L OOP Klassen-Design (static oder nicht?) Allgemeine Java-Themen 3
X Eigene Annotation - mit Bedingung für ganze Klassen oder Methoden Allgemeine Java-Themen 2
O Klassen Programm in Klassen unterteilt, werte werden nicht mehr übernommen Allgemeine Java-Themen 3
J C++ Projekt (QT) in Java mit Klassen (nicht imperativ) nutzen (BridJ? JavaCPP? SWIG? JNA? JNI?) Allgemeine Java-Themen 2
T Datentypen Eine Liste - verschiedenen Klassen - eine Abstracte Klasse Allgemeine Java-Themen 3
S .jar hat nicht alle Klassen ??? Allgemeine Java-Themen 10
S Polymorphie Polymorphismus bei Abstrakten Klassen Allgemeine Java-Themen 2
S Tool um mehrere Klassen in einer Klasse vereinen? Allgemeine Java-Themen 6
T Wie kann ich alle existierenden Java-Klassen anzeigen lassen? Allgemeine Java-Themen 10
Landei Welche Klassen fehlen im JDK? Allgemeine Java-Themen 18
S Kapselung Statische Helper Klassen Allgemeine Java-Themen 5
A Vererbung Klassen-Downcasting wirft ClassCastException Allgemeine Java-Themen 2
N Java Klassen mit ID Allgemeine Java-Themen 21
antonbracke Klassen Klassen gegenseitig laden Allgemeine Java-Themen 4
R SecurityManager für einzelne Klassen/Threads? Allgemeine Java-Themen 38
T Java Klassen aus externer .jar laden und ausführen Allgemeine Java-Themen 3
S JPA und Entity-Klassen: Wert ungültig Allgemeine Java-Themen 6
M OO / Klassen / Projektstruktur Allgemeine Java-Themen 5
O Klassen werden nicht importiert Allgemeine Java-Themen 3
E selber Klassen kompilieren/ prüfen Allgemeine Java-Themen 5
Z Abstrakte Klassen /Interface Allgemeine Java-Themen 5
A Klassen und JLabel's Allgemeine Java-Themen 12
J Java-Implementierung diverser Beziehungen zwischen Klassen bzw. Objekten Allgemeine Java-Themen 2
M Methoden/Klassen für andere Projekte Allgemeine Java-Themen 4
J Suche: Tool zum Auffinden gleichnamiger Klassen (Name und Package gleich) in unteschiedlichen JARs Allgemeine Java-Themen 5
E instanceof mit nicht öffentlichen Klassen Allgemeine Java-Themen 2
D Datentypen Typbestimmung unbekannter Wrapper-Klassen Allgemeine Java-Themen 5
S Klassen in einer Schleife durchlaufen Allgemeine Java-Themen 11
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
N Vergleich eigener Klassen Allgemeine Java-Themen 5
M Klassen Array aus Klassen bestimmter Klassen ? Allgemeine Java-Themen 11
C OOP Klassen mit "Eigenschaften" Allgemeine Java-Themen 10
H Klassen kommunizieren lassen Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben