public class ClassDep extends Object
jar
tool, to create a JAR file containing precisely
those classes.
The following items are discussed below:
java -jar install_dir/lib/classdep.jar \ -cp input_classpath processing_options output_options
where install_dir is the directory where the River-Internet release is installed. Note that the options for this tool can be specified in any order, and can be intermixed.
The -cp
class path value,
input_classpath,
is an argument to the ClassDep
tool itself and should
include all of the classes that might need to be included in the
dependency analysis. Typically this will include all of your application
classes, classes from the River-Internet release, and any other classes on which
your classes might depend. It is safe to include more classes than are
actually necessary (since the purpose of this tool is, after all, to
determine which subset of these classes is actually necessary), but it is
not necessary to include any classes that are part of the Java 2 SDK.
The class path should be in the form of a list of directories or JAR
files, delimited by a colon (":") on UNIX platforms and a semi-colon
(";") on Microsoft Windows platforms. The order of locations in the path
does not matter. If you use JAR files, any Class-Path
manifest entries in those JAR files are ignored, so you must include the
values of those manifest entries explicitly in the path, or errors may
result. For example, if you include jini-ext.jar
then you
should explicitly include jini-core.jar
as well, because
jini-core.jar
is in the Class-Path
manifest
entry of jini-ext.jar
.
In general, you only need to specify concrete classes as roots, not
interface types. When analyzing classes for the class path of an
application, you typically need to include the top-level class (the one
with the main
method). When analyzing classes for the
codebase of a service, you typically need to include the top-level proxy
classes used by the service, any trust verifier classes for those
proxies, and any custom entry classes used by the service for lookup
service attributes. Also when analyzing classes for the codebase of a
service, if the service's proxy can return leases, registration objects,
or other proxies, or if your service generates events, and if those
objects are only referenced by interface type in the top-level proxy, not
by concrete class, then you also need to include the concrete classes of
those other objects. In all cases, you typically need to include any stub
classes that you generated with the rmic
tool.
-newdirbehavior
options is specified. The directory must
contain at least one filename separator character and be one of the
directories specified in input_classpath, or when the old
behavior is effective it can be a subdirectory of one of the directories on
the input_classpath. Each class in the tree needs to be in
a package that is defined to be "inside" the graph (as described further
below).
When the -newdirbehavior
options is set the -inroot
and -outroot
options can be used to include/exclude particular
subtrees from the potential set of roots. When the old behavior is effective
all classes are considered as root, but can be excluded through the
-prune
option.
-inroot
package-prefix (only valid with
-newdirbehavior
)
-out
, -skip
or -outroot
options. If not specified all found classes are considered roots. This option
can be specified zero or more times. Note that the argument to
-inroot
is a package namespace (delimited by "."), not a
directory.
-outroot
package-prefix (only valid with
-newdirbehavior
)
rootdir
element, any classes that are in the given package or a
subpackage of it are not treated as roots. This option can be specified zero
or more times. Note that the argument to -outroot
is a package
namespace (delimited by "."), not a directory.
-prune
package-prefix (old behavior only)
-prune
is a package
namespace (delimited by "."), not a directory.
The -skip
option (described further below) can be used to
exclude specific classes from the set of roots.
Starting with the root classes, a dependency graph is constructed by examining the compiled class file for a class, finding all of the classes it references, and then in turn examining those classes. The extent of the graph is determined by which packages are defined to be "inside" the graph and which are defined to be "outside" the graph. If a referenced class is in a package that is defined to be outside the graph, that class is not included in the graph, and none of classes that it references are examined. All of the root classes must be in packages that are defined to be "inside" the graph.
The inside and outside packages are specified by using the following options. Each of these options may be specified zero or more times. Some variations are illustrated in the Examples section of this page.
-in
package-prefix
-out
or -skip
options. This
option can be specified zero or more times. If no -in
options are specified, the default is that all packages are considered to
be inside packages. Note that the argument to -in
is a
namespace, so none of its subpackages need to be specified as an argument
to -in
.
If you use this option, you will likely need to use it multiple
times. For example, if your application classes are in the
com.corp.foo
namespace, and you also use some classes in the
org.apache.river
and net.jini
namespaces, then you
might specify:
-in com.corp.foo -in org.apache.river -in net.jini
-out
package-prefix
-in
options,
then each -out
namespace should be a subspace of some
-in
namespace. Note that the argument to -out
is a namespace, so none of its subpackages need to be specified as an
argument to -out
.
If you use this option, you will likely need to use it multiple
times. For example, if you do not specify any -in
options,
then all packages are considered inside the graph, including packages
defined in the Java 2 SDK that you typically want to exclude, so you
might exclude them by specifying:
-out java -out javaxAs another example, if you have specified
-in com.corp.foo
but you don't want to include any of the classes in the
com.corp.foo.test
or com.corp.foo.qa
namespaces
in the dependency graph, then you would specify:
-out com.corp.foo.test -out com.corp.foo.qa
-skip
class
-outer
-newdirbehavior
-inroot
and -outroot
options specified. When
this option is set subdirectories of the specified directory are no longer
considered as root for finding classes. When this option is not set, the
default, the utility maintains the old behavior with respect to the semantics
for the directories passed in and the -prune
option must be
used. You are advised to set this option as there are some edge cases for
which the old behavior won't work as expected, especially when no
-in
options are set.-edges
For example, you might exclude classes from the Java 2 SDK from the
dependency graph because you don't want to include them in your JAR file,
but you might be interested in knowing which classes from the Java 2 SDK
are referenced directly by the classes in your JAR file. The
-edges
option can be used to display this information.
-show
package-prefix
-show
options are specified, the default is that all classes
in the dependency graph are displayed (or all edge classes, if
-edges
is specified). Note that the argument to
-show
is a namespace, so none of its subpackages need to be
specified as an argument to -show
.
For example, to determine which classes from the Java 2 SDK your
application depends on, you might not specify any -in
options, but limit the output by specifying:
-show java -show javax
-hide
package-prefix
-show
options, then each -hide
namespace should
be a subspace of some -show
namespace. Note that the
argument to -hide
is a namespace, so none of its subpackages
need to be specified as an argument to -hide
.
For example, to determine which non-core classes from the
net.jini
namespace you use, you might specify:
-show net.jini -hide net.jini.core
-files
com\corp\foo\Bar.class
instead of
com.corp.foo.Bar
. This option should be used to generate
output suitable as input to the jar
tool.
For more information on the jar
tool, see:
-tell
class
classes
directory. Alternatively, if you have compiled from
the source code, substitute source/classes
for
classes
in the examples.)
The following example computes the classes required for a codebase JAR
file, starting with a smart proxy class and a stub class as roots, and
displays them in filename format. (A more complete example would include
additional roots for leases, registrations, events, and lookup service
attributes, and would exclude platform classes such as those in
jsk-platform.jar
.)
java -jar install_dir/lib/classdep.jar \ -cp install_dir/classes \ org.apache.river.reggie.RegistrarProxy org.apache.river.reggie.RegistrarImpl_Stub \ -in org.apache.river -in net.jini \ -files
The following example computes the classes required for a classpath JAR
file, starting with all of the classes in a directory as roots, and
displays them in class name format. (A more complete example would exclude
platform classes such as those in jsk-platform.jar
.)
java -jar install_dir/lib/classdep.jar \ -cp install_dir/classes \ install_dir/classes/org/apache/river/reggie \ -in org.apache.river -in net.jini
The following example computes the org.apache.river
classes used
by a service implementation, and displays the net.jini
classes that are immediately referenced by those classes.
java -jar install_dir/lib/classdep.jar \ -cp install_dir/classes \ org.apache.river.reggie.RegistrarImpl \ -in org.apache.river \ -edges \ -show net.jini
The following example computes all of the classes used by a service
implementation that are not part of the Java 2 SDK, and displays the
classes that directly reference the class java.awt.Image
.
java -jar install_dir/lib/classdep.jar \ -cp install_dir/classes \ org.apache.river.reggie.RegistrarImpl \ -out java -out javax \ -tell java.awt.Image
The following example computes all of the classes to include in
jini-ext.jar
and displays them in filename format. Note
that both -out
and -prune
options are needed
for the net.jini.core
namespace; -out
to
exclude classes from the dependency graph, and -prune
to
prevent classes from being used as roots.
java -jar install_dir/lib/classdep.jar \ -cp install_dir/classes \ -in net.jini -out net.jini.core -in org.apache.river \ install_dir/classes/net/jini -prune net.jini.core \ -files
Constructor and Description |
---|
ClassDep()
No argument constructor.
|
ClassDep(String[] cmdLine)
Constructor that takes command line arguments and fills in the
appropriate fields.
|
Modifier and Type | Method and Description |
---|---|
void |
addClasses(String className)
Add an entry into the set of classes that
dependencies are going to be computed on.
|
void |
addHides(String packagePrefix)
Add an entry into the set of package prefixes that
are to remain hidden from processing.
|
void |
addInside(String packagePrefix)
Add an entry into the working set of package prefixes
that will make up the working domain space.
|
void |
addInsideRoot(String packagePrefix)
Adds an entry into the set of package prefixes for which classes found
through the specified root directories will be considered for dependency
generation.
|
void |
addOutside(String packagePrefix)
Add an entry into the set of package prefixes
that will bypassed during dependency checking.
|
void |
addOutsideRoot(String packagePrefix)
Adds an entry into the set of package prefixes for which classes found
through the specified root directories, and that are part of the inside
root namespace, will be skipped as part of the dependency generation.
|
void |
addPrune(String packagePrefix)
Add an entry into the set of package prefixes
that will be skipped as part of the dependency
generation.
|
void |
addRoots(String rootName)
Add an entry into the set of directories to
look under for the classes that fall within
the working domain space as defined by the
intersection of the following sets:
inside,outside,prune,show, and hide.
|
void |
addShow(String packagePrefix)
Add an entry into the set of package prefixes
that we want to display.
|
void |
addSkip(String packagePrefix)
Add an entry into the set of classes that
should be skipped during dependency generation.
|
void |
addTells(String className)
Add an entry in to the set of classes whose dependents
that lie with the inside set are listed.
|
String[] |
compute()
Method that takes the user provided switches that
logically define the domain in which to look for
dependencies.
|
boolean |
getFiles()
If true classnames will be separated using
File.separator, else it will use dots.
|
String[] |
getResults()
Accessor method for the found dependencies.
|
boolean |
hasFailed()
Indicates whether computing the dependent classes as result of the last
call to
compute() resulted in one or more failures. |
static void |
main(String[] args)
Command line interface for generating the list of classes that
a set of classes depends upon.
|
void |
setClassPath(String classpath)
Set the classpath to use for finding our class definitions.
|
void |
setEdges(boolean edges)
Determines whether to include package references
that lie outside the declared set of interest.
|
void |
setFiles(boolean files)
Determines how to print out the fully qualified
class names.
|
void |
setRootDirBehavior(boolean newBehavior)
Controls whether the behavior for finding class files in the specified
directories, if any, must be based on the old behavior (the default) or
the new behavior that solves some of the problems with the old behavior.
|
void |
setupOptions(String[] args)
Convenience method for initializing an instance with specific
command line arguments.
|
static void |
usage()
Print out the usage for this utility.
|
public ClassDep()
public ClassDep(String[] cmdLine)
cmdLine
- public String[] compute()
Whether a failure has occurred during computing the dependent classes
can be found out with a call to hasFailed()
.
public static void usage()
public void setClassPath(String classpath)
classpath
- public void setFiles(boolean files)
true
it will use
File.separator
, else .
's
will be used.
If not set the default is false
.files
- public void addHides(String packagePrefix)
packagePrefix
- public void addInside(String packagePrefix)
packagePrefix
- public void setEdges(boolean edges)
If true edges will be processed as well, else
they will be ignored. If not set the default
will be false
.
Note: These edge classes must included in the classpath for this utility.
edges
- public void addOutside(String packagePrefix)
packagePrefix
- public void addPrune(String packagePrefix)
This method has no impact if the new behavior is effective for the interpretation of the root directories for finding class files to include for dependency checking.
packagePrefix
- public void setRootDirBehavior(boolean newBehavior)
newBehavior
- public void addInsideRoot(String packagePrefix)
Adding entries without a call to setRootDirBehavior(boolean)
with true
as the argument will cause compute()
to
fail.
packagePrefix
- public void addOutsideRoot(String packagePrefix)
Adding entries without a call to setRootDirBehavior(boolean)
with true
as the argument will cause compute()
to
fail.
packagePrefix
- public void addShow(String packagePrefix)
packagePrefix
- public void addSkip(String packagePrefix)
packagePrefix
- public void addTells(String className)
className
- public void addRoots(String rootName)
rootName
- public void addClasses(String className)
className
- public boolean getFiles()
public String[] getResults()
public boolean hasFailed()
compute()
resulted in one or more failures.true
in case a failure has happened, such as a
class not being found, false
otherwisepublic void setupOptions(String[] args)
args
- public static void main(String[] args)
Copyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.