conor 01/02/03 18:34:28
Modified: src/main/org/apache/tools/ant AntClassLoader.java
Log:
Fixes to AntClassLoader.
Changes AntClassLoader so it does not use the primordial class
loader for system classes. This is needed when the classloader itself was not
loaded with the primordial loader.
Submitted by: Jesse Glick <[EMAIL PROTECTED]>Reviewed by:
Revision Changes Path
1.14 +58 -7
jakarta-ant/src/main/org/apache/tools/ant/AntClassLoader.java
Index: AntClassLoader.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/AntClassLoader.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- AntClassLoader.java 2001/01/19 13:27:00 1.13
+++ AntClassLoader.java 2001/02/04 02:34:28 1.14
@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,7 @@
package org.apache.tools.ant;
+import java.lang.reflect.*;
import java.util.*;
import java.util.zip.*;
import java.io.*;
@@ -65,7 +66,8 @@
* system classpath by using the forceLoadClass method. Any subsequent
classes loaded by that
* class will then use this loader rather than the system class loader.
*
- * @author Conor MacNeill
+ * @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jesse Glick</a>
*/
public class AntClassLoader extends ClassLoader {
/**
@@ -101,6 +103,19 @@
*/
private Vector loaderPackages = new Vector();
+ private static Method getProtectionDomain = null;
+ private static Method defineClassProtectionDomain = null;
+ static {
+ try {
+ getProtectionDomain =
Class.class.getMethod("getProtectionDomain", new Class[0]);
+ Class protectionDomain =
Class.forName("java.security.ProtectionDomain");
+ Class[] args = new Class[] {String.class, byte[].class,
Integer.TYPE, Integer.TYPE, protectionDomain};
+ defineClassProtectionDomain =
ClassLoader.class.getDeclaredMethod("defineClass", args);
+ }
+ catch (Exception e) {}
+ }
+
+
/**
* Create a classloader for the given project using the classpath given.
*
@@ -198,7 +213,7 @@
Class theClass = findLoadedClass(classname);
if (theClass == null) {
- theClass = findSystemClass(classname);
+ theClass = findBaseClass(classname);
}
return theClass;
@@ -325,7 +340,7 @@
if (theClass == null) {
if (useSystemFirst) {
try {
- theClass = findSystemClass(classname);
+ theClass = findBaseClass(classname);
project.log("Class " + classname + " loaded from system
loader", Project.MSG_DEBUG);
}
catch (ClassNotFoundException cnfe) {
@@ -339,7 +354,7 @@
project.log("Class " + classname + " loaded from ant
loader", Project.MSG_DEBUG);
}
catch (ClassNotFoundException cnfe) {
- theClass = findSystemClass(classname);
+ theClass = findBaseClass(classname);
project.log("Class " + classname + " loaded from system
loader", Project.MSG_DEBUG);
}
}
@@ -387,10 +402,33 @@
byte[] classData = baos.toByteArray();
- return defineClass(classname, classData, 0, classData.length);
+ // Simply put:
+ // defineClass(classname, classData, 0, classData.length,
Project.class.getProtectionDomain());
+ // Made more elaborate to be 1.1-safe.
+ if (defineClassProtectionDomain != null) {
+ try {
+ Object domain = getProtectionDomain.invoke(Project.class,
new Object[0]);
+ Object[] args = new Object[] {classname, classData, new
Integer(0), new Integer(classData.length), domain};
+ return (Class)defineClassProtectionDomain.invoke(this, args);
+ }
+ catch (InvocationTargetException ite) {
+ Throwable t = ite.getTargetException();
+ if (t instanceof ClassFormatError) {
+ throw (ClassFormatError)t;
+ }
+ else {
+ throw new IOException(t.toString());
+ }
+ }
+ catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+ else {
+ return defineClass(classname, classData, 0, classData.length);
+ }
}
-
/**
* Search for and load a class on the classpath of this class loader.
*
@@ -445,6 +483,19 @@
}
}
catch (IOException e) {}
+ }
+ }
+
+ /**
+ * Find a system class (which should be loaded from the same classloader
as the Ant core).
+ */
+ private Class findBaseClass(String name) throws ClassNotFoundException {
+ ClassLoader base = AntClassLoader.class.getClassLoader();
+ if (base == null) {
+ return findSystemClass(name);
+ }
+ else {
+ return base.loadClass(name);
}
}
}