diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index c3364d05e78a358452fc35a360413047164fe5aa..88639b9fa6a084d48c3f4992018659b1bb72edb8 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -2,6 +2,30 @@
 
 	* name-finder.cc (_Jv_name_finder::lookup): Check for NULL dli_sname.
 
+	Eliminate use of C++ static constructors.		
+	* interpret.cc: Remove static Utf8Consts. Use namespace gcj. 
+	* jni.cc: Likewise.
+	* resolve.cc: Likewise.
+	* defineclass.cc: Likewise.
+	(_Jv_ClassReader::handleClassBegin): Synchronize call to 
+	_Jv_RegisterClass.
+	* include/jvm.h (void_signature, clinit_name, init_name, finit_name):
+	Declare in namespace gcj.
+	* java/lang/Class.h (Class): Remove initialization for primitive
+	types.
+	(friend void _Jv_InitPrimClass): This is in prims.cc.
+	* prims.cc (_Jv_InitPrimClass): Do primitive type initialization
+	here instead.
+	(void_signature, clinit_name, init_name, finit_name): Define in 
+	namespace gcj.
+	(_Jv_CreateJavaVM): Call _Jv_InitThreads, _Jv_InitGC, and 
+	_Jv_InitializeSyncMutex from here. Initialize Utf8 constants. 
+	Initialize primitive types.
+	* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Don't call
+	initialization routines. Don't synchronize.
+	* java/lang/natRuntime.cc (_load): Synchronize on java.lang.Class
+	across dlopen call.
+
 2001-10-15  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
 
 	* java/util/HashMap.java (HashEntry.clone): Removed.
diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc
index e25b106b2d80d8d3e6fd9f10b4d791f567f446d1..85f6ce3a65e234bfc16eaa2b846499ac6164b2dc 100644
--- a/libjava/defineclass.cc
+++ b/libjava/defineclass.cc
@@ -41,10 +41,7 @@ details.  */
 #include <java/lang/IncompatibleClassChangeError.h>
 #include <java/lang/reflect/Modifier.h>
 
-// we don't verify method names that match these.
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-
+using namespace gcj;
 
 // these go in some separate functions, to avoid having _Jv_InitClass
 // inserted all over the place.
@@ -934,7 +931,11 @@ _Jv_ClassReader::handleClassBegin
   // to include references to this class.
 
   def->state = JV_STATE_PRELOADING;
-  _Jv_RegisterClass (def);
+
+  {
+    JvSynchronize sync (&java::lang::Class::class$);
+    _Jv_RegisterClass (def);
+  }
 
   if (super_class != 0)
     {
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index 27a1c6f3223f7857c707ee93d613dde910c67849..bb54c8b58d883bf929bf4393e7ef19c0f62cc1a7 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -124,6 +124,15 @@ extern jboolean _Jv_equaln (_Jv_Utf8Const *, jstring, jint);
 // FIXME: remove this define.
 #define StringClass java::lang::String::class$
 
+namespace gcj
+{
+  /* Some constants used during lookup of special class methods.  */
+  extern _Jv_Utf8Const *void_signature; /* "()V" */
+  extern _Jv_Utf8Const *clinit_name;    /* "<clinit>" */
+  extern _Jv_Utf8Const *init_name;      /* "<init>" */
+  extern _Jv_Utf8Const *finit_name;     /* "finit$", */
+};
+
 /* Type of pointer used as finalizer.  */
 typedef void _Jv_FinalizerFunc (jobject);
 
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index 42c342a3281806a9d02499936e0c2477fd0bb10e..5bfe4e7fbba91d8b979b2955724cd6370a3801f2 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -37,7 +37,7 @@ details.  */
 
 #include <stdlib.h>
 
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+using namespace gcj;
 
 static void throw_internal_error (char *msg)
   __attribute__ ((__noreturn__));
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index 7b6b8b554a8b3a140c822cb0dcc4287357867e06..2ca7960466dc1f03f8970cc50e59fe077c2ad0bd 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -60,17 +60,10 @@ details.  */
 #define FieldClass java::lang::reflect::Field::class$
 #define ConstructorClass java::lang::reflect::Constructor::class$
 
-// Some constants we use to look up the class initializer.
-static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-static _Jv_Utf8Const *finit_name = _Jv_makeUtf8Const ("finit$", 6);
-// The legacy `$finit$' method name, which still needs to be
-// recognized as equivalent to the now prefered `finit$' name.
-static _Jv_Utf8Const *finit_leg_name = _Jv_makeUtf8Const ("$finit$", 7);
-
 
 
+using namespace gcj;
+
 jclass
 java::lang::Class::forName (jstring className, jboolean initialize,
                             java::lang::ClassLoader *loader)
@@ -341,9 +334,7 @@ java::lang::Class::getDeclaredMethods (void)
       if (method->name == NULL
 	  || _Jv_equalUtf8Consts (method->name, clinit_name)
 	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
+	  || _Jv_equalUtf8Consts (method->name, finit_name))
 	continue;
       numMethods++;
     }
