[Java] classes un-/reloaden

Pagina: 1
Acties:

  • Onno
  • Registratie: Juni 1999
  • Niet online
Ik ben met een Java programma bezig waarin ik een soort plugin-systeem wil bouwen. Dynamisch classes laden is geen probleem, maar ik wil ze natuurlijk ook kunnen unloaden en reloaden zonder het programma opnieuw te starten.

Ik begrijp uit de docs dat je daarvoor een eigen ClassLoader moet maken, zodat je door het trashen van die ClassLoader ook de bijbehorende classes kunt verwijderen. Maar hoe dat precies werkt is me niet geheel duidelijk, ik kan er eigenlijk ook geen duidelijke voorbeelden van vinden. Er zijn natuurlijk wel complete programma's die zoiets implementeren (Tomcat bijv.), maar daar zitten weer zoveel extra dingen omheen dat ik liever een wat simpeler voorbeeld vind om mee te prutsen.

Heeft iemand toevallig een idee waar ik hier duidelijke docs of voorbeelden over kan vinden? :)

  • MisterData
  • Registratie: September 2001
  • Laatst online: 26-08 21:52
code:
1
2
3
URLClassLoader loader = new URLClassLoader(urlstoloadfrom);
Class loadedclass = Class.forName(name,true,loader);
Object x = loadedclass.newInstance();

Dit brokje code laadt een klasse en maakt er een nieuwe instantie van. urlstoloadfrom is in dit geval een array met urls (dus URL[]).

btw wat bedoel je met unloaden ?? geheugen vrijmaken ?? dan doe je gewoon :
code:
1
2
3
x = null;
loadedclass = null;
System.gc();

of iets dergelijx ;)

  • Onno
  • Registratie: Juni 1999
  • Niet online
Hmmz... als dat gewoon werkt zat ik veeeeel te ingewikkeld te doen. :)

Ik zal het zo eens uitproberen.

  • Onno
  • Registratie: Juni 1999
  • Niet online
Werkt niet.

Ik heb er dit van gemaakt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.io.*;
import java.net.*;

class ReloadTest
{
  public static void main (String args[]) throws Exception
  {
    PrintStream ps=new PrintStream(new FileOutputStream("Bla.java"));
    ps.println("class Bla");
    ps.println("{");
    ps.println("  public Bla()");
    ps.println("  {");
    ps.println("    System.out.println (\"blaat!\");");
    ps.println("  }");
    ps.println("}");
    ps.close();
    Runtime.getRuntime().exec("javac Bla.java").waitFor();

    URL urls[] = {new URL("file://./")};
    URLClassLoader loader = new URLClassLoader(urls);
    Class loadedclass = Class.forName("Bla",true,loader);
    Object x = loadedclass.newInstance();
    x = null;
    loadedclass = null;
    loader = null;
    System.gc();

    ps=new PrintStream(new FileOutputStream("Bla.java"));
    ps.println("class Bla");
    ps.println("{");
    ps.println("  public Bla()");
    ps.println("  {");
    ps.println("    System.out.println (\"mooh!\");");
    ps.println("  }");
    ps.println("}");
    ps.close();
    Runtime.getRuntime().exec("javac Bla.java").waitFor();

    loader = new URLClassLoader(urls);
    loadedclass = Class.forName("Bla",true,loader);
    x = loadedclass.newInstance();
  }
}

De uitvoer is tweemaal "blaat!", terwijl ik de tweede keer toch echt "mooh!" wil zien.

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
waarom gebruik je een URLClassLoader? je kunt het gewoon zo doen:
code:
1
2
Class loadedclass = Class.forName("Bla");
Object x = loadedclass.newInstance();

ik weet niet of het voor je probleem iets uitmaakt (misschien dat je bij URLClassLoader last hebt van caching?)

  • Onno
  • Registratie: Juni 1999
  • Niet online
Op zondag 18 november 2001 18:08 schreef marcusk het volgende:
waarom gebruik je een URLClassLoader? je kunt het gewoon zo doen:
code:
1
2
Class loadedclass = Class.forName("Bla");
Object x = loadedclass.newInstance();

ik weet niet of het voor je probleem iets uitmaakt (misschien dat je bij URLClassLoader last hebt van caching?)
Als je de system classloader gebruikt is er sowieso geen enkele manier om je classes geunload te krijgen. En dat wil ik nou juist.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-08 22:44
Je moet rekening houden met het feit dat de bytecode in het geheugen gecompileerd is naar machine specifieke instructies.

De vraag is dus hoe ververs je dat. Ik heb nog geen antwoord.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 26-08 21:52
Die URLClassLoader is nodig om klasses vanaf een URL te laden. Je hebt die dus wel degelijk nodig ! maar de vraag is hoe je klassen kan unloaden, en als die worden gecached dan heb je een probleem want dan kan het dus niet.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-08 22:44
Ik denk dat deze link met wat creatief denken tot een werkende oplossing zal komen.
Summary
Testing a server class can be difficult. A test sequence written as a client program may have only limited access to the features of the server class. Likewise, a freestanding test program may not provide a realistic context for the server class. This tip will show you how to execute tests of your server class from within the virtual machine of the running server. This technique will even allow you to execute tests or diagnostic sequences that did not exist when the server was started. (1,950 words)
http://www.javaworld.com/javaworld/javatips/jw-javatip73.html

Ze gebruiken een Corba server als voorbeeld om test classes te injecteren. Ook het unloaden van de test class na gebruik komt aan de orde. (unloaden is wat anders dan er botweg geen instantie van hebben)

  • Onno
  • Registratie: Juni 1999
  • Niet online
Door de ClassLoader uit InjectorImpl2.java te gebruiken werkt het inderdaad wel. Bedankt! :)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-08 22:44
Op zondag 18 november 2001 20:07 schreef Onno het volgende:
Door de ClassLoader uit InjectorImpl2.java te gebruiken werkt het inderdaad wel. Bedankt! :)
He shoots, he scores!! Ik heers!! :P ;)

Vind het zelf ook leuke info, ben nu zelf ook aan het prutsen met die classloaders.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-08 22:44
Nog een vraagje, hoe "weet" je prog dat er een plug-in bij is gekomen? Via een config windowtje, een tooltje of volautomatisch?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Leuke stuff, waarom nu net als ik offline ben ;) .
The - DDD: Nog een vraagje, hoe "weet" je prog dat er een plug-in bij is gekomen? Via een config windowtje, een tooltje of volautomatisch?
Niet echt aan mij gericht, maar goed ;) . Zelf die ik het meestal via een XML config filetje, dat werkt vaak het duidelijkst.

Je kan ook een standaard formaat eisen van een jar met een config file daarin en een bepaalde dir scannen op jars die plugin willen zijn. Dat wordt erg veel gebruikt, o.a. door Jext en JBuilder

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1