Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2007

Tip: Looking for answers? Try searching our database.

Realtime class update

Thread view: 
O.L. - 26 Jul 2007 10:13 GMT
Hello,

I have a standalone Java application which has to be started and then
not stopped for weeks.
Is it possible to rebuild some of its classes and reload then inside
the running JVM, to be able to modify its behaviour without having to
stop and restart the application ?
I heard about ClassLoader and its caching functionnality ... ?

Thank you if you have any info :)
Olivier

Signature

Olivier Ligny
www.virgal.net (Monde persistant)

Andrew Thompson - 26 Jul 2007 12:06 GMT
...
>I have a standalone Java application which has to be started and then
>not stopped for weeks.
>Is it possible to rebuild some of its classes and reload then inside
>the running JVM, to be able to modify its behaviour without having to
>stop and restart the application ?

Not that I know of, but happy to be surpised.

>I heard about ClassLoader and its caching functionnality ... ?

'aggressively' is how I would describe CL caching.

>Thank you if you have any info :)

Have you considered web start* for this application?

Web start offers the DownloadService** that can check if
Jar's are updated.

This would still leave it up to the application to
a) check occasionally for upates
b) update the necesary parts or Jar archives.
c) inform the user they need to RESTART THE APP.

c) might not be necessary if you find some really
clever way to update the classes in the current
ClassLoader.

** <http://java.sun.com/javase/6/docs/jre/api/javaws/jnlp/javax/jnlp/DownloadService.html

* Gee, color everybody 'surprised'!

Signature

Andrew Thompson
http://www.athompson.info/andrew/

Lew - 26 Jul 2007 14:45 GMT
> ...
>> I have a standalone Java application which has to be started and then
[quoted text clipped - 4 lines]
>
> Not that I know of, but happy to be surpised.

Then be happy.  It's possible using the debugger hooks.  There was an article
by Daniel Savarese in JavaPro about it, probably still findable.

You can also play ClassLoader games to load the new version, letting the old
one die and get garbage collected, but getting client classes to recognize the
switch is hard, from what I hear.  I tend to avoid such complications.

Signature

Lew

Piotr Kobzda - 27 Jul 2007 00:55 GMT
>> Not that I know of, but happy to be surpised.
>
> Then be happy.  It's possible using the debugger hooks.  There was an
> article by Daniel Savarese in JavaPro about it, probably still findable.

I didn't found it.  But now (since 1.5) the instrumentation allows it also:
<http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#
redefineClasses(java.lang.instrument.ClassDefinition
...)>

The only JVM I know, which fully supports it (including "schema change"
HotSwap) is the J9VM (from IBM).

Fortunately, most of major JVMs allows for redefining executable code of
a class, which usually is enough.  If not enough...

> You can also play ClassLoader games to load the new version, letting the
> old one die and get garbage collected, but getting client classes to
> recognize the switch is hard, from what I hear.  I tend to avoid such
> complications.

It depends on what is expected.  Sometimes it's also desired to have the
old clients still using old versions of the classes, and a new classes
available for the new clients only (see "Hot Code Changes" section at
Java Glossary page linked by Roedy).  Otherwise, you may reference all
objects non-directly, e.g. via the map (or cache).  But, of course,
using instrumentation (or JPDA) is easier in such a case.

piotr
O.L. - 27 Jul 2007 12:38 GMT
Piotr Kobzda a formulé la demande :
> Fortunately, most of major JVMs allows for redefining executable code of a
> class, which usually is enough.

How ?

Signature

Olivier Ligny
www.virgal.net (Monde persistant)

Piotr Kobzda - 27 Jul 2007 13:27 GMT
> Piotr Kobzda a formulé la demande :
>> Fortunately, most of major JVMs allows for redefining executable code
>> of a class, which usually is enough.
>
> How ?

As I said -- using Java instrumentation.

With that, you will not have to care about class loading and references
to them, you will need simply replace already running classes with
theirs new bytes (loaded or generated at runtime).

For details refer to:
<http://java.sun.com/javase/6/docs/technotes/guides/instrumentation/index.html>

In particular, read the java.lang.instrument package description.  Usage
is explained there clearly.

