Patch: FYI: java.endorsed.dirs

Tom Tromey tromey@redhat.com
Wed Apr 6 21:34:00 GMT 2005


This moves the java.endorsed.dirs patch to the 4.0 branch.

I tested this on x86 FC2 and PPC Linux (not sure what release of the
OS -- but this was a multilib build).  So, I am reasonably confident
that it is working ok.  But, given the experience with this patch on
the trunk, I'd like to ask folks to give it a try asap.

This patch is needed for some real-world applications like jonas.
We'll also be expanding it to make it simpler to do things like
develop parts of libgcj itself without having to go through a full
rebuild cycle.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* Makefile.in: Rebuilt.
	* Makefile.am (lib_gnu_java_awt_peer_gtk_la_SOURCES): Removed
	gtk_awt_peer_sources.
	(lib_gnu_java_awt_peer_gtk_la_LIBADD): Added gtk-awt-peer.lo.
	(lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES): Likewise.
	($(gtk_awt_peer_sources:.java=.lo)): Removed.
	(gtk-awt-peer.lo): New target.

	* java/lang/natVMClassLoader.cc (getSystemClassLoaderInternal):
	Updated for name change.
	(nativeFindClass): New method.
	(loadClass): Use nativeFindClass.
	* java/lang/natClassLoader.cc (_Jv_FindClass): Use single-argument
	form of loadClass.
	* java/lang/VMClassLoader.java (tried_libraries, lib_control,
	LIB_FULL, LIB_CACHE, LIB_NEVER): New fields from old
	VMClassLoader.
	(initialize): New method.
	(nativeFindClass): Declare.
	* gnu/gcj/runtime/natVMClassLoader.cc: Removed.
	* gnu/gcj/runtime/VMClassLoader.java: Removed.
	* gnu/gcj/runtime/ExtensionClassLoader.java: Renamed from
	VMClassLoader.java.
	(definePackageForNative): Removed.
	(tried_libraries, LIB_CACHE, LIB_FULL, LIB_NEVER, lib_control):
	Moved to VMClassLoader.java.
	* prims.cc (_Jv_CreateJavaVM): Updated for renaming.
	* Makefile.am (gnu/gcj/runtime/ExtensionClassLoader.h): Renamed.
	(ordinary_java_source_files): Added ExtensionClassLoader.java,
	removed VMClassLoader.java.
	(nat_source_files): Removed natVMClassLoader.cc.

	* java/lang/natRuntime.cc (insertSystemProperties): Set
	gnu.gcj.runtime.endorsed.dirs.
	* Makefile.in: Rebuilt.
	* Makefile.am (ordinary_java_source_files): Added
	HelperClassLoader.java.
	(AM_CXXFLAGS): Define GCJ_ENDORSED_DIRS.
	* gnu/gcj/runtime/VMClassLoader.java (VMClassLoader): Extends
	HelperClassLoader.
	(init): Use addDirectoriesFromProperty.
	* gnu/gcj/runtime/BootClassLoader.java (BootClassLoader): Extends
	HelperClassLoader.  Use addDirectoriesFromProperty.  Handle
	gnu.gcj.runtime.endorsed.dirs.
	* gnu/gcj/runtime/HelperClassLoader.java: New file.

	* gnu/gcj/runtime/BootClassLoader.java (BootClassLoader): Don't
	add sax and w3c libraries.
	* Makefile.am (libgij_la_LIBADD): Added libsax-gcj.la and
	libw3c-gcj.la.
	* external/w3c_dom/Makefile.in: Rebuilt.
	* external/w3c_dom/Makefile.am (libw3c_gcj_la_GCJFLAGS): Include
	AM_GCJFLAGS.
	(libw3c_gcj_la_LDFLAGS): New variable.
	(noinst_LTLIBRARIES): Renamed.
	* external/sax/Makefile.in: Rebuilt.
	* external/sax/Makefile.am (libsax_gcj_la_GCJFLAGS): Include
	AM_GCJFLAGS.
	(libsax_gcj_la_LDFLAGS): New variable.
	(noinst_LTLIBRARIES): Renamed.

	* Makefile.in: Rebuilt.
	* Makefile.am (AM_CXXFLAGS): Define TOOLEXECLIBDIR.
	(libgcj0_convenience_la_SOURCES): Don't include
	gnu_xml_source_files.
	(libgcj0_convenience_la_LIBADD): New variable.
	(libgcj_la_LIBADD): Don't include sax or w3c_dom.
	(all_java_source_files): javax_imageio_source_files,
	javax_xml_source_files, and gnu_java_beans_source_files.
	($(gnu_xml_source_files:.java=.lo)): Removed target.
	(gnu-xml.lo): New target.
	(javax-imageio.lo): Likewise.
	(javax-xml.lo): Likewise.
	(gnu-java-beans.lo): Likewise.
	(gnu_java_beans_source_files): New variable.
	(javax_imageio_source_files): Likewise.
	(javax_xml_source_files): Likewise.
	(javax_source_files): Moved files to other variable.
	(awt_java_source_files): Likewise.
	(ordinary_java_source_files): Added BootClassLoader.java.
	* java/lang/natVMClassLoader.cc (defineClass): Use boot loader,
	not system class loader.
	(initBootLoader): New method.
	(loadClass): Search bootLoader.
	* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader): Use
	boot loader, not system class loader.
	(_Jv_UnregisterInitiatingLoader): Likewise.
	(_Jv_FindClass): Likewise.  Ensure entries in
	bootstrap_class_list are unique.
	* java/lang/natClass.cc (getClassLoader): Don't special case
	system class loader.
	* java/lang/VMClassLoader.java (bootLoader): New field.
	(getResource): Use bootLoader.
	(getResources): Likewise.
	(initBootLoader): Declare.
	* gnu/gcj/runtime/BootClassLoader.java: New file.
	* external/sax/org/xml/sax/helpers/NamespaceSupport.java
	(EMPTY_ENUMERATION): Now package-private.
	* external/w3c_com/Makefile.in: Rebuilt.
	* external/w3c_com/Makefile.am (MULTIBUILDTOP): New variable.
	(w3c.jar): New target.
	(classes.stamp): Updated.
	(toolexeclib_LTLIBRARIES): Renamed from noinst_LTLIBRARIES.
	Changed name of library.
	(libw3c_gcj_la_SOURCES): New variable.
	(libw3c_gcj_la_GCJFLAGS): Likewise.
	(source_files): Renamed from lib3c_convenience_la_SOURCES.
	* external/sax/Makefile.in: Rebuilt.
	* external/sax/Makefile.am (MULTIBUILDTOP): New variable.
	(sax.jar): New target.
	(classes.stamp): Updated.
	(toolexeclib_LTLIBRARIES): Renamed from noinst_LTLIBRARIES.
	Changed name of library.
	(libsax_gcj_la_SOURCES): New variable.
	(libsax_gcj_la_GCJFLAGS): Likewise.
	(source_files): Renamed from libsax_convenience_la_SOURCES.
	* prims.cc (_Jv_CreateJavaVM): Initialize the bootstrap class
	loader.
	(_Jv_RunMain): Handle case where 'runtime' is NULL at exit.

2005-03-28  Alexandre Oliva  <aoliva@redhat.com>

	* configure.ac: Revert 2005-03-25's patch.  Propagate MULTIlib
	settings to sub Makefiles.
	(GCJH, ZIP): Prefix with top_builddir.
	* configure: Rebuild.
	* external/w3c_dom/Makefile.am (MULTIBUILDTOP): Don't override.
	* external/w3c_dom/Makefile.in: Rebuild.
	* external/sax/Makefile.am (MULTIBUILDTOP): Don't override.
	* external/sax/Makefile.in: Rebuild.

Index: gcc/java/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* gcj.texi (libgcj Runtime Properties): Document
	gnu.gcj.runtime.endorsed.dirs.

Index: gcc/java/gcj.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/gcj.texi,v
retrieving revision 1.73.2.4
diff -u -r1.73.2.4 gcj.texi
--- gcc/java/gcj.texi 2 Apr 2005 02:30:15 -0000 1.73.2.4
+++ gcc/java/gcj.texi 6 Apr 2005 21:17:56 -0000
@@ -2556,6 +2556,15 @@
 tried again.  If this property is set to @samp{never}, then lookups
 are never done.  For more information, @xref{Extensions}.
 
