Arne Vajhøj
2024-03-27 13:11:43 UTC
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
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