Name: yyT116575 Date: 11/13/2000
Linux:
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
AND
Linux:
java version "1.2.2"
Classic VM (build 1.2.2_006, green threads, nojit)
AND
Windows98:
java version "1.2"
Classic VM (build JDK-1.2-V, native threads)
I'm trying do dynamic updates of classes using an explicit URLClassLoader, but
if I put the classes in a jar file, the updates aren't picked up correctly. If
I use a directory instead it works fine. Using the Unix tool fuser I can see
that the JVM keeps the jar file open. This is not the behavior I expect when
I create a URLClassLoader.
SOURCE:
// Interface for changable implementation.
public interface cInterface {
public void doStuff();
}
// Implementation
public class cImpl implements cInterface {
public void doStuff() {
System.out.println("\t\tdoStuff!");
//doMoreStuff();
//doYetMoreStuff();
}
/*
public void doMoreStuff() {
System.out.println("\t\tdoMoreStuff!");
}
public void doYetMoreStuff() {
System.out.println("\t\tdoYetMoreStuff!");
}
*/
}
// Client program
import java.io.*;
import java.net.*;
public class jarTest {
public static void main( String[] argv ) throws Exception {
URL[] auJars;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s;
while(true) {
System.out.println("Hit enter.");
s = br.readLine();
try {
auJars = new URL[1];
auJars[0]=new URL("file:test.jar");
ClassLoader cl = new java.net.URLClassLoader(auJars);
System.out.println("new Classloader:"+cl);
cInterface ci = (cInterface)
cl.loadClass("cImpl").newInstance();
ci.doStuff();
} catch( Exception e ) {
e.printStackTrace();
}
}
}
}
Procedure to reproduce:
$ javac *.java
$ jar cvf test.jar *.class
$ rm cImpl.class
$ java jarTest
Hit enter.
new Classloader:java.net.URLClassLoader@c3579d5b
doStuff!
Hit enter.
Open another window and perform the following steps
in the same directory:
1.uncomment other functions in cImpl.java
2.$ javac cImpl.java ; jar cvf test.jar *.class; rm cImpl.class
Switch back to the original window without restarting
jarTest and hit enter, a exception thrown:
new Classloader:java.net.URLClassLoader@caef9d5b
Exception in thread "main" java.lang.ClassFormatError: cImpl (Truncated class file)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:474)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:106)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:247)
at java.net.URLClassLoader.access$1(URLClassLoader.java:215)
at java.net.URLClassLoader$1.run(URLClassLoader.java:196)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at jarTest.main(jarTest.java:26)
The JDC Tech Tip:
http://developer.java.sun.com/developer/TechTips/2000/tt1027.html
...shows the general dynamic class update method. What I found is simply
that it doesn't work with jars.
Jim
(Review ID: 112059)
======================================================================
- duplicates
-
JDK-4353705 # Internal error in ZipFile code during compilation
- Closed