+@item gnu.gcj.runtime.endorsed.dirs
+This is like the standard @code{java.endorsed.dirs}, property, but
+specifies some extra directories which are searched after the standard
+endorsed directories.  This is primarily useful for telling
+@code{libgcj} about additional libraries which are ordinarily
+incorporated into the JDK, and which should be loaded by the bootstrap
+class loader, but which are not yet part of @code{libgcj} itself for
+some reason.
+
 @item gnu.gcj.jit.compiler
 @c FIXME we should probably have a whole node on this...
 This is the full path to @command{gcj} executable which should be
Index: libjava/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.455.2.9
diff -u -r1.455.2.9 Makefile.am
--- libjava/Makefile.am 6 Apr 2005 03:43:49 -0000 1.455.2.9
+++ libjava/Makefile.am 6 Apr 2005 21:18:03 -0000
@@ -192,8 +192,10 @@
         -DJAVA_HOME="\"$(JAVA_HOME_DIR)\"" \
         -DBOOT_CLASS_PATH="\"$(BOOT_CLASS_PATH_DIR)\"" \
 	-DJAVA_EXT_DIRS="\"$(jardir)/ext\"" \
+	-DGCJ_ENDORSED_DIRS="\"$(jardir)/gcj-endorsed\"" \
 	-DLIBGCJ_DEFAULT_DATABASE="\"$(dbexecdir)/$(db_name)\"" \
-	-DLIBGCJ_DEFAULT_DATABASE_PATH_TAIL="\"$(db_pathtail)\""
+	-DLIBGCJ_DEFAULT_DATABASE_PATH_TAIL="\"$(db_pathtail)\"" \
+	-DTOOLEXECLIBDIR="\"$(toolexeclibdir)\""
 
 AM_GCJFLAGS = \
 	@LIBGCJ_JAVAFLAGS@ \
@@ -230,7 +232,9 @@
 libgij_la_SOURCES = gij.cc
 libgij_la_DEPENDENCIES = libgcj.la libgcj.spec
 ## See jv_convert_LDADD.
-libgij_la_LIBADD = -L$(here)/.libs libgcj.la
+libgij_la_LIBADD = -L$(here)/.libs libgcj.la \
+	external/sax/libsax-gcj.la \
+	external/w3c_dom/libw3c-gcj.la
 ## The mysterious backslash in the grep pattern is consumed by make.
 libgij_la_LDFLAGS = -rpath $(toolexeclibdir) \
         -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC)
@@ -242,12 +246,16 @@
 libgcj0_convenience_la_SOURCES = prims.cc jni.cc exception.cc \
 	link.cc defineclass.cc interpret.cc verify.cc \
 	$(nat_source_files) $(math_c_source_files) $(java_source_files) \
-	$(gnu_xml_source_files) $(built_java_source_files) \
+	$(built_java_source_files) \
 	$(BOEHMGC_SRC) $(NOGC_SRC) \
 	$(BACKTRACE_SRC) \
 	$(POSIX_PLATFORM_SRC) $(WIN32_PLATFORM_SRC) $(ECOS_PLATFORM_SRC) \
 	$(DARWIN_CRT_SRC) \
 	$(POSIX_THREAD_SRC) $(WIN32_THREAD_SRC) $(NO_THREAD_SRC)
+libgcj0_convenience_la_LIBADD = \
+	gnu-xml.lo javax-imageio.lo \
+	javax-xml.lo gnu-java-beans.lo
+
 noinst_LTLIBRARIES = libgcj0_convenience.la
 
 libgcj_la_SOURCES =
@@ -263,13 +271,11 @@
 	$(LIBLTDL) $(SYS_ZLIBS) \
 	-version-info `grep -v '^\#' $(srcdir)/libtool-version`
 libgcj_la_LIBADD = \
-	external/sax/libsax_convenience.la \
-	external/w3c_dom/libw3c_convenience.la \
 	libgcj0_convenience.la \
 	$(LIBFFI) $(ZLIBS) $(GCLIBS) $(propertyo_files)
-libgcj_la_DEPENDENCIES = libgcj-@gcc_version@.jar \
+libgcj_la_DEPENDENCIES = libgcj-$(gcc_version).jar \
 	java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h \
-	$(libgcj_la_LIBADD)
+	$(LIBLTDL) $(libgcj_la_LIBADD)
 libgcj_la_LINK = $(LIBLINK)
 
 
@@ -474,7 +480,6 @@
 $(lib_gnu_java_awt_peer_gtk_la_OBJECTS): $(lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES)
 
 lib_gnu_java_awt_peer_gtk_la_SOURCES = \
-$(gtk_awt_peer_sources) \
 $(gtk_c_source_files) \
 jni/gtk-peer/gthread-jni.h \
 jni/gtk-peer/gtkpeer.h \
@@ -485,8 +490,8 @@
 	-I$(srcdir)/jni/gtk-peer $(PEDANTIC_CFLAGS) $(GTK_CFLAGS) $(LIBART_CFLAGS) \
 	$(X_CFLAGS) $(CAIRO_CFLAGS) $(PANGOFT2_CFLAGS)
 lib_gnu_java_awt_peer_gtk_la_GCJFLAGS = $(AM_GCJFLAGS) -fjni
-lib_gnu_java_awt_peer_gtk_la_LIBADD = $(GTK_LIBS) $(GLIB_LIBS) $(LIBART_LIBS) $(CAIRO_LIBS) $(PANGOFT2_LIBS)
-lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = $(gtk_jni_headers) libgcj-@gcc_version@.jar libgcj.la libgcj.spec
+lib_gnu_java_awt_peer_gtk_la_LIBADD = gtk-awt-peer.lo $(GTK_LIBS) $(GLIB_LIBS) $(LIBART_LIBS) $(CAIRO_LIBS) $(PANGOFT2_LIBS)
+lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = gtk-awt-peer.lo $(gtk_jni_headers) libgcj-$(gcc_version).jar libgcj.la libgcj.spec
 ## The mysterious backslash in the grep pattern is consumed by make.
 lib_gnu_java_awt_peer_gtk_la_LDFLAGS = \
         -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC) $(X_LIBS) -lXtst
@@ -524,7 +529,10 @@
     $(built_java_source_files) \
     $(gtk_awt_peer_sources) \
     $(xlib_java_source_files) \
-    $(gnu_xml_source_files)
+    $(gnu_xml_source_files) \
+    $(javax_imageio_source_files) \
+    $(javax_xml_source_files) \
+    $(gnu_java_beans_source_files)
 
 all_java_class_files = $(all_java_source_files:.java=.class)
 
@@ -621,9 +629,6 @@
 $(filter-out gnu/gcj/runtime/StackTrace.lo, $(javao_files)) $(xlib_javao_files): %.lo: %.java
 	$(LTGCJCOMPILE) -o $@ -c $<
 
-$(gtk_awt_peer_sources:.java=.lo) $(gnu_xml_source_files:.java=.lo): %.lo: %.java
-	$(LTGCJCOMPILE) -fjni -o $@ -c $<
-
 ## A special case.  The sibcall optimization can change the number of
 ## frames on the stack, and StackTrace makes assumptions about this
 ## number.
@@ -648,6 +653,69 @@
 ## ################################################################
 
 ##
