ReflectiveEnvironmnt#isPackage() now consult a list of classes loaded by given ClassLoader.
This is not only faster than searcing the filesystem, but also works with classes that have
been generated and loaded on the fly (such as those 'accepted' in a browser)
--- a/tools/java/src/stx/libjava/tools/environment/ReflectiveEnvironment.java Sun Jul 20 02:41:14 2014 +0100
+++ b/tools/java/src/stx/libjava/tools/environment/ReflectiveEnvironment.java Sun Jul 20 21:46:44 2014 +0100
@@ -26,6 +26,7 @@
public class ReflectiveEnvironment implements INameEnvironment {
private static final boolean DEBUG_isPackage = false;
+ private static Field FIELD_ClassLoader_Classes;
/**
* A java.lang.ClassLoader where to search for classes & packages
@@ -39,6 +40,16 @@
public TypeRegistry types;
+ static {
+ try {
+ FIELD_ClassLoader_Classes = ClassLoader.class.getDeclaredField("classes");
+ FIELD_ClassLoader_Classes.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ FIELD_ClassLoader_Classes = null;
+ } catch (SecurityException e) {
+ FIELD_ClassLoader_Classes = null;
+ }
+ }
public ReflectiveEnvironment() {
this(new TypeRegistry(), ClassLoader.getSystemClassLoader() );
@@ -174,10 +185,32 @@
* The default package is always assumed to exist.
*
*/
+ @SuppressWarnings("unchecked")
public boolean isPackage(String packageName, ClassLoader loader) {
if (loader == null) {
return isPackage(packageName, sun.misc.Launcher.getBootstrapClassPath().getURLs());
}
+ if (FIELD_ClassLoader_Classes != null) {
+ int packageNameLen = packageName.length();
+ Vector<Class<?>> classes;
+ try {
+ classes = (Vector<Class<?>>)FIELD_ClassLoader_Classes.get(loader);
+ Iterator<Class<?>> i = classes.iterator();
+ while (i.hasNext()) {
+ String className = i.next().getName();
+ int classNameLen = className.length();
+ if ((classNameLen > packageNameLen) &&
+ (className.charAt(packageNameLen) == '.') &&
+ (className.startsWith(packageName))) {
+ return true;
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ } catch (IllegalAccessException e) {
+ }
+ }
+
+
if (loader instanceof URLClassLoader) {
if (isPackage(packageName, ((URLClassLoader)loader).getURLs())) {
return true;