costin      01/02/10 00:12:42

  Modified:    src/share/org/apache/tomcat/startup Main.java
               src/share/org/apache/tomcat/util/compat Jdk11Compat.java
  Added:       src/share/org/apache/tomcat/util/compat
                        SimpleClassLoader.java
  Removed:     src/share/org/apache/tomcat/util SimpleClassLoader.java
  Log:
  Fixed the JDK1.1 build problem.
  
  It's very interesting - the code compiles fine on JDK1.2 because getParent()
  is now part of ClassLoader.
  
  It doesn't in JDK1.1, but adding a getParent in SimpleClassLoader will work
  only in JDK1.1 - in 1.2 it'll fail ( it's final in ClassLoader ). So we have to
  call the method getParentLoader() in SimpleClassLoader ( so it compiles in
  both ) and abstract if via JdkCompat.
  
  But we are lucky to have it behind JdkCompat and not have to worry about this
  in future.
  
  ( I also followed the XXX and moved SimpleClassLoader in compat - it shouldn't
  be used standalone - you want to use the real thing if available -
  URLClassLoader )
  
  Revision  Changes    Path
  1.21      +4 -2      jakarta-tomcat/src/share/org/apache/tomcat/startup/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/Main.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- Main.java 2001/02/10 00:55:37     1.20
  +++ Main.java 2001/02/10 08:12:41     1.21
  @@ -66,7 +66,8 @@
   import java.util.*;
   import java.net.*;
   
  -import org.apache.tomcat.util.SimpleClassLoader;
  +// XXX This should be replaced by JdkCompat
  +import org.apache.tomcat.util.compat.SimpleClassLoader;
   import org.apache.tomcat.util.IntrospectionUtils;
   
   // Depends:
  @@ -184,9 +185,10 @@
            urlV.addElement( new URL( "file", null , System.getProperty( "java.home" ) 
+"/../lib/tools.jar"));
               URL[] serverClassPath=getURLs(urlV);
               // ClassLoader for webapps it uses a shared dir as repository, distinct 
from lib
  +
               URL[] sharedClassPath=getURLs(getClassPathV(getSharedDir()));
               URL[] commonClassPath=getURLs(getClassPathV(getCommonDir()));
  -            ClassLoader commonCl= 
IntrospectionUtils.getURLClassLoader(commonClassPath , parentL );
  +         // XXX Should be: JdkCompat.newClassLoaderInstance !!            
ClassLoader commonCl= IntrospectionUtils.getURLClassLoader(commonClassPath , parentL );
            ClassLoader sharedCl= IntrospectionUtils.getURLClassLoader(sharedClassPath 
, commonCl );
               ClassLoader serverCl= 