+## Some packages must be built with the binary compatibility ABI.  We
+## compile each such package into a .so, broken down more or less by
+## conceptual unit.
+##
+
+## Depend on the sources, even though we are going to compile the
+## classes.
+gnu-xml.lo: $(gnu_xml_source_files)
+## FIXME: this is ugly.  We want to make sure the .class files have
+## been built, but we don't want a real dependency on them as this
+## would cause our target to be rebuilt whenever any .java file is
+## touched.
+	$(MAKE) classes.stamp
+	$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-xml.lo \
+		`find gnu/xml -name '*.class' -print`
+
+## Depend on the sources, even though we are going to compile the
+## classes.
+javax-imageio.lo: $(javax_imageio_source_files)
+## FIXME: this is ugly.  We want to make sure the .class files have
+## been built, but we don't want a real dependency on them as this
+## would cause our target to be rebuilt whenever any .java file is
+## touched.
+	$(MAKE) classes.stamp
+	$(LTGCJCOMPILE) -findirect-dispatch -c -o javax-imageio.lo \
+		`find javax/imageio -name '*.class' -print`
+
+## Depend on the sources, even though we are going to compile the
+## classes.
+javax-xml.lo: $(javax_xml_source_files)
+## FIXME: this is ugly.  We want to make sure the .class files have
+## been built, but we don't want a real dependency on them as this
+## would cause our target to be rebuilt whenever any .java file is
+## touched.
+	$(MAKE) classes.stamp
+	$(LTGCJCOMPILE) -findirect-dispatch -c -o javax-xml.lo \
+		`find javax/xml -name '*.class' -print`
+
+## Depend on the sources, even though we are going to compile the
+## classes.
+gnu-java-beans.lo: $(gnu_java_beans_source_files)
+## FIXME: this is ugly.  We want to make sure the .class files have
+## been built, but we don't want a real dependency on them as this
+## would cause our target to be rebuilt whenever any .java file is
+## touched.
+	$(MAKE) classes.stamp
+	$(LTGCJCOMPILE) -findirect-dispatch -c -o gnu-java-beans.lo \
+		`find gnu/java/beans -name '*.class' -print`
+
+## Depend on the sources, even though we are going to compile the
+## classes.
+gtk-awt-peer.lo: $(gtk_awt_peer_sources)
+## FIXME: this is ugly.  We want to make sure the .class files have
+## been built, but we don't want a real dependency on them as this
+## would cause our target to be rebuilt whenever any .java file is
+## touched.
+	$(MAKE) classes.stamp
+	$(LTGCJCOMPILE) -findirect-dispatch -fjni -c -o gtk-awt-peer.lo \
+		`find gnu/java/awt/peer/gtk -name '*.class' -print`
+
+## ################################################################
+
+##
 ## How to build header files.
 ##
 
@@ -764,7 +832,7 @@
 	$(GCJH) -classpath '' -bootclasspath $(top_builddir) \
 	'java/lang/reflect/Proxy$$ProxyType'
 
-gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class
+gnu/gcj/runtime/ExtensionClassLoader.h: gnu/gcj/runtime/ExtensionClassLoader.class
 	$(GCJH) -classpath '' -bootclasspath $(top_builddir) \
 	    -friend 'class ::java::lang::ClassLoader;' \
 	    $(basename $<)
@@ -1072,40 +1140,7 @@
 ## hand.
 special_java_source_files = java/lang/Class.java java/lang/Object.java
 
-awt_java_source_files =	\
-gnu/awt/LightweightRedirector.java \
-gnu/awt/j2d/AbstractGraphicsState.java \
-gnu/awt/j2d/DirectRasterGraphics.java \
-gnu/awt/j2d/Graphics2DImpl.java \
-gnu/awt/j2d/IntegerGraphicsState.java \
-gnu/awt/j2d/MappedRaster.java \
-gnu/java/awt/BitMaskExtent.java \
-gnu/java/awt/Buffers.java \
-gnu/java/awt/BitwiseXORComposite.java \
-gnu/java/awt/ComponentDataBlitOp.java \
-gnu/java/awt/ClasspathToolkit.java \
-gnu/java/awt/EmbeddedWindow.java \
-gnu/java/awt/EmbeddedWindowSupport.java \
-gnu/java/awt/EventModifier.java \
-gnu/java/awt/color/CieXyzConverter.java \
-gnu/java/awt/color/ClutProfileConverter.java \
-gnu/java/awt/color/ColorLookUpTable.java \
-gnu/java/awt/color/ColorSpaceConverter.java \
-gnu/java/awt/color/GrayProfileConverter.java \
-gnu/java/awt/color/GrayScaleConverter.java \
-gnu/java/awt/color/LinearRGBConverter.java \
-gnu/java/awt/color/ProfileHeader.java \
-gnu/java/awt/color/PyccConverter.java \
-gnu/java/awt/color/RgbProfileConverter.java \
-gnu/java/awt/color/SrgbConverter.java \
-gnu/java/awt/color/TagEntry.java \
-gnu/java/awt/color/ToneReproductionCurve.java \
-gnu/java/awt/image/ImageDecoder.java \
-gnu/java/awt/image/XBMDecoder.java \
-gnu/java/awt/peer/EmbeddedWindowPeer.java \
-gnu/java/awt/peer/GLightweightPeer.java \
-gnu/java/awt/peer/ClasspathFontPeer.java \
-gnu/java/awt/peer/ClasspathTextLayoutPeer.java \
+gnu_java_beans_source_files = \
 gnu/java/beans/decoder/AbstractContext.java \
 gnu/java/beans/decoder/AbstractCreatableObjectContext.java \
 gnu/java/beans/decoder/AbstractElementHandler.java \
@@ -1157,7 +1192,42 @@
 gnu/java/beans/DummyAppletContext.java \
 gnu/java/beans/DummyAppletStub.java \
 gnu/java/beans/ExplicitBeanInfo.java \
-gnu/java/beans/IntrospectionIncubator.java \
+gnu/java/beans/IntrospectionIncubator.java
+
+awt_java_source_files =	\
+gnu/awt/LightweightRedirector.java \
+gnu/awt/j2d/AbstractGraphicsState.java \
+gnu/awt/j2d/DirectRasterGraphics.java \
+gnu/awt/j2d/Graphics2DImpl.java \
+gnu/awt/j2d/IntegerGraphicsState.java \
+gnu/awt/j2d/MappedRaster.java \
+gnu/java/awt/BitMaskExtent.java \
+gnu/java/awt/Buffers.java \
+gnu/java/awt/BitwiseXORComposite.java \
+gnu/java/awt/ComponentDataBlitOp.java \
+gnu/java/awt/ClasspathToolkit.java \
+gnu/java/awt/EmbeddedWindow.java \
+gnu/java/awt/EmbeddedWindowSupport.java \
+gnu/java/awt/EventModifier.java \
+gnu/java/awt/color/CieXyzConverter.java \
+gnu/java/awt/color/ClutProfileConverter.java \
+gnu/java/awt/color/ColorLookUpTable.java \
+gnu/java/awt/color/ColorSpaceConverter.java \
+gnu/java/awt/color/GrayProfileConverter.java \
+gnu/java/awt/color/GrayScaleConverter.java \
+gnu/java/awt/color/LinearRGBConverter.java \
+gnu/java/awt/color/ProfileHeader.java \
+gnu/java/awt/color/PyccConverter.java \
+gnu/java/awt/color/RgbProfileConverter.java \
+gnu/java/awt/color/SrgbConverter.java \
+gnu/java/awt/color/TagEntry.java \
+gnu/java/awt/color/ToneReproductionCurve.java \
+gnu/java/awt/image/ImageDecoder.java \
+gnu/java/awt/image/XBMDecoder.java \
+gnu/java/awt/peer/EmbeddedWindowPeer.java \
+gnu/java/awt/peer/GLightweightPeer.java \
+gnu/java/awt/peer/ClasspathFontPeer.java \
+gnu/java/awt/peer/ClasspathTextLayoutPeer.java \
 java/applet/Applet.java \
 java/applet/AppletStub.java \
 java/applet/AppletContext.java \
@@ -2000,7 +2070,7 @@
 gnu/java/rmi/server/UnicastServer.java \
 gnu/java/rmi/server/UnicastServerRef.java
 
-javax_source_files = \
+javax_imageio_source_files = \
 javax/imageio/ImageWriteParam.java \
 javax/imageio/ImageReader.java \
 javax/imageio/ImageWriter.java \
@@ -2046,7 +2116,63 @@
 javax/imageio/ImageTranscoder.java \
 javax/imageio/ImageTypeSpecifier.java \
 javax/imageio/ImageIO.java \
