Change a method at runtime via a hot swap mechanism
Asked Answered
Q

7

61

Assume we have a trivial Java program that consists of just one class:

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}

After it's compiled and run, output will be this:

Today is a nice day with a number 0

Today is a nice day with a number 1

Today is a nice day with a number 2

Today is a nice day with a number 3

...

My question: does there exist (or is there on the horizon) some way to swap replacable method at runtime? Something like writing another version of HelloWorld with a new version of replacable, compiling it and then the old version in an already running JVM?

So, if I write the new version like this:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  

is there something similar to Erlang's hot code swapping where I can do this:

  1. run original program
  2. write modified version
  3. using a command line program, connect to running JVM and replace existing method

so that, during runtime, this will happen:

Today is a nice day with a number 15000

Today is a nice day with a number 15001

Today is an even nicer day with a number 15002

Today is an even nicer day with a number 15003

...

Assume that above program is standalone, runs in a standard Java SE environment, there is nothing else on classpath, so it's almost a Hello world style program.

Note: I know that technologies like bytecode manipulation (cglib), aspectJ, jRebel, JMX, hotswapping of methods in Java EE etc. exist, but they aren't what I'm thinking of. Think of Erlang.

Quasimodo answered 29/12, 2010 at 10:38 Comment(4)
Can you explain why you can't use the Strategy Pattern (e.g. a variable object implementing the required variable functionality)? Swapping methods sounds complicated to achieve what you want.Condensate
@ivy: I could use that, of course, but I'm just wondering if it's possible to do what I described in my question. You can think of it as a "theoretical" question in some way.Quasimodo
@Condensate the mechanism is there for upgrading a running service, not for selecting between a set of known implementations.Henrieta
@Pete Sure, but you could load alternatives at runtime, or even redefine classes of the alternatives at runtime. I was hinting at using some kind of proxy mechanism. The 'problem' with the example is that even while redefining the class, the current Thread will not use the redefined class. But I guess that makes it an interesting question...Condensate
S
41

You can either use the open-source HotSpot VM or the commercial JRebel IDE plugin to easily achieve your goal (view comparison table here).

Santalaceous answered 3/1, 2011 at 7:46 Comment(2)
is this robust and suitable for production environments? As in, hot upgrade to running services with no downtime? Or is it really just a way to shorten a edit/compile/run cycle in dev?Tempestuous
No- it is not suitable for productionPolyglot
R
15

You can do it via class loaders. For example if you are familiar with Servlet containers such as tomcat that reload pages as you modify them in development. Here is a great explanation of creating dynamic code in java. It not only explains loading but also compiling source on the fly. You should be able to apply the concepts covered to any strategy of reloading code you want to utilize.

Ruelle answered 29/12, 2010 at 20:13 Comment(0)
F
9

I've used this hotswap ant task in many projects. The target java application can be launched via Ant, Eclipse, a command prompt, or any other means as long as it is launched in debug mode with the appropriate port open. The linked page provides instructions on how to do this via Ant.

Any number of classes can be hotswapped as long as the changes are not structural. Method body changes generally hotswap with ease. Code can be hotswapped by running an ant script via a shell or Eclipse.

At work, I utilize a script that hotswaps code changes automatically by comparing timestamps on the class files. This is similar to the sample on the project page that shows a simple example that only hotswaps changed classes.

Additional note: This utilizes the JPDA.

Foreordination answered 3/1, 2011 at 15:39 Comment(1)
Plus 1 because you mention JPDA, which is the actual JVM interface used by the tools. Now I just want to see a minimal runnable example :-)Valdovinos
H
4

You can do this through the JPDA (Java Platform Debugger Architecture) interface: http://download.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

It's not automatic as the Erlang case - the JVM doesn't monitor the class path for changes to class files then reload and relink them if changed, for fairly obvious reasons (Java was designed for web deployment you don't want to be polling a http URL for changes).

Henrieta answered 29/12, 2010 at 10:45 Comment(3)
I'll try JPDA one day. What I had in mind was reverse. JVM not monitoring class file changes, but you handing to the running JVM directly a "fresh" version of one class.Quasimodo
Most of this is automated with modern IDEs. Tools like IntelliJ IDEA and Eclipse will hot swap the code with the click of a button.Omit
@Omit yes, and AFAIK the IDEs still use the JPDA interfaces to do that, but the question was not about running in development but swapping live code in production.Henrieta
P
3

I've found the relatively newer Hotswap Agent is well-documented and feature-rich (and best of all, open source).

Please answered 21/6, 2015 at 15:56 Comment(0)
I
1

What about OSGi? Hot swapping is sorta "built in" to the spec - I would think this would be one possible solution as well.

Incomputable answered 4/1, 2011 at 8:44 Comment(0)
S
1

You could use the Strategy design pattern, so you have a an object to manipulate rather than a method, and a protocol for communicating with the program to tell it to use a given class name as the class of the Strategy object.

Sw answered 4/1, 2011 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.