IntrospectionUtils.getURLClassLoader(serverClassPath , commonCl );
            if( commonCl==null ) {
  
  
  
  1.4       +1 -3      
jakarta-tomcat/src/share/org/apache/tomcat/util/compat/Jdk11Compat.java
  
  Index: Jdk11Compat.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/compat/Jdk11Compat.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Jdk11Compat.java  2001/02/10 00:55:37     1.3
  +++ Jdk11Compat.java  2001/02/10 08:12:42     1.4
  @@ -60,8 +60,6 @@
   package org.apache.tomcat.util.compat;
   
   import java.net.URL;
  -// XXX move it here, it's 1.1 specific
  -import org.apache.tomcat.util.SimpleClassLoader; 
   
   /** General-purpose utility to provide backward-compatibility and JDK
       independence. This allow use of JDK1.2 ( or higher ) facilities if
  @@ -117,7 +115,7 @@
       }
       public URL[] getParentURLs(ClassLoader cl){
           SimpleClassLoader scl=(SimpleClassLoader)cl;
  -        return ((SimpleClassLoader)scl.getParent()).getURLs();
  +        return ((SimpleClassLoader)scl.getParentLoader()).getURLs();
       }
       // Other methods, as needed
           
  
  
  
  1.1                  
jakarta-tomcat/src/share/org/apache/tomcat/util/compat/SimpleClassLoader.java
  
  Index: SimpleClassLoader.java
  ===================================================================
  /*
   * Copyright (c) 1997-1999 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and 
   *    "Java Apache Project" must not be used to endorse or promote products 
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without 
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *    
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  package org.apache.tomcat.util.compat;
  
  import java.io.*;
  import java.lang.*;
  import java.net.*;
  import java.text.*;
  import java.util.*;
  import java.util.zip.*;
  import java.security.*;
  
  /**
   * This is a JDK1.1 equivalent of URLClassLoader. It have no dependency on
   * tomcat or any other api - just standard java. 
   *
   * Based on AdaptiveClassLoader from JServ1, with the dependency check
   * and reloading features removed ( and moved to an external component)
   *  This is based on the fact that class loading and dependency checking can
   * be separated and we want to support multiple forms of class loaders.
   *
   * The interface also changed to match URLClassLoader. 
   * This class should be used _only_ with JDK1.1, for JDK1.2 you
   * should use a class loader that is aware of Permissions and the
   * new rules ( sealing, etc )
   *
   * This class loader respects the standard order defined in the ClassLoader
   * documentation - for a different order you can plug in a different
   * class loader ( in the configurations ).
   *
   * Since this class loader will be visible to applications we need
   * to prevent exploits - we'll minimize the public method usage.
   * 
   * The class path can be set only when the object is constructed.
   */
  public class SimpleClassLoader extends ClassLoader {
      private static final int debug=0;
      
      /**
       * The classpath which this classloader searches for class definitions.
       * Each element of the vector should be either a directory, a .zip
       * file, or a .jar file.
       * <p>
       * It may be empty when only system classes are controlled.
       */
      protected URL urls[];
  
      /**
       * A parent class loader for delegation of finding a class definition.
       * JDK 1.2 contains parent class loaders as part of java.lang.ClassLoader,
       * the parent being passed to a constructor, and retreived with
       * getParent() method. For JDK 1.1 compatibility, we'll duplicate the
       * 1.2 private member var.
       */
      protected ClassLoader parent;
  
      /** Reserved names - this class loader will not allow creation of
        classes that start with one of those strings.
      */
      protected String reserved[];
  
      SecurityManager sm;
      //------------------------------------------------------- Constructors
  
      public SimpleClassLoader( URL urls[]) {
        super(); // will check permissions 
        this.urls=urls;
        sm=System.getSecurityManager();
        checkURLs();
      }
  
      public SimpleClassLoader( URL urls[], ClassLoader parent ) {
        super(); // will check permissions 
        this.urls=urls;
        this.parent=parent;
        sm=System.getSecurityManager();
        checkURLs();
      }
  
      /** This is the prefered constructor to be used with this class loader
       */
      public SimpleClassLoader( URL urls[], ClassLoader parent,
                                 String reserved[] ) {
        super(); // will check permissions 
        this.urls=urls;
        this.parent=parent;
        this.reserved=reserved;
        sm=System.getSecurityManager();
        checkURLs();
      }
  
      /** We can't declare a method "getParent" since it'll not compile in
        JDK1.2 - the method is final. But we don't have to - this will
        be used via JdkCompat
      */
      public ClassLoader getParentLoader() {
        return parent;
      }
  
      private void checkURLs() {
        int cnt=0;
        for( int i=0; i<urls.length; i++ ) {
            URL cp = urls[i];
              String fileN = cp.getFile();
            File file=new File( fileN );
            if( ! file.exists() )
                urls[i]=null;
            if( file.isDirectory() &&
                ! fileN.endsWith("/") ) {
                try {
                    urls[i]=new URL("file", null,
                                    fileN + "/" );
                } catch(MalformedURLException e ) {
                }
            }
        }
      }
      
      // debug only 
      void log( String s ) {
        System.out.println("SimpleClassLoader: " + s );
      }
  
      //------------------------------------ Implementation of Classloader
  
      /*
       * XXX: The javadoc for java.lang.ClassLoader says that the
       * ClassLoader should cache classes so that it can handle repeated
       * requests for the same class.  On the other hand, the JLS seems
       * to imply that each classloader is only asked to load each class
       * once.  Is this a contradiction?
       *
       * Perhaps the second call only applies to classes which have been
       * garbage-collected?
       */
  
      /**
       * Resolves the specified name to a Class. The method loadClass()
       * is called by the virtual machine.  As an abstract method,
       * loadClass() must be defined in a subclass of ClassLoader.
       *
       * @param      name the name of the desired Class.
       * @param      resolve true if the Class needs to be resolved;
       *             false if the virtual machine just wants to determine
       *             whether the class exists or not
       * @return     the resulting Class.
       * @exception  ClassNotFoundException  if the class loader cannot
       *             find a the requested class.
       */
      protected synchronized Class loadClass(String name, boolean resolve)
          throws ClassNotFoundException
      {
          if( debug>0) log( "loadClass() " + name + " " + resolve);
        // The class object that will be returned.
          Class c = null;
  
        // check if the class was already loaded
        c = findLoadedClass( name );
        if (c!= null ) {
            if(resolve) resolveClass(c);
            return c;
          }
  
        // Attempt to load the class from the parent class loader
        // (untrusted case)
        if (parent != null) {
            try {
                c = parent.loadClass(name);
                if (c != null) {
                    if( debug>0) log( "loadClass() from parent " + name);
                    if (resolve) resolveClass(c);
                    return c;
                }
            } catch (Exception e) {
                c = null;
            }
        }
  
          // Attempt to load the class from the system class loader
        try {
            c = findSystemClass(name);
            if (c != null) {
                if( debug>0) log( "loadClass() from system " + name);
                if (resolve) resolveClass(c);
                return c;
            }
        } catch (Exception e) {
            c = null;
        }
        
          // Make sure we can access this class when using a SecurityManager
          if (sm != null) {
              int i = name.lastIndexOf('.');
              if (i >= 0) {
                  sm.checkPackageAccess(name.substring(0,i)); 
                  sm.checkPackageDefinition(name.substring(0,i));
            }
        }
  
        // make sure the class is not in a "reserved" package.
        if( reserved!=null ) {
            for( int i=0; i<reserved.length; i++ ) {
                if( name.startsWith( reserved[i] )) {
                    if( debug>0) log( "reserved: " + name + " " + reserved[i]);
                    throw new ClassNotFoundException(name);
                }
            }
        }
  
        if( urls==null ) 
            throw new ClassNotFoundException(name);
        
          // Translate class name to file name
          String classFileName =
              name.replace('.', '/') + ".class";
        // It's '/' not File.Separator - at least that's how URLClassLoader
        // does it and I suppose there are reasons ( costin )
  
  
        Resource r=doFindResource( classFileName );
        if( r==null )
            throw new ClassNotFoundException(name);
  
        byte[] classData=null;
  
        if( r.file != null ) {
            InputStream in=null;
              try {
                in = new FileInputStream(r.file);
                  classData=loadBytesFromStream(in, (int) r.file.length());
              } catch (IOException ioex) {
                  return null;
              } finally {
                  try {
                    if( in!=null) in.close();
                } catch( IOException ex ) {}
              }
        } else if( r.zipEntry != null ) {
            try {
                  classData=loadBytesFromStream(r.zipFile.
                                              getInputStream(r.zipEntry),
                                              (int)r.zipEntry.getSize());
              } catch (IOException ioex) {
                  return null;
            } finally {
                try {
                    r.zipFile.close();
                } catch ( IOException ignored ) {
                }
            }
        }
  
        if (classData != null) {
            try {
                c = defineClass(name, classData, 0, classData.length );
                if (resolve) resolveClass(c);
                if( debug>0) log( "loadClass() from local repository " +
                                  name);
                return c;
            } catch(Throwable t ) {
                t.printStackTrace();
            }
        }
  
          // If not found in any repository
          throw new ClassNotFoundException(name);
      }
  
      /**
       * Find a resource with a given name.  The return is a URL to the
       * resource. Doing a getContent() on the URL may return an Image,
       * an AudioClip,or an InputStream.
       *
       * @param   name    the name of the resource, to be used as is.
       * @return  an URL on the resource, or null if not found.
       */
      public URL getResource(String name) {
          if( debug > 0 ) log( "getResource() " + name );
  
        URL u = getSystemResource(name);
        if (u != null) {
            return u;
        }
  
        Resource r=doFindResource( name );
  
        if( r==null )
            return null;
  
        // Construct a file://-URL if the repository is a directory
        if( r.file != null ) { // Build a file:// URL form the file name
            try {
                return new URL("file", null,
                               r.file.getAbsolutePath());
            } catch(java.net.MalformedURLException badurl) {
                badurl.printStackTrace();
                return null;
            }
        }
  
        // a jar:-URL *could* change even between minor releases, but
        // didn't between JVM's 1.1.6 and 1.3beta. Tested on JVM's from
        // IBM, Blackdown, Microsoft, Sun @ Windows and Sun @ Solaris
        if( r.zipEntry != null ) {
            try {
                return new URL("jar:file:" +
                               r.repository.getPath() + "!/" +
                               name);
            } catch(java.net.MalformedURLException badurl) {
                badurl.printStackTrace();
                return null;
            } finally {
                try {
                    r.zipFile.close();
                } catch ( IOException ignored ) {
                }
            }
        }
        // Not found
          return null;
  
      }
  
      /**
       * Get an InputStream on a given resource.  Will return null if no
       * resource with this name is found.
       * <p>
       * The JServClassLoader translate the resource's name to a file
       * or a zip entry. It looks for the resource in all its repository
       * entry.
       *
       * @see     java.lang.Class#getResourceAsStream(String)
       * @param   name    the name of the resource, to be used as is.
       * @return  an InputStream on the resource, or null if not found.
       */
      public InputStream getResourceAsStream(String name) {
          // Try to load it from the system class
          if( debug > 0 ) log( "getResourceAsStream() " + name );
        //      InputStream s = getSystemResourceAsStream(name);
        InputStream s = null;
  
        // Get this resource from system class loader 
        s = getSystemResourceAsStream(name);
  
          if( debug>0 ) log( "System resource " + s );
        if (s != null) {
            return s;
        }
                
        Resource r=doFindResource( name );
  
        if( r==null ) return null;
        
        if( r.file!=null ) {
            if( debug > 0 ) log( "Found "  + r.file);
            try {
                  InputStream res=new FileInputStream(r.file);
                return res;
              } catch (IOException shouldnothappen) {
                shouldnothappen.printStackTrace();
                return null;
              }
        } else if( r.zipEntry != null ) {
            if( debug > 0 ) log( "Found "  + r.zipEntry);
            // workaround - the better solution is to not close the
            // zipfile !!!!
            try {
                byte[] data= loadBytesFromStream(r.zipFile.
                                                 getInputStream(r.zipEntry),
                                                 (int) r.zipEntry.getSize());
                if(data != null) {
                    InputStream istream = new ByteArrayInputStream(data);
                    return istream;
                }
            } catch(IOException e) {
            } finally {
            // if we close the zipfile bad things will happen -
                // we can't read the stream on some VMs
                if ( r.zipFile != null ) {
                    try {
                        r.zipFile.close();
                    } catch ( IOException ignored ) {
                    }
                }
            }
        }
          return s;
      }
  
      // -------------------- Private methods --------------------
      /** Private class used to store the result of the search 
       */
      private class Resource {
        /* Repository used to find the resource */
        File repository;
        /* File - if the resource is a file */
        File file;
  
        /* Zip file and entry if it's in a jar */
        ZipEntry zipEntry;
        ZipFile zipFile;
      }
  
      // common code to find the resource
      private Resource doFindResource( String name ) {
        Resource r=new Resource();
        
        for( int i=0; i<urls.length; i++ ) {
            URL cp = urls[i];
            if( cp==null ) continue;
              String fileN = cp.getFile();
            File file=new File( fileN );
            
            if (fileN.endsWith("/")) {
                  String fileName = name.replace('/', File.separatorChar);
                  File resFile = new File(file, fileName);
                  if (resFile.exists()) {
                    r.file=resFile;
                    r.repository=file;
                    return r;
                  }
              } else {
                  try {
                      ZipFile zf = new ZipFile(file.getAbsolutePath());
                      ZipEntry ze = zf.getEntry(name);
                    //if( debug > 0 ) log( "Searching " + file + " " + name );
                                        
                      if (ze != null) {
                        r.zipEntry=ze;
                        r.zipFile=zf;
                        r.repository=file;
                        return r;
                      }
                  } catch (IOException ioe) {
                      ioe.printStackTrace();
                    System.out.println("Name= " + name + " " + file );
                      return null;
                  }
              }   
          }
        return null;
      }
      
      /**
       * Loads all the bytes of an InputStream.
       */
      private byte[] loadBytesFromStream(InputStream in, int length)
          throws IOException
      {
          byte[] buf = new byte[length];
          int nRead, count = 0;
  
          while ((length > 0) && ((nRead = in.read(buf,count,length)) != -1)) {
              count += nRead;
              length -= nRead;
          }
          return buf;
      }
  
      public URL[] getURLs() {
          //TODO:  Add custom implementation.
          return urls;
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to