-javax/imageio/IIOImage.java \
+javax/imageio/IIOImage.java
+
+javax_xml_source_files = \
+javax/xml/xpath/XPathConstants.java \
+javax/xml/xpath/XPathFunction.java \
+javax/xml/xpath/XPathVariableResolver.java \
+javax/xml/xpath/XPathExpressionException.java \
+javax/xml/xpath/XPathFunctionResolver.java \
+javax/xml/xpath/XPath.java \
+javax/xml/xpath/XPathFactoryConfigurationException.java	\
+javax/xml/xpath/XPathFactory.java \
+javax/xml/xpath/XPathException.java \
+javax/xml/xpath/XPathExpression.java \
+javax/xml/xpath/XPathFunctionException.java \
+javax/xml/validation/ValidatorHandler.java \
+javax/xml/validation/Validator.java \
+javax/xml/validation/TypeInfoProvider.java \
+javax/xml/validation/SchemaFactory.java	\
+javax/xml/validation/Schema.java \
+javax/xml/parsers/SAXParserFactory.java	\
+javax/xml/parsers/FactoryConfigurationError.java \
+javax/xml/parsers/SAXParser.java \
+javax/xml/parsers/DocumentBuilderFactory.java \
+javax/xml/parsers/ParserConfigurationException.java \
+javax/xml/parsers/DocumentBuilder.java \
+javax/xml/datatype/DatatypeFactory.java	\
+javax/xml/datatype/XMLGregorianCalendar.java \
+javax/xml/datatype/Duration.java \
+javax/xml/datatype/DatatypeConfigurationException.java \
+javax/xml/datatype/DatatypeConstants.java \
+javax/xml/XMLConstants.java \
+javax/xml/namespace/NamespaceContext.java \
+javax/xml/namespace/QName.java \
+javax/xml/transform/TransformerException.java \
+javax/xml/transform/TransformerFactoryConfigurationError.java \
+javax/xml/transform/sax/SAXResult.java \
+javax/xml/transform/sax/TransformerHandler.java	\
+javax/xml/transform/sax/SAXTransformerFactory.java \
+javax/xml/transform/sax/SAXSource.java \
+javax/xml/transform/sax/TemplatesHandler.java \
+javax/xml/transform/OutputKeys.java \
+javax/xml/transform/stream/StreamResult.java \
+javax/xml/transform/stream/StreamSource.java \
+javax/xml/transform/Source.java	\
+javax/xml/transform/SourceLocator.java \
+javax/xml/transform/ErrorListener.java \
+javax/xml/transform/TransformerConfigurationException.java \
+javax/xml/transform/Templates.java \
+javax/xml/transform/Result.java	\
+javax/xml/transform/URIResolver.java \
+javax/xml/transform/dom/DOMSource.java \
+javax/xml/transform/dom/DOMLocator.java	\
+javax/xml/transform/dom/DOMResult.java \
+javax/xml/transform/Transformer.java \
+javax/xml/transform/TransformerFactory.java
+
+javax_source_files = \
 javax/net/VanillaSocketFactory.java \
 javax/net/ssl/TrustManagerFactorySpi.java \
 javax/net/ssl/SSLKeyException.java \
@@ -2285,58 +2411,6 @@
 javax/naming/RefAddr.java \
 javax/naming/CompositeName.java	\
 javax/naming/Name.java \
-javax/xml/xpath/XPathConstants.java \
-javax/xml/xpath/XPathFunction.java \
-javax/xml/xpath/XPathVariableResolver.java \
-javax/xml/xpath/XPathExpressionException.java \
-javax/xml/xpath/XPathFunctionResolver.java \
-javax/xml/xpath/XPath.java \
-javax/xml/xpath/XPathFactoryConfigurationException.java	\
-javax/xml/xpath/XPathFactory.java \
-javax/xml/xpath/XPathException.java \
-javax/xml/xpath/XPathExpression.java \
-javax/xml/xpath/XPathFunctionException.java \
-javax/xml/validation/ValidatorHandler.java \
-javax/xml/validation/Validator.java \
-javax/xml/validation/TypeInfoProvider.java \
-javax/xml/validation/SchemaFactory.java	\
-javax/xml/validation/Schema.java \
-javax/xml/parsers/SAXParserFactory.java	\
-javax/xml/parsers/FactoryConfigurationError.java \
-javax/xml/parsers/SAXParser.java \
-javax/xml/parsers/DocumentBuilderFactory.java \
-javax/xml/parsers/ParserConfigurationException.java \
-javax/xml/parsers/DocumentBuilder.java \
-javax/xml/datatype/DatatypeFactory.java	\
-javax/xml/datatype/XMLGregorianCalendar.java \
-javax/xml/datatype/Duration.java \
-javax/xml/datatype/DatatypeConfigurationException.java \
-javax/xml/datatype/DatatypeConstants.java \
-javax/xml/XMLConstants.java \
-javax/xml/namespace/NamespaceContext.java \
-javax/xml/namespace/QName.java \
-javax/xml/transform/TransformerException.java \
-javax/xml/transform/TransformerFactoryConfigurationError.java \
-javax/xml/transform/sax/SAXResult.java \
-javax/xml/transform/sax/TransformerHandler.java	\
-javax/xml/transform/sax/SAXTransformerFactory.java \
-javax/xml/transform/sax/SAXSource.java \
-javax/xml/transform/sax/TemplatesHandler.java \
-javax/xml/transform/OutputKeys.java \
-javax/xml/transform/stream/StreamResult.java \
-javax/xml/transform/stream/StreamSource.java \
-javax/xml/transform/Source.java	\
-javax/xml/transform/SourceLocator.java \
-javax/xml/transform/ErrorListener.java \
-javax/xml/transform/TransformerConfigurationException.java \
-javax/xml/transform/Templates.java \
-javax/xml/transform/Result.java	\
-javax/xml/transform/URIResolver.java \
-javax/xml/transform/dom/DOMSource.java \
-javax/xml/transform/dom/DOMLocator.java	\
-javax/xml/transform/dom/DOMResult.java \
-javax/xml/transform/Transformer.java \
-javax/xml/transform/TransformerFactory.java \
 javax/security/cert/CertificateNotYetValidException.java \
 javax/security/cert/Certificate.java \
 javax/security/cert/X509Certificate.java \
@@ -2937,18 +3011,20 @@
 gnu/gcj/io/DefaultMimeTypes.java \
 gnu/gcj/io/MimeTypes.java \
 gnu/gcj/io/SimpleSHSStream.java	\
+gnu/gcj/runtime/BootClassLoader.java \
+gnu/gcj/runtime/ExtensionClassLoader.java \
 gnu/gcj/runtime/FileDeleter.java \
 gnu/gcj/runtime/FinalizerThread.java \
+gnu/gcj/runtime/HelperClassLoader.java \
 gnu/gcj/runtime/JNIWeakRef.java \
 gnu/gcj/runtime/MethodRef.java \
 gnu/gcj/runtime/NameFinder.java \
 gnu/gcj/runtime/PersistentByteMap.java \
 gnu/gcj/runtime/SharedLibHelper.java \
 gnu/gcj/runtime/SharedLibLoader.java \
-gnu/gcj/runtime/StackTrace.java \
 gnu/gcj/runtime/StringBuffer.java \
+gnu/gcj/runtime/StackTrace.java \
 gnu/gcj/runtime/SystemClassLoader.java \
-gnu/gcj/runtime/VMClassLoader.java \
 gnu/gcj/util/Debug.java \
 gnu/java/io/ASN1ParsingException.java \
 gnu/java/io/Base64InputStream.java \
@@ -3709,7 +3785,6 @@
 gnu/gcj/runtime/natSharedLibLoader.cc \
 gnu/gcj/runtime/natStackTrace.cc \
 gnu/gcj/runtime/natStringBuffer.cc \
-gnu/gcj/runtime/natVMClassLoader.cc \
 gnu/gcj/util/natDebug.cc \
 gnu/java/lang/natMainThread.cc \
 gnu/java/net/natPlainDatagramSocketImpl.cc \
Index: libjava/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.ac,v
retrieving revision 1.19.2.3
diff -u -r1.19.2.3 configure.ac
--- libjava/configure.ac 6 Apr 2005 03:43:56 -0000 1.19.2.3
+++ libjava/configure.ac 6 Apr 2005 21:18:14 -0000
@@ -162,13 +162,6 @@
 AM_PROG_CC_C_O
 AC_CONFIG_SUBDIRS(libltdl)
 
-if test -z "$with_target_subdir" || test "$with_target_subdir" = "."; then
-   COMPPATH=.
-else
-   COMPPATH=..
-fi
-AC_SUBST(COMPPATH)
-
 # The -no-testsuite modules omit the test subdir.
 AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
 
@@ -1046,7 +1039,7 @@
 
 # Which gcj do we use?
 which_gcj=default
-built_gcc_dir="`cd ${builddotdot}/../../gcc && ${PWDCMD-pwd}`"
+built_gcc_dir="`cd ${builddotdot}/../../${host_subdir}/gcc && ${PWDCMD-pwd}`"
 if test -n "${with_cross_host}"; then
   # We are being configured with a cross compiler. We can't
   # use ac_exeext, because that is for the target platform.
@@ -1085,8 +1078,8 @@
 case "${which_gcj}" in
    built)
       GCJ="$built_gcc_dir/gcj -B`${PWDCMD-pwd}`/ -B$built_gcc_dir/"
