Contract4J5 Is Available through GitHub and Maven
March 11th, 2010
This is looong overdue, but you can now manage dependencies on Contract4J5 using Maven. The details are here. Also, I moved the code from a private subversion repository to GitHub.
Contract4J5 is my Design by Contract library for Java. I haven’t worked on it in a while, but I hope to return to it sometime this year to solve the one issue that keeps it from being practical for many teams: performance. Currently, the runtime overhead slows down tests considerably. It is already feature complete and stable.
The Maven bundle includes the all the sources and javadocs, as well as the runtime jar file. However, it is still built with Ant. If you want to work with the source code, clone or fork the GitHub repo.
Speaking at CJUG, 5/19
May 19th, 2009
Update: The talk is tonight (Tuesday). The 4th Chicago Area Scala Enthusiasts meeting is Thursday evening.
I’m giving my JavaOne talk at CJUG this Tuesday evening.
The title is Don’t Do This! How Not to Write Java Software. I’ll discuss ten issues I often encounter in Enterprise Java applications, why they are bad, and how to correct them.
Please join me!
"The Seductions of Scala" Presentation
December 16th, 2008
I posted an S5-based presentation called The Seductions of Scala (Zip). I'm giving this presentation tonight at CJUG.
To view it, unzip the file and open html/all.html in your browser. Use the arrow keys to navigate or the controls in the lower right-hand corner (visible when you mouse over).
The corresponding code is in the code directory.
Feedback welcome and I hope to see you tonight!
ANN: Aquarium V0.4.0 Released with Initial Support for Java Aspects in Aquarium
February 26th, 2008
CJUG Downtown 12/18/07: Aspect-Oriented Programming and Software Design
December 8th, 2007
CJUG West 9/6/07: Aspect-Oriented Programming and Software Design
September 4th, 2007
ANN: OOPSLA Tutorial on "Principles of Aspect-Oriented Design in Java and AspectJ"
September 4th, 2007
AspectJ: Testing that Classes Implement All Required Interfaces
February 25th, 2007
declare error that would enforce the requirement that all classes implementing one interface, let's call it Foo, also implement a second interface Bar. He tried something like the following:
1 2 |
declare error: within(*..Foo+) && !within(*..*Bar+): |
within(*..Foo+) you get an error just on the Foo interface, not on any implementing classes or extending interfaces.
Through trial and error, I figured out that if you put these interfaces in dedicated packages, say ..foo and ..bar, respectively, the following does work:
1 2 |
declare error: within(*..foo.*+) && !within(*..foo.*) && !within(*..bar.*+): |
!within(*..foo.*) prevents errors on the interfaces in package foo itself.
This isn't especially obvious and you may find it inconvenient to package your interfaces like this, but it does work. Actually, there's a good case to be made for putting interfaces in separate packages like this, based on the Stable Abstractions Principle (PDF, see also here).
Groovy, JRuby, vs. Jexl Performance, Using Java 5 and Java 6
December 31st, 2006
I just released v0.7.0 of Contract4J5, which now supports Groovy and JRuby as alternative scripting languages, in addition to Jexl, the original language used. Along the way, I collected some performance numbers for the three alternatives.
The following discussion is adapted from the README for the v0.7.0 release.
I ran the JUnit test suite with all three languages. The numbers below show the performance when using binary weaving and load-time weaving (LTW) and also the performance using the JVMs in JDK 5 and JDK 6.
| JDK 5 (sec.) | JDK 6 (sec.) | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Jexl | Goovy | JRuby | Jexl | Goovy | JRuby | ||||||
| Binary | LTW | Binary | LTW | Binary | LTW | Binary | LTW | Binary | LTW | Binary | LTW |
| 21.7 | 98.6 | 54.9 | 324.4 | 79.6 | 189.4 | 17.7 | 62.9 | 44.8 | 133.5 | 63.2 | 108.4 |
These times are approximate "user times", averaged over a few runs, measured on a ThinkPad T42 running Ubuntu Linux. There are slightly different build activities and I/O overhead involved in the LTW numbers, adding a few percentage points to the numbers. The tests do some different manipulations depending on which interpreter is used. Hence, the results are rough, at best. Most likely, the numbers reflect the relative amounts of overhead to load the interpreters and to set up the "environments" for evaluating the scripts, which happens frequently in the test suite. Since the scripts are always very small, evaluation is probably not a large percentage of the execution time. (However, this is speculation!) Your mileage may vary...
Note that the JDK 6 performance is significantly better. The code was compiled
with the JDK 5 javac and executed using the JDK 6 JVM. Ironically, the performance was slightly slower when compiled with the JDK 6 javac. (This is not reflected in the numbers)
The Jexl test runs are roughly twice as fast as the Groovy and JRuby runs, probably because Jexl is a more "minimalist" environment, incurring less startup and execution overhead.
While not shown, I observed that the memory requirements for Groovy and JRuby are also higher, as you would expect. I didn't actually measure memory usage, but I observed this because it was necessary to increase the maximum heap size for the LTW JUnit run when using Groovy or JRuby. Also, when using JRuby, I had to increase the heap size for the binary-weaving JUnit runs in Eclipse.
The LTW test runs take significantly longer, but the results are somewhat hard to interpret. Under JDK 5, the Jexl and Groovy runs are five to six times longer, while the JRuby runs are only about 2.5 times longer. Under JDK 6, the Jexl and Groovy runs are a little more than three times longer, while the JRuby run is under twice as long. It is not clear why JRuby LTW configurations perform so much better under both JDKs. However, it is clear that, for all the interpreters, the startup byte-code instrumentation required for LTW is much better under JDK 6.
In general, the longer LTW times occur because a weaving step happens at the beginning of each TestCase, as the class is loaded. The JDK 6 speed-up is a good argument for running this VM, at least for your tests!
LTW is the most convenient way to adopt Contract4J5 (true for other aspects, as well), but if the startup time is too long for your needs, then binary weaving of compiled code provides better performance with only a modest change in your build process.
Contract4J5 v0.7.0 Is Now Available
December 31st, 2006
I just released v0.7.0 of Contract4J5. This release adds support for using Groovy or JRuby instead of Jexl as the scripting engine for the test scripts embedded in annotations. In fact, Groovy is now the default.
The advantage of Groovy or JRuby is that they provide a richer environment for more sophisticated testing. They are also better suited for planned, long-term enhancements of Contract4J5 to support user-configurable annotations and behaviors, which will take the tool beyond Design by Contract support.
The only major disadvantage over Jexl is lower performance. I'll blog about those results next. You can also find details in the README.
I was pleased to find that all but a few of the existing Jexl-based unit tests worked without modification for Groovy. With a few hacks, I got them to work for JRuby as well. The differences for Groovy include slight differences in how Goovy vs. Jexl handle protected access (private, protected, etc.). Also, Groovy does not force you to provide a public accessor to evaluate tests on member fields, which Jexl required.
For JRuby, I found that almost all Ruby vs. Java differences could be handled if I did a few simple replacements of the most common Java idioms in scripts with the corresponding Ruby idioms:
- Replace
equals(...)witheql?(...) - Replace
compareTo(...)with<=>(...) - Replace
nullwithnil
That is, Contract4J5, when using JRuby, will make these substitutions in your test expressions so they work, most of the time, even though they are written in Java syntax. This tends to work because the test expressions tend to be relatively simple and they often consist of comparisons to null or calls to String comparison methods.
Contract4J5 v0.6.0 Is Now Available
September 21st, 2006
Aspect-Oriented Design: "Humane Pointcut Languages"
April 21st, 2006
@MyAnnotation
public class Foo {
public Foo(...) {...}
...
}
He needed help writing the pointcut and advice for this case. Without repeating the whole conversation here, at one point I remarked that
call( @MyAnnotation * *.new(..) )matches constructors annotated with
@MyAnnotation, while
call( * (@MyAnnotation *).new(..) )matches constructors in classes where the class has the annotation. In fact, both are invalid expressions because the first
* is for the return type and there is no return type for constructors, so the first * shouldn't be there. Hence, the correct statement is that
call( @MyAnnotation *.new(..) )matches constructors annotated with
@MyAnnotation, while
call( (@MyAnnotation *).new(..) )matches constructors in classes where the class has the annotation.
p. This is the sort of mistake I make fairly often and I'm sure beginners really struggle with the pointcut syntax, although it's generally great for experts because it is both succinct and powerful. However, sometimes a more "human-readable", that is "humane", syntax can be a real benefit. In fact, I've been thinking about expressive pointcut languages quite a bit recently, not so much in this context, but more in the context of higher-level AOP abstractions. As I said in the discussion thread, it bothers me that we discuss high-level concerns, say for example security, then turn around and write PCD(Pointcut Definitions)s using very low-level primitives that tend to reference specific classes, methods, _etc._ Of course, I'm not the only person who thinks this way and the recent work on AO interface-based programming is a huge step towards making it possible to express aspects with appropriate levels of abstraction. I would like to comment on this issue more in future blogs, but for now, let's return to the original problem and look at some things we might do to make PCD(Pointcut Definitions)s more humane. The first thing I suggested in the thread is the addition of special keywords that could be substituted for some of the wild-cards: table{border:1px solid black; background:#eee}. |_<. Keyword |_. Maps To: |_<. Context | |
$any_return |{text-align:center}. * | Used for any return type |
| $any_arg |{text-align:center}. * | Used for any _one_ method argument |
| $any_arglist |{text-align:center}. .. | Used for zero-many method arguments |
| $any_type |{text-align:center}. * | Used for any type expression (class, interface, ...) |
So, our previous PCD(Pointcut Definition) that matches calls to the constructors could be written
call( (@MyAnnotation $any_type).new($any_arglist) )This is a little more readable, especially for new users, while experts will prefer the more terse form for its brevity. As an aside, you could use a similar mechanism to support regular expression matching while minimizing the potential for confusion, as discussed "here":http://aspectprogramming.com/papers/The%20Challenges%20of%20Writing%20Reusable%20Aspects%20in%20AspectJ%20v3.pdf. Something like
$re(/(foo|bar)$/) to match names ending in foo or bar, for example.
Let's combine our new PCD(Pointcut Definition) with after advice, to see a little more context. We want to "bind" the newly-created Foo instance to a variable foo. Handling newly-created objects is "tricky":http://www.eclipse.org/aspectj/doc/released/faq.html#q:adviseconstructors.
after() returning(Foo foo):
call( (@MyAnnotation $any_type).new($any_arglist) ) {
...
}
Another approach, if we're using the execution join point, is the following:
after(Foo foo):
execution( (@MyAnnotation $any_type).new($any_arglist) ) && this(foo) {
...
}
However, the keywords are a small improvement. Let me suggest that a real "humane" PCD language should read more like English. Consider this rewriting of the same two expressions, using a made-up pointcut DSL(Domain Specific Language):
after() returning(Foo foo):
call(constructors().takingAnyArgs().inClassesAnnotatedWith(@MyAnnotation)) {
...
}
and
after(Foo foo):
execution(constructors().takingAnyArgs().inClassesAnnotatedWith(@MyAnnotation))
&& bindNewlyConstructedObjectTo(foo) {
...
}
This syntax is inspired by the syntax of mocking frameworks like "JMock":http://www.jmock.org and equivalents in Ruby. Certainly my toy DSL(Domain Specific Language) could be improved; I made it up on the fly during the discussion thread yesterday.
However, because it reads like English, it is very self-documenting, making comprehension easier by AspectJ neophytes and even experienced AspectJ users who are new to the application.
I think it's useful to remember that most code is _write once, read many_. We may not like to type a lot, but a literate style pays dividends over time.
Note that the syntax of this DSL(Domain Specific Language) and the standard syntax express essentially the same pointcut language "abstraction" for AspectJ.
So, I think there is a place for a more "humane" form of the AspectJ pointcut DSL(Domain Specific Language). Similarly, I think that we need DSL(Domain Specific Languages)s appropriate for higher-level AOP abstractions (_e.g._, at the design level) and ideally AOP DSL(Domain Specific Languages)s that are domain-specific for non-trivial domains.
Read the rest of this entry



