A good Design-by-Contract library for Java? [closed]
Asked Answered
S

10

47

A few years ago, I did a survey of DbC packages for Java, and I wasn't wholly satisfied with any of them. Unfortunately I didn't keep good notes on my findings, and I assume things have changed. Would anybody care to compare and contrast different DbC packages for Java?

Sabec answered 2/7, 2009 at 17:38 Comment(0)
V
24

There is a nice overview on WikiPedia about Design by Contract, at the end there is a section regarding languages with third party support libraries, which includes a nice serie of Java libraries. Most of these Java libraries are based on Java Assertions.

In the case you only need Precondition Checking there is also a lightweight Validate Method Arguments solution, at SourceForge under Java Argument Validation (Plain Java implementation).

Depending on your problem, maybe the OVal framework, for field/property Constraints validation is a good choice. This framework lets you place the Constraints in all kind of different forms (Annotations, POJO, XML). Create customer constraints through POJO or scripting languages (JavaScript, Groovy, BeanShell, OGNL, MVEL). And it also party implements Programming by Contract.

Victimize answered 30/1, 2010 at 14:7 Comment(2)
OVal looks impressive. I'd venture to say it's about as good as DbC in Java can get.Sabec
I'm not sure a comment here is the best place/way, but just for the next ones reading: Contracts for Java - cofoja is a recent addition straight from Google's 20% time research.Dedradedric
U
6

Google has a open source library called contracts for java.

Contracts for Java is our new open source tool. Preconditions, postconditions, and invariants are added as Java boolean expressions inside annotations. By default these do nothing, but enabled via a JVM argument, they’re checked at runtime.

• @Requires, @Ensures, @ThrowEnsures and @Invariant specify contracts as Java boolean expressions
• Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime

contracts for java.

Unutterable answered 30/6, 2013 at 5:21 Comment(0)
E
2

I tested contract4J one time and found it usable but not perfect. You are creating contracts for for and after method calls and invars over the whole class.

The contract is created as an assertion for the method. The Problem is that the contract itself is written in a string so you don't have IDE support for the contracts or compile time cheching if the contract still works.

A link to the library

Estivate answered 2/7, 2009 at 17:59 Comment(0)
B
2

It's been a long time since I've looked at these, but found some old links. One was for JASS.

The other one that I had used (and liked) was iContract by Reliable Systems. It had an ant task that you would run as a preprocessor. However, I can't seem to find it with some google searches, it looks like it has vanished. The original site is now a link farm. Check out this link for some possible ways to get to it.

Blowtorch answered 2/7, 2009 at 21:17 Comment(1)
The most recent version of JASS is from July 2005. I'm not going to speculate about what versions of the JDK it supports. JASS has a link to JML, though, which looks to be under active development.Sabec
A
2

I'd highly recommend you to consider the Java Modeling Language (JML).

Apospory answered 18/4, 2010 at 22:29 Comment(0)
V
2

There is a Groovy extensions that enables Design by Contract(tm) in Groovy/Java code - GContracts. It uses so-called closure annotations to specify class invariants, pre- and postconditions. Examples can be found on the project's github wiki.

Major advantage: it is only a single jar without external dependencies and it can be resolved via Maven compliant repositories since its been placed in the central Maven repo.

Vyborg answered 3/8, 2010 at 7:59 Comment(2)
I do not think we can use GContracts in a Java Project, as GContracts makes heavy use of Groovy ClosuresGordan
That's right, it's a Groovy-only library.Vyborg
H
1

If you want a plain and simple basic support for expressing your contracts, have a look on valid4j (found on Maven Central as org.valid4j:valid4j). It lets you express your contracts using regular hamcrest-matchers in plain code (no annotations, nor comments).

For preconditions and postconditions (basically assertions -> throwing AssertionError):

import static org.valid4j.Assertive.*;

require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));

If you are not happy with the default global policy (throwing AssertionError), valid4j provides a customization mechanism that let's you provide your own implementation of org.valid4j.AssertiveProvider.

Links:

Hoopla answered 8/12, 2014 at 23:3 Comment(2)
Anybody got a spreadsheet of the comparisons for this ? A feature matrix would be great.Glacis
valid4j looks more like assertion library (just like Java's popular AssertJ, or Groovy's advanced assert), not as like full DBC tool (like OVal or Cofoja)Ameeameer
A
1

I would suggest a combination of a few tools:

  • Java's assert condition... or it's more advanced Groovy cousin, Guava's Preconditions.checkXXXX(condition...) and Verify.verify(condition...), or a library like AssertJ, if all you need is just to do simple checks in your 'main' or 'test' code

  • you'll get more features with a tool like OVal; it can check both objects as well as method arguments and results, you can also fire checks manually (eg to show validation errors on UI before a method is called). It can understand existing annotations eg from JPA or javax.validation (like @NotNull, @Pattern, @Column), or you can write inline constraints like @Pre(expr="x >= 0 && x <= y"). If the annotation is @Documented, the checks will be also visible in Javadocs (you don't have to describe them there as well).

  • OVal uses reflection, which can make performance issues and other problems in some environments like Android; then you should consider tool like Google's Cofoja, which has less functionality, but depends on compile-time Annotation Processing Tool instead of reflection

Ameeameer answered 9/3, 2016 at 14:47 Comment(0)
L
0

I think that many DbC libraries were surclassed by the builtin assert keyword, introduced since Java 1.4:

  • it is a built-in, no other library is required
  • it works with inheritance
  • you can activate/deactivate on package basis
  • easy to refactoring (e.g. no assertions in comments)
Ladyfinger answered 2/7, 2009 at 17:53 Comment(2)
but SUN writes "Do not use assertions to check the parameters of a public method" in java.sun.com/javase/6/docs/technotes/guides/language/…Uninterrupted
More to the point, DbC should make it easy to add contracts to your code. If it's not easy, most developers won't do it. It's possible to implement class invariants using assertions and calls to a class invariant method, but it's clumsy.Sabec
G
0

I personally think that the DbC libraries available at present have left a lot to be desired, none of the libraries i looked at played well with the Bean Validation API.

The libraries i looked at have been documented here

The Bean Validation API has a lot of over lap with the concepts from DbC. In certain cases Bean Validation API cannot be used like simple POJO's (non CDI managed code). IMO a think wrapper around the Bean Validation API should suffice.

I found that the existing libraries are a little tricky to add into existing web projects given that they are implemented either via AOP or Byte code instrumentation. Probably with the advent of Bean Validation API this kind of complexity to implement DbC is unwarranted.

I have also documented my rant in this post and hope to build a small library which leverages on the Bean Validation API

Gordan answered 10/9, 2013 at 16:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.