-      GCJH='$(MULTIBUILDTOP)../$(COMPPATH)/gcc/gcjh'
-      ZIP='$(MULTIBUILDTOP)../$(COMPPATH)/fastjar/fastjar'
+      GCJH='$(top_builddir)/$(MULTIBUILDTOP)../../$(host_subdir)/gcc/gcjh'
+      ZIP='$(top_builddir)/$(MULTIBUILDTOP)../../$(host_subdir)/fastjar/fastjar'
    ;;
    cross)
       if test "x${with_newlib}" = "xyes"; then
@@ -1103,7 +1096,7 @@
       GCJ="gcj -B`${PWDCMD-pwd}`/"
       ## In this case, gcj is found outside the build tree.  However, zip is
       ## found in the build tree.
-      ZIP='$(MULTIBUILDTOP)../$(COMPPATH)/fastjar/fastjar'
+      ZIP='$(top_builddir)/$(MULTIBUILDTOP)../$(COMPPATH)/fastjar/fastjar'
       GCJH=gcjh
    ;;
 esac
@@ -1420,6 +1413,12 @@
    ac_file=Makefile . ${libgcj_basedir}/../config-ml.in
    ;;
 esac
+for ac_multi_file in $CONFIG_FILES; do
+  case $ac_multi_file in
+  */Makefile)
+    grep "^MULTI[[^ ]]* =" Makefile >> "$ac_multi_file" ;;
+  esac
+done
 ],
 srcdir=${srcdir}
 host=${host}
Index: libjava/prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.104.2.1
diff -u -r1.104.2.1 prims.cc
--- libjava/prims.cc 2 Apr 2005 02:30:39 -0000 1.104.2.1
+++ libjava/prims.cc 6 Apr 2005 21:18:14 -0000
@@ -59,10 +59,11 @@
 #include <java/io/PrintStream.h>
 #include <java/lang/UnsatisfiedLinkError.h>
 #include <java/lang/VirtualMachineError.h>
-#include <gnu/gcj/runtime/VMClassLoader.h>
+#include <gnu/gcj/runtime/ExtensionClassLoader.h>
 #include <gnu/gcj/runtime/FinalizerThread.h>
 #include <execution.h>
 #include <gnu/java/lang/MainThread.h>
+#include <java/lang/VMClassLoader.h>
 
 #ifdef USE_LTDL
 #include <ltdl.h>
@@ -1242,8 +1243,9 @@
   // of VMClassLoader.
   _Jv_InitClass (&java::lang::ClassLoader::class$);
 
-  // Set up the system class loader.
-  gnu::gcj::runtime::VMClassLoader::initialize();
+  // Set up the system class loader and the bootstrap class loader.
+  gnu::gcj::runtime::ExtensionClassLoader::initialize();
+  java::lang::VMClassLoader::initialize(JvNewStringLatin1(TOOLEXECLIBDIR));
 
   _Jv_RegisterBootstrapPackages();
 
@@ -1316,7 +1318,10 @@
       java::lang::System::err->println (JvNewStringLatin1 
         ("Exception during runtime initialization"));
       t->printStackTrace();
-      runtime->exit (1);
+      if (runtime)
+	runtime->exit (1);
+      // In case the runtime creation failed.
+      ::exit (1);
     }
 
   _Jv_AttachCurrentThread (main_thread);
Index: libjava/external/sax/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/external/sax/Makefile.am,v
retrieving revision 1.2
diff -u -r1.2 Makefile.am
--- libjava/external/sax/Makefile.am 10 Feb 2005 18:33:53 -0000 1.2
+++ libjava/external/sax/Makefile.am 6 Apr 2005 21:18:14 -0000
@@ -4,7 +4,7 @@
 
 ## The compiler with whatever flags we want for both -c and -C
 ## compiles.
-GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated -fbootclasspath=$(BOOTCLASSPATH)
+GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated -fclasspath= -fbootclasspath=$(BOOTCLASSPATH)
 
 BOOTCLASSPATH = $(here)'$(CLASSPATH_SEPARATOR)'$(srcdir)'$(CLASSPATH_SEPARATOR)'$(top_srcdir)'$(CLASSPATH_SEPARATOR)'$(top_builddir)
 
@@ -17,18 +17,24 @@
 
 BUILT_SOURCES = classes.stamp
 
-classes.stamp:	$(libsax_convenience_la_SOURCES)
+sax.jar: classes.stamp
+	find org -name '*.class' -print | $(ZIP) -cfME@ $@
+
+classes.stamp:	$(source_files)
 	here=`pwd`; cd $(srcdir); \
-	$(GCJ_WITH_FLAGS) -C -d $$here $(libsax_convenience_la_SOURCES)
+	$(GCJ_WITH_FLAGS) -C -d $$here $(source_files)
 	echo > classes.stamp
 
 mostlyclean-local:
 	-find . -name '*.class' | xargs rm
-	-rm classes.stamp
+	-rm classes.stamp sax.jar
+
+noinst_LTLIBRARIES = libsax-gcj.la
 
-noinst_LTLIBRARIES = libsax_convenience.la
+libsax_gcj_la_SOURCES =	sax.jar
+libsax_gcj_la_GCJFLAGS = -findirect-dispatch $(AM_GCJFLAGS)
 
-libsax_convenience_la_SOURCES =	\
+source_files = \
 org/xml/sax/SAXNotSupportedException.java \
 org/xml/sax/helpers/NamespaceSupport.java \
 org/xml/sax/helpers/AttributesImpl.java	\
Index: libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java,v
retrieving revision 1.1
diff -u -r1.1 NamespaceSupport.java
--- libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java 2 Feb 2005 00:41:54 -0000 1.1
+++ libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java 6 Apr 2005 21:18:14 -0000
@@ -2,7 +2,7 @@
 // http://www.saxproject.org
 // Written by David Megginson
 // This class is in the Public Domain.  NO WARRANTY!
-// $Id: NamespaceSupport.java,v 1.1 2005/02/02 00:41:54 tromey Exp $
+// $Id: NamespaceSupport.java,v 1.2 2005/03/24 00:04:07 tromey Exp $
 
 package org.xml.sax.helpers;
 
@@ -113,7 +113,8 @@
     /**
      * An empty enumeration.
      */
-    private final static Enumeration EMPTY_ENUMERATION =
+    // GCJ LOCAL: work around gcj bug by making this package-private
+    final static Enumeration EMPTY_ENUMERATION =
 	new Vector().elements();
 
 
Index: libjava/external/w3c_dom/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/external/w3c_dom/Makefile.am,v
retrieving revision 1.2
diff -u -r1.2 Makefile.am
--- libjava/external/w3c_dom/Makefile.am 10 Feb 2005 18:33:54 -0000 1.2
+++ libjava/external/w3c_dom/Makefile.am 6 Apr 2005 21:18:14 -0000
@@ -4,7 +4,7 @@
 
 ## The compiler with whatever flags we want for both -c and -C
 ## compiles.
-GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated -fbootclasspath=$(BOOTCLASSPATH)
+GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated -fclasspath= -fbootclasspath=$(BOOTCLASSPATH)
 
 BOOTCLASSPATH = $(here)'$(CLASSPATH_SEPARATOR)'$(srcdir)'$(CLASSPATH_SEPARATOR)'$(top_srcdir)'$(CLASSPATH_SEPARATOR)'$(top_builddir)
 
@@ -17,18 +17,24 @@
 
 BUILT_SOURCES = classes.stamp
 
-classes.stamp:	$(libw3c_convenience_la_SOURCES)
+w3c.jar: classes.stamp
+	find org -name '*.class' -print | $(ZIP) -cfME@ $@
+
+classes.stamp:	$(source_files)
 	here=`pwd`; cd $(srcdir); \
-	$(GCJ_WITH_FLAGS) -C -d $$here $(libw3c_convenience_la_SOURCES)
+	$(GCJ_WITH_FLAGS) -C -d $$here $(source_files)
 	echo > classes.stamp
 
 mostlyclean-local:
 	-find . -name '*.class' | xargs rm
-	-rm classes.stamp
+	-rm classes.stamp w3c.jar
+
+noinst_LTLIBRARIES = libw3c-gcj.la
 
-noinst_LTLIBRARIES = libw3c_convenience.la
+libw3c_gcj_la_SOURCES =	w3c.jar
+libw3c_gcj_la_GCJFLAGS = -findirect-dispatch $(AM_GCJFLAGS)
 