piotr
Twisted - 27 Jul 2007 11:36 GMT
> > ...
> >> I have a standalone Java application which has to be started and then
[quoted text clipped - 11 lines]
> one die and get garbage collected, but getting client classes to recognize the
> switch is hard, from what I hear.

If you only want newly created objects to use the new version of the
class, you could create these objects via a Factory that uses
reflection to dynamically load the latest class version if newer than
what it's currently using, and then to generate an instance of the
current version (whether that was just updated or not), when invoked.
O.L. - 27 Jul 2007 12:41 GMT
Il se trouve que Twisted a formulé :
>>> ...
>>>> I have a standalone Java application which has to be started and then
[quoted text clipped - 17 lines]
> what it's currently using, and then to generate an instance of the
> current version (whether that was just updated or not), when invoked.

Thank you :)

I suppose this will cause problems with 'instanceof' and old/new
instances, but I think this is the best (and only) solution.

Signature

Olivier Ligny
www.virgal.net (Monde persistant)

Twisted - 27 Jul 2007 13:58 GMT
> I suppose this will cause problems with 'instanceof' and old/new
> instances, but I think this is the best (and only) solution.

Use instanceof on a common supertype, e.g. have WhateverBase and make
WhateverDerived1, WhateverDerived2, etc. be your versions. If they
adhere to a common contract checking for being "instanceof
WhateverBase" should suffice where you are forced somehow to use
instanceof and not polymorphism.

Maybe equals()? Define that in WhateverBase in terms of contract
methods if possible. If you must do special stuff depending on exact
implementation, make WhateverBase have a getVersion method and write:

(in WhateverBase)

public final boolean equals (Object o) {
   if (this == o) return true;
   if (o == null || !(o instanceof WhateverBase)) return false;
   WhateverBase wb = (WhateverBase)o;
   if (wb.getVersion() > getVersion()) return wb.equalsImpl(this);
   return equalsImpl(wb);
}

protected abstract int getVersion ();

protected abstract boolean equalsImpl (WhateverBase wb);

(in WhateverDerived1)

protected int getVersion () { return 1; }
protected boolean equalsImpl (WhateverBase wb) {
   WhateverDerived1 wd = (WhateverDerived1)wb;
   // Whatever to compare two WhateverDerived1s
   return something;
}

(in WhateverDerived2)

protected int getVersion () { return 2; }
protected boolean equalsImpl (WhateverBase wb) {
   if (wb instanceof WhateverDerived1) return
equalsImpl2((WhateverDerived1)wb);
   WhateverDerived2 wd = (WhateverDerived2)wb;
   // Whatever to compare two WhateverDerived2s
   return something;
}
private boolean equalsImpl2 (WhateverDerived1 wd) {
   // Whatever to compare a WD2 and a WD1
   return something;
}

I trust you see the pattern here. The key thing is to assign version
numbers sequentially. Each class needs to know how to compare itself
to each previous version, and needs its equalsImpl to be the one that
gets called. If you do otherwise the code will break -- it will
sometimes call an old version equalsImpl with a newer version
parameter and consequently throw a ClassCastException on the last cast
in the called equalsImpl method.

This is assuming all the WDs extend WB directly, never each other,
which I'll also recommend to ensure the CCE is thrown instead of
subtler broken behavior occurring instead, such as simply wrong return
values from some calls to equals().

This can be generalized to anything else that needs to effectively
dispatch on two run-time types and not just one. It won't be nearly as
easy or tidy however if you end up with two different serially-
versioned types and a binary operation between them...
Roedy Green - 26 Jul 2007 14:38 GMT
>I have a standalone Java application which has to be started and then
>not stopped for weeks.
>Is it possible to rebuild some of its classes and reload then inside
>the running JVM, to be able to modify its behaviour without having to
>stop and restart the application ?
>I heard about ClassLoader and its caching functionnality ... ?

This is tricky.  Basically what you must do is fire up a new
ClassLoader.  any class A objects created via class A reloaded are
considered logically distinct from the original class A objects.  You
still have the problem of converting objects to the new format.
See http://mindprod.com/jgloss/classloader.html
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.