So running classlib tests w/ DRLVM w/ the change to URLClassloader
works *except* I have one consistent problem. I get 68 errors, all
the same :
java.util.MissingResourceException: Could not load data
com.ibm.icu.impl.data.BreakIteratorRules
at com.ibm.icu.impl.ICULocaleData.instantiate(ICULocaleData.java:288)
at com.ibm.icu.impl.ICULocaleData.instantiate(ICULocaleData.java:231)
at com.ibm.icu.impl.ICULocaleData.instantiate(ICULocaleData.java:231)
at com.ibm.icu.impl.ICULocaleData.instantiate(ICULocaleData.java:300)
at com.ibm.icu.impl.ICULocaleData.getResourceBundle
(ICULocaleData.java:112)
at com.ibm.icu.impl.ICULocaleData.getResourceBundle
(ICULocaleData.java:94)
at com.ibm.icu.text.BreakIteratorFactory.createBreakInstance
(BreakIteratorFactory.java:123)
at com.ibm.icu.text.BreakIteratorFactory.createBreakInstance
(BreakIteratorFactory.java:112)
at com.ibm.icu.text.BreakIteratorFactory.createBreakIterator
(BreakIteratorFactory.java:65)
at com.ibm.icu.text.BreakIterator.getBreakInstance(BreakIterator.java:
715)
at com.ibm.icu.text.BreakIterator.getWordInstance(BreakIterator.java)
at com.ibm.icu.text.BreakIterator.getWordInstance(BreakIterator.java:
440)
at java.text.BreakIterator.getWordInstance(BreakIterator.java:209)
...
Now, we do hide the bootloader's "com.ibm.icu.", but I think all is
well there because it's only one single class we're having a problem
with. Does anyone have any insight why this one class is problematic?
The impl module comments for brevity here looks like this :
protected synchronized Class<?> loadClass(String className,
boolean resolveClass) throws ClassNotFoundException {
if (this == getSystemClassLoader()) {
int index = className.lastIndexOf('.');
if (index > 0) {
String pkgName = className.substring(0, index + 1);
if (pkgName.startsWith("java.") ||
pkgName.startsWith("javax.") ||
pkgName.startsWith("org.ietf.jgss.") ||
pkgName.startsWith("org.omg.") ||
pkgName.startsWith("org.w3c.") ||
pkgName.startsWith("org.xml.sax.")) {
return super.loadClass(className, resolveClass);
}
/* if we get this far, use list of verboten */
String[] verboten =
VMUtil.getAppDeniedSysloaderPackages();
for (String pkg : verboten) {
if (pkgName.startsWith(pkg)) {
throw new ClassNotFoundException();
}
}
}
}
return super.loadClass(className, resolveClass);
}
Where VMUtil.getAppDeniedSysloaderPackages() (a name I will change
before checkin) returns :
deniedList = {
"mx4j.",
"org.apache.bcel.",
"com.ibm.icu.",
"com.ibm.icu4jni",
"org.apache.xalan",
"org.apache.xml",
"org.apache.xpath"};
Thoughts?
geir
On Feb 8, 2007, at 12:25 AM, Geir Magnusson Jr. wrote:
So based on Tim's suggestion, I have something working. I'm
running full tests now, and if things are hunky, will commit w/
tests in the morning...
geir
On Feb 7, 2007, at 8:48 PM, Geir Magnusson Jr. wrote:
On Feb 7, 2007, at 11:24 AM, Glyn Normington wrote:
"Geir Magnusson Jr." <[EMAIL PROTECTED]> wrote on 07/02/2007 15:36:01:
>
> On Feb 7, 2007, at 7:56 AM, Tim Ellison wrote:
>
> >
> >
> > protected synchronized Class<?> loadClass(String className,
> > boolean resolveClass) throws ClassNotFoundException {
> >
> > if (this == getSystemClassLoader()) {
> > int index = className.lastIndexOf('.');
> > String pkgName = index > 0 ? className.substring(0,
> > index) : "";
> >
> > System.out.println("Checking visibility for " +
pkgName);
> > if (!pkgName.startsWith("java.") && !pkgName.startsWith
> > ("javax.")
> > && !pkgName.startsWith("org.ietf.jgss")
> > && !pkgName.startsWith("org.omg")
> > && !pkgName.startsWith("org.w3c.dom")
> > && !pkgName.startsWith("org.xml.sax")) {
> > throw new ClassNotFoundException(className);
> > }
> > }
> > return super.loadClass(className, resolveClass);
> > }
> >
>
> Revealing my ignorance about java classloading :
>
> Why wouldn't we need to care about the caller? (This is what
had me > going into the VM first...) What if loadClass() is
getting called by > an implementation class, which does need
access to the internal > packages that are prohibited for app
classes?
If the VM needs to resolve a reference from class A to class B,
it will call loadClass on the defining class loader of A. (The
defining class loader of A is the class loader whose defineClass
created class A. You can get the defining class loader of a class
via Class.getClassLoader, although the bootstrap class loader is
represented as null.)
This I knew :)
Back to your questions. An implementation class will have been
defined by the bootstrap class loader so if it needs to reference
other classes, the VM will resolve those references using the
bootstrap class loader. so you don't need to worry about the
caller as the application class loader (AKA the system class
loader) won't get a look in when implementation classes are being
resolved.
Yes, this solves my confusion. I was getting confused by the sys
loader vs the boot loader.
Thanks, Glyn. Good to see you around here :)
geir
Glyn
PS. I subscribed to this list earlier in order to post. But my
post didn't get sent back to me and I'm not using gmail.