Download Latest Version chex4j-core-1.0.2-javadoc.jar (87.4 kB)
Email in envelope

Get an email when there's a new version of chex4j

Home / 1.0.2
Name Modified Size InfoDownloads / Week
Parent folder
README.txt 2011-04-03 8.8 kB
chex4j-core-1.0.2-sources.jar.asc 2011-04-03 490 Bytes
chex4j-core-1.0.2-sources.jar 2011-04-03 17.6 kB
chex4j-core-1.0.2-javadoc.jar.asc 2011-04-03 490 Bytes
chex4j-core-1.0.2-javadoc.jar 2011-04-03 87.4 kB
chex4j-core-1.0.2.pom.asc 2011-04-03 490 Bytes
chex4j-core-1.0.2.pom 2011-04-03 2.3 kB
chex4j-core-1.0.2.jar.asc 2011-04-03 490 Bytes
chex4j-core-1.0.2.jar 2011-04-03 28.0 kB
chex4j-1.0.2.pom.asc 2011-04-03 490 Bytes
chex4j-1.0.2.pom 2011-04-03 5.3 kB
Totals: 11 Items   151.9 kB 0
Copyright 2010 Simon Massey. All rights reserved. net.sf.chex4j is licensed 
under the terms of the Eclipse Public License v1.0, as defined by the attached 
file LICENSE-ECLIPSE.txt. 

Simon Massey (simon at my full name ( no punctuation ) dot org).

Description: 

	chex4j is a framework for documenting and enforcing the pre- and post-
	conditions of method calls. Inspired by contract4j it is intended to 
	enforce a form of Design By Contract.
	
	To use chex4j you add @Contract, @Pre and @Post conditions to methods 
	within your classes and interfaces:
	
	@Contract
	public class SimplePublicBankAccount {
	 
	    @Post("amount.doubleValue() >= 0.0d")
	    public SimplePublicBankAccount(BigDecimal amount ){
	        this.balance = amount;
	    }
	     
	    @Post("$_.doubleValue() >= 0.0d")
	    public BigDecimal getBalance() {
	        return this.balance;
	    }
	 
	    ... // other members
	 
	}
	
	Alternatively you can leave the annotation value propery blank and chex4j 
	will automatically resolve and invoke a $Pre or $Post method as the chex:
	
	@Contract
	public class SimplePublicBankAccount {
	 
	    @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;
	    }
	     
	    @SuppressWarnings("unused")
	    private boolean deposit$Pre(BigDecimal amount){
	        return amount.doubleValue() >= 0.0d;
	    }
	     
	    @SuppressWarnings("unused")
	    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 
	value attribute of the annotations (the "chex") will be compiled into java 
	bytecode using the jboss javassist framework and injected into the body of 
	the method. Should the boolean chex expression return false an assertion 
	error will be thrown detailing the chex that failed - this reflects the 
	fact that it is a programmatic error to violate the constraint.
	
	Chex4j has an offline mode where it can be used to transform classes as 
	part of your build.
	
	The annotations (know as "chex") act as additional documentation about your 
	code. If you annotate methods on an interface then any class which 
	implements your interface the chex will compiled and injected into it at 
	class load time. This will work even if it is 3rd party code where you do 
	not have access to the source code.
	
	The syntax of the injected code can be any valid Javassist code which 
	evaluates to a boolean e.g. "$_" is the value returned by the method:

	whatever		Any valid java code. Javassist appears to reverse engineer the source code of the class and method body.
	$0, $1, $2, ...	Actual parameters by position (typically just use the method argument name not the argument position)
	$args			An array of parameters. The type of $args is Object[].
	$$				All actual parameters. For example, m($$) is equivalent to m($1,$2,...)
 	$cflow(...)		cflow variable
	$r				The result type. It is used in a cast expression.
	$w				The wrapper type. It is used in a cast expression.
	$_				The resulting value
	$sig			An array of java.lang.Class objects representing the formal parameter types.
	$type			A java.lang.Class object representing the formal result type.
	$class			A java.lang.Class object representing the class currently edited.  

	see http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial2.html#before
	
