Bug in defineClass()

Eduardo Takahashi takahasi+ at cs.cmu.edu
Fri May 2 10:37:05 PDT 1997


Hi All,

When I moved from version 0.8.1 to 0.8.4 some days ago one of my
applications stopped working. I was getting NullPointerException
from a newInstance() call that worked fine before. I traced the
problem to defineClass() call, that was returning a class with
constant pool index as superclass instead of a pointer to the
superclass. That eventually breaks the VM at initializeClass().

Then I started checking what had changed between the two versions
and the cause of that is the addition of

        /* Signal that we are linking */
        class->state = CSTATE_DOING_LINK;

on linkClass() (classMethod.c) version 0.8.4

Setting a higher state (CSTATE_DOING_LINK > CSTATE_DOING_PREPARE)
actually prevents the class from being prepared at all!! On version
0.8.1 a class created by defineClass() would keep its CSTATE_LOADED
state on linkClass() allowing it to be prepared.

However, it makes more sense to set state CSTATE_DOING_LINK inside
linkClass() so the solution must be a change in some other place.

My suggestion is to use an approach similar to what is done on
loadClass(), where prepareClass() is called just after findClass().

(BTW, readClass.c still uses Class* instead of Hjava_lang_Class* !!!)

Here is the patch:
-------------- next part --------------
*** packages/tjwassoc.co.uk/APIcore/lib/java.lang/ClassLoader.c.orig	Wed Apr 16 04:11:45 1997
--- packages/tjwassoc.co.uk/APIcore/lib/java.lang/ClassLoader.c	Fri May 02 12:52:08 1997
***************
*** 31,40 ****
  java_lang_ClassLoader_defineClass0(struct Hjava_lang_ClassLoader* this, HArrayOfByte* data, jint offset, jint length)
  {
  	classFile hand;
  	hand.base = &unhand(data)->body[offset];
  	hand.buf = hand.base;
  	hand.size = length;
! 	return (readClass(alloc_class(), &hand, (struct _classLoader*)this));
  }
  
  /*
--- 31,44 ----
  java_lang_ClassLoader_defineClass0(struct Hjava_lang_ClassLoader* this, HArrayOfByte* data, jint offset, jint length)
  {
  	classFile hand;
+ 	struct Hjava_lang_Class* newclass;
+ 
  	hand.base = &unhand(data)->body[offset];
  	hand.buf = hand.base;
  	hand.size = length;
! 	newclass = readClass(alloc_class(), &hand, (struct _classLoader*)this);
! 	prepareClass (newclass);
! 	return (newclass);
  }
  
  /*
*** kaffe/kaffevm/classMethod.h.orig	Wed Apr 16 04:10:56 1997
--- kaffe/kaffevm/classMethod.h	Fri May 02 13:17:48 1997
***************
*** 212,217 ****
--- 212,218 ----
  Hjava_lang_Class*	getClass(constIndex, Hjava_lang_Class*);
  Utf8Const*		makeUtf8Const(char*, int);
  struct Hjava_lang_String* Utf8Const2JavaString(Utf8Const*);
+ void			prepareClass(Hjava_lang_Class*);
  void			linkClass(Hjava_lang_Class*);
  Hjava_lang_Class*	classFromSig(char**, struct _classLoader*);
  Hjava_lang_Class*	loadStaticClass(Utf8Const*);
*** kaffe/kaffevm/classMethod.c.orig	Wed Apr 16 04:10:55 1997
--- kaffe/kaffevm/classMethod.c	Fri May 02 13:15:46 1997
***************
*** 48,54 ****
  extern void verify2(Hjava_lang_Class*);
  extern void verify3(Hjava_lang_Class*);
  
! static void prepareClass(Hjava_lang_Class*);
  static Hjava_lang_Class* simpleLookupClass(Utf8Const*, struct _classLoader*);
  static Hjava_lang_Class* internalAddClass(Hjava_lang_Class*, Utf8Const*, int, int, struct _classLoader*);
  
--- 48,54 ----
  extern void verify2(Hjava_lang_Class*);
  extern void verify3(Hjava_lang_Class*);
  
! extern void prepareClass(Hjava_lang_Class*);
  static Hjava_lang_Class* simpleLookupClass(Utf8Const*, struct _classLoader*);
  static Hjava_lang_Class* internalAddClass(Hjava_lang_Class*, Utf8Const*, int, int, struct _classLoader*);
  
***************
*** 432,438 ****
  	class->state = CSTATE_PREPARED;
  }
  
- static
  void
  prepareClass (Hjava_lang_Class* class)
  {
--- 432,437 ----


More information about the kaffe mailing list