Archiv der Kategorie: Java

Java Themes

Hudson vs. Jenkins – Hudsons future

Yesterday Sonatype announced a free webinar about the future of Hudson. I am very interested in the presentation from Jason van Zyl and the outcome therefor. So, I guess up until then, there will be no real news about this topic.

The presentation seems to be focused on Sonatypes (positive) influence on Hudson and the changes they would like to do. I guess, that this will contain also some output from the survey Sonatype has taken on the „Future of Hudson“.

Since JSR330 (Dependency Inejction) is now already implemented in Hudson, I guess that the Plugin API will change slightly, to use this new concept (which is great IMHO). Furthermore there will be (IMHO) some changes to the UI of Hudson to make a clearer distinction between Hudson and Jenkins.

So, IMHO Hudson is going to be an integral part of the offerings from Sonatype, let’s see where this leads the project and the community.

Spring 3 and Hibernate Envers

I wanted to add Audit functionalities to an application I am writing currently. I know that this seems to be possible with Spring Data JPA, but since this project has just reached Version 1.0.0.M1 I wanted to wait to use this one. Furthermore the application I am working on is already based on hibernate and some GenericDAO stuff we did with Hibernate, therefor a move does not seem to be too easy. Therefor I wanted to use Hibernate Envers.

The setup seems to be quite easy, following the steps in the documentation (Envers Documentation). I provided the @Audited Annotation to all Entities to be audited and provided also a new RevEntity and a new RevListener:

import javax.persistence.Entity;

import org.hibernate.envers.DefaultRevisionEntity;
import org.hibernate.envers.RevisionEntity;

@Entity
@RevisionEntity(RevListener.class)
public class RevEntity extends DefaultRevisionEntity {

    private String userName;

    public String getUserName() {
 	return userName;
    }

    public void setUserName(String userName) {
 	this.userName = userName;
    }
}
import org.hibernate.envers.RevisionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class RevListener implements RevisionListener {

    @Autowired
    private Member member;

    public void newRevision(Object revisionEntity) {
	RevEntity revEntity = (RevEntity)revisionEntity;

	Member member = MemberHolder.getMember();

	String userName = null;
	if (member != null) {
		userName = member.getUsername();
	}

	revEntity.setUserName(userName);
    }
}

The point here is to show, that I am using the Member, to find out what the current user is in our application.

Now, how do I use the newly created listener in Spring? After using Google a little, I found this post, which uses Envers, but unfortunately with the SessionFactory instead of the JPA EntityManager, like we are using. Furthermore I found this, which did not really help me as well, since there was another error message coming up, that my RevListener could not get instantiated. Since the custom EventListener was using Spring Dependency Injections for the Member, I could not use the above mentioned solution. I had to find a way to use the Spring Beans. See this blog post, which describes the problem and a possible solution.

So, basically one step back and the whole stuff again, this time using a Holder for our Members, which provides the current Member (User) of the system. This is done using the current security-context of the application and determine the member therein (see StackOverflow).

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

/**
 * @link http://stackoverflow.com/questions/360520/unit-testing-with-spring-security
 */
public class MemberHolder {

    private MemberHolder() {
        // hidden default constructor, this is a "normal" utility class
    }

    public static Member getMember() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Object principal = auth.getPrincipal();
        Member member;

        if (principal instanceof Member) {
            member = (Member) principal;
        } else {
            return null;
        }

        if (member.getId() == null) {
            return null;
        }
        return member;
    }
}

This member-holder is then called in the RevisionListener:

import org.hibernate.envers.RevisionListener;

import de.xxx.RevEntity;
import de.xxx.model.MemberHolder;

public class RevListener implements RevisionListener {

    public void newRevision(Object revisionEntity) {
	RevEntity revEntity = (RevEntity)revisionEntity;

	String userName = MemberHolder.getMember().getUsername();

	revEntity.setUserName(userName);
    }
}

