log4p

Peter Maas’s Weblog

Archive for the 'java' Category

Binding mmbase nodes to strongly typed object graphs

In past years I've spend quite some time converting MMBase node graphs to strongly typed object graphs. One of the reasons for doing this is to define 'meta' models on top of the cloud. 'What is a newsitem?' (i.e. which rules need to be applied to get all the needed data from MMBase).

Due to recent developments within the VPRO I decided to have another go at it. And I came up with a working prototype of something which I think might be useful to others; or where others might be able to provide valuable feedback!

The small framework I created is annotation based; one specifies the bindings to MMBase using annotations:

  1. // --------- NewsItem.java
  2. @Entity(builder = "news", root = true)
  3. public class NewsItem {
  4.   private Long number;
  5.   private String title;
  6.   private String subtitle;
  7.   private String credits;
  8.  
  9.   @Field(nodeField = "intro")
  10.   private String description;
  11.   private String body;
  12.  
  13.   @Embedded(builder = "mmevents", field = "start", convertor = EpochDateConvertor.class)
  14.   private Date created;
  15.  
  16.   @PosRel(orderDirection = Direction.DESC, queryDirection = QueryDirection.BOTH)
  17.   private List<Image> image;
  18.  
  19.   @Rel(orderDirection = Direction.DESC, orderField = "value", queryDirection = QueryDirection.DESTINATION)
  20.   private List<Tag> tag;

  1. // --------- Image.java
  2. @Entity(builder = "images")
  3. public class Image {
  4.   private Long number;
  5.   private String title;

  1. // --------- Tag.java
  2. @Entity(builder = "tags")
  3. public class Tag {
  4.   private Long number;
  5.   private String value;

The implementation is still in concept phase, but as you can see it is already possible to define mappings for:

  • associations (works for typed collections only)
  • fields (populated by default, @Field annotation use to override properties)
  • Embedded values from one-to-one associations which are treated as embedded objects.

Note: at the moment I'm only considering read operations.

Entity definitions are automatically retrieved at startup (using Springs' ClassPathBeanDefinitionScanner) of a simple MMBase module, after which binding can be done as follows:

  1. NewsItem item = (NewsItem) populator.unmarshallNode(newsItemNode, "news");

There is still a lot of ground to cover, but the basics work, and the populator class is still less then 200 lines of code! No public sourcecode yet, but I'd be more than happy to contribute/make it availlable in the near future if others are interested.

looking forwards to ideas, criticism etc.

2 comments

Oracle buys Sun…

After the news of IBM pulling back from the deal to buy Sun Microsystems rumors about other possible candidates scoured the web. Oracle was on top of most lists. Today the news hit the web. Oracle actually bought Sun (well, they're still in the process of solving a lot legal stuff).

I don't know why, but it makes me feel sad. Although I didn't like everything Sun came up with they made and/or own a lot of stuff I like:

  • Java/JVM
  • MySQL
  • Netbeans
  • Glassfish
  • JRuby/Jython
  • Solaris (yes, I've cursed it as well)
  • ZFS
  • Project Looking Glass (Great in it's time)

For sure they did some dreadful things as well:

  • Java Desktop System
  • JCreator
  • The JSF spec
  • java.util.Date
  • Endless Sun Spot demo's
  • JavaFX

Still I sort of like them. Which Oracle never managed to achieve. Hopefully good will come from it... but I really think Oracle will gain far to much power on the Java side of the story to not cause agony in the community.What will happen to the JPA spec? What about JRuby? Time for a Fork?

3 comments

Composited objects with shared id’s in Hibernate

One of the models a developed in a previous project used embedded/embeddable annotations to create a composite object. The (simplified) object model looks like this:

avattributes object model

The embedded/embeddable solution would store the entire graph in a single table, all attributes flattened to one row:

avattributes_table

That works great as long as you don't mind minor annoyances like:

  • when loaded, embedded object are filled with null values if no attributes are present in the database.
  • you have no constraints which need to be satisfied only if an entire object exists (ie. if I set videoattributes, the null value is required)

Or in other words: only do this if the objects are always supposed to be present. Which in the case above is simply not true. If you would like to describe audio-only content you don't want to set the 'required' video codec.

My current project is a spin-off of the project mentioned above and uses some concepts of the model on a new database. I decided to alter the mappings and give Audio- and VideoAttributes their own table. This proved to be somewhat harder then I expected:

  • alter the embeddable annotation of Audio- and VideoAttributes, make them entities
  • since Audio- and VideoAttributes are entities now the need an id
  • add a reference to the AVAttributes object to Audio- and VideoAttributes
  • create a bi-directional one-to-one mapping between avattributes and audio- and VideoAttributes. mappedBy on the Audio- and VideoAttributes side
  • add cascade annotations to the Audio- and VideoAttributes in the AVAttributes class

I started out with generated id's for the Audio- and VideoAttributes. Hibernate will generate two columns in the AVAttributes containing a foreign keys to the Audio- and VideoAttributes tables. This synthetic id seemed a bit unnecessary IMHO. It took me a while to figure out how to do this. I ended up with the following annotations:

AVAttributes

  1. @Entity
  2. public class AVAttributes implements Serializable {
  3.     @Id
  4.     @GeneratedValue(strategy = GenerationType.AUTO)
  5.     private Long id;
  6.  
  7.     @OneToOne(optional = true)
  8.     @PrimaryKeyJoinColumn
  9.     @org.hibernate.annotations.Cascade({
  10.       org.hibernate.annotations.CascadeType.ALL,
  11.       org.hibernate.annotations.CascadeType.DELETE_ORPHAN
  12.     })
  13.     private AudioAttributes audioAttributes;
  14.  
  15.     @OneToOne(optional = true)
  16.     @PrimaryKeyJoinColumn
  17.     @org.hibernate.annotations.Cascade({
  18.       org.hibernate.annotations.CascadeType.ALL,
  19.       org.hibernate.annotations.CascadeType.DELETE_ORPHAN
  20.     })
  21.     private VideoAttributes videoAttributes;
  22. }

AudioAttributes (Same annotations used for VideoAttributes)

  1. @Entity
  2. public class AudioAttributes implements Serializable {
  3.     @Id
  4.     @GeneratedValue(generator="fk")
  5.     @GenericGenerator(name="fk",strategy="foreign",parameters = {
  6.         @Parameter(name="property",value="avAttributes")
  7.     })     
  8.     private Long id;
  9.    
  10.     @OneToOne(mappedBy = "audioAttributes",  optional = false)
  11.     private AVAttributes avAttributes;
  12. }

The generated table structure looks like this:

avattributes_split_table

Id's are automatically cascaded when a AVAttributes object is persisted. And yes, it's a lot of annotations and I even stripped out the JAXB2 annotations which are also present.

No comments

CouchDB meetup in Amsterdam

Tonight I went to the CouchDB meetup in Amsterdam ('In De Wildeman') to discuss the architecture I'm designing for upcoming VPRO projects (more on that in a following blogpost). We had a really nice discussion about mostly the 'edges' of what CouchDB can do. Impressive numbers, that's for sure! Big sites/companies are showing interest (craigslist, yahoo, myspace, facebook, BBC).
Read more

1 comment

Ioke @ Amsterdam.rb

Tonight I visited Amsterdam.rb. Mainly because I wanted to see Ola Bini talk about his pet project Ioke. Although Ioke is far from finished, or even usable in real life it was really nice to see someone try out new language concepts.

Ioke is a strongly typed, extremely dynamic, prototype based object oriented language. It’s homoiconic and got built in support for several kinds of macros. The languages that most closely influence Ioke is Io, Smalltalk, Self, Ruby and Lisp (Specifically Common Lisp).

Ioke seems to be mainly focussed at writing nice-to-talk-to code, it gives developers much more freedom to shape the language into DSL-like syntax.

In contrast to what you would expect from a 'pet language' Ola demonstrated nice generated documentation and some cool debugger features. And even a RSpec-like testing framework: ISpec. Really nice. Here is an example of a parser definition (from paser_comb.ik example) written in Ioke:

  1. IParse Parser(
  2.   digit = 0..9
  3.   letter = ("a".."z") | ("A".."Z")
  4.   id = letter (letter | digit)*
  5.   id2 = letter* (letter | digit)
  6.   number = 1..9 digit*
  7.   primary = "(" expr ")" | number | id
  8.   term = primary ("*" | "/") term | primary
  9.   expr = term ("+" | "-") expr | term
  10.   and = expr "and" expr | expr
  11. )

Looks kinda neat, doesn't it? I don't see Ioke as the next big thing, but I think it is a really nice testbed for new languages and language concepts.

No comments

I want closures “bolted on to Java”

After seeing Blochs' session on Javapolis last year and some of the Java 7 sessions at JavaOne this year I gave up on closures in Java. I just didn't believe that they would be part of Java 7 anymore. I also had my doubts on the 'quircks' of the BGGA proposal.

Playing around with the BGGA prototype changed my opinion though. It might not be as concise as closures in Ruby, but it _is_ a really useful extension of the Java language.

The following code I wrote runs fine with the BGGA prototype:

  1. package com.finalist.closures;
  2.  
  3. import java.util.*;
  4.  
  5. public final class ClosuresExample {
  6.  
  7.     public static void main(String[] args){
  8.         List<String> words = toWords("altijd is kortjakje ziek");
  9.         Collections.sort(words, {String a, String b => b.compareTo(a)});   
  10.         System.out.println(words);
  11.         List<String> wordsContainingK = select(words, {String it => it.contains("k")});
  12.         System.out.println(wordsContainingK);
  13.     }
  14.    
  15.     public static <T> List<T> select(List<T> list, {T=>boolean} filter) {
  16.           List<T> results = new ArrayList<T>();
  17.           for (T t : list){
  18.             if(filter.invoke(t))
  19.               results.add(t);
  20.           }
  21.        return results;
  22.     }
  23.  
  24.     public static List<String> toWords(String input){
  25.         return Arrays.asList(input.split("\\W"));
  26.     }
  27. }

This is just one example, you can do _much_ more with the BGGA proposal. It integrates with the existing API. I like this. I want this. I feel a bit sad about the fact that it might not make it to Java7.

But...

Yesterday @headius / Charles Nutter came up with a very interesting idea on twitter:

@danny_l Gafter made the same mistake; I don't mean a forked Java any more than Groovy is a fork. I want a "mostly Java" with closures.

or the reply by @danny_l / Danny Lagrouw:

@headius or could the BGGA prototype be "bolted on" any future version of Java? That might be useful

That really is what I would like to see as well. Can't we have some sort of bytecode preprocessor to make the BGGA prototype work on any modern Java version? I mean scala, Groovy and JRuby have closures and produce valid bytecode!

I would even like to help and put effort in it. Although I don't really know where to start.

11 comments

Review: “Clean Code: A handbook of agile software craftmanship”


The following product description of Clean Code written by Robert C. Martin managed to trigger my interest:

Noted software expert Robert C. Martin presents a revolutionary paradigm with Clean Code: A Handbook of Agile Software Craftsmanship. Martin has teamed up with his colleagues from Object Mentor to distill their best agile practice of cleaning code on the fly into a book that will instill within you the values of a software craftsman and make you a better programmer—but only if you work at it.

A software craftsman. That is what I’d like to be. It is however a fairly bold claim; wasn’t craftsmanship something you learn through experience? After having read Clean Code however, I can tell you that the Robert C. Martin did a really good job at doing just that.

The content

Clean Code is divided into three parts. The first part describes the principles, patterns, and practices of writing clean code. The second part consists of several case studies. The third part is a single chapter containing a list of heuristics and smells gathered while creating the case studies.

In part one Robert explains the fundamentals of good code. Robert introduces some great concepts like “the newspaper metaphor – ‘think of headlines, synopsis, increasing detail as you continue downward’” and “boyscout rule – ‘leave the campground cleaner than you found it’”. He dives into how to do this: meaningful names, what should a good function look like (in terms of abstraction, arguments, error handling), comments in code, formatting, objects and data structures, error handling in general, talking to third party code, unittests, class hierarchy, architectures and concurrency.
The level of detail is spectacular. Robert doesn’t just tell you how it should be, he also explains how to achieve it; with good, modern, Java code. This part also contains excerpts and metrics gathered from different open-source project illustrating his points; a nice touch.

Part two contains two cases where Robert applies his principles, patterns and practices to real-life projects (JUnit and JFree). What I really like about this part is that Robert explains every single refactor he did; even if he decided to revert his changes later on. The JUnit example is great. The JFree example is a bit tougher; mostly due to the fact that the code for this case is not part of the text but located in an appendix; it takes a lot of ‘random access’ to actually read it.

Part three is a concise list of ‘rules’ you should apply to write good code. Really useful as a reference.

The verdict

I think every (Java) programmer should read this book. It will make you a better programmer. Even if you know all the concepts Robert talks about. Seeing the concepts being applied to code from real-life projects by a skilled developer with a complete explanation is really valuable. I’ll be pointing developers in my team and teams to come to this book!

4 comments

JavaOne 2008 – Summary & Reflection

1 day of CommunityOne and 4 days of JavaOne went by in a flash. I've been to a lot of great, a couple of not-so-great and some really bad sessions.

To avoid information overload on semi-interesting topics I really tried to only go to sessions about topics I'm really interested in. For this JavaOne these where (in no particular order):

  • alternative languages on the virtual machine
  • methodologies
  • the future of Java / JEE
  • cool new stuff

I tried to avoid product pitches as much as possible! Some of my personal highlights:

  • the No Fluff Just Stuff session at the g2one party
  • Both Neal Ford presentations I've attended (JRuby vs. Groovy / Enterprise Debugging techniques)
  • the scripting bowl
  • Taming the Leopard with Java

I'm still processing everything I've seen, but so far I didn't see to much I didn't know about before; certainly nothing shocking. Here are some of my observations:

Java 7

Sun is adding more and more annotations, the Java 7 spec-leads feel it's a safe way of extending the language; even though it decreases readability (well, that is MY opinion). They are even planning to extend the number of targets for annotations; in the future we will probably see annotations inside generic type definitions... auch!

I also sincerely doubt that we will see a useful implementation of closures in Java 7; the spec-leads don't want to burn their hands on it; Gafter seems the only one who dares to risk his neck...

Alternative languages on the VM

Groovy gained a lot of traction the past years. Most mayor app-servers offer out of the box support and major speakers are promoting it (Neal Ford repeatedly called it JDK 2.0).
JRuby is looking better and better. It is now even possible to just drop your Rails app in Glassfish to make it run. I do however feel that some users should stand-up and really demonstrate the virtues of Ruby on the VM to get peoples' attention. The Jython presentation(s) where horrible; I think they did more harm to the language than good. I saw some great demonstrations of scala; but popularity seems to be at an alltime low.

As I said I'm still processing al the information and probably blog about various nice details and insights. Now I'm heading towards a restaurant and some beers!

4 comments

Closures and the return of the return

I attended Joshua Blochs' presentation on closures at JavaPolis last week (watch the video here). This slides about return not return from what you'd expect kept me wondering: how do other languages solve this 'problem'.

The example from Bloch, taken from Slide 38 of Blochs' closures controversy presentation:

  1. static <E> Boolean contains(Iterable<E> seq, {E => Boolean} p) {
  2.     for (E e : seq)
  3.         if (p.invoke(e))
  4.             return true;
  5.     return false;
  6. }
  7.  
  8. static Boolean test() {
  9.     List<Character> list = Arrays.asList(
  10.             'h', 'e', 'l', 'l', 'o');
  11.     return contains(list, { Character c => return c> 'j'; } );
  12. }

The point Josh tried to make was that due to this 'copy and paste' error the contains method would return on the first invocation of the passed block. Auch....

It asked around at Morning coffee but nobody really knew what this would actually do in Ruby.

So, let's just try it. In Ruby this might look a bit like this:

  1. def contains(enumerable, &test)
  2.   enumerable.each do |e|
  3.     return true if test.call(e)
  4.   end
  5.   false
  6. end
  7.  
  8. puts contains(['h','e','l','l','o']){|v| return v == "z"}

In the Ruby a return statement in a block returns from the enclosing function as well. However, if the return statement is part of a closure passed to a function returning is not allowed:

closure_return.rb:9: unexpected return (LocalJumpError)
from closure_return.rb:4:in `call'
from closure_return.rb:4:in `contains'
from closure_return.rb:3:in `each'
from closure_return.rb:3:in `contains'
from closure_return.rb:9

Throwing an error might be considered a better solution. The problem in this case is the fact that the error is thrown at the first invocation of the block; code before the invocation of the block will be called... but code after the invocation won't. Of coarse this is 'just' a matter of taking this into account:

  1. def contains(enumerable, &test)
  2.   begin
  3.     puts "a"
  4.     enumerable.each do |e|
  5.       return true if test.call(e)
  6.     end
  7.   rescue
  8.     puts "Error in passed test-block: #{$!}"
  9.   ensure   
  10.     puts "b"
  11.   end 
  12.    
  13.   false
  14. end
  15.  
  16. puts contains(['h','e','l','l','o']){|v| return v == "z"}

In this case the ensure statement will always be called. I'm not really in favor of adding closures to Java; just go to Ruby/Groovy/Scala if you want them). I do however think that the 'return' argument Josh made isn't to strong; a solution similar to the way it works in Ruby could probably be found for Java.

13 comments

CPD with maven2 and PMD

Detecting copy/pasted code is a useful technique to find potential buggy code. Duplicated code often results in bugs being fixed in only one version of the copied code. PMD is a great sourcecode analysis tool which integrates nicely with maven and has CPD (copy/paste detection) capabilities.

To configure with default settings and CPD support add the following to the pom:

  1. <plugin>
  2.   <groupId>org.apache.maven.plugins</groupId>
  3.   <artifactId>maven-pmd-plugin</artifactId>
  4.   <configuration>
  5.     <sourceEncoding>utf-8</sourceEncoding>
  6.     <minimumTokens>100</minimumTokens>
  7.     <targetJdk>1.5</targetJdk>
  8.   </configuration>
  9. </plugin>

You can configure the minimum code size which trips the CPD. The default of 100 tokens corresponds to approximately 5-10 lines of code.

Generated reports look like this and show the file in which the duplicates where found and the duplicated code:

CPD Report

Really useful, great hooks for DRY-ing out code!

No comments

Next Page »