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);
           }
       }
   }
  
  
  

Reply via email to