-libw3c_convenience_la_SOURCES =	\
+source_files = \
 org/w3c/dom/xpath/XPathNamespace.java \
 org/w3c/dom/xpath/XPathResult.java \
 org/w3c/dom/xpath/XPathException.java \
Index: libjava/gnu/gcj/runtime/BootClassLoader.java
===================================================================
RCS file: libjava/gnu/gcj/runtime/BootClassLoader.java
diff -N libjava/gnu/gcj/runtime/BootClassLoader.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/gnu/gcj/runtime/BootClassLoader.java 6 Apr 2005 21:18:14 -0000
@@ -0,0 +1,71 @@
+/* Copyright (C) 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.runtime;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+/**
+ * This is a helper for the bootstrap class loader.  It is a
+ * URLClassLoader so that we can read a class path and re-use all the
+ * existing code for finding classes, extracting them from jars, etc.
+ * However, it is never called the way that an ordinary ClassLoader is
+ * called.  For instance, loadClass() is never used.
+ */
+public final class BootClassLoader extends HelperClassLoader
+{
+  BootClassLoader(String libdir)
+  {
+    addDirectoriesFromProperty("java.endorsed.dirs");
+    addDirectoriesFromProperty("gnu.gcj.runtime.endorsed.dirs");
+
+    try
+      {
+	// Add core:/ to the end so any resources compiled into this
+	// executable may be found.
+	addURL(new URL("core", "", -1, "/"));
+      }
+    catch (java.net.MalformedURLException x)
+      {
+	// This should never happen.
+	throw new RuntimeException(x);
+      }
+  }
+
+  public Class bootLoadClass(String name)
+    throws ClassNotFoundException
+  {
+    Class c = findLoadedClass(name);
+    if (c == null)
+      {
+	try
+	  {
+	    // We could hack URLClassLoader to make this more
+	    // efficient, if it mattered.
+	    c = findClass(name);
+	  }
+	catch (ClassNotFoundException _)
+	  {
+	    c = null;
+	  }
+      }
+    return c;
+  }
+
+  public URL bootGetResource(String name)
+  {
+    return findResource(name);
+  }
+
+  public Enumeration bootGetResources(String name) throws IOException
+  {
+    return findResources(name);
+  }
+}
Index: libjava/gnu/gcj/runtime/ExtensionClassLoader.java
===================================================================
RCS file: libjava/gnu/gcj/runtime/ExtensionClassLoader.java
diff -N libjava/gnu/gcj/runtime/ExtensionClassLoader.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/gnu/gcj/runtime/ExtensionClassLoader.java 6 Apr 2005 21:18:14 -0000
@@ -0,0 +1,40 @@
+/* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org>  */
+
+package gnu.gcj.runtime;
+
+import java.net.URL;
+
+// The extension loader for libgcj.  Class loader bootstrap is a bit
+// tricky, see prims.cc and SystemClassLoader for some details.
+public final class ExtensionClassLoader extends HelperClassLoader
+{
+  private ExtensionClassLoader ()
+  {	
+  }
+
+  private void init() 
+  {
+    addDirectoriesFromProperty("java.ext.dirs");
+  }
+
+  // This can be package-private because we only call it from native
+  // code during startup.
+  static void initialize ()
+  {
+    instance.init();
+    system_instance.init();
+  }
+
+  // The only ExtensionClassLoader that can exist.
+  static ExtensionClassLoader instance = new ExtensionClassLoader();
+  // The system class loader.
+  static SystemClassLoader system_instance = new SystemClassLoader(instance);
+}
Index: libjava/gnu/gcj/runtime/HelperClassLoader.java
===================================================================
RCS file: libjava/gnu/gcj/runtime/HelperClassLoader.java
diff -N libjava/gnu/gcj/runtime/HelperClassLoader.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/gnu/gcj/runtime/HelperClassLoader.java 6 Apr 2005 21:18:14 -0000
@@ -0,0 +1,67 @@
+/* Copyright (C) 2005  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.runtime;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.StringTokenizer;
+
+/**
+ * This is a URLClassLoader that has an extra helper method for
+ * handling things like java.ext.dirs.
+ */
+class HelperClassLoader extends URLClassLoader
+{
+  HelperClassLoader()
+  {
+    super(new URL[0]);
+  }
+
+  /**
+   * This is a helper method that adds all the jar and zip files from
+   * a given list of paths to this class loader.  The paths are taken
+   * from a system property whose name is provided as an argument.
+   */
+  final void addDirectoriesFromProperty(String propName)
+  {
+    StringTokenizer st
+      = new StringTokenizer (System.getProperty (propName, ""),
+			     File.pathSeparator);
+    try
+      {
+	while (st.hasMoreElements ())
+	  {
+	    String dirname = st.nextToken ();
+	    File dir = new File (dirname);
+            if (dir.exists ())
+	      {
+		if (! dirname.endsWith (File.separator))
+		  dirname = dirname + File.separator;
+		String files[] = dir.list (new FilenameFilter ()
+		  {
+		    public boolean accept (File dir, String name)
+		    {
+		      return name.endsWith (".jar") || name.endsWith (".zip");
+		    }
+		  });
+		for (int i = files.length - 1; i >= 0; i--)
+		  addURL(new URL("file", "", -1, dirname + files[i]));
+	      }
+	  }
+      }
+    catch (java.net.MalformedURLException x)
+      {
+	// This should never happen.
+	throw new RuntimeException(x);
+      }
+  }
+}
Index: libjava/gnu/gcj/runtime/VMClassLoader.java
===================================================================
RCS file: libjava/gnu/gcj/runtime/VMClassLoader.java
diff -N libjava/gnu/gcj/runtime/VMClassLoader.java
--- libjava/gnu/gcj/runtime/VMClassLoader.java 2 Feb 2005 20:59:40 -0000 1.18
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,135 +0,0 @@
-/* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005  Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-/* Author: Kresten Krab Thorup <krab@gnu.org>  */
-
-package gnu.gcj.runtime;
-
-import java.io.*;
-import java.util.StringTokenizer;
-import java.util.HashSet;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-// Despite its name, this class is really the extension loader for
-// libgcj.  Class loader bootstrap is a bit tricky, see prims.cc and
-// SystemClassLoader for some details.
-public final class VMClassLoader extends URLClassLoader
-{
-  private VMClassLoader ()
-  {	
-    super (new URL[0]);
-    String p
-      = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
-			    "");
-    if ("never".equals(p))
-      lib_control = LIB_NEVER;
-    else if ("cache".equals(p))
-      lib_control = LIB_CACHE;
-    else if ("full".equals(p))
-      lib_control = LIB_FULL;
-    else
-      lib_control = LIB_CACHE;
-  }
-
-  private void init() 
-  {
-    // Add the contents of the extensions directories.  
-    StringTokenizer st
-      = new StringTokenizer (System.getProperty ("java.ext.dirs"),
-			     File.pathSeparator);
-
-    try
-      {
-	while (st.hasMoreElements ())
-	  {
-	    String dirname = st.nextToken ();
-	    File dir = new File (dirname);
-            if (dir.exists ())
-            {
-              if (! dirname.endsWith (File.separator))
-        	  dirname = dirname + File.separator;
-              String files[] 
-        	= dir.list (new FilenameFilter ()
-                            { 
-                              public boolean accept (File dir, String name)
-                              {
-                        	return (name.endsWith (".jar") 
-                                	|| name.endsWith (".zip"));
-                              }
-                            });
-              for (int i = files.length - 1; i >= 0; i--)
-        	addURL(new URL("file", "", -1, dirname + files[i]));
-            }
-	  }
-
-	// Add core:/ to the end so any resources compiled into this
-	// executable may be found.
-	addURL(new URL("core", "", -1, "/"));
-      }
-    catch (java.net.MalformedURLException x)
-      {
-	// This should never happen.
-	throw new RuntimeException(x);
-      }
-  }
-
-  /** This is overridden to search the internal hash table, which 
-   * will only search existing linked-in classes.   This will make
-   * the default implementation of loadClass (in ClassLoader) work right.
-   * The implementation of this method is in
-   * gnu/gcj/runtime/natVMClassLoader.cc.
-   */
-  protected native Class findClass(String name) 
-    throws java.lang.ClassNotFoundException;
-
-  // This can be package-private because we only call it from native
-  // code during startup.
-  static void initialize ()
-  {
-    instance.init();
-    system_instance.init();
-  }
-
-  // Define a package for something loaded natively.
-  void definePackageForNative(String className)
-  {
-    int lastDot = className.lastIndexOf('.');
-    if (lastDot != -1)
-      {
-	String packageName = className.substring(0, lastDot);
-	if (getPackage(packageName) == null)
-	  {
-	    // FIXME: this assumes we're defining the core, which
-	    // isn't necessarily so.  We could detect this and set up
-	    // appropriately.  We could also look at a manifest file
-	    // compiled into the .so.
-	    definePackage(packageName, "Java Platform API Specification",
-			  "GNU", "1.4", "gcj", "GNU",
-			  null, // FIXME: gcj version.
-			  null);
-	  }
-      }
-  }
-
-  // This keeps track of shared libraries we've already tried to load.
-  private HashSet tried_libraries = new HashSet();
-
-  // Holds one of the LIB_* constants; used to determine how shared
-  // library loads are done.
-  private int lib_control;
-
-  // The only VMClassLoader that can exist.
-  static VMClassLoader instance = new VMClassLoader();
-  // The system class loader.
-  static SystemClassLoader system_instance = new SystemClassLoader(instance);
-
-  private static final int LIB_FULL = 0;
-  private static final int LIB_CACHE = 1;
-  private static final int LIB_NEVER = 2;
-}
Index: libjava/gnu/gcj/runtime/natVMClassLoader.cc
===================================================================
RCS file: libjava/gnu/gcj/runtime/natVMClassLoader.cc
diff -N libjava/gnu/gcj/runtime/natVMClassLoader.cc
--- libjava/gnu/gcj/runtime/natVMClassLoader.cc 10 Jan 2005 19:39:25 -0000 1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,79 +0,0 @@
-// Native code for VMClassLoader
-
-/* Copyright (C) 2002, 2003, 2005  Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-#include <config.h>
-
-#include <gcj/cni.h>
-#include <jvm.h>
-
-#include <gnu/gcj/runtime/VMClassLoader.h>
-#include <java/lang/Class.h>
-#include <java/lang/StringBuffer.h>
-#include <java/net/URLClassLoader.h>
-#include <java/lang/Runtime.h>
-#include <java/util/HashSet.h>
-
-jclass
-gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
-{
-  _Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
-  jclass klass = _Jv_FindClassInCache (name_u);
-
-  if (! klass && lib_control != LIB_NEVER)
-    {
-      // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'.  Then search for
-      // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
-      // by `lib-gnu-pkg.so' and `lib-gnu.so'.  If loading one of
-      // these causes the class to appear in the cache, then use it.
-      java::lang::StringBuffer *sb = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
-      // Skip inner classes
-      jstring cn;
-      jint ci = name->indexOf('$');
-      if (ci == -1)
-	cn = name;
-      else
-	cn = name->substring (0, ci);
-      jstring so_base_name = (sb->append (cn)->toString ())->replace ('.', '-');
-
-      using namespace ::java::lang;
-      Runtime *rt = Runtime::getRuntime();
-
-      // Compare against `3' because that is the length of "lib".
-      while (! klass && so_base_name && so_base_name->length() > 3)
-	{
-	  if (lib_control == LIB_CACHE)
-	    {
-	      // If we've already tried this name, we're done.
-	      if (tried_libraries->contains(so_base_name))
-		break;
-	      tried_libraries->add(so_base_name);
-	    }
-
-	  jboolean loaded = rt->loadLibraryInternal (so_base_name);
-
-	  jint nd = so_base_name->lastIndexOf ('-');
-	  if (nd == -1)
-	    so_base_name = NULL;
-	  else
-	    so_base_name = so_base_name->substring (0, nd);
-
-	  if (loaded)
-	    klass = _Jv_FindClassInCache (name_u);
-	}
-    }
-
-  // Either define the package, or try loading using the interpreter.
-  if (klass)
-    definePackageForNative(name);
-  else
-    klass = java::net::URLClassLoader::findClass (name);
-
-  return klass;
-}
Index: libjava/java/lang/VMClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/VMClassLoader.java,v
retrieving revision 1.13
diff -u -r1.13 VMClassLoader.java
--- libjava/java/lang/VMClassLoader.java 2 Feb 2005 20:59:40 -0000 1.13
+++ libjava/java/lang/VMClassLoader.java 6 Apr 2005 21:18:20 -0000
@@ -51,8 +51,10 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.StringTokenizer;
+import gnu.gcj.runtime.BootClassLoader;
 
 /**
  * java.lang.VMClassLoader is a package-private helper for VMs to implement
@@ -82,6 +84,21 @@
 
   static final HashMap definedPackages = new HashMap();
 
+  // This is a helper for handling java.endorsed.dirs.  It is null
+  // until we've initialized the system, at which point it is created.
+  static BootClassLoader bootLoader;
+
+  // This keeps track of shared libraries we've already tried to load.
+  private static HashSet tried_libraries;
+
+  // Holds one of the LIB_* constants; used to determine how shared
+  // library loads are done.
+  private static int lib_control;
+
+  private static final int LIB_FULL = 0;
+  private static final int LIB_CACHE = 1;
+  private static final int LIB_NEVER = 2;
+
   /**
    * Helper to define a class using a string of bytes. This assumes that
    * the security checks have already been performed, if necessary.
@@ -153,6 +170,8 @@
    */
   static URL getResource(String name)
   {
+    if (bootLoader != null)
+      return bootLoader.bootGetResource(name);
     return null;
   }
 
