You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2002/06/12 01:16:20 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

costin      2002/06/11 16:16:19

  Modified:    src/share/org/apache/tomcat/util/depend
                        DependClassLoader.java DependClassLoader12.java
  Log:
  A small change in the hack to load the right DependClassLoader.
  
  This allows DCL12 to extend URLClassLoader, which avoids a lot
  of problems ( there is user code that may cast to URLClassLoader,
  etc ).
  
  If there is any problem - please let me know.
  
  Revision  Changes    Path
  1.16      +9 -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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- DependClassLoader.java	5 Jan 2002 02:44:58 -0000	1.15
  +++ DependClassLoader.java	11 Jun 2002 23:16:19 -0000	1.16
  @@ -92,16 +92,18 @@
       protected Object pd;
       static Jdk11Compat jdkCompat=Jdk11Compat.getJdkCompat();
   
  -    public static DependClassLoader getDependClassLoader( DependManager depM,
  -							  ClassLoader parent,
  -							  Object pd, int debug ) {
  +    public static interface DCLFactory {
  +        public ClassLoader createDependLoader(  DependManager depM, ClassLoader parent, Object pd, int debug );
  +    }
  +    
  +    public static ClassLoader getDependClassLoader( DependManager depM,
  +                                                    ClassLoader parent,
  +                                                    Object pd, int debug ) {
   	if( jdkCompat.isJava2() ) {
   	    try {
   		Class c=Class.forName( "org.apache.tomcat.util.depend.DependClassLoader12");
  -		DependClassLoader dcl=(DependClassLoader)c.newInstance();
  -		dcl.init( depM, parent, pd );
  -		dcl.debug=debug;
  -		return dcl;
  +		DCLFactory dcl=(DCLFactory)c.newInstance();
  +                return dcl.createDependLoader( depM, parent, pd, debug );
   	    } catch(Exception ex ) {
   		ex.printStackTrace();
   	    }
  
  
  
  1.10      +172 -9    jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependClassLoader12.java
  
  Index: DependClassLoader12.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/depend/DependClassLoader12.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DependClassLoader12.java	28 Feb 2002 03:15:48 -0000	1.9
  +++ DependClassLoader12.java	11 Jun 2002 23:16:19 -0000	1.10
  @@ -65,20 +65,37 @@
   import java.security.*;
   
   import org.apache.tomcat.util.compat.*;
  +
  +public class DependClassLoader12 implements DependClassLoader.DCLFactory {
  +
  +    public ClassLoader createDependLoader(DependManager depM, ClassLoader parent, Object pd, int debug ) {
  +        return new DependClassLoader12Impl( depM, parent, pd, debug );
  +    }
  +}
  +
   /** 
    * 1.2 support for DependClassLoader
    * 
    */
  -public class DependClassLoader12 extends DependClassLoader {
  -	
  +class DependClassLoader12Impl extends URLClassLoader {
  +
       private final static String FILE_PROTOCOL = "file:";
       private final static String BANG = "!";
  -	
  -    DependClassLoader12() {
  -    }
  +
  +    protected ClassLoader parent;
  +    protected ClassLoader parent2;
       
  -    public DependClassLoader12( DependManager depM, ClassLoader parent, Object pd ) {
  -	super(depM, parent, pd);
  +    private static int debug=0;
  +    DependManager dependM;
  +    protected Object pd;
  +
  +    public DependClassLoader12Impl( DependManager depM, ClassLoader parent, Object pd, int debug ) {
  +        super( new URL[0], parent );
  +	this.parent=parent;
  +	this.parent2=parent.getParent();
  +	dependM=depM;
  +	this.pd=pd;
  +        this.debug=debug;
       }
   
       protected synchronized Class loadClass(String name, boolean resolve)
  @@ -102,7 +119,6 @@
   	}
       }
   
  -    
       protected Class defineClassCompat( String name, byte data[], int s, int end, URL res )
   	throws ClassNotFoundException
       {
  @@ -155,6 +171,10 @@
           }
    	return defineClass(name, data, s, end, (ProtectionDomain)pd);
       }
  +
  +    public URL[] getURLs() {
  +        return ((URLClassLoader)parent).getURLs();
  +    }
       
       private String getAttribute(Attributes.Name key, Attributes main, Attributes pkg)
       {
  @@ -168,8 +188,151 @@
         return value;
        }
   
  -    protected Enumeration findResources(String name) 
  +    public Enumeration findResources(String name) 
   	throws IOException {
   	return parent.getResources(name);
  +    }
  +
  +    // debug only
  +    final void log( String s ) {
  +	System.out.println("DependClassLoader12: " + s );
  +    }
  +
  +    /** Actual class loading. The name 'loadClassInternal' generates a warning,
  +     *  as a private method with the same name exists int ClassLoader in JDK1.1 ( Sun impl ).
  +     */
  +    protected Class loadClassInternal1( String name, boolean resolve )
  +	throws ClassNotFoundException
  +    {
  +	if( debug>9) log( "loadClass() " + name + " " + resolve);
  +	// The class object that will be returned.
  +        Class c = null;
  +
  +	// check if  we already loaded this class
  +	c = findLoadedClass( name );
  +	if (c!= null ) {
  +	    if(resolve) resolveClass(c);
  +	    return c;
  +        }
  +
  +        String classFileName = name.replace('.', '/' ) + ".class";
  +
  +	URL res=getResource( classFileName );
  +
  +	// If it's in parent2, load it ( we'll not track sub-dependencies ).
  +	try {
  +	    c = parent2.loadClass(name);
  +	    if (c != null) {
  +		if (resolve) resolveClass(c);
  +		// No need, we can't reload anyway
  +		// dependency( c, res );
  +		return c;
  +	    }
  +	} catch (Exception e) {
  +	    c = null;
  +	}
  +
  +	if( res==null ) 
  +	    throw new ClassNotFoundException(name);
  +
  +	// This should work - SimpleClassLoader should be able to get
  +	// resources from jar files. 
  +	InputStream is=getResourceAsStream( classFileName );
  +	if( is==null ) 
  +	    throw new ClassNotFoundException(name);
  +
  +
  +	// 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;
  +	    is.close();
  +	} 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=defineClassCompat( name, data, 0, data.length, res );
  +	dependency( c, res );
  +	
  +	if (resolve) resolveClass(c);
  +
  +	return c;
  +    }
  +
  +    public URL getResource(String name) {
  +	return parent.getResource(name);
  +    }
  +
  +    public InputStream getResourceAsStream(String name) {
  +	return parent.getResourceAsStream( name );
  +    }
  +
  +    private void dependency( Class c, URL res ) {
  +	if( res==null) return;
  +	File f=null;
  +	if( "file".equals( res.getProtocol() )) {
  +	    f=new File( res.getFile());
  +	    if( debug > 9 ) log( "File dep "  +f );
  +	    if( ! f.exists()) f=null;
  +	}
  +	if( "jar".equals( res.getProtocol() )) {
  +	    String fileN=res.getFile();
  +	    int idx=fileN.indexOf( "!" );
  +	    if( idx>=0 )
  +		fileN=fileN.substring( 0, idx) ;
  +	    // Bojan Smojver <bo...@binarix.com>: remove jar:
  +	    if( fileN.startsWith( "file:" ))
  +		fileN=fileN.substring( 5 );
  +	    // If the standard URL parser is used ( jdk1.1 compat )
  +	    if( fileN.startsWith( "/file:" ))
  +		fileN=fileN.substring( 6 );
  +	    f=new File(fileN);
  +	    if( debug > 9 ) log( "Jar dep "  +f + " " + f.exists() );
  +	    if( ! f.exists()) f=null;
  +	}
  +
  +	if( f==null ) return;
  +	Dependency dep=new Dependency();
  +	dep.setLastModified( f.lastModified() );
  +	dep.setTarget( c );
  +	dep.setOrigin( f );
  +
  +	dependM.addDependency( dep );
  +    }
  +
  +    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;
  +	    }
  +        }
       }
   }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message -----
