No reply to this one yet, so gently asking again whether this will make
it into 1.3, or whether I will need to ship a patched ant.jar with
NetBeans...doable but not desirable.

#1 is the important part, since without this nothing works inside the
IDE. So I am reattaching it, this time as a standalone patch without #2.
Original description below for reference.

For #2, it may suffice for NetBeans to automatically define some
additional properties, like:

        -Dnetbeans.filesystems.path=/my/sources/part1:/my/sources/part2

and so on (taken from GUI project configuration). Then

        <taskdef name="foo" classname="MyCustomTask"/>

will still not work, but this more explicit version will:

        <taskdef name="foo" classname="MyCustomTask">
          <classpath>
            <pathelement path="${netbeans.filesystems.path}"/>
          </classpath>
        </taskdef>

I tried this and it seems OK, provided AntClassLoader is patched.

Thanks,
-Jesse

Jesse Glick wrote:
> 1. AntClassLoader. [This patch can actually stand on its own, if the one
> reference to project.getDefaultClassLoader() is changed to e.g.
> AntClassLoader.class.getClassLoader().] AntClassLoader currently when
> trying to resolve "system" classes, uses the primordial classloader. If
> Ant itself was *not* loaded with the primordial classloader, this is
> unworkable: e.g. a user task may be loadable but Task itself is not
> (from within that AntClassLoader) -> NoClassDefFoundError when
> resolving. The patch simply makes the loading work logically, wherever
> Ant itself was loaded from.
> 
> Furthermore, previously AntClassLoader under Java 2 would provide no
> permissions for loaded classes. This means that in a VM with an
> installed security manager, any task performing a controlled action
> (pretty much any task at all: e.g. open a file, ...) would throw
> AccessControlException and be useless. The patch (under Java 2) supplies
> loaded classes with the same permissions as Ant itself (matching the
> commandline behavior), under the assumption that tasks and build scripts
> are trusted and there is no sandboxing needed or wanted. Under JDK 1.1,
> it should compile (note the reflection calls) but do nothing different;
> someone with a 1.1 installation, please double-check!

-- 
Jesse Glick   <mailto:[EMAIL PROTECTED]>
NetBeans, Open APIs  <http://www.netbeans.org/>
tel (+4202) 3300-9161 Sun Micro x49161 Praha CR
Index: src/main/org/apache/tools/ant/AntClassLoader.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/AntClassLoader.java,v
retrieving revision 1.13
diff -c -t -r1.13 AntClassLoader.java
*** src/main/org/apache/tools/ant/AntClassLoader.java   2001/01/19 13:27:00     
1.13
--- src/main/org/apache/tools/ant/AntClassLoader.java   2001/01/31 12:34:27
***************
*** 54,59 ****
--- 54,60 ----
  
  package org.apache.tools.ant;
  
+ import java.lang.reflect.*;
  import java.util.*;
  import java.util.zip.*;
  import java.io.*;
***************
*** 198,204 ****
          Class theClass = findLoadedClass(classname);
  
          if (theClass == null) {
!             theClass = findSystemClass(classname);
          }
          
          return theClass;
--- 199,205 ----
          Class theClass = findLoadedClass(classname);
  
          if (theClass == null) {
!             theClass = findBaseClass(classname);
          }
          
          return theClass;
***************
*** 325,331 ****
          if (theClass == null) {
              if (useSystemFirst) {
                  try {
!                     theClass = findSystemClass(classname);
                      project.log("Class " + classname + " loaded from system 
loader", Project.MSG_DEBUG);
                  }
                  catch (ClassNotFoundException cnfe) {
--- 326,332 ----
          if (theClass == null) {
              if (useSystemFirst) {
                  try {
!                     theClass = findBaseClass(classname);
                      project.log("Class " + classname + " loaded from system 
loader", Project.MSG_DEBUG);
                  }
                  catch (ClassNotFoundException cnfe) {
***************
*** 339,345 ****
                      project.log("Class " + classname + " loaded from ant 
loader", Project.MSG_DEBUG);
                  }
                  catch (ClassNotFoundException cnfe) {
!                     theClass = findSystemClass(classname);
                      project.log("Class " + classname + " loaded from system 
loader", Project.MSG_DEBUG);
                  }
              }
--- 340,346 ----
                      project.log("Class " + classname + " loaded from ant 
loader", Project.MSG_DEBUG);
                  }
                  catch (ClassNotFoundException cnfe) {
!                     theClass = findBaseClass(classname);
                      project.log("Class " + classname + " loaded from system 
loader", Project.MSG_DEBUG);
                  }
              }
***************
*** 387,393 ****
          
          byte[] classData = baos.toByteArray();
  
!         return defineClass(classname, classData, 0, classData.length); 
      }
  
  
--- 388,430 ----
          
          byte[] classData = baos.toByteArray();
  
!         // 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); 
!         }
!     }
! 
!     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) {}
      }
  
  
***************
*** 445,450 ****
--- 482,500 ----
                  }
              }
              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);
          }
      }
  }

Reply via email to