|
What this is
Other links
The source code/* * Copyright 1997-2004 The Apache Sofware Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomcat.util.depend; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.apache.tomcat.util.compat.Jdk11Compat; /** * This is a wrapper class loader that will delegate all calls to * the parent. It will also generate events for every loaded class, * for use in maintaining dependencies. * * In order to keep this generic we'll use findResource() to find the * source of the class, and then forward to the class loader - that * means we duplicate the search operation. * * Class loading happens only once per request, and this will have probably * little effect. * Also, the alternative is to use custom class loaders - there are many * reasons to avoid this. * * In "production" sites reloading should be turned off anyway, so the * class loader will not be "wrapped" * */ public class DependClassLoader extends ClassLoader { static org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory.getLog(DependClassLoader.class); protected ClassLoader parent; protected ClassLoader parent2; private static int debug=0; DependManager dependM; protected Object pd; static Jdk11Compat jdkCompat=Jdk11Compat.getJdkCompat(); 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"); DCLFactory dcl=(DCLFactory)c.newInstance(); return dcl.createDependLoader( depM, parent, pd, debug ); } catch(Exception ex ) { ex.printStackTrace(); } } return new DependClassLoader( depM, parent, pd ); } DependClassLoader() { } public DependClassLoader( DependManager depM, ClassLoader parent, Object pd ) { super(); // will check permissions init( depM, parent, pd ); } void init( DependManager depM, ClassLoader parent, Object pd ) { this.parent=parent; this.parent2=jdkCompat.getParentLoader( parent ); dependM=depM; this.pd=pd; } /** * 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 { return loadClassInternal1( name, resolve ); } /** 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( logger.isTraceEnabled() ) logger.trace( "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 { if( is.available() > 0) { data=readFully( is ); if( data.length==0 ) data=null; } is.close(); } catch(IOException ex ) { if( logger.isDebugEnabled() ) logger.debug(" error reading " + name, ex); 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; } /** This method must be overriden to provide additional functionality, like associating a protection domain */ protected Class defineClassCompat( String name, byte data[], int s, int end, URL res ) throws ClassNotFoundException { return defineClass(data, s, end); } 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( logger.isTraceEnabled() ) logger.trace( "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 |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.