GContracts 1.1.3 Released!I am proud to announce that GContracts 1.1.3 has just been released and is available now in the Central Maven repository  and at Github . The release includes bug fixes and advanced support Spring bean classes annotated with GContracts' annotations.
In parallel with
@EnsuresGContracts 1.1.3 provides separate exception types which all are descendants of
AssertionErrorand I guess do not need further explanation:
Advanced Support for Spring BeansOne of the problems with GContracts is its lack of compatibility especially with Grails artifact classes, i.e. controllers, services, domain classes etc. This topic has been brought to me a few times and if you just want to apply let's say class invariants on Spring bean classes the Spring application container's initialization lifecycle can quickly become your enemy. Let's consider the following service:
MyServiceis a simple Grails service class, annotated with a class invariant which ensures that the reference to
anotherServicewill never be
null, during the entire life-time of the
MyServicebean. Sadly enough, whenever the Spring application container tries to create a new instance of a
MyServicebean it fails because GContracts checks the class invariant directly after the object's constructor has completed successfully. By that time, the Spring application container is not yet done with object construction. From a theoretical perspective throwing a
ClassInvariantViolationin this place is completely reasonable since an object's class invariant needs to be fulfilled by the object instance during its entire life-time. But from a practical perspective, this is kind of pain. It means that you have to duplicate the class invariant to all methods in the service class, e.g. It is not that Design by Contract can not be applied here, it is that Spring simply does define its own rules for object creation and destruction, meaning that whenever an object is created with its constructor the initialization process is not done in the case of the Spring application container. This circumstance confuses programmers who simply want to apply DbC on their bean classes without thinking about Spring initialization mechanisms and GContracts assertion injection. GContracts 1.1.3 is the starting point for a bunch of features which are targeted to iron out such integration issues with Spring/Grails applications. Of course it might be questionable whether it makes sense to focus primarily on the Spring framework, but that has been a practical decision (GContracts is for Groovy, Grails uses Groovy, Grails uses Spring...). Furthermore, I tried to make the integration as light as possible without actually introducing a classpath dependency on Spring framework classes. The first feature which comes with 1.1.3 is a solution for the problem described above: class invariant checks on Spring beans. Henceforth, GContracts will not make class invariant checks on Spring beans during constructor calls, but will create a synthetic
@PostConstructmethod which overtakes the class invariant check. Since GContracts has no mechanism to know that the given class is a Spring-managed class at runtime, programmers need to annotate their artifact classes with appropriate stereotype annotations , e.g. a service class with
@Service, a controller with
@Controller, etc. The
@Servicestereotype annotation above triggers GContracts' "Spring compliance mode". Whenever the service bean above has been constructed by the Spring application container it will automatically check the class invariant. The programmer clearly needs to make a compromise in this case, because the class invariant won't be checked after a construction call anymore (e.g. in a test-case where the programmer simply creates an instance of this service class). But this is a consequence of outsourcing object creation to the application container. Hint: GContracts supports the
-daVM parameters  which you can use to deactivate assertion checking during application execution, whereas activating assertion checking only during test-cases.