Classycle logo

4. Dependency Definition File

Classycle's Dependency Checker uses a dependency definition file (file type .ddf) in order to check unwanted dependencies. Dependency definition files are text files (with a syntax as explained below) which define sets of classes and independency relations between them. These relations are checked and reported if they fail.

4.1 Example

The following example file contains all types of commands:

# This is an example of a dependency definition file
show allResults

{package} = classycle

[util] = ${package}.util.*
[non-util] = ${package}.* excluding [util]
[class-file] = ${package}.classfile.*

check sets [util] [non-util] [class-file]

check [util] independentOf [non-util]
check [class-file] independentOf [util]
check ${package}.ant.* independentOf java.util.* java.awt.* \

check absenceOfClassCycles > 1 in [util]
check absenceOfPackageCycles > 1 in ${package}.*

layer basic = [class-file] [util]
layer dependency = ${package}.dependency.*

check layeringOf basic dependency
With the default result renderer the output reads
show onlyShortestPaths allResults
Set [util] has 8 classes.
Set [non-util] has 78 classes.
Set [class-file] has 14 classes.
check [util] independentOf [non-util]   OK
check [class-file] independentOf [util] OK
check classycle.ant.* independentOf java.util.*
  Dependency found:
    -> java.util.LinkedList
    -> java.util.ArrayList
    -> java.util.Iterator
    -> java.util.HashSet
    -> java.util.Map
    -> java.util.Hashtable
    -> java.util.Properties
check classycle.ant.* independentOf java.awt.*  OK
check classycle.ant.* independentOf javax.swing.*       OK
check absenceOfClassCycles > 1 in [util]        OK
check absenceOfPackageCycles > 1 in classycle.*
  classycle.renderer et al. contains 2 packages:
check [class-file] directlyIndependentOf [util] OK
check [util] directlyIndependentOf [class-file] OK
check [class-file] directlyIndependentOf classycle.dependency.* OK
check [util] directlyIndependentOf classycle.dependency.*       OK

4.2 Syntax

4.2.1 Definitions Property Definition

Defines a property which can be used in any following line.
       {<property name>} = <any string>
where <property name> is the name of the property and <any string> is any string without leading and trailing spaces.

Properties are referred by

       ${<property name>}
Properties can be used after their definition. Before a line in the file is parsed possible property references are resolved. Refering an undefined property leads to an error. Properties can be redefined.

In a dependency definition file all system properties are available as default properties. Their can be set by the Java VM command line argument

       -D<property name>=<any string>

In the case of embedded dependency definition commands in a DependencyCheckingTask the properties defined in the ant script are available as default properties (see Chapter 1.2.2. for an example).

Note: Redefining default properties do not alter the original system properties or ant properties. Set Definition

Defines a set of classes.
       [<set name>] = <term>1..*
       [<set name>] = <term>0..* excluding <term>1..* 
where <set name> is the unique name of the set. It should not contain '[', ']', or whitespaces. <term> is either a set denoted by its name and brackets or a wild-card pattern for a fully-qualified class name. Note, that only '*' is allowed as a wild-card character. The subscripts 1..* denotes one-or-many terms.
Each term defines a set of classes. The sequence of terms means the union set of these terms. The excluding operation means the creation of a difference set. Note, that a set may also include external classes. Layer Definition

Defines a layer as a set of sets of classes.
       layer <layer name> = <term>1..*
where <layer name> is the unique name of the layer. It should not contain whitespaces. <term> is either the name of a set as defined in a set definition or a wild-card pattern.
Each term defines a set of classes. The layer is a set of such sets.

4.2.2 Statements

All statements yield a result which is either ok or not ok. Set Display Preference

Define display preferences.
       show <preference>
where <preference> is a preference recognized by the used ResultRenderer. Currently all ResultRenderers take care of preferenced created by the DefaultPreferenceFactory.
The display preference controls rendering of the results of all statements following this statement. The result of this statement type is always ok. Check Sets

Checks whether sets of classes are empty or not.
       check sets <set>1..*
where <set> is either the name of a set as defined in a set definition or a wild-card pattern.
Checks whether the specified sets are empty or not. The result is ok if each set contains at least one class.

The main purpose of this command is to find out missspelled set definitions. Check Cycles

Checks whether a set of classes has a class/package cycles exceeding a defined size.
       check absenceOfClassCycles > <maximum size> in <set>
       check absenceOfPackageCycles > <maximum size> in <set>
where <maximum size> is the maximum number of classes/package a cycle (more precisely: a strong component) is allowed to have. It must be a positive number. <set> is either the name of a set as defined in a set definition or a wild-card pattern.
If there are no cycles in the specified set exceeding the maximum size the result is ok.

Note that strong components might not be detected if they are only partially covered by the specified set. Check Classes Dependency

Checks whether sets of classes are dependent/independent from other sets of classes.
       check <set>1..* independentOf <set>1..*
       check <set>1..* directlyIndependentOf <set>1..*
       check <set>1..* dependentOnlyOn <set>1..*
where <set> is either the name of a set as defined in a set definition or a wild-card pattern.
  • independentOf/directlyIndependentOf: It checks whether a path is found from a class in a set defined by the sets in the left group to a class in a set of the right group. The result is ok if no path is found. The operation directlyIndependentOf does a weaker check: It looks only for direct references from classes in the left sets to classes in the right sets. If dependencies are found the subgraph will be stored in the result.

    If groups of sets are specified either left or right the statement will be broken down to statements for pairs where one set is from the left group and the other one from the right group. Thus a original statement with n left sets and m right sets turns into n times m statements.

  • dependentOnlyOn: It checks whether each set of the left group depends directly only on itself or on the union of all sets of the right group. That is, the check fails if there is a class of one of the sets of the left group which directly depends on a class which is neither in its defining set nor in one of the sets of the right group.

    If the left group has more than one set the statement will be broken down to n statements, where n is the number of sets in the left group. Each statement checks the dependency of only one set. Check Layering

Checks a layer architecture.
       check layeringOf <layer>1..*
       check strictLayeringOf <layer>1..*
where <layer> denotes a name of a layer defined in a layer definition.
This is a convenient statement for checking whether a stack of layers build a layered architecture or not. The left-most (right-most) layer is the bottom (top) layer. The statement is turned into several statements of the type checking direct independency (directlyIndependentOf) for the following dependencies which are all not allowed:
  • Between the sets defining a layer.
  • From a lower layer to an upper layer.
  • From an upper layer to a layer not directly underneath if strictLayeringOf is used.
Here is an example with five sets organized in three layers. The arrows show the allowed direct dependencies. All other direct dependencies are forbidden. The dashed arrows show forbidden dependencies in the case of strict layering.
This article has been translated to