Methods Summary |
---|
public void | addJavaLibraries()add any libraries that come with different java versions
here
Vector packages = JavaEnvUtils.getJrePackages();
Enumeration e = packages.elements();
while (e.hasMoreElements()) {
String packageName = (String) e.nextElement();
addSystemPackageRoot(packageName);
}
|
public void | addLoaderPackageRoot(java.lang.String packageRoot)Adds a package root to the list of packages which must be loaded using
this loader.
All subpackages are also included.
loaderPackages.addElement(packageRoot
+ (packageRoot.endsWith(".") ? "" : "."));
|
public void | addPathElement(java.lang.String pathElement)Adds an element to the classpath to be searched.
File pathComponent
= project != null ? project.resolveFile(pathElement)
: new File(pathElement);
try {
addPathFile(pathComponent);
} catch (IOException e) {
throw new BuildException(e);
}
|
protected void | addPathFile(java.io.File pathComponent)Add a file to the path.
Reads the manifest, if available, and adds any additional class path jars
specified in the manifest.
pathComponents.addElement(pathComponent);
if (pathComponent.isDirectory()) {
return;
}
String absPathPlusTimeAndLength =
pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-"
+ pathComponent.length();
String classpath = (String) pathMap.get(absPathPlusTimeAndLength);
if (classpath == null) {
ZipFile jarFile = null;
InputStream manifestStream = null;
try {
jarFile = new ZipFile(pathComponent);
manifestStream
= jarFile.getInputStream(new ZipEntry("META-INF/MANIFEST.MF"));
if (manifestStream == null) {
return;
}
Reader manifestReader
= new InputStreamReader(manifestStream, "UTF-8");
org.apache.tools.ant.taskdefs.Manifest manifest
= new org.apache.tools.ant.taskdefs.Manifest(manifestReader);
classpath
= manifest.getMainSection().getAttributeValue("Class-Path");
} catch (org.apache.tools.ant.taskdefs.ManifestException e) {
// ignore
} finally {
if (manifestStream != null) {
manifestStream.close();
}
if (jarFile != null) {
jarFile.close();
}
}
if (classpath == null) {
classpath = "";
}
pathMap.put(absPathPlusTimeAndLength, classpath);
}
if (!"".equals(classpath)) {
URL baseURL = FILE_UTILS.getFileURL(pathComponent);
StringTokenizer st = new StringTokenizer(classpath);
while (st.hasMoreTokens()) {
String classpathElement = st.nextToken();
URL libraryURL = new URL(baseURL, classpathElement);
if (!libraryURL.getProtocol().equals("file")) {
log("Skipping jar library " + classpathElement
+ " since only relative URLs are supported by this"
+ " loader", Project.MSG_VERBOSE);
continue;
}
String decodedPath = Locator.decodeUri(libraryURL.getFile());
File libraryFile = new File(decodedPath);
if (libraryFile.exists() && !isInPath(libraryFile)) {
addPathFile(libraryFile);
}
}
}
|
public void | addSystemPackageRoot(java.lang.String packageRoot)Adds a package root to the list of packages which must be loaded on the
parent loader.
All subpackages are also included.
systemPackages.addElement(packageRoot
+ (packageRoot.endsWith(".") ? "" : "."));
|
public void | buildFinished(BuildEvent event)Cleans up any resources held by this classloader at the end
of a build.
cleanup();
|
public void | buildStarted(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public synchronized void | cleanup()Cleans up any resources held by this classloader. Any open archive
files are closed.
for (Enumeration e = zipFiles.elements(); e.hasMoreElements();) {
ZipFile zipFile = (ZipFile) e.nextElement();
try {
zipFile.close();
} catch (IOException ioe) {
// ignore
}
}
zipFiles = new Hashtable();
if (project != null) {
project.removeBuildListener(this);
}
project = null;
|
protected java.lang.Class | defineClassFromData(java.io.File container, byte[] classData, java.lang.String classname)Define a class given its bytes
definePackage(container, classname);
// XXX should instead make a new ProtectionDomain with a CodeSource
// corresponding to container.toURI().toURL() and the same
// PermissionCollection as Project.class.protectionDomain had
return defineClass(classname, classData, 0, classData.length,
Project.class.getProtectionDomain());
|
protected void | definePackage(java.io.File container, java.lang.String className)Define the package information associated with a class.
int classIndex = className.lastIndexOf('.");
if (classIndex == -1) {
return;
}
String packageName = className.substring(0, classIndex);
if (getPackage(packageName) != null) {
// already defined
return;
}
// define the package now
Manifest manifest = getJarManifest(container);
if (manifest == null) {
definePackage(packageName, null, null, null, null, null,
null, null);
} else {
definePackage(container, packageName, manifest);
}
|
protected void | definePackage(java.io.File container, java.lang.String packageName, java.util.jar.Manifest manifest)Define the package information when the class comes from a
jar with a manifest
String sectionName = packageName.replace('.", '/") + "/";
String specificationTitle = null;
String specificationVendor = null;
String specificationVersion = null;
String implementationTitle = null;
String implementationVendor = null;
String implementationVersion = null;
String sealedString = null;
URL sealBase = null;
Attributes sectionAttributes = manifest.getAttributes(sectionName);
if (sectionAttributes != null) {
specificationTitle
= sectionAttributes.getValue(Name.SPECIFICATION_TITLE);
specificationVendor
= sectionAttributes.getValue(Name.SPECIFICATION_VENDOR);
specificationVersion
= sectionAttributes.getValue(Name.SPECIFICATION_VERSION);
implementationTitle
= sectionAttributes.getValue(Name.IMPLEMENTATION_TITLE);
implementationVendor
= sectionAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
implementationVersion
= sectionAttributes.getValue(Name.IMPLEMENTATION_VERSION);
sealedString
= sectionAttributes.getValue(Name.SEALED);
}
Attributes mainAttributes = manifest.getMainAttributes();
if (mainAttributes != null) {
if (specificationTitle == null) {
specificationTitle
= mainAttributes.getValue(Name.SPECIFICATION_TITLE);
}
if (specificationVendor == null) {
specificationVendor
= mainAttributes.getValue(Name.SPECIFICATION_VENDOR);
}
if (specificationVersion == null) {
specificationVersion
= mainAttributes.getValue(Name.SPECIFICATION_VERSION);
}
if (implementationTitle == null) {
implementationTitle
= mainAttributes.getValue(Name.IMPLEMENTATION_TITLE);
}
if (implementationVendor == null) {
implementationVendor
= mainAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
}
if (implementationVersion == null) {
implementationVersion
= mainAttributes.getValue(Name.IMPLEMENTATION_VERSION);
}
if (sealedString == null) {
sealedString
= mainAttributes.getValue(Name.SEALED);
}
}
if (sealedString != null && sealedString.equalsIgnoreCase("true")) {
try {
sealBase = new URL(FileUtils.getFileUtils().toURI(container.getAbsolutePath()));
} catch (MalformedURLException e) {
// ignore
}
}
definePackage(packageName, specificationTitle, specificationVersion,
specificationVendor, implementationTitle,
implementationVersion, implementationVendor, sealBase);
|
private java.lang.Class | findBaseClass(java.lang.String name)Finds a system class (which should be loaded from the same classloader
as the Ant core).
For JDK 1.1 compatibility, this uses the findSystemClass method if
no parent classloader has been specified.
if (parent == null) {
return findSystemClass(name);
} else {
return parent.loadClass(name);
}
|
public java.lang.Class | findClass(java.lang.String name)Searches for and load a class on the classpath of this class loader.
log("Finding class " + name, Project.MSG_DEBUG);
return findClassInComponents(name);
|
private java.lang.Class | findClassInComponents(java.lang.String name)Finds a class on the given classpath.
// we need to search the components of the path to see if
// we can find the class we want.
InputStream stream = null;
String classFilename = getClassFilename(name);
try {
Enumeration e = pathComponents.elements();
while (e.hasMoreElements()) {
File pathComponent = (File) e.nextElement();
try {
stream = getResourceStream(pathComponent, classFilename);
if (stream != null) {
log("Loaded from " + pathComponent + " "
+ classFilename, Project.MSG_DEBUG);
return getClassFromStream(stream, name, pathComponent);
}
} catch (SecurityException se) {
throw se;
} catch (IOException ioe) {
// ioe.printStackTrace();
log("Exception reading component " + pathComponent
+ " (reason: " + ioe.getMessage() + ")",
Project.MSG_VERBOSE);
}
}
throw new ClassNotFoundException(name);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
//ignore
}
}
|
protected java.util.Enumeration | findResources(java.lang.String name)Returns an enumeration of URLs representing all the resources with the
given name by searching the class loader's classpath.
Enumeration/*<URL>*/ mine = new ResourceEnumeration(name);
Enumeration/*<URL>*/ base;
if (parent != null && parent != getParent()) {
// Delegate to the parent:
base = parent.getResources(name);
// Note: could cause overlaps in case ClassLoader.this.parent has matches.
} else {
// ClassLoader.this.parent is already delegated to from
// ClassLoader.getResources, no need:
base = new CollectionUtils.EmptyEnumeration();
}
if (isParentFirst(name)) {
// Normal case.
return CollectionUtils.append(base, mine);
} else if (ignoreBase) {
return getRootLoader() == null
? mine
: CollectionUtils.append(
mine, getRootLoader().getResources(name));
} else {
// Inverted.
return CollectionUtils.append(mine, base);
}
|
public java.lang.Class | forceLoadClass(java.lang.String classname)Loads a class through this class loader even if that class is available
on the parent classpath.
This ensures that any classes which are loaded by the returned class
will use this classloader.
log("force loading " + classname, Project.MSG_DEBUG);
Class theClass = findLoadedClass(classname);
if (theClass == null) {
theClass = findClass(classname);
}
return theClass;
|
public java.lang.Class | forceLoadSystemClass(java.lang.String classname)Loads a class through this class loader but defer to the parent class
loader.
This ensures that instances of the returned class will be compatible
with instances which have already been loaded on the parent
loader.
log("force system loading " + classname, Project.MSG_DEBUG);
Class theClass = findLoadedClass(classname);
if (theClass == null) {
theClass = findBaseClass(classname);
}
return theClass;
|
private java.lang.String | getClassFilename(java.lang.String classname)Converts the class dot notation to a filesystem equivalent for
searching purposes.
return classname.replace('.", '/") + ".class";
|
private java.lang.Class | getClassFromStream(java.io.InputStream stream, java.lang.String classname, java.io.File container)Reads a class definition from a stream.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) {
baos.write(buffer, 0, bytesRead);
}
byte[] classData = baos.toByteArray();
return defineClassFromData(container, classData, classname);
|
public java.lang.String | getClasspath()Returns the classpath this classloader will consult.
StringBuffer sb = new StringBuffer();
boolean firstPass = true;
Enumeration componentEnum = pathComponents.elements();
while (componentEnum.hasMoreElements()) {
if (!firstPass) {
sb.append(System.getProperty("path.separator"));
} else {
firstPass = false;
}
sb.append(((File) componentEnum.nextElement()).getAbsolutePath());
}
return sb.toString();
|
private java.util.jar.Manifest | getJarManifest(java.io.File container)Get the manifest from the given jar, if it is indeed a jar and it has a
manifest
if (container.isDirectory()) {
return null;
}
JarFile jarFile = null;
try {
jarFile = new JarFile(container);
return jarFile.getManifest();
} finally {
if (jarFile != null) {
jarFile.close();
}
}
|
public java.net.URL | getResource(java.lang.String name)Finds the resource with the given name. A resource is
some data (images, audio, text, etc) that can be accessed by class
code in a way that is independent of the location of the code.
// we need to search the components of the path to see if
// we can find the class we want.
URL url = null;
if (isParentFirst(name)) {
url = (parent == null) ? super.getResource(name)
: parent.getResource(name);
}
if (url != null) {
log("Resource " + name + " loaded from parent loader",
Project.MSG_DEBUG);
} else {
// try and load from this loader if the parent either didn't find
// it or wasn't consulted.
Enumeration e = pathComponents.elements();
while (e.hasMoreElements() && url == null) {
File pathComponent = (File) e.nextElement();
url = getResourceURL(pathComponent, name);
if (url != null) {
log("Resource " + name
+ " loaded from ant loader",
Project.MSG_DEBUG);
}
}
}
if (url == null && !isParentFirst(name)) {
// this loader was first but it didn't find it - try the parent
if (ignoreBase) {
url = (getRootLoader() == null) ? null
: getRootLoader().getResource(name);
} else {
url = (parent == null) ? super.getResource(name)
: parent.getResource(name);
}
if (url != null) {
log("Resource " + name + " loaded from parent loader",
Project.MSG_DEBUG);
}
}
if (url == null) {
log("Couldn't load Resource " + name, Project.MSG_DEBUG);
}
return url;
|
public java.io.InputStream | getResourceAsStream(java.lang.String name)Returns a stream to read the requested resource name.
InputStream resourceStream = null;
if (isParentFirst(name)) {
resourceStream = loadBaseResource(name);
if (resourceStream != null) {
log("ResourceStream for " + name
+ " loaded from parent loader", Project.MSG_DEBUG);
} else {
resourceStream = loadResource(name);
if (resourceStream != null) {
log("ResourceStream for " + name
+ " loaded from ant loader", Project.MSG_DEBUG);
}
}
} else {
resourceStream = loadResource(name);
if (resourceStream != null) {
log("ResourceStream for " + name
+ " loaded from ant loader", Project.MSG_DEBUG);
} else {
resourceStream = loadBaseResource(name);
if (resourceStream != null) {
log("ResourceStream for " + name
+ " loaded from parent loader", Project.MSG_DEBUG);
}
}
}
if (resourceStream == null) {
log("Couldn't load ResourceStream for " + name,
Project.MSG_DEBUG);
}
return resourceStream;
|
private java.io.InputStream | getResourceStream(java.io.File file, java.lang.String resourceName)Returns an inputstream to a given resource in the given file which may
either be a directory or a zip file.
try {
if (!file.exists()) {
return null;
}
if (file.isDirectory()) {
File resource = new File(file, resourceName);
if (resource.exists()) {
return new FileInputStream(resource);
}
} else {
// is the zip file in the cache
ZipFile zipFile = (ZipFile) zipFiles.get(file);
if (zipFile == null) {
zipFile = new ZipFile(file);
zipFiles.put(file, zipFile);
}
ZipEntry entry = zipFile.getEntry(resourceName);
if (entry != null) {
return zipFile.getInputStream(entry);
}
}
} catch (Exception e) {
log("Ignoring Exception " + e.getClass().getName()
+ ": " + e.getMessage() + " reading resource " + resourceName
+ " from " + file, Project.MSG_VERBOSE);
}
return null;
|
protected java.net.URL | getResourceURL(java.io.File file, java.lang.String resourceName)Returns the URL of a given resource in the given file which may
either be a directory or a zip file.
try {
if (!file.exists()) {
return null;
}
if (file.isDirectory()) {
File resource = new File(file, resourceName);
if (resource.exists()) {
try {
return FILE_UTILS.getFileURL(resource);
} catch (MalformedURLException ex) {
return null;
}
}
} else {
ZipFile zipFile = (ZipFile) zipFiles.get(file);
if (zipFile == null) {
zipFile = new ZipFile(file);
zipFiles.put(file, zipFile);
}
ZipEntry entry = zipFile.getEntry(resourceName);
if (entry != null) {
try {
return new URL("jar:" + FILE_UTILS.getFileURL(file)
+ "!/" + entry);
} catch (MalformedURLException ex) {
return null;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
|
private java.lang.ClassLoader | getRootLoader()Used for isolated resource seaching.
ClassLoader ret = getClass().getClassLoader();
while (ret != null && ret.getParent() != null) {
ret = ret.getParent();
}
return ret;
|
public static void | initializeClass(java.lang.Class theClass)Forces initialization of a class in a JDK 1.1 compatible, albeit hacky
way.
// ***HACK*** We ask the VM to create an instance
// by voluntarily providing illegal arguments to force
// the VM to run the class' static initializer, while
// at the same time not running a valid constructor.
final Constructor[] cons = theClass.getDeclaredConstructors();
//At least one constructor is guaranteed to be there, but check anyway.
if (cons != null) {
if (cons.length > 0 && cons[0] != null) {
final String[] strs = new String[NUMBER_OF_STRINGS];
try {
cons[0].newInstance((Object[]) strs);
// Expecting an exception to be thrown by this call:
// IllegalArgumentException: wrong number of Arguments
} catch (Exception e) {
// Ignore - we are interested only in the side
// effect - that of getting the static initializers
// invoked. As we do not want to call a valid
// constructor to get this side effect, an
// attempt is made to call a hopefully
// invalid constructor - come on, nobody
// would have a constructor that takes in
// 256 String arguments ;-)
// (In fact, they can't - according to JVM spec
// section 4.10, the number of method parameters is limited
// to 255 by the definition of a method descriptor.
// Constructors count as methods here.)
}
}
}
|
protected boolean | isInPath(java.io.File component)Indicate if the given file is in this loader's path
for (Enumeration e = pathComponents.elements(); e.hasMoreElements();) {
File pathComponent = (File) e.nextElement();
if (pathComponent.equals(component)) {
return true;
}
}
return false;
|
private boolean | isParentFirst(java.lang.String resourceName)Tests whether or not the parent classloader should be checked for
a resource before this one. If the resource matches both the
"use parent classloader first" and the "use this classloader first"
lists, the latter takes priority.
// default to the global setting and then see
// if this class belongs to a package which has been
// designated to use a specific loader first
// (this one or the parent one)
// XXX - shouldn't this always return false in isolated mode?
boolean useParentFirst = parentFirst;
for (Enumeration e = systemPackages.elements(); e.hasMoreElements();) {
String packageName = (String) e.nextElement();
if (resourceName.startsWith(packageName)) {
useParentFirst = true;
break;
}
}
for (Enumeration e = loaderPackages.elements(); e.hasMoreElements();) {
String packageName = (String) e.nextElement();
if (resourceName.startsWith(packageName)) {
useParentFirst = false;
break;
}
}
return useParentFirst;
|
private java.io.InputStream | loadBaseResource(java.lang.String name)Finds a system resource (which should be loaded from the parent
classloader).
if (parent == null) {
return getSystemResourceAsStream(name);
} else {
return parent.getResourceAsStream(name);
}
|
protected synchronized java.lang.Class | loadClass(java.lang.String classname, boolean resolve)Loads a class with this class loader.
This class attempts to load the class in an order determined by whether
or not the class matches the system/loader package lists, with the
loader package list taking priority. If the classloader is in isolated
mode, failure to load the class in this loader will result in a
ClassNotFoundException.
// 'sync' is needed - otherwise 2 threads can load the same class
// twice, resulting in LinkageError: duplicated class definition.
// findLoadedClass avoids that, but without sync it won't work.
Class theClass = findLoadedClass(classname);
if (theClass != null) {
return theClass;
}
if (isParentFirst(classname)) {
try {
theClass = findBaseClass(classname);
log("Class " + classname + " loaded from parent loader "
+ "(parentFirst)", Project.MSG_DEBUG);
} catch (ClassNotFoundException cnfe) {
theClass = findClass(classname);
log("Class " + classname + " loaded from ant loader "
+ "(parentFirst)", Project.MSG_DEBUG);
}
} else {
try {
theClass = findClass(classname);
log("Class " + classname + " loaded from ant loader",
Project.MSG_DEBUG);
} catch (ClassNotFoundException cnfe) {
if (ignoreBase) {
throw cnfe;
}
theClass = findBaseClass(classname);
log("Class " + classname + " loaded from parent loader",
Project.MSG_DEBUG);
}
}
if (resolve) {
resolveClass(theClass);
}
return theClass;
|
private java.io.InputStream | loadResource(java.lang.String name)Returns a stream to read the requested resource name from this loader.
// we need to search the components of the path to see if we can
// find the class we want.
InputStream stream = null;
Enumeration e = pathComponents.elements();
while (e.hasMoreElements() && stream == null) {
File pathComponent = (File) e.nextElement();
stream = getResourceStream(pathComponent, name);
}
return stream;
|
protected void | log(java.lang.String message, int priority)Logs a message through the project object if one has been provided.
if (project != null) {
project.log(message, priority);
}
// else {
// System.out.println(message);
// }
|
public void | messageLogged(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public void | resetThreadContextLoader()Resets the current thread's context loader to its original value.
if (LoaderUtils.isContextLoaderAvailable()
&& isContextLoaderSaved) {
LoaderUtils.setContextClassLoader(savedContextLoader);
savedContextLoader = null;
isContextLoaderSaved = false;
}
|
public void | setClassPath(org.apache.tools.ant.types.Path classpath)Set the classpath to search for classes to load. This should not be
changed once the classloader starts to server classes
pathComponents.removeAllElements();
if (classpath != null) {
Path actualClasspath = classpath.concatSystemClasspath("ignore");
String[] pathElements = actualClasspath.list();
for (int i = 0; i < pathElements.length; ++i) {
try {
addPathElement(pathElements[i]);
} catch (BuildException e) {
// ignore path elements which are invalid
// relative to the project
}
}
}
|
public synchronized void | setIsolated(boolean isolated)Sets whether this classloader should run in isolated mode. In
isolated mode, classes not found on the given classpath will
not be referred to the parent class loader but will cause a
ClassNotFoundException.
ignoreBase = isolated;
|
public void | setParent(java.lang.ClassLoader parent)Set the parent for this class loader. This is the class loader to which
this class loader will delegate to load classes
if (parent == null) {
this.parent = AntClassLoader.class.getClassLoader();
} else {
this.parent = parent;
}
|
public void | setParentFirst(boolean parentFirst)Control whether class lookup is delegated to the parent loader first
or after this loader. Use with extreme caution. Setting this to
false violates the class loader hierarchy and can lead to Linkage errors
this.parentFirst = parentFirst;
|
public void | setProject(Project project)Set the project associated with this class loader
this.project = project;
if (project != null) {
project.addBuildListener(this);
}
|
public void | setThreadContextLoader()Sets the current thread's context loader to this classloader, storing
the current loader value for later resetting.
if (isContextLoaderSaved) {
throw new BuildException("Context loader has not been reset");
}
if (LoaderUtils.isContextLoaderAvailable()) {
savedContextLoader = LoaderUtils.getContextClassLoader();
ClassLoader loader = this;
if (project != null
&& "only".equals(project.getProperty("build.sysclasspath"))) {
loader = this.getClass().getClassLoader();
}
LoaderUtils.setContextClassLoader(loader);
isContextLoaderSaved = true;
}
|
public void | subBuildFinished(BuildEvent event)Cleans up any resources held by this classloader at the end of
a subbuild if it has been created for the subbuild's project
instance.
if (event.getProject() == project) {
cleanup();
}
|
public void | subBuildStarted(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public void | targetFinished(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public void | targetStarted(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public void | taskFinished(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public void | taskStarted(BuildEvent event)Empty implementation to satisfy the BuildListener interface.
// Not significant for the class loader.
|
public java.lang.String | toString()Returns a String representing this loader.
return "AntClassLoader[" + getClasspath() + "]";
|