Re: RFC: VMClassLoader changes proposition

2006-03-14 Thread Nicolas Geoffray

Hi Olivier,

Olivier Jolly wrote:


Hi,
 it seems to me that there is a missing/incomplete feature in the
VMClassLoader.
 For now, the vm implementation are not encouraged, helped nor told to
define packages in which classes are loaded from when the boot class
loader is defining them. Notably, this makes such that java.lang package
is not defined (i.e. basically getPackage on the VMClassLoader for
java.lang is null)
 


Well the actual comment on the getBootPackages method are
/**
  * Returns a String[] of native package names. The default
  * implementation returns an empty array, or you may decide
  * this needs native help.
  */

So if the VM implementer decides that he wants to return the strings
of all gnu-classpath + vm-specific packages, he has to redefine 
getBootPackages.

We could force getBootPackages to be native though.


 I spent my week end trying to hack cacao to call a new VMClassLoader
method (definePackageIfNeeded) in the native implementation of
VMClassLoader.loadClass. I had to skip this call when the loaded class
was coming from java.lang.** since the definePackageIfNeeded was using
java.lang.** classes and we would run into an infinite loop else. The
definePackageIfNeeded is taking a class name as parameter and extract
the package name and then defines the package using default values for
vendor and such (like the reference clinit of VMClassLoader) if it's
not defined yet.
 Since java.lang.** packages can not be defined by this method, I
overrided the getBootPackages reference method to return the
java.lang.** packages (which are then defined by the clinit)
 Please find attached the hack I did on my environment (which I do not
consider to be usable but a working proof of concept) as a support of my
explanations.

 

This looks complex compared to the (native - should be) getBootPackages 
method.

Maybe I'm missing something, but all of this can be solved by implementing
the getBootPackages on the VM side.

Best,
Nicolas




RFC: VMClassLoader changes proposition

2006-03-13 Thread Olivier Jolly
Hi,
  it seems to me that there is a missing/incomplete feature in the
VMClassLoader.
  For now, the vm implementation are not encouraged, helped nor told to
define packages in which classes are loaded from when the boot class
loader is defining them. Notably, this makes such that java.lang package
is not defined (i.e. basically getPackage on the VMClassLoader for
java.lang is null)
  I spent my week end trying to hack cacao to call a new VMClassLoader
method (definePackageIfNeeded) in the native implementation of
VMClassLoader.loadClass. I had to skip this call when the loaded class
was coming from java.lang.** since the definePackageIfNeeded was using
java.lang.** classes and we would run into an infinite loop else. The
definePackageIfNeeded is taking a class name as parameter and extract
the package name and then defines the package using default values for
vendor and such (like the reference clinit of VMClassLoader) if it's
not defined yet.
  Since java.lang.** packages can not be defined by this method, I
overrided the getBootPackages reference method to return the
java.lang.** packages (which are then defined by the clinit)
  Please find attached the hack I did on my environment (which I do not
consider to be usable but a working proof of concept) as a support of my
explanations.

  So basically, I'm asking about your thought on how to make the boot
class loader (which is out of range of classpath) defines packages as it
load classes.
  TIA, cheers

+Olivier

P.S: the signature of definePackageIfNeeded is a String[] instead of a
String because I did not manage to call the String version from cacao
code, but it should be a simple String.
Index: src/native/vm/VMClassLoader.c
===
--- src/native/vm/VMClassLoader.c	(révision 4586)
+++ src/native/vm/VMClassLoader.c	(copie de travail)
@@ -259,12 +259,45 @@
 {
 	classinfo *c;
 	utf *u;
-
+	methodinfo *m;
+	classinfo *vmclclass;
+	char askedname[1024];
+	int i = 0;
+	java_objectarray *oa; 	
+	
 	if (!name) {
 		exceptions_throw_nullpointerexception();
 		return NULL;
 	}
 
+	m = NULL;
+
+	vmclclass = NULL;
+
+	for (i = 0; i  name-value-header.size; i++) {
+		askedname[i] = name-value-data[i];
+	}
+	askedname[i] = '\0';
+
+	fprintf(stderr,   - calling loadClass on %s  -\n, askedname);
+	fflush(stderr);
+
+	oa = builtin_anewarray(1, class_java_lang_String);
+	oa-data[0] = (java_objectheader *) javastring_new(utf_new_char(askedname));
+
+	if (strncmp(askedname, java.lang., 10))
+		vmclclass = load_class_from_sysloader(utf_new_char(java.lang.VMClassLoader));
+
+	if (vmclclass) {
+		fprintf(stderr, Found VMClassLoader class\n);
+		fflush(stderr);
+		m = class_resolveclassmethod(vmclclass,
+ utf_new_char(definePackageIfNotDefined),  	   
+ utf_new_char(([Ljava/lang/String;)V),
+ class_java_lang_Object,
+ false);
+	}
+
 	/* create utf string in which '.' is replaced by '/' */
 
 	u = javastring_toutf(name, true);
@@ -274,6 +307,11 @@
 	if (!(c = load_class_bootstrap(u)))
 		goto exception;
 
+	if (m) {
+		fprintf(stderr, Calling definePackageIfNotDefined for %s\n, askedname);
+		fflush(stderr);
+		vm_call_method(m, NULL, oa);
+	}
 	/* resolve class -- if requested */
 	/* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
 /*  	if (resolve) { */
Index: src/lib/vm/reference/java/lang/VMClassLoader.java
===
--- src/lib/vm/reference/java/lang/VMClassLoader.java	(révision 4586)
+++ src/lib/vm/reference/java/lang/VMClassLoader.java	(copie de travail)
@@ -259,7 +259,7 @@
*/
   private static String[] getBootPackages()
   {
-return new String[0];
+return new String[] {java.lang, java.lang.ref, java.lang.reflect};
   }
 
 
@@ -405,4 +405,35 @@
 return defineClass(loader, name, data, offset, len, pd);
 //}
   }
+  
+  static final void definePackageIfNotDefined(String[] classNameArray) {
+	  System.err.println(called definePackageIfNotDefined with an array of size  + classNameArray.length);
+	  	for (int i = 0; i  classNameArray.length; i++) {
+			String className = classNameArray[i];
+			int lastDot = className.lastIndexOf('.');
+			System.err.println(called definePackageIfNotDefined for 
+	+ className + , [ // + className.length()
+	+ ] lastDot =  + lastDot);
+			if (lastDot != -1  className.length()  0) {
+String packageName = className.substring(0, lastDot);
+// Look if the package already exists
+if (getPackage(packageName) == null) {
+	String specName = SystemProperties
+			.getProperty(java.specification.name);
+	String vendor = SystemProperties
+			.getProperty(java.specification.vendor);
+	String version = SystemProperties
+			.getProperty(java.specification.version);
+
+	Package p;
+
+	p = new Package(packageName, specName, vendor, version,
+			GNU Classpath, GNU,
+			

Re: RFC: VMClassLoader changes proposition

2006-03-13 Thread Archie Cobbs

Olivier Jolly wrote:

  So basically, I'm asking about your thought on how to make the boot
class loader (which is out of range of classpath) defines packages as it
load classes.


JCVM doesn't have any support for Packages, so any general-use code
that gets added to Classpath and can save me work has my vote :-)

-Archie

__
Archie Cobbs  *CTO, Awarix*  http://www.awarix.com