|
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.