Furthermore the application-context.xml was now corrected to look like this:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		  depends-on="transactionManager">
	<property name="persistenceUnitName" value="persistenceUnit"/>
	<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
	<property name="jpaVendorAdapter">
		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
	</property>
	<property name="jpaDialect">
		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
	</property>
	<property name="jpaProperties">
		<props>
			<prop key="hibernate.dialect">${hibernate.dialect}</prop>
			<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
			<prop key="org.hibernate.envers.auditTablePrefix">AUD_</prop>
			<prop key="org.hibernate.envers.auditTableSuffix"></prop>
			<prop key="org.hibernate.envers.storeDataAtDelete">true</prop>
			<prop key="hibernate.ejb.event.post-insert">
	org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener
			</prop>
			<prop key="hibernate.ejb.event.post-update">
	org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener
			</prop>
			<prop key="hibernate.ejb.event.post-delete">
	org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener
			</prop>
		        <prop key="hibernate.ejb.event.pre-collection-update">
				org.hibernate.envers.event.AuditEventListener
			</prop>
			<prop key="hibernate.ejb.event.pre-collection-remove">
				org.hibernate.envers.event.AuditEventListener
			</prop>
			<prop key="hibernate.ejb.event.post-collection-recreate">
				org.hibernate.envers.event.AuditEventListener
			</prop>
		</props>
	</property>
</bean>

Some pitfalls I stumbled upon. Do not make the property look nice, e.g.:

<prop key="hibernate.ejb.event.post-update">
    org.hibernate.ejb.event.EJB3PostUpdateEventListener,
    org.hibernate.envers.event.AuditEventListener
</prop>

Your application Context will look nice, but you will get a ClassNotFoundException ;-(

Furthermore, your Custom Event Listener should not appear in the Events, e.g. do not do:

<prop key="hibernate.ejb.event.post-update">
    org.hibernate.ejb.event.EJB3PostUpdateEventListener,de.xxx.RevListener
</prop>

This will lead to an exception like

Caused by: org.hibernate.MappingException: Unable to instantiate specified event (post-update) listener class: de.xxx.RevListener
	at org.hibernate.cfg.Configuration.setListeners(Configuration.java:1766)
	at org.hibernate.ejb.Ejb3Configuration.setListeners(Ejb3Configuration.java:1550)
	at org.hibernate.ejb.EventListenerConfigurator.setProperties(EventListenerConfigurator.java:183)
	at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1085)
	at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:685)
	at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
	... 53 more
Caused by: java.lang.ArrayStoreException: de.xxx.RevListener
	at org.hibernate.cfg.Configuration.setListeners(Configuration.java:1763)

So, I do hope, that this helps you. It did help me 😉

Hudson / Jenkins – Butler wars

Today I found a nice article about the split of Hudson and Jenking. It has a nice title and is really well written. Furthermore it shows some of the possible implications of this „war“.

Butler Wars.

Read on.

For more information about this story please also visit:

Hudson and Jenkins now on GitHub
Hudson vs. Jenkins – more thoughts
Hudson vs. Jenkins

Hudson and Jenkins now on GitHub

I think, the whole fork stuff with Hudson and Jenkins gets even more hilarious. In a vote, the Hudson community decided to move (take your breath) to github.com.

See InfoQ for more details about this movement. Now both Hudson as well as Jenkins are on github.

Jason (van Zyl) seem to have made already quite some changes to Hudson so, I would expect some major changes coming up for the next Hudson release. Of course these changes are related to (guess what?) Maven. These changes are going to diverge Hudson and Jenkins, and I guess that in the long run these two projects are going to diverge so much, that there is no „drop-in“ of Jenkins Plugins into Hudson and Vice-versa. On the other hand, Sonatype is known for their strong commitment to backward compatibility (see Maven 2/3), but is the same true for the Jenkins guys? I do hope so.

Still, new features developed for one of these forks will not directly appear in the other version. Since Sonatype seems to be doing some major restructuring of the hudson core, I doubt, that features on Hudson will easily be transportable to Jenkins, and vice versa.

