A task to manage Java class file dependencies.
The depend
task works by determining which classes are out of date with respect to
their source and then removing the class files of any other classes which depend on the out-of-date
classes.
To determine the class dependencies, the depend
task analyzes the class files of all
class files passed to it. The task does not parse your source code in any way but relies upon the
class references encoded into the class files by the compiler. This is generally faster than parsing
the Java source files.
To learn more about how this information is obtained from the class files, please refer to the Java Virtual Machine Specification
Since a class' dependencies only change when the class itself changes, the
depend
task is able to cache dependency information. Only those class files which have
changed will have their dependency information re-analysed. Note that if you change a class'
dependencies by changing the source, it will be recompiled anyway. You can examine the dependency
files created to understand the dependencies of your classes. Please do not rely, however, on the
format of the information, as it may change in a later release.
Once depend
discovers all of the class dependencies, it "inverts" this
relation to determine, for each class, which other classes are dependent upon it. This
"affects" list is used to discover which classes are invalidated by the out of date
class. The class files of the invalidated classes are removed, triggering the compilation of the
affected classes.
The depend
task supports an attribute, closure, which controls
whether depend
will only consider direct class-class relationships or whether it will
also consider transitive, indirect relationships. For example, say there are three classes, A, which
depends on B, which in-turn depends on C. Now say that class C is out of
date. Without closure, only class B would be removed
by depend
. With closure set, class A would also be removed. Normally direct
relationships are sufficient—it is unusual for a class to depend on another without having a
direct relationship. With closure set, you will notice that depend
typically
removes far more class files.
The classpath attribute for <depend>
is optional. If it is
present, depend
will check class dependencies against classes and jars on this
classpath. Any classes which depend on an element from this classpath and which are older than that
element will be deleted. A typical example where you would use this facility would be where you are
building a utility jar and want to make sure classes which are out of date with respect to this jar
are rebuilt. In this classpath, you should not include jars that you do not expect
to change, such as the JDK runtime jar or third party jars, since doing so will just slow down the
dependency check. This means that if you do use a classpath for the depend
task it may
be different from the classpath necessary to actually compile your code.
The performance of the depend
task is dependent on a number of factors such as class
relationship complexity and how many class files are out of date. The decision about whether it is
cheaper to just recompile all classes or to use the depend
task will depend on the size
of your project and how interrelated your classes are.
There are some source dependencies which depend
will not detect:
depend
nor the compiler tasks can detect when a non-public
class is missing. Inner classes are handled by the depend
task.The most obvious example of these limitations is that the task can't tell which classes to recompile when a constant primitive data type exported by other classes is changed. For example, a change in the definition of something like
public final class Constants { public final static boolean DEBUG=false; }
will not be picked up by other classes.
Attribute | Description | Required |
---|---|---|
srcDir | This is the directory where the source exists. depend will examine this to
determine which classes are out of date. If you use multiple source directories you can pass
this attribute a path of source directories. |
Yes |
destDir | This is the root directory of the class files which will be analysed. | No; defaults to srcdir |
cache | This is a directory in which depend can store and retrieve dependency
information. |
No; defaults to no cache |
closure | This attribute controls whether depend only removes classes which directly
depend on out of date classes. If this is set to true, depend will
traverse the class dependency graph deleting all affected classes. |
No; defaults to false |
dump | If true the dependency information will be written to the debug level log | No; default is false |
classpath | The classpath containing jars and classes for which <depend> should also
check dependencies |
No |
warnOnRmiStubs | Flag to disable warnings about files that look like rmic generated stub/skeleton classes and have no .java source. Useful when doing RMI development. | No; default true |
The depend
task's classpath attribute is
a path-like structure and can also be set via a
nested <classpath>
element.
Additionally, this task forms an implicit FileSet and
supports most attributes of <fileset>
(dir becomes srcdir),
as well as the nested <include>
, <exclude>
,
and <patternset>
elements.
Remove any classes in the ${build.classes} directory that depend on out-of-date
classes. Classes are considered out-of-date with respect to the source in
the ${java.dir} directory, using the same mechanism as the <javac>
task. In this example, the <depend>
task caches its dependency information in
the depcache directory.
<depend srcdir="${java.dir}" destdir="${build.classes}" cache="depcache" closure="yes"/>
Do the same as the previous example, but explicitly include all .java files, except those that match the list given in ${java.dir}/build_excludes.
<depend srcdir="${java.dir}" destdir="${build.classes}" cache="depcache" closure="yes"> <include name="**/*.java"/> <excludesfile name="${java.dir}/build_excludes"/> </depend>