Code Quality & Java 01 Aug 2007 01:30 pm

Enforcing Package Dependencies (Part 4)

Macker is my prefered tool for java package dependency enforment. It is a free tool licenced under GPL.

While Macker is not as simple as Japan to configure, it is not difficult and is considerably more powerful. Like Japan, Macker is configured via XML and is designed to be integrated into an ant build.

Here is a sample macker configuration file.

<?xml version="1.0"?>
<macker>
<ruleset name="Module dependency checking rules">
<var name="base" value="com.gigantiq.bedrock"/>

<pattern name=”root”>
<include class=”${base}.**”/>
</pattern>

<pattern name=”model”>
<include class=”${base}.model.**”/>
</pattern>

<pattern name=”ui”>
<include class=”${base}.ui.**”/>
</pattern>

<pattern name=”util”>
<include class=”${base}.util.**”/>
</pattern>

<!– Dependency rules –>
<access-rule>
<message>model package class ${from} cannot use class ${to}</message>
<deny><from pattern=”model”/><to pattern=”root”/></deny>
<allow><to pattern=”model”/></allow>
<allow><to pattern=”ui”/></allow>
</access-rule>

<access-rule>
<message>ui package class ${from} cannot use class ${to}</message>
<deny><from pattern=”ui”/><to pattern=”root”/></deny>
<allow><to pattern=”ui”/></allow>
</access-rule>

<access-rule>
<message>util package class ${from} cannot use class ${to}</message>
<deny><from pattern=”util”/><to pattern=”root”/></deny>
<allow><to pattern=”util”/></allow>
<allow><to pattern=”model”/></allow>
<allow><to pattern=”ui”/></allow>
</access-rule>
</ruleset>
</macker>
The pattern element allows us to define patterns that can be re-used in the macker rules that we define. In this example I have used the pattern elements to define the packages that will be referred to in the macker rules.

We can now define our package dependencies using the access-rule element. For example:

<access-rule>
<message>model package class ${from} cannot use class ${to}</message>
<deny><from pattern="model"/><to pattern="root"/></deny>
<allow><to pattern="model"/></allow>
<allow><to pattern="ui"/></allow>
</access-rule>

In this fragment I define that the model and ui packages are the only packages that can depend on the model package. I have also used the ${from} and ${to} in the message element to ensure that a readible message is produced on an access rule voilation. The message produced will contain the names of the classes responsible for the voilation.

The macker site contains plenty of examples that illustrate some of the capabilities of macker.

Like Japan, Macker includes a built in ant target that makes integration with an ant build very simple. The added time introduced to your build by adding macker should be minimal even on a large code base (less than 10 seconds).

Something I considered trying at one stage was to use XSLT to produce a GraphML file from the macker configuration file so that the defined package dependencies could be viewed in graphical manner using tools such as yEd. I have not had an opportunity to try this yet to see if it would work. If I do, I will post the results on this blog.

Comments are closed.