Lets see whats going to happen 😉

For more information about this story please also visit:

Hudson vs. Jenkins – more thoughts
Hudson vs. Jenkins

Hudson vs. Jenkins – more thoughts

After having released the last post about Hudson vs. Jenkins, I have read quite a lot about this issue. Sonatype seems to have started a new „campaign“ on their relationship to and investments into hudson (see their latest banner on their homepage, where they state: „Maven + Hudson = a heart is shown here“).

Of course Sonatype (which is a heavily risk capital backed company) would like to earn money with this move. Some of the reasons are IMHO really well explained on Thomas Ferris Nicolaisen’s blogpost. Right now it looks like the whole community is in an real outcry about this move and especially the involvement of Sonatype and seem to be slightly annoyed by this move (see: Jerome’s Coffebreak).

Not all the critics of Jason on Hudson are 100% right, but he has a point. The only real question here is, why he (Sonatype that is) has not taken Benson (Sonatypes own Hudson Fork, without a real Homepage or anything like that, so it does not seem to „active“) and put it into the Hudson code? There could be several reasons, e.g. Koshuke was not really into making Hudson a totally Maven focused application.

Most probably Jason and Sonatype like to push Maven 3 into the market quite heavily. They are not the only company doing this, though. Hudson is a very good fit in Sonatypes software stack. So Sonatype is building up their software stack with Maven 3, Nexus, Hudson and Eclipse kind of stuff. Like Thomas Ferris Nicolaisen points out, there is still the option, that Oracle is going to buy-out Sonatype and that would most probably a good fit for Sonatypes investors 😉 (The whole discussion seems to be money related, doesn’t it?)

The least we can say is, that Hudson and especially Sonatype is now receiving a lot of attention due to this move, and they should have this attention, because otherwise Hudson would be dead (long live Jenkins ;-)).

On a sidenote, why did Jason and Sonatype not support Continuum instead of Hudson, Jason seemed to be a contributor to this project as well? The answer stays unsure, but I guess, Jason is going to put his bets all on market leaders to become a market leader on its own (well, with maven he is already, but what about Sonatype?). There are some strong competitors in the ALM market (is this the right name for this niche?) like e.g. the guys from MaestroDev, but they do not have this momentum as Sonatype has right now. The product portfolio seems to be (at least at a first glance) quite similar, only the selected/made tools are different. Maestro totally focusses on Apache Projects, whereas Sonatype implements its own products (at least this is true for Nexus).

So the question, who will win the race for the most usage in the CI market is still open. I strongly believe that there is a place for Hudson as well as Jenkins in the market. Oracle is going to offer professional support to Hudson and Sonatype is doing it already, something, Jenkins does not have right now (at least not that I am aware of). I and the company I work for am not a real contributor to the success of Sonatype and neither Oracle through buying their products or support, but we will stick to Hudson at least in the near future. Lets see the outcome of all this. Probably I re-decide on this one, depending who fixes the well known GZIP Problem first 😉

Another side note is some missing pieces in the Sonatype Software stack, after they do have already the whole Development Cycle in their portfolio (pretty close to IntelliJ and Atlassian, I guess). One piece of software still missing the from Sonatypes stack would be Sonar (IMHO), which is used in the IT industry quite often as well. So, lets see, if Sonar stays with the current company or if some other company is going to buy this piece of software as well, it would fit perfectly into the Sonatype offerings though.

So, the whole Java Open Source market, especially in the Development and Apllication Lifecycle management, seems to change right now. Sonatype seems to be one of the leaders in this market, next to Atlassian, which has a slightly different target group. It is nowadays all about earning money. Hopefully the support into Open Source projects will stay as it is right now from these kind of companies 😉

For more information about this story please also visit:

Hudson and Jenkins now on GitHub
Hudson vs. Jenkins

Hudson vs. Jenkins