Running It - Online Mode

	chex4j has a javaagent which instruments classes at load time using the 
	JBoss Javaassist toolkit. This means that Javassist has to be loadable 
	when your classes are loaded to run in 'online mode'.
	
	The correct version of Javassit to use is named within the chex4j 
	pom.xml this can be made accessible to the chex4j javaagent with a JVM 
	argument such as following (note the "/a:" is not a drive letter it is 
	the jvm flag meaning "append to boot classpath"):
	
		-Xbootclasspath/a:/some/path/to/javassist-3.14.0-GA.jar
	
	The chex4j javaagent is then run from within the chex4j jar file with 
	a VM flag such as:
	
		-javaagent:target/chex4j-core-1.0.1.jar=net.sf.chex4j...,chex4j.test...,dir=target/chex4j
	
	where after the '=' is a comma separated list of package names for 
	the javaagent to byte code instrument. Note that you must add the 
	"..." to each package name which is the same syntax as the standard 
	JVM -ea flag. The optional 'dir=' flag is the location to dump out 
	the instrumented class files.
	
	Take a look at the embedded ant task within the 
	chex4j-test/ant-run-time-chex4j.xml to see an example of using ant to 
	fork a jvm enabling the javaagent as documented above.

Running It - Offline Mode

	The javaagent is very useful when running your junit tests particular 
	within an IDE as it will be immediate. If you want to deploy the code 
	with the chex enabled you may wish to use the ChexOfflineMain class 
	as part of your build. Take a look at the ant example in 
	chex4j-test/ant-compile-time-chex4j.xml

Building It

	On the commandline a build looks like:
	
	mvn install

	Note that because it is a javaagent the test cases are in a separate 
	subproject which forks a jvm to set the javaagent vm setting. This 
	means that you will notice that mvn outputs that it is skipping 
	tests but you will also see output of JUnit4.7 text test runner 
	actually running the tests that are launched using the 
	maven-ant-plugin within the chex4j-test project.

Release Notes:

	1.0.2
	
	Pom change to support release to maven central via oss.sonatype.org. 

	1.0.1
	
	Upgraded to javassist 3.14.0-GA.

	1.0.0
	
	No new features. Worked on the maven website build. Polished the code 
	coverage.  

	1.0.0-RC2

	Implemented David Gargiulo feature request to have a convention where the 
	code for the chex can be a regular method in the class. A @Pre or a @Post
	which does not have a value will look to invoke methodName$Pre or 
	methodName$Post as the chex logic; where methodName is the name of the 
	method which carries the annotation.  

	1.0.0-RC1
	
	Release Candidate 1. Fixed missing Hamcrest jar on forked jvm chex-test. 

	1.0.0-FL20100815
	
	Finally settled on a strategy for junit testing the javaagent: moved the  
	tests into a different project 'chex4j-test' as the main classes in that  
	project. The test project has skip-tests true but then forks a jvm with  
	ant which runs activates the javaagent and invokes junit test runner on 
	a test suite.     

	1.0.0-FL20100221
	
	Have refactored to create OfflineClassTransformer to do build time class 
	transformations.  

	1.0.0-FL20100221
	
	Broken out the main code into a module below a superpom and have added the  
	beginnings of maven plugin. The plugin is there to launch a new JVM with 
	the chex4j javaagent enabled during the course of the build.
	
	For test builds throwing an AssertionEror might be a bit too strong. The 
	Assert class now looks for 
	
	 	-Dnet.sf.chex4j.internal.Assert.DONT_THROW_ERROR=true
	
	and will only complain to System.err if it finds that entry. 

	1.0.0-FL20100216
	
	Added ant build script (mostly generated with "mvn ant:ant") with a target
	test-instrumented-classes which forks java and runs the instrumented classes
	within junit. 
	
	Added skip tests 'true' to the maven surefile plug-in configuration. 
	
	Added an option to dump out the instrumented class files using an optional
	dir= option to the javaagent: 
	
		-javaagent:target/chex4j-1.0.0-FL20100216.jar=net.sf.chex4j...,chex4j.test...,dir=target/chex4j

	This should allow for packaging up the instrumented classes to run on a 
	test server. May also be a good route into ant integration.
	
	1.0.0-FL20100214
	
	For features see the JUnit tests under src/test/java. 
	@Pre and @Post seem to work on constructors, public class methods, 
	package protected methods, interface methods and in abstract class 
	hierarchies.
	
	Works with linux jre1.5.0_21, jdk1.6.0_16 and jdk1.7.0_b83 
	as well as windows jre1.6.   
	
	To use this library you must specify the following VM argument: 
		-javaagent:path/to/chex4j-1.0.0-FL20100214.jar=com.x.y...,com.a.b...
	where com.x.y and com.a.b are the package name of the classes that 
	you wish to instrument. You must add three full stops to the end of them 
	to match the syntax of the standard JVM -ea option. 
	
	"mvn test" does not run the tests successfully as the javaagent is not 
	being applied. Eclipse junit runner works fine with the javaagent flag. 
	This is likely to be classworlds/plexus classloader stuff. I will take a 
	look at alternative ways to fork the tests.  

Enjoy, 

Simon
Source: README.txt, updated 2011-04-03