From: <co...@covalent.net>
To: "Tomcat Developers List" <to...@jakarta.apache.org>
Sent: Tuesday, June 11, 2002 7:37 PM
Subject: Re: cvs commit:
jakarta-tomcat/src/share/org/apache/tomcat/util/depend
DependClassLoader.java DependClassLoader12.java


> On Tue, 11 Jun 2002, Bill Barker wrote:
>
> > > I'll add a check.
> > >
> > > If JDK1.2 is used, we also use URLClassLoader ( and DCL12 can't
> > > be used with 1.1 ). At least with the standard set of modules.
> > >
> >
> > Unless the use11Loader="true" attribute is set on LoaderInterceptor11.
>
> :-)
>
> I missed that. Thanks. ( I think now it should work, for 1.1 we use
> SimpleClassLoader and that is checked )
>
> DCL12 just calls the parent loader, so it shouldn't lock any resource.
>
> I can roll back the change if you think there are other issues - but
> I kind of need it to extend URLClassLoader ( I can use a separate
> pacakge, but is better to reuse ).
>

I can't think of any other issues, and if any turn up I'd rather start from
here to fix them.

>
> > > I don't see any good reason to use anything but a URLClassLoader ( or
> > > extension of ) if JDK1.2 is available, it is more secure and simpler.
> >
> > The main reason is that using a URLClassLoader prevents you from being
able
> > to replace jar file in WEB-INF/lib on the fly.  Of course, it would
probably
> > be better long term to jump through all of the same hoops that Remy does
for
> > 4.x to get around this problem.
>
>
> Costin
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

