[Info-vax] Versioning fun

Arne Vajhøj arne at vajhoej.dk
Wed Mar 27 09:11:43 EDT 2024


A relative little know fact about the JVM is that
it implicit prefixes class names with the id of
the classloader.

That mean that it is possible to load and use
different version of the same class within the
same application. If one knows how.

$ type HasTest.java
public interface HasTest {
     public void test();
}
$ javac HasTest.java
$ copy X_v1.java X.java
$ type X.java
public class X implements HasTest {
     public void test() {
         System.out.printf("Technically I am a %s, but I am version 
1\n", this.getClass().getName());
     }
}
$ javac X.java
$ jar cvf v1.jar X.class
added manifest
adding: X.class(in = 588) (out= 376)(deflated 36%)
$ del X.class;*
$ copy X_v2.java X.java
$ type X.java
public class X implements HasTest {
     public void test() {
         System.out.printf("Technically I am a %s, but I am version 
2\n", this.getClass().getName());
     }
}
$ javac X.java
$ jar cvf v2.jar X.class
added manifest
adding: X.class(in = 588) (out= 376)(deflated 36%)
$ del X.class;*
$ type TestX.java
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;

public class TestX {
     public static void main(String[] args) throws Exception {
         ClassLoader v1 = new URLClassLoader(new URL[] { (new 
File("v1.jar")).toURI().toURL() });
         HasTest o1 = (HasTest)Class.forName("X", true, v1).newInstance();
         o1.test();
         ClassLoader v2 = new URLClassLoader(new URL[] { (new 
File("v2.jar")).toURI().toURL() });
         HasTest o2 = (HasTest)Class.forName("X", true, v2).newInstance();
         o2.test();
     }
}
$ javac TestX.java
$ java "TestX"
Technically I am a X, but I am version 1
Technically I am a X, but I am version 2

Arne



More information about the Info-vax mailing list