costin      01/08/15 17:22:17

  Modified:    src/share/org/apache/tomcat/util/depend
                        DependClassLoader.java
  Log:
  Fix for reloading bug reported by Ovidiu Predescu. Now DependClassLoader will
  be used to define the classes instead of the wrapped classloader, and all
  classes that are needed by a webapp class will be added to the dependency list.
  
  Revision  Changes    Path
  1.5       +65 -7     
jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependClassLoader.java
  
  Index: DependClassLoader.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependClassLoader.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DependClassLoader.java    2001/06/17 18:09:18     1.4
  +++ DependClassLoader.java    2001/08/16 00:22:17     1.5
  @@ -63,6 +63,8 @@
   import java.util.zip.*;
   import java.security.*;
   
  +import org.apache.tomcat.util.compat.*;
  +
   /**
    * This is a wrapper class loader that will delegate all calls to
    * the parent. It will also generate events for every loaded class,
  @@ -83,12 +85,16 @@
    */
   public class DependClassLoader extends ClassLoader {
       protected ClassLoader parent;
  +    protected ClassLoader parent2;
  +    
       final static int debug=0;
       DependManager dependM;
  -
  +    static Jdk11Compat jdkCompat=Jdk11Compat.getJdkCompat();
  +    
       public DependClassLoader( DependManager depM, ClassLoader parent ) {
        super(); // will check permissions
        this.parent=parent;
  +     this.parent2=jdkCompat.getParentLoader( parent );
        dependM=depM;
       }
   
  @@ -123,25 +129,48 @@
            if(resolve) resolveClass(c);
            return c;
           }
  +
           String classFileName = name.replace('.', '/' ) + ".class";
   
        URL res=getResource( classFileName );
  -     if( res==null ) {
  -         if( debug >0  )  log( "Resource not found !!! " + name + " " + 
classFileName);
  -     }
  +     InputStream is=getResourceAsStream( classFileName );
  +     if( res==null || is==null ) 
  +         throw new ClassNotFoundException(name);
   
  +     // If it's in parent2, load it ( we'll not track sub-dependencies ).
        try {
  -         c = parent.loadClass(name);
  +         c = parent2.loadClass(name);
            if (c != null) {
                if (resolve) resolveClass(c);
  -             dependency( c, res );
  +             // No need, we can't reload anyway
  +             // dependency( c, res );
                return c;
            }
        } catch (Exception e) {
            c = null;
        }
  +
  +     // It's in our parent. Our task is to track all class loads, the parent
  +     // should load anything ( otherwise the deps are lost ), but just resolve
  +     // resources.
  +     byte data[]=null;
  +     try {
  +         data=readFully( is );
  +         if( data.length==0 ) data=null;
  +     } catch(IOException ex ) {
  +         if( debug > 0 ) ex.printStackTrace();
  +         data=null;
  +         throw new ClassNotFoundException( name + " error reading " + 
ex.toString());
  +     }
  +     if( data==null ) 
  +         throw new ClassNotFoundException( name + " lenght==0");
  +
  +     c=defineClass(data, 0, data.length);
  +     dependency( c, res );
  +     
  +     if (resolve) resolveClass(c);
   
  -        throw new ClassNotFoundException(name);
  +     return c;
       }
   
       public URL getResource(String name) {
  @@ -181,5 +210,34 @@
   
       public ClassLoader getParentLoader() {
           return parent;
  +    }
  +
  +    private byte[] readFully( InputStream is )
  +     throws IOException
  +    {
  +     byte b[]=new byte[1024];
  +     int count=0;
  +
  +     int available=1024;
  +     
  +     while (true) {
  +         int nRead = is.read(b,count,available);
  +         if( nRead== -1 ) {
  +             // we're done reading
  +             byte result[]=new byte[count];
  +             System.arraycopy( b, 0, result, 0, count );
  +             return result;
  +         }
  +         // got a chunk
  +         count += nRead;
  +            available -= nRead;
  +         if( available == 0 ) {
  +             // buffer full
  +             byte b1[]=new byte[ b.length * 2 ];
  +             available=b.length;
  +             System.arraycopy( b, 0, b1, 0, b.length );
  +             b=b1;
  +         }
  +        }
       }
   }
  
  
  

Reply via email to