Architecture Definition and Checking with Classycle

Wissenswertes
1 Kommentar

Classycle [1] is a nice little utility for checking your internal Java program architecture. It can find cycles and can also check conformance with an architecture definition. You can check at the package level and at the class level. It’s compact, runs fast and it’s quite easy to use. Another neat fact is that it is open source and therefore doesn’t cost anything.

At Catalysts we use it for defining the Taskmind [2] architecture and I recently used it to help define the architecture for a customer project. The customer requires keeping license costs to a minimum (or preferably zero) so commercial tools cannot really be considered.

Why Manage Your Internal Code Dependencies?

In short to promote reuse, modularization, maintainability etc and to avoid rigidity etc. See Robert C Martin’s paper for a great explanation [3].

Parts of Classycle

There are two main parts to Classycle: the Analyzer and the Dependency Checker.

Analyzer

The analyzer doesn’t require you to define any input parameters (except telling it where the code is). It runs through your code and outputs a report which contains details of package cycles, class cycles and automatically determined layers.

The Analyzer firstly uses “Tarjan’s strongly connected components algorithm” to condense the directed graph of components into groups of strongly connected components. Then it walks this graph to find cycles.

Here is some sample analyzer output:

Sample of Classycle Analyzer Output

Dependency Checker

The Dependency Checker takes an architecture definition and checks your code against it. Anything which does not conform to the architecture is flagged. The architecture is defined by you in a “.ddf” file. You can specify which sets of packages are allowed to use which other sets of packages. You can also specify horizontal and vertical layers.

Example of a Classycle DDF file (from Classycle website):

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.* 
javax.swing.*

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

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

check layeringOf basic dependency

Ant Tasks

Classycle provides Ant [4] tasks for integrating the Analyzer and DependencyChecker into your build process.

Example of an ANT xml task definition (from Classycle website):

<project name="Classycle Ant Task Example" default="report" basedir=".">
  <taskdef name="classycleReport" classname="classycle.ant.ReportTask"/>

  <target name="report">
    <classycleReport reportFile="classycle.xml">
      <fileset dir=".">
        <include name="classycle.jar"/>
      </fileset>
    </classycleReport>
  </target>
</project>

Modifications by Me

Although the Analyzer generates a nice XML report, the existing Dependency Checker report just consists of plain text. Our customer requested that we produce a nicer looking dependency report. Looking at the documentation I saw that there was a ReportRenderer interface with one implementation class (DefaultReportRenderer). I assumed I could just create a different implementation which outputs HTML so I told the customer it would be no problem.

However when I started trying to implement it I saw that it was not as easy as injecting one different class. The plain text output was distributed across several classes and was actually impossible to replace (without code modification) because it came from toString() methods in internal classes which in turn used concrete classes not visible outside their package. This shows that the actual implementation of Classycle does not use dependency injection (everywhere). I then decided to import the Classycle source code into my Eclipse [5] workspace and start refactoring the code to make it possible to do what I originally wanted.

Unfortunately the refactoring was taking too long so (on the suggestion of a colleague) I went a different route. Instead of writing a replacement “renderer”, I wrote a class that takes the text output from the existing renderer and converts it to HTML in a separate step. Doing it this way required only minimal refactoring (mostly just a bit in the Dependency Checker Ant Task).

Things I Learned While Developing

How to write an Ant Task

I was surprised that it’s quite easy to write an Ant Task. You just need to extend org.apache.tools.ant.Task and implement the execute() method. You can define set methods for setting configuration parameters which can be passed from the Ant XML.

How to Debug an Ant Task

I needed a way to debug into the Classycle Ant Task and custom renderer. When you start an Ant Task from Eclipse you can’t debug into it because Ant runs as a separate program from Eclipse. One way to solve this is to start a headless Eclipse instance (eclipsec.exe) with the antRunner application and include the “wait for debugger” parameters:

set ECLIPSE_HOME=C:eclipseeclipse-jee-galileo-SR2-win32
set WORKSPACE=C:workspacestemp_dependency_checker_dev
set PROJECTS_BASE_DIR=C:project
set PROJECT=my.project.name

%ECLIPSE_HOME%eclipsec.exe -nosplash -data %WORKSPACE%
-application org.eclipse.ant.core.antRunner -buildfile
%PROJECTS_BASE_DIR%%PROJECT%classycledependencyCheck.xml
-vmargs -Xdebug -Xnoagent -Djava.compiler=NONE
-Dclasspath=%PROJECTS_BASE_DIR%%PROJECT%libclassycle.jar;
%PROJECTS_BASE_DIR%%PROJECT%libclassycle_extensions.jar
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8086

Then back in your original Eclipse you start the remote debugger (connecting to the specified port) and it will stop at your breakpoints.

Shortcomings

One thing I would like to see in Classycle is some kind of X ‘uses only’ Y keyword. Availing of the ‘independentOf’ keyword, it is still possible to achieve the same effect but you first have to define the complement set of Y and then say X ‘independentOf’ Y-complement. Unfortunately this leads to poor readability of the definition file for a big code base.

Alternatives to Classycle

There are quite a few commercial alternatives to Classycle which generally provide nice graphical user interfaces (Classycle itself is command-line), IDE integration, some more powerful commands and fancier reports. They usually enable you to track metrics over time, so you can get an idea whether your architecture is improving or not. The alternatives include Structure101 [6], SonarJ [7], and Lattix [8].

Conclusion

Classycle seems to be the best free tool available at the moment for internal dependency checking and management. However, if you want 1) nicer reports 2) more convenient syntax 3) a graphical user interface you will probably need to look at a commercial tool.

Links

[1] Classycle http://classycle.sourceforge.net/
[2] Taskmind http://www.taskmind.net/en/
[3] Design Principles and Design Patterns by Robert C Martin http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf
[4] Ant http://ant.apache.org/
[5] Eclipse http://www.eclipse.org/
[6] Structure101 http://www.headwaysoftware.com/products/structure101/index.php
[7] SonarJ http://www.hello2morrow.com/products/sonarj
[8] Lattix http://www.lattix.com/

Vorheriger Beitrag
VMWare Server 2 unter Windows 7 64 bit: 503 Service Unavailable
Nächster Beitrag
Usability-Tests für Jedermann

Related Posts

21. Wissensspritze: Actionscript Strukturanalyse mit Structure101g

Structure101 ist im Java Umfeld schon länger als mächtiges Werkzeug zur Sourcecode-Strukturalanyse und Überwachung bekannt. Mit Structure101g bietet Headwaysoftware eine generische Variante dieses Tools, die mittels geeigneten Plugins beliebige Daten analysieren kann. Diese Wissenspritze widmet sich Structure101g für Actionscript, das von Headwaysoftware und Catalysts gemainsam entwickelt wurde.

Weiterlesen

1 Kommentar. Hinterlasse eine Antwort

Hi Ray,

If I understood correctly classycle from the documentation it analyzes for cycles first and then does the layering, because a layered architecture doesn’t contain cycles.

As for producing reports, what I did (I wanted to insert the data in a database for further processing, not reporting) is that I used a tool called trang to create an xml schema definition from the xml file produced by classycle. I then used xjc to get JAXB classes and then it was straightforward with JAXB to get the data from the XML file and store (some of it) in a database.

Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Bitte füllen Sie dieses Feld aus
Bitte füllen Sie dieses Feld aus
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren

Menü