Java Forum / General / December 2005
Eclipse and dynamic code: Not the current but an old class is used.
Ulrich Scholz - 05 Dec 2005 14:07 GMT 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
Chris Smith - 05 Dec 2005 19:34 GMT > my project dynamically generates a Java-file, compiles it, and creates > an object of that type. Unfortunately, it seems that the eclipse sdk [quoted text clipped - 3 lines] > > 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.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 05 Dec 2005 20:40 GMT >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 [quoted text clipped - 3 lines] >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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Thomas Hawtin - 05 Dec 2005 21:08 GMT > 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
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Roedy Green - 05 Dec 2005 22:09 GMT On Mon, 05 Dec 2005 21:09:45 +0000, Thomas Hawtin <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone who said :
>Probably somewhat faster than creating a new ClassLoader every time, but >it will leak. Technically it is not a leak, but correct, the method code for the old versions will never be garbage collected.
see http://mindprod.com/jgloss/leak.html http://mindprod.com/jgloss/packratting.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Thomas Hawtin - 06 Dec 2005 00:37 GMT > On Mon, 05 Dec 2005 21:09:45 +0000, Thomas Hawtin > <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone [quoted text clipped - 5 lines] > 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.
> see http://mindprod.com/jgloss/leak.html > http://mindprod.com/jgloss/packratting.html 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
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Ulrich Scholz - 06 Dec 2005 11:20 GMT 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
Chris Uppal - 06 Dec 2005 12:25 GMT > 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
Ulrich Scholz - 06 Dec 2005 13:13 GMT > 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
Chris Smith - 06 Dec 2005 14:34 GMT > 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.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|