Posted by co...@covalent.net.
On Tue, 11 Jun 2002, Bill Barker wrote:

> > I'll add a check.
> >
> > If JDK1.2 is used, we also use URLClassLoader ( and DCL12 can't
> > be used with 1.1 ). At least with the standard set of modules.
> >
> 
> Unless the use11Loader="true" attribute is set on LoaderInterceptor11.

:-)

I missed that. Thanks. ( I think now it should work, for 1.1 we use
SimpleClassLoader and that is checked ) 

DCL12 just calls the parent loader, so it shouldn't lock any resource.

I can roll back the change if you think there are other issues - but
I kind of need it to extend URLClassLoader ( I can use a separate 
pacakge, but is better to reuse ). 


> > I don't see any good reason to use anything but a URLClassLoader ( or
> > extension of ) if JDK1.2 is available, it is more secure and simpler.
> 
> The main reason is that using a URLClassLoader prevents you from being able
> to replace jar file in WEB-INF/lib on the fly.  Of course, it would probably
> be better long term to jump through all of the same hoops that Remy does for
> 4.x to get around this problem.


Costin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message -----
From: <co...@covalent.net>
To: "Tomcat Developers List" <to...@jakarta.apache.org>
Sent: Tuesday, June 11, 2002 5:09 PM
Subject: Re: cvs commit:
jakarta-tomcat/src/share/org/apache/tomcat/util/depend
DependClassLoader.java DependClassLoader12.java


> On Tue, 11 Jun 2002, Bill Barker wrote:
>
> > >   +
> > >   +    public URL[] getURLs() {
> > >   +        return ((URLClassLoader)parent).getURLs();
> > >   +    }
> > >
> >
> > This can (and will) cause a ClassCastException.  You can't assume that
> > parent is a URLClassLoader.
>
> I'll add a check.
>
> If JDK1.2 is used, we also use URLClassLoader ( and DCL12 can't
> be used with 1.1 ). At least with the standard set of modules.
>

Unless the use11Loader="true" attribute is set on LoaderInterceptor11.

> I don't see any good reason to use anything but a URLClassLoader ( or
> extension of ) if JDK1.2 is available, it is more secure and simpler.

The main reason is that using a URLClassLoader prevents you from being able
to replace jar file in WEB-INF/lib on the fly.  Of course, it would probably
be better long term to jump through all of the same hoops that Remy does for
4.x to get around this problem.

>
> Costin
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

Posted by co...@covalent.net.
On Tue, 11 Jun 2002, Bill Barker wrote:

> >   +
> >   +    public URL[] getURLs() {
> >   +        return ((URLClassLoader)parent).getURLs();
> >   +    }
> >
> 
> This can (and will) cause a ClassCastException.  You can't assume that
> parent is a URLClassLoader.

I'll add a check.

If JDK1.2 is used, we also use URLClassLoader ( and DCL12 can't
be used with 1.1 ). At least with the standard set of modules.

I don't see any good reason to use anything but a URLClassLoader ( or 
extension of ) if JDK1.2 is available, it is more secure and simpler.

Costin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/depend DependClassLoader.java DependClassLoader12.java

Posted by Bill Barker <wb...@wilshire.com>.
>   +
>   +    public URL[] getURLs() {
>   +        return ((URLClassLoader)parent).getURLs();
>   +    }
>

This can (and will) cause a ClassCastException.  You can't assume that
parent is a URLClassLoader.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>