Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mehrfachladen von Klassen mit statischen Inhalt

0 views
Skip to first unread message

Bernd Varga

unread,
Jun 4, 2002, 5:37:15 AM6/4/02
to
Hallo NG!

Ich habe gestern eine Nachricht mit den Titel "Java-Prozessstarter aus
Java-Prozess".

Aufgrund der Antworten habe ich mittels ClassLoad-Mechanismus ein kleines
Testprogramm geschrieben.
Diese sollte mir Aufschluss geben, ob die Möglichkeit besteht eine Klasse
mehrmals zu laden, um so eine Statische Variable öfters zu verwenden.

Leider schafte ich es nicht.

Im ersten Testbeispiel versuchte ich es mittels "Class.forName". Jedoch
erhält man das selbe Ergebenis wie bei "normaler" Instanzerzeugung.
Class classObject1 = Class.forName( "HelloWorld" );
Class classObject2 = Class.forName( "HelloWorld" );

IHelloWorld obj1 = (IHelloWorld) classObject1.newInstance();
IHelloWorld obj2 = (IHelloWorld) classObject2.newInstance();

System.out.println ( "Objekt 1: " + obj1 );
System.out.println ( "Objekt 2: " + obj2 );

obj1.setText ( "Hello World 1!!!" );
obj2.setText ( "Hello World 2!!!!!!!" );

System.out.println ( "Ausgabe 1: " + obj1.getText());
System.out.println ( "Ausgabe 2: " + obj2.getText());
Ausgabe:
Objekt 1: HelloWorld@4b222f
Objekt 2: HelloWorld@3169f8
Ausgabe 1: Hello World 2!!!!!!!
Ausgabe 2: Hello World 2!!!!!!!

Im zweiten Testbeispiel versuchte ich es über eine eigenen Classloader
bei dem dynamisch der Klassenname vergaben wird. Jedoch tritt hier eine
Exception auf:
DynamicClassLoader loader = new DynamicClassLoader();

Class classObject1 = loader.loadClass( "HelloWorld" );
Class classObject2 = loader.loadClass( "HelloWorld" );


public class DynamicClassLoader
extends ClassLoader
{
private static int counter = 0;

public Class loadClass( String name )
{
counter++;

byte[] b = loadClassData ( name );
System.out.println ( "Klasse geladen: " + b );
return defineClass ( name + counter, b, 0, b.length );
}

private byte[] loadClassData ( String name )
{
byte result[];

try
{
FileInputStream fi = new FileInputStream ( name +
".class" );
result = new byte [ fi.available() ];
fi.read ( result );
return result;
}
catch ( Exception exc )
{
exc.printStackTrace();
return null;
}
}
}

Ausgabe:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld1
(wrong name: HelloWorld)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:486)
at java.lang.ClassLoader.defineClass(ClassLoader.java:426)
at DynamicClassLoader.loadClass(DynamicClassLoader.java:14)
at ClassLoadTest.main(ClassLoadTest.java:9)

Sieht so aus, als könnte man den Klassennamen nicht dynamisch vergeben.

Gibt es noch sonstige Möglichkeiten oder müssen wirklich ein eigener
Prozess gestartet werden, damit man in einer VM die gleiche Klasse
mit eindeutigen statischen Inhalt erhält?

Ich sehe mehr keine Möglichkeit.

lg Bernd

Patrick Roemer

unread,
Jun 4, 2002, 6:23:08 AM6/4/02
to
Hallo,

Bernd Varga wrote:

> Im ersten Testbeispiel versuchte ich es mittels "Class.forName". Jedoch
> erhält man das selbe Ergebenis wie bei "normaler" Instanzerzeugung.
> Class classObject1 = Class.forName( "HelloWorld" );
> Class classObject2 = Class.forName( "HelloWorld" );

Der CL cached einmal geladene Klassen duer Folgeanfragen -
und das sollten selbstgeschriebene CLs auch tun.

> DynamicClassLoader loader = new DynamicClassLoader();
>
> Class classObject1 = loader.loadClass( "HelloWorld" );
> Class classObject2 = loader.loadClass( "HelloWorld" );

Der Trick besteht darin, fuer jeden 'Namensraum' eine eigene
CL-Instanz zu verwenden, also:

Class c1=new MyLoader().loadClass("Hello");
Class c2=new MyLoader().loadClass("Hello");

Das Problem ist, dass man ja irgendwo den Uebergang zum
System-CL vollziehen muss. Ueblicherweise sollten zumindest
alle Anfragen nach Klassen mit java.*-Prefix vom eigenen
CL an den System-CL delegiert werden. Da gibt's aber auch
statische Members. Also muesste man im Prinzip fuer jeden
Namensraum die komplette Standard-API mit hochziehen.

Deine eigene CL-Implementierung sollte sich spec-konform
verhalten (Caching, Delegation, etc.), wenn nicht extrem
ueberzeugende Gruende vorliegen, warum sie das nicht tun
sollte. Schau mal auf den JavaWorld-Seiten; da sind einige
Artikel zum Thema ClassLoader zu finden. Die Links wurden
hier schon oefter mal gepostet.

Viele Gruesse,
Patrick

0 new messages