@@ -168,6 +187,8 @@
    */
   static Enumeration getResources(String name) throws IOException
   {
+    if (bootLoader != null)
+      return bootLoader.bootGetResources(name);
     return EmptyEnumeration.getInstance();
   }
 
@@ -287,6 +308,32 @@
 
   static native ClassLoader getSystemClassLoaderInternal();
 
+  static native void initBootLoader(String libdir);
+
+  static void initialize(String libdir)
+  {
+    initBootLoader(libdir);
+
+    String p
+      = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
+			    "");
+    if ("never".equals(p))
+      lib_control = LIB_NEVER;
+    else if ("cache".equals(p))
+      lib_control = LIB_CACHE;
+    else if ("full".equals(p))
+      lib_control = LIB_FULL;
+    else
+      lib_control = LIB_CACHE;
+
+    tried_libraries = new HashSet();
+  }
+
+  /**
+   * Possibly load a .so and search it for classes.
+   */
+  static native Class nativeFindClass(String name);
+
   static ClassLoader getSystemClassLoader()
   {
     // This method is called as the initialization of systemClassLoader,
@@ -304,14 +351,13 @@
 	    default_sys
 	      = (ClassLoader) c.newInstance(new Object[] { default_sys });
 	  }
-	catch (Exception e)
+	catch (Exception ex)
 	  {
-	    System.err.println("Requested system classloader "
-			       + loader + " failed, using "
-			       + "gnu.gcj.runtime.VMClassLoader");
-	    e.printStackTrace();
+	    throw new Error("Failed to load requested system classloader "
+			       + loader, ex);
 	  }
       }
+
     return default_sys;
   }
 }
Index: libjava/java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.76.6.1
diff -u -r1.76.6.1 natClassLoader.cc
--- libjava/java/lang/natClassLoader.cc 9 Mar 2005 20:59:04 -0000 1.76.6.1
+++ libjava/java/lang/natClassLoader.cc 6 Apr 2005 21:18:20 -0000
@@ -26,7 +26,6 @@
 #include <java/lang/Character.h>
 #include <java/lang/Thread.h>
 #include <java/lang/ClassLoader.h>
-#include <gnu/gcj/runtime/VMClassLoader.h>
 #include <java/lang/InternalError.h>
 #include <java/lang/IllegalAccessError.h>
 #include <java/lang/LinkageError.h>
@@ -43,6 +42,7 @@
 #include <java/io/Serializable.h>
 #include <java/lang/Cloneable.h>
 #include <java/util/HashMap.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
 
 // Size of local hash table.
 #define HASH_LEN 1013
@@ -106,7 +106,7 @@
 _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
 {
   if (! loader)
-    loader = java::lang::ClassLoader::systemClassLoader;
+    loader = java::lang::VMClassLoader::bootLoader;
   loader->loadedClasses->put(klass->name->toString(), klass);
 }
 
