This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Eager vs Lazy resolution of classes
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: java at gcc dot gnu dot org
- Date: Tue, 20 Jul 2004 16:50:15 -0400
- Subject: Eager vs Lazy resolution of classes
The following test case creates a class on the fly in the classpath and
then tries to call into that class statically, as opposed to via
Class.forName() or some other classloader based mechanism.
On Sun's 1.5 beta JVM, I get:
$ rm Bar.class
$ java Resolve
start
99
hello!!
The Java Specification makes it clear that resolution of class
dependencies is "eager". That is, all references from a given class can
be resolved at link time, provided that any errors from resolution are
deferred until active use. However, it also states that implementations
MAY choose to resolve dependencies more lazily if they wish. This seems
to be what Sun's implementation does. This is a concern because the
BC-ABI in its current form is designed for eager resolution. While
spec-compliant, there may be code out there which depends on Sun-like
behaviour.
Interestingly, gij fails this test too, and in fact is not compliant
with the spec at all because it is throwing NoClassDefFoundError before
the first active use of the missing class:
$ rm Foo.class
$ gij Resolve
Exception in thread "main" java.lang.NoClassDefFoundError: while
resolving class: Resolve
at java.lang.VMClassLoader.resolveClass(java.lang.Class)
(/local/gcc-clean/lib/libgcj.so.6.0.0)
at java.lang.Class.initializeClass()
(/local/gcc-clean/lib/libgcj.so.6.0.0)
at java.lang.Class.forName(java.lang.String, boolean,
java.lang.ClassLoader) (/local/gcc-clean/lib/libgcj.so.6.0.0)
....etc
I think its quite possible to make the BC-ABI compatible with Suns
behaviour, but its a little complicated. We'll have to remember which
(if any) otable/atable entries that remain unresolved after linking,
associate them with their class, and then go back and fill in those
entries during linking/initialization of that class (at first active use).
Since it will likely be quite a bit of extra work to implement this, it
would be good to get an understanding of how important this feature is.
ie: is it something that we should be concentrating on for 3.5, or can
it be deferred for later? Does anyone know of popular applications that
rely on being able to do this? My understanding is that Eclipse 3 now
runs on gij, so presumably it does not fall into this category?
Regards
Bryce
public class Bar
{
static void zot()
{
System.out.println("hello!!");
}
static int field = 99;
}
import java.io.*;
public class Resolve
{
public static void main(String[] args) throws Exception
{
System.out.println("start");
File f = new File("Bar.class");
FileOutputStream fos = new FileOutputStream(f);
for (int i=0; i < barClassData.length; i++)
fos.write((byte) barClassData[i] & 0xff);
fos.close();
System.out.println (Bar.field);
Bar.zot();
f.delete();
}
static int[] barClassData = new int[] {
0xca, 0xfe, 0xba, 0xbe, 0x0, 0x0, 0x0, 0x30, 0x0, 0x21,
0xa, 0x0, 0x7, 0x0, 0x12, 0x9, 0x0, 0x13, 0x0, 0x14,
0x8, 0x0, 0x15, 0xa, 0x0, 0x16, 0x0, 0x17, 0x9, 0x0,
0x6, 0x0, 0x18, 0x7, 0x0, 0x19, 0x7, 0x0, 0x1a, 0x1,
0x0, 0x5, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x1, 0x0, 0x1,
0x49, 0x1, 0x0, 0x6, 0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e,
0x1, 0x0, 0x3, 0x28, 0x29, 0x56, 0x1, 0x0, 0x4, 0x43,
0x6f, 0x64, 0x65, 0x1, 0x0, 0xf, 0x4c, 0x69, 0x6e, 0x65,
0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c,
0x65, 0x1, 0x0, 0x3, 0x7a, 0x6f, 0x74, 0x1, 0x0, 0x8,
0x3c, 0x63, 0x6c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x1, 0x0,
0xa, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c,
0x65, 0x1, 0x0, 0x8, 0x42, 0x61, 0x72, 0x2e, 0x6a, 0x61,
0x76, 0x61, 0xc, 0x0, 0xa, 0x0, 0xb, 0x7, 0x0, 0x1b,
0xc, 0x0, 0x1c, 0x0, 0x1d, 0x1, 0x0, 0x7, 0x68, 0x65,
0x6c, 0x6c, 0x6f, 0x21, 0x21, 0x7, 0x0, 0x1e, 0xc, 0x0,
0x1f, 0x0, 0x20, 0xc, 0x0, 0x8, 0x0, 0x9, 0x1, 0x0,
0x3, 0x42, 0x61, 0x72, 0x1, 0x0, 0x10, 0x6a, 0x61, 0x76,
0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x1, 0x0, 0x10, 0x6a, 0x61, 0x76, 0x61,
0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x53, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x1, 0x0, 0x3, 0x6f, 0x75, 0x74, 0x1, 0x0,
0x15, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x69, 0x6f, 0x2f,
0x50, 0x72, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x3b, 0x1, 0x0, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x2f,
0x69, 0x6f, 0x2f, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x1, 0x0, 0x7, 0x70, 0x72, 0x69,
0x6e, 0x74, 0x6c, 0x6e, 0x1, 0x0, 0x15, 0x28, 0x4c, 0x6a,
0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x29, 0x56, 0x0, 0x21,
0x0, 0x6, 0x0, 0x7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x8,
0x0, 0x8, 0x0, 0x9, 0x0, 0x0, 0x0, 0x3, 0x0, 0x1,
0x0, 0xa, 0x0, 0xb, 0x0, 0x1, 0x0, 0xc, 0x0, 0x0,
0x0, 0x1d, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x5,
0x2a, 0xb7, 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, 0x1, 0x0,
0xd, 0x0, 0x0, 0x0, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0,
0x1, 0x0, 0x8, 0x0, 0xe, 0x0, 0xb, 0x0, 0x1, 0x0,
0xc, 0x0, 0x0, 0x0, 0x25, 0x0, 0x2, 0x0, 0x0, 0x0,
0x0, 0x0, 0x9, 0xb2, 0x0, 0x2, 0x12, 0x3, 0xb6, 0x0,
0x4, 0xb1, 0x0, 0x0, 0x0, 0x1, 0x0, 0xd, 0x0, 0x0,
0x0, 0xa, 0x0, 0x2, 0x0, 0x0, 0x0, 0x5, 0x0, 0x8,
0x0, 0x6, 0x0, 0x8, 0x0, 0xf, 0x0, 0xb, 0x0, 0x1,
0x0, 0xc, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x1, 0x0, 0x0,
0x0, 0x0, 0x0, 0x6, 0x10, 0x63, 0xb3, 0x0, 0x5, 0xb1,
0x0, 0x0, 0x0, 0x1, 0x0, 0xd, 0x0, 0x0, 0x0, 0x6,
0x0, 0x1, 0x0, 0x0, 0x0, 0x8, 0x0, 0x1, 0x0, 0x10,
0x0, 0x0, 0x0, 0x2, 0x0, 0x11 };
}