All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tools.ant.taskdefs.Classloader Maven / Gradle / Ivy

There is a newer version: 1.10.15
Show newest version
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.tools.ant.taskdefs;

import java.io.File;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.StringUtils;

/**
 * EXPERIMENTAL
 * Create or modifies ClassLoader. The required pathRef parameter
 * will be used to add classpath elements.
 *
 * The classpath is a regular path. Currently only file components are
 * supported (future extensions may allow URLs).
 *
 * You can modify the core loader by not specifying any name or using
 * "ant.coreLoader". (the core loader is used to load system ant
 * tasks and for taskdefs that don't specify an explicit path).
 *
 * Taskdef and typedef can use the loader you create if the name follows
 * the "ant.loader.NAME" pattern. NAME will be used as a pathref when
 * calling taskdef.
 *
 * This tasks will not modify the core loader if "build.sysclasspath=only"
 *
 * The typical use is:
 * 
 *  <path id="ant.deps" >
 *     <fileset dir="myDir" >
 *        <include name="junit.jar, bsf.jar, js.jar, etc"/>
 *     </fileset>
 *  </path>
 *
 *  <classloader pathRef="ant.deps" />
 *
 * 
* */ public class Classloader extends Task { /** @see MagicNames#SYSTEM_LOADER_REF */ public static final String SYSTEM_LOADER_REF = MagicNames.SYSTEM_LOADER_REF; private String name = null; private Path classpath; private boolean reset = false; private boolean parentFirst = true; private String parentName = null; /** Name of the loader. If none, the default loader will be modified * * @param name the name of this loader */ public void setName(String name) { this.name = name; } /** * Reset the classloader, if it already exists. A new loader will * be created and all the references to the old one will be removed. * (it is not possible to remove paths from a loader). The new * path will be used. * * @param b true if the loader is to be reset. */ public void setReset(boolean b) { this.reset = b; } /** * Set reverse attribute. * @param b if true reverse the normal classloader lookup. * @deprecated use setParentFirst with a negated argument instead */ @Deprecated public void setReverse(boolean b) { this.parentFirst = !b; } /** * Set reverse attribute. * @param b if true reverse the normal classloader lookup. */ public void setParentFirst(boolean b) { this.parentFirst = b; } /** * Set the name of the parent. * @param name the parent name. */ public void setParentName(String name) { this.parentName = name; } /** Specify which path will be used. If the loader already exists * and is an AntClassLoader (or any other loader we can extend), * the path will be added to the loader. * @param pathRef a reference to a path. * @throws BuildException if there is a problem. */ public void setClasspathRef(Reference pathRef) throws BuildException { classpath = (Path) pathRef.getReferencedObject(getProject()); } /** * Set the classpath to be used when searching for component being defined * * @param classpath an Ant Path object containing the classpath. */ public void setClasspath(Path classpath) { if (this.classpath == null) { this.classpath = classpath; } else { this.classpath.append(classpath); } } /** * Create a classpath. * @return a path for configuration. */ public Path createClasspath() { if (this.classpath == null) { this.classpath = new Path(null); } return this.classpath.createPath(); } /** * do the classloader manipulation. */ @Override public void execute() { try { // Gump friendly - don't mess with the core loader if only classpath if ("only".equals(getProject().getProperty("build.sysclasspath")) && (name == null || SYSTEM_LOADER_REF.equals(name))) { log("Changing the system loader is disabled by build.sysclasspath=only", Project.MSG_WARN); return; } String loaderName = (name == null) ? SYSTEM_LOADER_REF : name; Object obj = getProject().getReference(loaderName); if (reset) { // Are any other references held ? Can we 'close' the loader // so it removes the locks on jars ? obj = null; // a new one will be created. } // TODO maybe use reflection to addPathElement (other patterns ?) if (obj != null && !(obj instanceof AntClassLoader)) { log("Referenced object is not an AntClassLoader", Project.MSG_ERR); return; } @SuppressWarnings("resource") AntClassLoader acl = (AntClassLoader) obj; boolean existingLoader = acl != null; if (acl == null) { // Construct a new class loader Object parent = null; if (parentName != null) { parent = getProject().getReference(parentName); if (!(parent instanceof ClassLoader)) { parent = null; } } // TODO: allow user to request the system or no parent if (parent == null) { parent = this.getClass().getClassLoader(); } if (name == null) { // The core loader must be reverse //reverse=true; } getProject().log("Setting parent loader " + name + " " + parent + " " + parentFirst, Project.MSG_DEBUG); // The param is "parentFirst" acl = AntClassLoader.newAntClassLoader((ClassLoader) parent, getProject(), classpath, parentFirst); getProject().addReference(loaderName, acl); if (name == null) { // This allows the core loader to load optional tasks // without delegating acl.addLoaderPackageRoot("org.apache.tools.ant.taskdefs.optional"); getProject().setCoreLoader(acl); } } if (existingLoader && classpath != null) { for (String path : classpath.list()) { File f = new File(path); if (f.exists()) { log("Adding to class loader " + acl + " " + f.getAbsolutePath(), Project.MSG_DEBUG); acl.addPathElement(f.getAbsolutePath()); } } } // TODO add exceptions } catch (Exception ex) { log(StringUtils.getStackTrace(ex), Project.MSG_ERR); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy