Classloader

Description

This task is designed to

The classloader to create, modify and/or get the path from, is referred by the loader attribute.
If the referenced object does not exist (or reset is "true"), a new classloader will be created and the reference will be set. Otherwise the classpath will appended to the referenced classloader. In this case, the classloader remains untouched if no classpath is set.

If the property build.sysclasspath is set to "only", create/append actions on the System-, Project- or CoreLoader are omitted with a warning.

If property is set, the classpath of loader is set as value of the specified property. Create/append and property can be executed in one task.

See also: ClassloaderReport Task

Creating classloaders

Appending classpathes to existing classloaders

See also: Supporting custom classloaders

Usage notes

This task is designed to provide more flexibility but it should used with caution.

Parameters

Attribute Description Required
loader Id or symbolic name of the classloader to create, manipulate or get the path from. See nested element's description for further information. Yes, unless nested loader element is specified.
classpath The classpath to create or append to loader. No
classpathRef Id of the classpath to create or append to loader. It can be a reference to a Fileset, Filelist, Dirset, Path or Urlpath. No
duplicateEntry Handling of duplicate entries in the classpath. One of "ignore" (don't check), "warn" (log warning but add entry) or "omit" (omit entry and log in verbose mode). No, defaults to "omit".
property Name of the property to put loaders classpath in. No
reset If "true", reset loader if it already exists. I.e. a new classloader will be created and the reference to the old one will be replaced. (It is not possible to remove paths from a loader). NOTE: Use this option with care, as it may deliver unexpected results. No, defaults to "false".
parameters Id of the Loaderparameters to use when creating a new classloader. See nested element's description for further information. No, defaults to an empty Antloaderparameters.
handler Id of the Loaderhandler to use when creating a new classloader. Overwrites the default Loaderhandler of parameters. See "Supporting custom classloaders" for further information. No, defaults to parameters's default Loaderhandler.
handlerSet Id of the LoaderhandlerSet to use when modifying an existing classloader or getting it's classpath. See "Supporting custom classloaders" for further information. No, defaults to a generic LoaderhandlerSet containing the predefined Loaderhandlers and handler.
failonerror Stop the build process if an error occurs. No, defaults to "true".
parentLoader Id or symbolic name of a classloader to use as the parent of a newly created classloader. See nested element's description for further information. No, defaults to "none".
superLoader Id or symbolic name of a classloader to use as the classloader of a newly created classloader. See nested element's description for further information. No, defaults to "current".

Parameters specified as nested elements

<loader>, <parentLoader> and <superLoader>

loader specifies the classloader to create, modify or get the path from.
parentLoader specifies the classloader to use as parent of a newly created classloader.
superLoader specifies the classloader to use as classloader of a newly created classloader. It depends on the particular adapter, whether or not this parameter is supported.

To specify classloaders, Classloader uses Loaderref types. Classloader's loader, parentLoader and superLoader attributes are Loaderrefs with one of the attributes set due to the following algorithm:

  1. If the attribute's value is found in the reference table of the current project and denotes a LoaderRef, set attribute's value as refid.
  2. Else if the attribute's value is found in the reference table of the current project and denotes a classloader, set attribute's value as loaderRef.
  3. Else if the attribute's value is found in the reference table of the current project, throw a BuildException.
  4. Else if the attribute's value is a symbolic classloader name, set attribute's value as loader.
  5. Else set attribute's value as loaderRef.
To explicitely set a Loaderref's attribute, you can can define one via a nested loader, parentLoader resp. superLoader element.

Attribute Description Required
loader Symbolic name of a classloader. Exactly one of these.
loaderref Refers to the id of a classloader defined elsewhere.
refid Makes this Loaderref a reference to a Loaderref defined somewhere else.
Symbolic classloader names
Symbolic Name Description reset="true"
core The result of getProject().getCoreLoader(). If used as parentLoader or superLoader and getProject().getCoreLoader() returns null, "project" is used as delegation parent resp. superloader. Calls getProject().setCoreLoader and updates the current Project reference id "ant.coreLoader".
current The result of this.getClass().getClassLoader(). Error
none Explicitely no classloader. Can not be used as Classloader's loader. (Typically used to specify the bootstrap classloader.) Error
project The result of getProject().getClass().getClassLoader(). Error
system The result of ClassLoader.getSystemClassLoader(). Error
thread The result of Thread.currentThread().getContextClassLoader(). Calls Thread.currentThread().setContextClassLoader.

<classpath>

Classloader's classpathRef attribute is a reference to an extended PATH like structure and can also be set via a nested classpath element. The extended path can also be set outside the task via a Urlpath element. In addition to the attributes and nested elements of Path, Urlpath supports the following parameters:

Attribute Description Required
urlpath a ';' separated list of files or directories specified as files or URLs No
Nested element <urlpathelement>
Attribute Description Required
location a single file or directory specified as file or URL Exactly one of those
path a ';' separated list of files or directories specified as files or URLs
Nested element <urlpath>
Specifies another Urlpath as part of the current one.
Nested element <reference>

A reference to a Fileset, Filelist, Dirset, Path or Urlpath defined elsewhere as part of the current Urlpath.

<parameters>

Classloader's parameters attribute is a reference to a Loaderparameters or compatible type defined elsewhere.

Loaderparameters and compatible types are defining the parameters used to modify a newly created classloader.
Furthermore they are defining a default Loaderhandler used to create a new classloader.
Loaderparameters default Loaderhandler is "ant.clhandler.URLClassLoader".
Ant ships with the following compatible types:
- Antloaderparameters
NOTE: In Ant versions 1.6.5 (and prior) <taskdef> and <typedef> requires instances of AntClassloader to define tasks or types..

Instead of referring to existing Loaderparameters, you can can define them via a nested parameters element.

Attribute Description Required
defaultAssertionStatus The argument for calling setDefaultAssertionStatus(Boolean) at the newly created classloader. Will be ignored on Java < 1.4. No
refid Makes this Loaderparameters a reference to a Loaderparameters or compatible type defined somewhere else. No
Nested Element <classAssertionStatus>

Describes the arguments for a call of setClassAssertionStatus at a classloader. Will be ignored on Java < 1.4.

Attribute Description Required
class Classname. Yes
status Desired assertion status for the class. No, defaults to "false".
Nested Element <packageAssertionStatus>

Describes the arguments for a call of setPackageAssertionStatus at a classloader. Will be ignored on Java < 1.4.

Attribute Description Required
package Package name. Yes
status Desired assertion status for the package. No, defaults to "false".

<antparameters>

Antloaderparameters is a Loaderparameters-compatible type that defines the parameters of an AntClassLoader. Instead of referring to existing Antloaderparameters, you can can define them via a nested antparameters element.

Attribute Description Required
addJavaLibraries If "true", addJavaLibraries will called at the newly created AntClassLoader. No, defaults to "false".
defaultAssertionStatus The argument for calling setDefaultAssertionStatus(Boolean) at the newly created classloader. Will be ignored on Java < 1.4. No
isolated The argument for calling setIsolated(boolean) at the newly created AntClassLoader. No, defaults to "false".
loaderPackageRoot ';', ':' or ',' separated list of Packagenames used as argument for calling setLoaderPackageRoot(String) at the newly created AntClassLoader. No
parentFirst The argument for calling setParentFirst(boolean) at the newly created AntClassLoader. No, defaults to "true".
systemPackageRoot ';', ':' or ',' separated list of Packagenames used as argument for calling setSystemPackageRoot(String) at the newly created AntClassLoader. No
refid Makes this Antloaderparameters a reference to a Loaderparameters or compatible type defined somewhere else. No
Nested Element <classAssertionStatus>

See Loaderparameters's classAssertionStatus.

Nested Element <packageAssertionStatus>

See Loaderparameters's packageAssertionStatus.

<handler>

See Supporting custom classloaders.

<handlerSet>

See Supporting custom classloaders.

Examples

...
<jar destfile="dist/lib/my.jar" 
      basedir="build/classes" 
     includes="mypackage/MyTask.class"/>
<classloader loader="project" classpath="dist/lib/my.jar"/>
<taskdef name="mytask" classname="mypackage.MyTask"/>
<mytask .../>
Adds the newly created jar ${basedir}/dist/lib/my.jar to the ProjectClassLoader, so that the following taskdef can load the new task in the same classloader as Ant's Core Tasks.

<classloader loader="my-new-antloader" parentloader="project">
    <classpath>
        <pathelement path="dist/lib/my2nd.jar:${junit.dir}/junit.jar"/>
        <urlpathelement path="dist/lib/my3rd.jar"/>
    </classpath>
</classloader>
Creates a new AntClassLoader with the ProjectClassLoader as delegating parent and a classpath consisting of ${basedir}/dist/lib/my2nd.jar followed by ${junit.dir}/junit.jar followed by ${basedir}/dist/lib/my3rd.jar and adds it to the reference table with id my-new-loader. Ant Tasks in this classloader can be loaded by the current project as it is a childloader of the project classloader.

<classloader loader="my-new-loader" parentloader="system">
    <classpath>
        <pathelement path="dist/lib/my2nd.jar:${junit.dir}/junit.jar"/>
        <urlpathelement path="http://some.domain.com/lib/remote.jar;dist/lib/my3rd.jar"/>
    </classpath>
    <parameters/>
</classloader>
Creates a new java.net.URLClassLoader with the SystemClassLoader as delegating parent and a classpath consisting of ${basedir}/dist/lib/my2nd.jar followed by ${junit.dir}/junit.jar followed by http://some.domain.com/lib/remote.jar followed by ${basedir}/dist/lib/my3rd.jar and adds it to the reference table with id my-new-loader. Ant Tasks in this classloader can not be loaded by the current project as it is not a childloader of the project classloader.


Supporting custom classloaders

This task can be extended to work with any arbitrary classloader.

Adapter classes

To support your custom classloader, you need to write an adapter class for it. Take a look at the provided adapters in the package org.apache.tools.ant.taskdefs.classloader.adapter. Your class should derive from SimpleClassLoaderAdapter or - if it fits - one of the derived classes. If the supported classloader is not in Java's bootstrap classpath, you should use reflection for all the object access. (Example: AntClassLoaderAdapter)
To provide this adapter you need to define a <Loaderhandler> in or outside the Classloader task and add it to a <LoaderhandlerSet> via handler or addAll.

<handler>

To deal with arbitrary classloaders, Classloader uses adapter classes that are defined by Loaderhandler types.
Classloader's handler attribute is a reference to a Loaderhandler defined elsewhere. Instead of referring to an existing Loaderhandler, you can can define one via a nested handler element.

Attribute Description Required
adapter The classname of the adapter class. Yes, unless refid is specified.
loader The class- or interfacename of a classloader to modify or introspect. This class is used to test the assignability of an existing classloader. (The instantiating class is defined in the Adapter.) Yes, unless refid is specified.
refid Makes this Loaderhandler a reference to a Loaderhandler defined somewhere else. No
predefined Loaderhandlers

Ant ships with loaderhandlers and adapters for some widely used classloaders:

<loaderhandler id="ant.clhandler.URLClassLoader"
          adapter="org.apache.tools.ant.taskdefs.classloader.URLClassLoaderAdapter"
           loader="java.net.URLClassLoader"/>
covers Java's most used classloader that is used in Ant as Project- and SystemClassLoader.
<loaderhandler id="ant.clhandler.AntClassLoader"
          adapter="org.apache.tools.ant.taskdefs.classloader.AntClassLoaderAdapter"
           loader="org.apache.tools.ant.AntClassLoader"/>
covers Ant's classloader that is implicitely created in Typedef and Taskdef.
<loaderhandler id="ant.clhandler.ClassLoader"
          adapter="org.apache.tools.ant.taskdefs.classloader.SimpleClassLoaderAdapter"
           loader="java.lang.ClassLoader"/>
covers trivial reports for any other classloader but doesn't support create, append and property actions.

<handlerSet>

To find the compatible and best fitting Loaderhandler by reflection, Classloader uses a LoaderhandlerSet type, that contains all possible Loaderhandlers.
Classloader's handlerSet attribute is a reference to a LoaderhandlerSet defined elsewhere. Instead of referring to an existing LoaderhandlerSet, you can can define one via a nested handlerset element.

Attribute Description Required
handler The Id of a LoaderHandler to add to this LoaderhandlerSet. No
addAll If "true", all Loaderhandlers that are specified in Reference table of the current Project will be added to this LoaderhandlerSet. No, defaults to "false".
addDefault If "true", all predefined Loaderhandlers will be added to the LoaderhandlerSet. No, defaults to "true".
refid Makes this handler a reference to a LoaderhandlerSet defined somewhere else. No
nested Element <handler>
You can use nested handler elements to define a Loaderhandler directly and add multiple Loaderhandlers to the LoaderhandlerSet.

Additional Parameters

To support additional parameters for your classloader, you need to write a compatible parameter class. This should be derived from org.apache.tools.ant.types.LoaderParameters. (Example: org.apache.tools.ant.types.AntLoaderParameters) Your adapter class needs to handle the parameters. (Example: AntClassLoaderAdapter)
To provide this parameters you have to declare them outside the Classloader task with id="myid" and refer to them.

Contributing to Ant

If your adapter supports a frequently used classloader, feel free to contribute it to Ant. You should make it's handler a predefined one (See: org.apache.tools.ant.types.LoaderHandler.DEFAULT_HANDLERS). If your adapter supports additional parameters, they should be supported as nested element inside the Classloader task like antparameters. (Example: Classloader.addAntparameters) Don't forget to update this documentation.

Examples

Assuming you support the classloader mypackage.MyClassLoader with your adapter class mypackage.MyClassLoaderAdapter:

<loaderhandler id="my.handler" 
    adapter="mypackage.MyClassLoaderAdapater"
    loader="mypackage.MyClassLoader"/>
<classloader
    classpath="load/with/my/loader"
    reset="true"
    loader="my.custom.loader"
    handler="my.handler">
    <handlerset addDefault="true"/>
</classloader>
This creates a new mypackage.MyClassLoader with the initial classpath ${basedir}/load/with/my/loader and makes it referencable with id "my.custom.loader".

Assuming your classloader and adapter support custom parameters and you've written a loaderparameters class mypackage.MyLoaderParameters that is compatible to Loaderparameters, the fragment

<loaderhandler id="my.handler" 
    adapter="mypackage.MyClassLoaderAdapater"
    loader="myPackage.MyClassLoader"/>
<typedef name="myloaderparameters" 
    classname="mypackage.MyLoaderParameters"/>
<myloaderparameters id="my.parameters" 
    myargument="myvalue"/>
<classloader
    classpath="load/with/my/loader"
    reset="true"
    loader="my.custom.loader"
    handler="my.handler"
    parameters="my.parameters">
    <handlerset addDefault="true"/>
</classloader>
is the same as above but with support for you custom parameters. The handler attribute may be dispensable if your adapter supports the correct default handler.


© Copyright 2004-2005 The Apache Software Foundation. All rights Reserved.