|
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 java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.tomcat.util.compat.SimpleClassLoader;
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
*
*/
class DependClassLoader12Impl extends URLClassLoader {
static org.apache.commons.logging.Log logger =
org.apache.commons.logging.LogFactory.getLog(DependClassLoader12Impl.class);
private final static String FILE_PROTOCOL = "file:";
private final static String BANG = "!";
protected ClassLoader parent;
protected ClassLoader parent2;
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)
throws ClassNotFoundException
{
final String lname=name;
final boolean lresolve=resolve;
try {
return (Class)AccessController.doPrivileged( new PrivilegedExceptionAction() {
public Object run() throws Exception {
return loadClassInternal1( lname, lresolve );
}
});
} catch( PrivilegedActionException pex ) {
Exception ex=pex.getException();
if( ex instanceof ClassNotFoundException )
throw (ClassNotFoundException)ex;
// unknown - better display it
ex.printStackTrace();
throw new ClassNotFoundException( name );
}
}
protected Class defineClassCompat( String name, byte data[], int s, int end, URL res )
throws ClassNotFoundException
{
// JDK1.2 - XXX need to fix for JDK1.1 compat
// CodeSource cs=new CodeSource( res , null);
// PermissionCollection perms=Policy.getPolicy().getPermissions(cs);
// ProtectionDomain pd=new ProtectionDomain( cs,perms);
// System.out.println("XXX " + name + ": " + cs + "\n" + perms );
int idx = name.lastIndexOf(".");
String pkgname = idx != -1 ? name.substring(0, idx) : null;
if ( pkgname != null ) {
Package p = getPackage(pkgname);
if ( p == null ) {
if ( "jar".equals(res.getProtocol()) ) {
try {
String JarN = res.getFile();
if (JarN.startsWith(FILE_PROTOCOL))
JarN = JarN.substring(FILE_PROTOCOL.length());
int bang = JarN.indexOf(BANG);
if (bang != -1) JarN = JarN.substring(0, bang);
JarFile JarF = new JarFile(JarN);
Manifest mf = JarF.getManifest();
if(mf == null) // Jar may not be Java2
throw new IOException("No Manifest");
Attributes main = mf.getMainAttributes();
Attributes pkg = mf.getAttributes(
pkgname.replace('.', '/').concat("/")
);
boolean sealed = Boolean.valueOf(
getAttribute(Attributes.Name.SEALED, main, pkg)
).booleanValue();
definePackage(
pkgname,
getAttribute(Attributes.Name.SPECIFICATION_TITLE, main, pkg),
getAttribute(Attributes.Name.SPECIFICATION_VERSION, main, pkg),
getAttribute(Attributes.Name.SPECIFICATION_VENDOR, main, pkg),
getAttribute(Attributes.Name.IMPLEMENTATION_TITLE, main, pkg),
getAttribute(Attributes.Name.IMPLEMENTATION_VERSION, main, pkg),
getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR, main, pkg),
sealed ? res : null
);
JarF.close();
} catch ( IOException e ) {
definePackage(pkgname, null, null, null, null, null, null, null);
}
} else {
definePackage(pkgname, null, null, null, null, null, null, null);
}
}
}
return defineClass(name, data, s, end, (ProtectionDomain)pd);
}
public URL[] getURLs() {
if( parent instanceof URLClassLoader )
return ((URLClassLoader)parent).getURLs();
if( parent instanceof SimpleClassLoader )
return ((SimpleClassLoader)parent).getURLs();
return super.getURLs();
}
private String getAttribute(Attributes.Name key, Attributes main, Attributes pkg)
{
String value = null;
if ( pkg != null ) {
value = (String)pkg.get(key);
}
if ( value == null ) {
value = (String)main.get(key);
}
return value;
}
public Enumeration findResources(String name)
throws IOException {
return parent.getResources(name);
}
/** 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;
}
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.