In my last blog post, I mentioned, that we are still using Hudson instead of the new community fork Jenkins. You can ask now why we are doing this. This is mainly a personal decision, and it is not about Oracle and their „relationship“ to open source communities, but more about Sonatype and their involvement in the future of Hudson (see blog post here, here and here). I think that if the leader of Maven (Jason van Zyl) is investing time and resources into the hudson project, it is definitly worthwhile to stay there. Lets see if this is going to work out.

For more information about this story please also visit:

Hudson and Jenkins now on GitHub
Hudson vs. Jenkins – more thoughts

Maven CI Best Practices

Yesterday our Admin came to me and told me, that the Harddrive on our CI Server is nearly full. This is due to the fact that our Nexus Repository as well as our Hudson CI Server are installed on the same machine. Hudson is using it’s own locale repository and therefor all Snapshots are filling up the diskspace.

Hudson has its own local repository due to the fact, that we are following the best practices mentioned by Jason Van Zyl on this blog post.

What I did now, was to purge the local repository of Hudson. Unfortunately we are not following all Maven best practices and therefor one project (the master pom for all other projects) is then missing from the local repository. I hope that I can clean this up during the next couple of days (hey, we are in a pretty tough project right now, and therefor the time for this is not really there). This means, that we do have to build and „mvn install“ this project (base-build) directly after the purge. Furthermore I am cleaning up the Backups we are doing using ThinBackup (a small Hudson Plugin). Therefor we are using the following script:


#!/bin/sh -e
# fetches all changes in all repositories and sync it to redmine
cd /var/cache/hudson/mvn-repository
rm -rf *
cd /var/lib/hudson/jobs/base-build/workspace
su hudson -c 'mvn clean install' > /dev/null
cd /var/cache/hudson/backup
find . -mtime +5 -exec rm {} \;

Furthermore we are now using a scheduled Task in nexus to purge the Nexus Repository from any Snapshots older then 5 days, but keeping at least the latest snapshot (see another blog post).

After some more cleaning of e.g. log files and more, the disk is now half full (or half empty, depending on your point of view). This was more then enough for me.

Hope this helps.

Spring WebMVC and BindingResult Errors

We have the need to add FieldErrors inside the Controller, we have tried it several times using the usual FieldError-Constructor:


FieldError error = new FieldError("objectname", "fieldName", "text", false, new String[]{"error.invalid.fieldcontent"}, new Object[]{"argument"}, "defaultMessage");
result.addError(error);

This wasn’t working, until I stumbled across this posting from TechnoBabble. You (We) needed to add the @ModelAttribute(MODEL_NAME) annotation to our method signature, like so:


@RequestMapping(method = RequestMethod.PUT)
public String update(@ModelAttribute(MODEL_NAME) @Valid Model model, BindingResult result, ModelMap modelMap)

Now everything works fine. Thanks to Antonio Gonzalez from TechnoBabbel.

Additional Note:
If you would like to skip the @ModelAttribute Annotation, it is possible as well, but then the modelMap needs to contain the object name in CamelCase (e.g. „objectName“ and not „objectname“). This works as well.

More thoughts on the ALM Stack

I am just thinking, that just providing some Toolset, like the ALM Stack is not enough. There is some documentation needed, not only for configuration, maintance and usage of the ALM Stack, but also some hints and best practices for the handling of projects.

Since we are already providing a wiki in our toolbox (Redmine contains a wiki), we will most probably provide an initial project in Redmine which will be configured the „right“ way and contain some documentation.

Most of these best practices are already documented elsewhere, so we will mostly provide links to these resources, as well as additional resources we can provide ourselves.

If you have any input on this, do not hesitate to contact me anytime.

A Home for the ArchLinux Development Stack

The ArchLinux Development Stack found a Home. I received some very friendly, personel and quick support from the guys at Open+Pario and that was the main reason I chose this one. They are hosting a Redmine instance and GIT, so this is a perfect fit for the stack.

Please browse to http://openpario.mime.oregonstate.edu:3000/projects/archdevstack to get an impression of the project.

Like already stated, any help is welcome, so register yourself and provide feedback, suggestions and everything else you can think of.