This section describes how you can check specified project rules during your application's build process. The idea behind this concept
is that the build server normally is the machine that holds most of the code base. So searching here should check all code available (or better
the code that should be checked really). The CQL AntTask checks CQL rules defined in XML files.
In this context it has to be distinguished between ruleset (Ruleset XSD) and execution logic
(Instruction Book XSD). A ruleset consists of several CQL rules. They can be run against diverse codebases
or shared among various projects. Because rules are executed in different environments they do not contain any environment specific
information. To specify which rules are executed and to associate environment specific information with an rule, the concept of
instruction book is employed. Furthermore, result thresholds, fail criteria or build messages can be specified within an instruction book.
The specification can be found here.
Simple Usage Example
Let's assume there exists a company that develops various java-based applications sharing the core module.
For the core module there exist several project rules defined by the chief architects. Because each application depends on that module,
these rules are also relevant for the applications' code. But different applications also require different rules to fit the application's
architecture (e.g. J2SE application vs. J2EE application).
In other words: for each application there exists a custom instruction book that uses rules of the core module and application
specific rules. Furthermore this instruction book imports some instruction of the core module's instruction book as well as defines own instructions.
The take a look at a simple configuration for the CQL Ant Task. The ruleset is the Codestyle Ruleset published by REFLECTK.
The instruction book is shown in the following listing. Because the build process runs on a multi-processor system and some rules need
much execution time, the instruction book specifies that the rules should be check by 2 concurrent threads. To check only the 10 most
important rules the following instruction book is used.
The following picture shows how the CQL Ant Task is used.
The output may look like this:
Extended Usage Example
There exists a bunch of situations where you want to break your build process because the resulting software contains errors that would prevent a normal execution of the software. One example is to check the classes you'll load by reflection inside your application if they have a public default (noarg) constructor.
You can archive this by adding a CQL rule like this to your ruleset/instruction book:
That way all classes inheriting iface.or.superclass.of.classes.loaded.by.Reflection must define a public default constructor otherwise the build will break.
In the example above you'd have to add other classes each time you introducing other reflection based hierarchies, e.g:
We suggest the usage of annotations to ensure that new classes/class hierarchies can easily be included in this check. When using annotations you can define the following fixed CQL which no more has to be changed or extended:
You don't have to change the CQL any more; If there's a new class or even an whole class hierarchy you're going to load in your application just annotate the class with the your.pkg.LoadedByReflection annotation.
Why not use APT to solve this problem? There's an really nice article by Dr. Heinz M. Kabutz describing how to solve the mentioned
problem by using APT but this is not a safe solution: You're checking the bytecode the compiler generated not the bytecode you would deliver to your customers.
It's not uncommonness that an compiler generates or leave an existing default constructor untouched while a following obfuscator/shrinker removes this default constructor because it can't find a reference to it and therefore wrongly thinks it's unused.
So your check would have pass but your production code would fail at your customers.
Other things to check during build to prevent errors at runtime:
- Check your classnames to be free of special characters (like umlauts)
- Check for unresolved references (missing classes/jars)
- Check your serialzable classes if they can be serialized and deserialized (we provide such CQLs, see our CQL library)
How to integrate in your Build Process
- Create an instructionbook (based on cql-instbook.xsd), containing the names of the rules you want to check and the paths to the rulesets defining this rulesets
- Save reflectk-ant-nodeps-1.2.0.jar to the computer the build.xml resides on
- Add a task definition to your build.xml
- use the cql task in a target in the buildfile
Use your own rulesets
It's very easy to integrate your company and/or project specific rule into the scenarios created above.
First create a ruleset containing your rules to be checked and place them at the same location you did with the other rulesets.
Now you can use the in your instructionbook by adding the location in the location section:
and by referencing them in an instruction like the others described above:
yourIdentifier is only used for informational output if the rule will fail