Eclipse and dynamic code: Not the current but an old class is used.

U

Ulrich Scholz

Dear all,

my project dynamically generates a Java-file, compiles it, and creates
an object of that type. Unfortunately, it seems that the eclipse sdk
does not realize that the class file changed and sometimes generates
objects of an older version of the class, usually the one of the last
run.

How can I make eclipse always use the current class?

Is this a problem of eclipse or of Java, i.e., will I have a similar
problem by using the Java virtual machine w/o eclipse?

Thank you,

Uli
 
C

Chris Smith

Ulrich Scholz said:
my project dynamically generates a Java-file, compiles it, and creates
an object of that type. Unfortunately, it seems that the eclipse sdk
does not realize that the class file changed and sometimes generates
objects of an older version of the class, usually the one of the last
run.

How can I make eclipse always use the current class?

Once a Java virtual machine loads a class, that class cannot change for
the remainder of the application. Overwriting a class file that's in
use is dangerous, but will probably do nothing.

If you need to load newly generated code, then you will need to create a
new ClassLoader, which will then be able to load the new class in that
new ClassLoader.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Roedy Green

Once a Java virtual machine loads a class, that class cannot change for
the remainder of the application. Overwriting a class file that's in
use is dangerous, but will probably do nothing.

If you need to load newly generated code, then you will need to create a
new ClassLoader, which will then be able to load the new class in that
new ClassLoader.

The other simpler way to do it is to have the class implement some
fixed interface, and give the class a new name each time you generate
it.
 
T

Thomas Hawtin

Roedy said:
The other simpler way to do it is to have the class implement some
fixed interface, and give the class a new name each time you generate
it.

Probably somewhat faster than creating a new ClassLoader every time, but
it will leak.

Tom Hawtin
 
T

Thomas Hawtin

Roedy said:
Technically it is not a leak, but correct, the method code for the old
versions will never be garbage collected.

Okay, object lifetime contention issues.

I suspect some of your examples may be out of date. Not sure. AWT and
Swing are such a mess.

My favorite example is a ThreadLocal assigned to a static variable of
class with the same class loader as a class referenced by the value
(following? - the normal case for ThreadLocal), causes the the class
loader with all its classes to become ineligible for collection. Sun
refuses to fix that one.

Tom Hawtin
 
U

Ulrich Scholz

Thanks for your explanation. It points me to another problem that I
will have in the future (right now, I haven't gotten so far).
Once a Java virtual machine loads a class, that class cannot change for
the remainder of the application.

I have to change that class once in a while. Now I know that I cannot
just overwrite the .java file. Would it be a solution to use the
defineClass method, i.e., would the following guaranteed always crate
an instance of the new .java file? Are there backdraws?

- write the .java file to the file system and compile it
- load the new .class file into a byte array b
- Class newClass = defineClass(" .... .MyType", b, 0, b.length());
- MyType MyObject = newClass.newInstance();

Thank you, Uli
 
C

Chris Uppal

Ulrich said:
I have to change that class once in a while. Now I know that I cannot
just overwrite the .java file. Would it be a solution to use the
defineClass method, i.e., would the following guaranteed always crate
an instance of the new .java file?

To be able to define a new version of a class you /HAVE/ to use a new
Classloader. It's that simple and there are no exceptions.

So you start off with classloader #1 which is used to load the first version of
your code. If you then decide you need a new version of that code, you will
have to discard the orginal classloader, create a new one, classsloader #2, and
use that to load the next version of your class. If you want to redefine your
class again then you'll have to create classloader #3. And so on.

Note very carefully that introducing a new definition of a class via a new
classloader does not, in itself, remove the old one. The old one will only go
away when there are no more references to that class, or to the classloader, or
to any other class loaded by that classloader.

Even more importantly, you must realise that instantances of the old class are
not changed to become instances of the new version. So changing the class
definition (or more acurately defining a new class with the same name) will not
change the behaviour of existing objects.

-- chris
 
U

Ulrich Scholz

To be able to define a new version of a class you /HAVE/ to use a new
Classloader.

OK, I got that!

Will the objects of two different classes with same class name
(generated by separate class loaders) have the same type? In other
words, if both have a function foo with the same signature, can I store
instances of both classes one after the other in the same variable and
call that function? So, does the following work:

MyClass class;
MyObject obj;
class = ... ; // (the first version)
obj = class.newInstance();
obj.foo(); // 1st call
class = ... ; // (the second version)
obj = class.newInstance();
obj.foo(); // 2nd call

Uli
 
C

Chris Smith

Ulrich Scholz said:
Will the objects of two different classes with same class name
(generated by separate class loaders) have the same type? In other
words, if both have a function foo with the same signature, can I store
instances of both classes one after the other in the same variable and
call that function?

The two classes are different, so you can't use a reference to the class
itself. However, the two may have a common supertype (this is,
interface or superclass) which can be the type of the reference. That
supertype should be loaded in a COMMON classloader, generally the normal
Eclipse classloader. Your new classloaders, from which you create the
customized classes, should be loaded in a classloader that has that one
as a parent.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top