Over a million developers have joined DZone.
Platinum Partner

Assert Yourself With Chex4j

· Java Zone

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.

Chex4j is a framework for documenting and enforcing the pre- and post-conditions of Java method calls.  To use chex4j you add @Contract, @Pre and @Post conditions to the methods of your Java classes and interfaces:

public class SimpleBankAccount {

@Pre(value="amount.doubleValue() >= 0.0d", message="Can only withdraw a postive amount.")
@Post(value="$_.doubleValue() >= 0.0d", message="Cannot go overdrawn.")
public BigDecimal withdraw(BigDecimal amount) {
this.balance = this.balance.subtract(amount);
return this.balance;
... // other members

The chex annotations act as additional documentation about your code. If you add chex to your interfaces then any class which implements your interface will have the logic injected into it at load-time. This will work even if it is 3rd party code where you do not have access to the source code.

Alternatively you can leave the annotation value property blank and chex4j will automatically resolve and invoke a $Pre or $Post method:

public class LimitedMaximumBankAccount {
@Pre(message="Negative deposit.") // invokes deposit$Pre(amount)
@Post(message="Balance exceeds 25k.") // invokes deposit$Post(amount)
public BigDecimal deposit(BigDecimal amount) {
this.balance = this.balance.add(amount);
return this.balance;

private boolean deposit$Pre(BigDecimal amount){
return amount.doubleValue() >= 0.0d;

private boolean deposit$Post(BigDecimal amount){
return this.balance.doubleValue() <= 25000;
... // other members

When you enable the chex4j javaagent within your IDE (or test server) the annotation value (the "chex") will be injected into the body of the method. Should the chex expression return false an assertion error will be thrown naming the chex which failed; this reflects the fact that it is a programmatic error to violate the constraint.

The syntax of the injected code can be any valid Java code. You can also use Javassist variables of the annotated method. A selection of useful method variables are shown below:  

$0, $1, $2, ...
Actual parameters by position (consider just using the method argument name)
Array of parameters. The type of $args is Object[]
All actual parameters. For example, m($$) is equivalent to m($1,$2,...)
The return type. It is used in a cast expression.
The resulting value (the anonymous return variable).

Running It - Online Mode
Chex4j supplies a javaagent which instruments classes at load-time using the JBoss Javassist toolkit. With online mode the Javassist jar has to be available when your classes are loaded.
The correct version of Javassist to use is named within the chex4j pom.xml. It can be made accessible to the chex4j javaagent with a JVM argument:


Note the "/a:" is not a drive letter it is the jvm flag meaning "append to boot classpath".

The chex4j javaagent is enabled with a VM parameter such as:


where after the '=' is a comma separated list of package names for the javaagent to instrument. Note that you must add the "..." to each package name. This is the syntax used by the the standard JVM -ea flag.

Running It - Offline Mode

The javaagent is very useful when running your junit tests within an IDE as it will be immediate. If you want to deploy the code with the chex enabled (and without using a javaagent) you can use the ChexOfflineMain class as part of your build. The chex4j source code provides an example ant file "ant-compile-time-chex4j.xml" which runs ChexOfflineMain to bake the chex bytecode into the class files for easy deployment onto an application server

When running in offline mode there is no requirement for either a javaagent nor the javassist library. There will be a runtime dependency on the chex4j jar file to supply the assertion throwing behaviour.


The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}