@@ -357,9 +348,7 @@ java::lang::Class::getDeclaredMethods (void)
       if (method->name == NULL
 	  || _Jv_equalUtf8Consts (method->name, clinit_name)
 	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
+	  || _Jv_equalUtf8Consts (method->name, finit_name))
 	continue;
       java::lang::reflect::Method* rmethod
 	= new java::lang::reflect::Method ();
@@ -522,9 +511,7 @@ java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
       if (method->name == NULL
 	  || _Jv_equalUtf8Consts (method->name, clinit_name)
 	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
+	  || _Jv_equalUtf8Consts (method->name, finit_name))
 	continue;
       // Only want public methods.
       if (! java::lang::reflect::Modifier::isPublic (method->accflags))
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index 004b9d14b735d2d0dc347cb9dd24f4fdbe2b524d..3c2679bd8b4367d78191a0c93ae15a6191657945 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -175,7 +175,6 @@ java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass)
   klass->notifyAll ();
 }
 
-
 // This is the findClass() implementation for the System classloader. It is 
 // the only native method in VMClassLoader, so we define it here.
 jclass
@@ -419,24 +418,13 @@ _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
 }
 
 // This function is called many times during startup, before main() is
-// run.  We do our runtime initialization here the very first time we
-// are called.  At that point in time we know for certain we are
-// running single-threaded, so we don't need to lock when modifying
-// `init'.  CLASSES is NULL-terminated.
+// run.  At that point in time we know for certain we are running 
+// single-threaded, so we don't need to lock when adding classes to the 
+// class chain.  At all other times, the caller should synchronize on
+// Class::class$.
 void
 _Jv_RegisterClasses (jclass *classes)
 {
-  static bool init = false;
-
-  if (! init)
-    {
-      init = true;
-      _Jv_InitThreads ();
-      _Jv_InitGC ();
-      _Jv_InitializeSyncMutex ();
-    }
-
-  JvSynchronize sync (&ClassClass);
   for (; *classes; ++classes)
     {
       jclass klass = *classes;
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
index 0551ba620a6a13dec4665f8f78042f263ae599a9..18bc3cb9bf9eb205dd209d49e64ee3093756c633 100644
--- a/libjava/java/lang/natRuntime.cc
+++ b/libjava/java/lang/natRuntime.cc
@@ -138,8 +138,15 @@ java::lang::Runtime::_load (jstring path, jboolean do_search)
 #endif
   jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
   buf[offset + total] = '\0';
+  lt_dlhandle h;
   // FIXME: make sure path is absolute.
-  lt_dlhandle h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
+  {
+    // Synchronize on java.lang.Class. This is to protect the class chain from
+    // concurrent modification by class registration calls which may be run
+    // during the dlopen().
+    JvSynchronize sync (&java::lang::Class::class$);
+    h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
+  }
   if (h == NULL)
     {
       const char *msg = lt_dlerror ();
diff --git a/libjava/jni.cc b/libjava/jni.cc
index 8f4e4f14e228f2c5c7a480158bca6dcdcf3ebc19..8e586fa38f1a3039fecebb9220a157e1ef563283 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -48,6 +48,8 @@ details.  */
 #include <java-interp.h>
 #include <java-threads.h>
 
+using namespace gcj;
+
 // This enum is used to select different template instantiations in
 // the invocation code.
 enum invocation_type
@@ -1502,9 +1504,6 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
 {
   using namespace java::lang::reflect;
 
-  // FIXME.
-  static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-
   jobject result = NULL;
 
   try
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 7205e1f6bfce04f8f1415027a153d5ac3d01b0dd..7b3dd6c6a005e0ddbac6622ca7b1e79c43429d77 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -574,21 +574,39 @@ _Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
 
 
 
-#define DECLARE_PRIM_TYPE(NAME, SIG, LEN)				\
-  _Jv_ArrayVTable _Jv_##NAME##VTable;					\
-  java::lang::Class _Jv_##NAME##Class ((jobject) #NAME,			\
-				       (jbyte) SIG, (jint) LEN,		\
-				       (jobject) &_Jv_##NAME##VTable);
-
-DECLARE_PRIM_TYPE(byte, 'B', 1);
-DECLARE_PRIM_TYPE(short, 'S', 2);
-DECLARE_PRIM_TYPE(int, 'I', 4);
-DECLARE_PRIM_TYPE(long, 'J', 8);
-DECLARE_PRIM_TYPE(boolean, 'Z', 1);
-DECLARE_PRIM_TYPE(char, 'C', 2);
-DECLARE_PRIM_TYPE(float, 'F', 4);
-DECLARE_PRIM_TYPE(double, 'D', 8);
-DECLARE_PRIM_TYPE(void, 'V', 0);
+#define DECLARE_PRIM_TYPE(NAME)			\
+  _Jv_ArrayVTable _Jv_##NAME##VTable;		\
+  java::lang::Class _Jv_##NAME##Class;
+
+DECLARE_PRIM_TYPE(byte);
+DECLARE_PRIM_TYPE(short);
+DECLARE_PRIM_TYPE(int);
+DECLARE_PRIM_TYPE(long);
+DECLARE_PRIM_TYPE(boolean);
+DECLARE_PRIM_TYPE(char);
+DECLARE_PRIM_TYPE(float);
+DECLARE_PRIM_TYPE(double);
+DECLARE_PRIM_TYPE(void);
+
+void
+_Jv_InitPrimClass (jclass cl, char *cname, char sig, int len, 
+                   _Jv_ArrayVTable *array_vtable)
+{    
+  using namespace java::lang::reflect;
+
+  // We must initialize every field of the class.  We do this in the
+  // same order they are declared in Class.h, except for fields that
+  // are initialized to NULL.
+  cl->name = _Jv_makeUtf8Const ((char *) cname, -1);
+  cl->accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT;
+  cl->method_count = sig;
+  cl->size_in_bytes = len;
+  cl->vtable = JV_PRIMITIVE_VTABLE;
+  cl->state = JV_STATE_DONE;
+  cl->depth = -1;
+  if (sig != 'V')
+    _Jv_NewArrayClass (cl, NULL, (_Jv_VTable *) array_vtable);
+}
 
 jclass
 _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
@@ -848,11 +866,49 @@ process_gcj_properties ()
 }
 #endif // DISABLE_GETENV_PROPERTIES
 
+namespace gcj
+{
+  _Jv_Utf8Const *void_signature;
+  _Jv_Utf8Const *clinit_name;
+  _Jv_Utf8Const *init_name;
+  _Jv_Utf8Const *finit_name;
+}
+
 jint
 _Jv_CreateJavaVM (void* /*vm_args*/)
 {
+  using namespace gcj;
+  
+  static bool init = false;
+
+  if (init)
+    return -1;
+
+  init = true;
+
   PROCESS_GCJ_PROPERTIES;
 
+  _Jv_InitThreads ();
+  _Jv_InitGC ();
+  _Jv_InitializeSyncMutex ();
+
+  /* Initialize Utf8 constants declared in jvm.h. */
+  void_signature = _Jv_makeUtf8Const ("()V", 3);
+  clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
+  init_name = _Jv_makeUtf8Const ("<init>", 6);
+  finit_name = _Jv_makeUtf8Const ("finit$", 6);
+
+  /* Initialize built-in classes to represent primitive TYPEs. */
+  _Jv_InitPrimClass (&_Jv_byteClass,    "byte",    'B', 1, &_Jv_byteVTable);
+  _Jv_InitPrimClass (&_Jv_shortClass,   "short",   'S', 2, &_Jv_shortVTable);
+  _Jv_InitPrimClass (&_Jv_intClass,     "int",     'I', 4, &_Jv_intVTable);
+  _Jv_InitPrimClass (&_Jv_longClass,    "long",    'J', 8, &_Jv_longVTable);
+  _Jv_InitPrimClass (&_Jv_booleanClass, "boolean", 'Z', 1, &_Jv_booleanVTable);
+  _Jv_InitPrimClass (&_Jv_charClass,    "char",    'C', 2, &_Jv_charVTable);
+  _Jv_InitPrimClass (&_Jv_floatClass,   "float",   'F', 4, &_Jv_floatVTable);
+  _Jv_InitPrimClass (&_Jv_doubleClass,  "double",  'D', 8, &_Jv_doubleVTable);
+  _Jv_InitPrimClass (&_Jv_voidClass,    "void",    'V', 0, &_Jv_voidVTable);
+
   // Turn stack trace generation off while creating exception objects.
   _Jv_InitClass (&java::lang::Throwable::class$);
   java::lang::Throwable::trace_enabled = 0;
diff --git a/libjava/resolve.cc b/libjava/resolve.cc
index df48c269c67fe373095bf6f236a7d43650f63c29..ea0faadf22155ab219ec9616f9c5b71a96d8e022 100644
--- a/libjava/resolve.cc
+++ b/libjava/resolve.cc
@@ -32,6 +32,8 @@ details.  */
 #include <java/lang/IncompatibleClassChangeError.h>
 #include <java/lang/reflect/Modifier.h>
 
+using namespace gcj;
+
 void
 _Jv_ResolveField (_Jv_Field *field, java::lang::ClassLoader *loader)
 {
@@ -65,9 +67,6 @@ _Jv_BuildResolvedMethod (_Jv_Method*,
 			 jint);
 
 
-// We need to know the name of a constructor.
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-
 static void throw_incompatible_class_change_error (jstring msg)
 {
   throw new java::lang::IncompatibleClassChangeError (msg);