@@ -116,7 +116,7 @@
 _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
 {
   if (! loader)
-    loader = java::lang::ClassLoader::systemClassLoader;
+    loader = java::lang::VMClassLoader::bootLoader;
   loader->loadedClasses->remove(klass->name->toString());
 }
 
@@ -211,35 +211,37 @@
   // See if the class was already loaded by this loader.  This handles
   // initiating loader checks, as we register classes with their
   // initiating loaders.
-  java::lang::ClassLoader *sys = java::lang::ClassLoader::systemClassLoader;
+
+  java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
   java::lang::ClassLoader *real = loader;
   if (! real)
-    real = sys;
+    real = boot;
   jstring sname = name->toString();
   // We might still be bootstrapping the VM, in which case there
-  // won't be a system class loader yet.
+  // won't be a bootstrap class loader yet.
   jclass klass = real ? real->findLoadedClass (sname) : NULL;
 
   if (! klass)
     {
       if (loader)
 	{
-	  // Load using a user-defined loader, jvmspec 5.3.2
-	  klass = loader->loadClass(sname, false);
+	  // Load using a user-defined loader, jvmspec 5.3.2.
+	  // Note that we explicitly must call the single-argument form.
+	  klass = loader->loadClass(sname);
 
 	  // If "loader" delegated the loadClass operation to another
 	  // loader, explicitly register that it is also an initiating
 	  // loader of the given class.
-	  java::lang::ClassLoader *delegate = (loader == sys
+	  java::lang::ClassLoader *delegate = (loader == boot
 					       ? NULL
 					       : loader);
 	  if (klass && klass->getClassLoaderInternal () != delegate)
 	    _Jv_RegisterInitiatingLoader (klass, loader);
 	}
-      else if (sys)
+      else if (boot)
 	{
 	  // Load using the bootstrap loader jvmspec 5.3.1.
-	  klass = sys->loadClass (sname, false); 
+	  klass = java::lang::VMClassLoader::loadClass (sname, false); 
 
 	  // Register that we're an initiating loader.
 	  if (klass)
@@ -250,15 +252,30 @@
 	  // Not even a bootstrap loader, try the built-in cache.
 	  klass = _Jv_FindClassInCache (name);
 
-	  if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
-	    abort ();
-	  bootstrap_class_list[bootstrap_index++] = klass;
+	  if (klass)
+	    {
+	      bool found = false;
+	      for (int i = 0; i < bootstrap_index; ++i)
+		{
+		  if (bootstrap_class_list[i] == klass)
+		    {
+		      found = true;
+		      break;
+		    }
+		}
+	      if (! found)
+		{
+		  if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
+		    abort ();
+		  bootstrap_class_list[bootstrap_index++] = klass;
+		}
+	    }
 	}
     }
   else
     {
-      // we need classes to be in the hash while
-      // we're loading, so that they can refer to themselves. 
+      // We need classes to be in the hash while we're loading, so
+      // that they can refer to themselves.
       _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
     }
 
Index: libjava/java/lang/natRuntime.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natRuntime.cc,v
retrieving revision 1.47.2.4
diff -u -r1.47.2.4 natRuntime.cc
--- libjava/java/lang/natRuntime.cc 6 Apr 2005 03:43:58 -0000 1.47.2.4
+++ libjava/java/lang/natRuntime.cc 6 Apr 2005 21:18:20 -0000
@@ -550,6 +550,11 @@
   // The java extensions directory.
   SET ("java.ext.dirs", JAVA_EXT_DIRS);
 
+  // The endorsed directories that libgcj knows about by default.
+  // This is a way to get other jars into the boot class loader
+  // without overriding java.endorsed.dirs.
+  SET ("gnu.gcj.runtime.endorsed.dirs", GCJ_ENDORSED_DIRS);
+
   // The path to libgcj's boot classes
   SET ("sun.boot.class.path", BOOT_CLASS_PATH);
 
Index: libjava/java/lang/natVMClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natVMClassLoader.cc,v
retrieving revision 1.6.8.1
diff -u -r1.6.8.1 natVMClassLoader.cc
--- libjava/java/lang/natVMClassLoader.cc 9 Mar 2005 20:59:04 -0000 1.6.8.1
+++ libjava/java/lang/natVMClassLoader.cc 6 Apr 2005 21:18:20 -0000
@@ -23,13 +23,17 @@
 
 #include <java/lang/VMClassLoader.h>
 #include <java/lang/VMCompiler.h>
-#include <gnu/gcj/runtime/VMClassLoader.h>
+#include <gnu/gcj/runtime/ExtensionClassLoader.h>
 #include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
 #include <java/lang/ClassLoader.h>
 #include <java/lang/Class.h>
 #include <java/lang/Throwable.h>
 #include <java/security/ProtectionDomain.h>
 #include <java/lang/ClassFormatError.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Runtime.h>
+#include <java/util/HashSet.h>
 
 void
 java::lang::VMClassLoader::resolveClass (jclass klass)
@@ -66,9 +70,9 @@
       // until we're done loading.
       JvSynchronize sync (klass);
 
-      // Record the defining loader.  For the system class loader, we
-      // record NULL.
-      if (loader != java::lang::ClassLoader::systemClassLoader)
+      // Record the defining loader.  For the bootstrap class loader,
+      // we record NULL.
+      if (loader != bootLoader)
 	klass->loader = loader;
 
       if (name != 0)
@@ -109,8 +113,8 @@
 java::lang::ClassLoader *
 java::lang::VMClassLoader::getSystemClassLoaderInternal()
 {
-  _Jv_InitClass (&gnu::gcj::runtime::VMClassLoader::class$);
-  return gnu::gcj::runtime::VMClassLoader::system_instance;
+  _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
+  return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
 }
 
 jclass
@@ -119,14 +123,93 @@
   char sig[2];
   sig[0] = (char) type;
   sig[1] = '\0';
+  // Note: this cannot return NULL, since the input is always correct.
   return _Jv_FindClassFromSignature (sig, NULL);
 }
 
+void
+java::lang::VMClassLoader::initBootLoader(jstring libdir)
+{
+  bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
+}
+
+jclass
+java::lang::VMClassLoader::nativeFindClass (jstring name)
+{
+  jclass klass = NULL;
+
+  if (lib_control != LIB_NEVER)
+    {
+      // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'.  Then search for
+      // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
+      // by `lib-gnu-pkg.so' and `lib-gnu.so'.  If loading one of
+      // these causes the class to appear in the cache, then use it.
+      java::lang::StringBuffer *sb
+	= new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
+      // Skip inner classes
+      jstring cn;
+      jint ci = name->indexOf('$');
+      if (ci == -1)
+	cn = name;
+      else
+	cn = name->substring (0, ci);
+      jstring so_base_name
+	= (sb->append (cn)->toString ())->replace ('.', '-');
+
+      using namespace ::java::lang;
+      Runtime *rt = Runtime::getRuntime();
+
+      _Jv_Utf8Const *name_u = NULL;
+
+      // Compare against `3' because that is the length of "lib".
+      while (! klass && so_base_name && so_base_name->length() > 3)
+	{
+	  if (lib_control == LIB_CACHE)
+	    {
+	      // If we've already tried this name, we're done.
+	      if (tried_libraries->contains(so_base_name))
+		break;
+	      tried_libraries->add(so_base_name);
+	    }
+
+	  jboolean loaded = rt->loadLibraryInternal (so_base_name);
+
+	  jint nd = so_base_name->lastIndexOf ('-');
+	  if (nd == -1)
+	    so_base_name = NULL;
+	  else
+	    so_base_name = so_base_name->substring (0, nd);
+
+	  if (loaded)
+	    {
+	      if (name_u == NULL)
+		name_u = _Jv_makeUtf8Const (name);
+	      klass = _Jv_FindClassInCache (name_u);
+	    }
+	}
+    }
+
+  if (klass)
+    definePackageForNative(name);
+
+  return klass;
+}
+
 jclass
 java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
 {
-  _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
-  jclass klass = _Jv_FindClassInCache (utf);
+  // We try the boot loader first, so that the endorsed directory
+  // overrides compiled-in classes.
+  jclass klass = NULL;
+  if (bootLoader)
+    klass = bootLoader->bootLoadClass(name);
+  if (! klass)
+    {
+      _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
+      klass = _Jv_FindClassInCache (utf);
+    }
+  if (! klass)
+    klass = nativeFindClass(name);
   if (klass)
     {
       // We never want to return a class without its supers linked.



More information about the Java-patches mailing list