<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="/blog/templates/gridshore/atom.css" type="text/css" ?>

<feed 
   xmlns="http://www.w3.org/2005/Atom"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <link href="http://www.gridshore.nl/blog/index.php?/feeds/atom10.xml" rel="self" title="Gridshore software engineering weblog" type="application/atom+xml" />
    <link href="http://www.gridshore.nl/blog/"                        rel="alternate"    title="Gridshore software engineering weblog" type="text/html" />
    <link href="http://www.gridshore.nl/blog/rss.php?version=2.0"     rel="alternate"    title="Gridshore software engineering weblog" type="application/rss+xml" />
    <title type="html">Gridshore software engineering weblog</title>
    <subtitle type="html">This weblog is about everything that has to do with software engineering. It will focus on items like Springframework, acegi, hibernate and other tools to help creating good software</subtitle>
    <icon>http://www.gridshore.nl/blog/templates/gridshore/img/s9y_banner_small.png</icon>
    <id>http://www.gridshore.nl/blog/</id>
    <updated>2008-01-29T10:27:03Z</updated>
    <generator uri="http://www.s9y.org/" version="1.2.1">Serendipity 1.2.1 - http://www.s9y.org/</generator>
    <dc:language>en</dc:language>

    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/74-Last-entry-....html" rel="alternate" title="Last entry ..." />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-01-19T19:58:56Z</published>
        <updated>2008-01-29T10:27:03Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=74</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=74</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/7-acegi" label="acegi" term="acegi" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/12-ajax" label="ajax" term="ajax" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/10-Announcements" label="Announcements" term="Announcements" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/3-Books" label="Books" term="Books" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/8-gridshore" label="gridshore" term="gridshore" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/2-News" label="News" term="News" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/13-spring-osgi" label="spring-osgi" term="spring-osgi" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/1-Technology" label="Technology" term="Technology" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/11-Webservices" label="Webservices" term="Webservices" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/4-Websitesproducts" label="Websites&amp;products" term="Websites&amp;products" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/74-guid.html</id>
        <title type="html">Last entry ...</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Welcome to the last entry of this blog. No I am not quitting, I am just moving. I just installed a new blog software framework. I was starting to dislike the way to interact and I wanted something that contained more out of the box. I am in the middle of moving to wordpress software. There is a very good reason to do this. I had found a great tool on the mac called MarsEdit. And again this could not be used with serendipity. I hope I did make a good choice. Since there is a lot of information in the old blog, I did not take this blog offline. It will stay to exist, but I will not make changes there anymore.<br />
<br />
I hope to see you at the new version of the blog (check the page at http://www.gridshore.nl). You can attach you feedreader to the following url: feed://www.gridshore.nl/feed/ 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/73-Spring-Experience-2007.html" rel="alternate" title="Spring Experience 2007" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-01-06T20:20:01Z</published>
        <updated>2008-01-06T20:20:01Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=73</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=73</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/2-News" label="News" term="News" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/73-guid.html</id>
        <title type="html">Spring Experience 2007</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <a href="http://www.thespringexperience.com"  title="springexperience">Spring Experience 2008</a><br />
&#65532;<br />
It feels like a year ago, actually it was last year, that I went to Miami, Florida, USA together with two colleques. There we were able to follow a lot of presentations about the springframework. These presentations were given by the contributors of all different springframework modules. For us three it was a three day learning experience. In this article I want to give you an impression of these days.<br />
<br />
I started of my presentations with a presentation about <strong>Full Stack Web Frameworks</strong>. What is a Full Stack Web Framework? To be honest, I did not really care about that question, but it was a nice presentation about the current status of Spring web projects and the future. The separation between Spring webmvc and Spring webflow is going to disappear. It is going to be one fully integrated web project. I think this is a good think, it will became easier to use webflow when you need it and not make the choice to do webmvc or webflow. Some important things in the presentation were:<br />
- Using REST like urls for web resources.<br />
- Support rendering of different views (xml, html, json) by state of the request (REST as well)<br />
- Convention over configuration resulting in easier spring config files (or annotations)<br />
<br />
&#65532;The next presentation was about the <strong>new features in Springframework</strong> 2.0/2.5 by Jürgen Höller. There are three big groups of changes:<br />
<strong>Platforms</strong> : There is now support for Java 6 and Java EE 5, better support for JCA and JPA. The most important platform improvement is out of the box support for OSGi modules. Every springframework module is now an OSGi module. This does result in some name changes, so beware when upgrading. Another thing I like a lot is that there is finally officially support for spingframework on websphere. So finally you can do threading and transactions on websphere with support from IBM. The catch? You need websphere 6.0.2.19+ or 6.1.9+.<br />
<strong>Annotation Configuration</strong> : more and more xml type of configurations can now be replaced by annotation driven configuration. These annotations can be market standard annotations like @PersistenceUnit or @TransactionAttribute or special spring framework annotations like @Controller and @Autowired. The Test framework is also completely annotation driven. You can switch between junit 3.8, 4.x and TestNG without really making code changes.<br />
<strong>AspectJ support</strong> : There is still a lot of proxy based aspects, there is however a new kid on the block. It is called load time weaving. The good part, you can use aspectJ without a change to the jdk your server is running on. There are some buts, have a look at the reference documentation to find out the specifics.<br />
<br />
&#65532;After this tough Jürgen presentation I had a presentation about <strong>Ajax integration guide for 2008</strong>. Nice but not a lot of new things. I did learn about an ajax framework called jQuery. A very nice and lightweight ajax framework. I will an article about jQuery in the future. I did use it for a demo application, more on that later. You can also check the web page of course. &#65532;Another presentation about ajax was actually about JSF or Java Server Faces. If you like the idea of Java Server Faces, then this framework is a must see. The framework is called <strong>icefaces</strong> and there is a very good integration between icefaces and springframework. Its all looking very sharp and there is a nice petshop implementation with icefaces available.<br />
<br />
&#65532;Back to more springframework, well actually it can become more springframework. The next presentation was about <strong>Useful Spring Extensions</strong>. This presentation is about the spring-modules project, sorry it is renamed to spring extensions. This project has some extensions to the springframework that sometimes become part of the springframework. It has a lot of different modules. There are three modules I want to bring to attention right now:<br />
<strong>Caching</strong> - Should be as non intrusive as possible, do not think about caching when creating your business logic. The caching solution as provided by spring extensions is an abstraction of multiple caching solutions. So it is not a caching provider, it integrates with EHCache, JBoss cache, JCS, Gigasoaces and OCache. <br />
<strong>DB40</strong> - This is an object database that makes extensive use of the data layer as defined by the springframework. So very good integration with spring. There is a Template and a support class available just like for jdbc, jpa, jms, spring-batch, etc. A very nice way to start experimenting with an object database.<br />
<strong>Validation</strong> - Nice integration with validation frameworks like: Commons validator, Valang and Bean Validation. The bean validation is now enhanced with some nice annotations to specify which beans to validate and with what rules.<br />
<br />
Another presentation is about <strong>Grails for spring developers</strong>, I am not going to talk about&#65532; this very long. If you are interested in stuff like ruby on rails, check this out. Without any prior knowledge Allard, Roel and me were able to create a complete application in a few minutes while waiting for the plane. Maybe I will write something about this as well, but the available documentation is already pretty good.<br />
<br />
In the past I have done a lot with acegi security, now called Spring-security. Therefore I was curious to find out about the direction of the 2.0 release. So I went to <strong>Whats new in Spring Security 2.0</strong>. &#65532;It was a nice presentation. The morale can be described in one sentence. More convention, less configuration (if you want). The amount of necessary configuration lines decreased from around 120 to around 20. Not bad is it? Due to the name change all the package names have changed as well. There is the possibility (for backwards compatibillity) to keep using your old configuration, you do need to do a find replace on package names.<br />
<br />
Another presentation I attended is <strong>RESTful web services</strong>. One thing I can tell, this is going to be big according to the springframework people.<br />
<br />
The last presentation I would like to mention is the <strong>Spring Dynamic Modules</strong>. Some of you will think, what no OSGi? Well, they had to change the name of spring-osgi into Spring Dynamic Modules for OSGi(tm) Service Platforms. To be honest, this was the main reason why Allard and me wanted to go to miami. Not the nice weather, not the everglades, not the florida keys. We wanted to learn about the next release of spring dynamic modules. Along the way we got Roel in there as well. Why? Well, OSGi is all about SOA. Yes, so there is a very nice bridge between cool custom development and commercial architectures. When talking about OSGi, you are talking about services. These services come with a certain version, dependencies and visibility. Using a light weight BPM framework (available using the Spring-extension project I mentioned) you can create a very light weight Service Oriented Architecture using components instead of web services. The fact that each component in itself CAN be a web service is not important anymore. This is all very hot and cool technology. Hope to be blogging about this in the future as well.<br />
<br />
Concluding, it was a great event, very good talks, good atmosphere. Hope to be there again next year. 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/72-Creating-an-application-with-maven2,-jpa,-springframework-and-intellij.html" rel="alternate" title="Creating an application with maven2, jpa, springframework and intellij" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-11-21T18:49:46Z</published>
        <updated>2007-11-21T20:02:55Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=72</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=72</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/72-guid.html</id>
        <title type="html">Creating an application with maven2, jpa, springframework and intellij</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Some time ago I started working with intellij, recently I bought a mac, and now I want to start programming. But where to start? There are some mandatory things, or not? Well lets just start and try to make it as flexible as possible so we can use other frameworks for some layers. For now I will focus on the following technologies:<br />
<ul><li>Springframework</li><li>JPA, the hibernate implementation</li><li>Java 5 and annotations</li></ul><br />
<br />
When creating the sample I started of programming in Intellij. Even with the excellent integration of JPA and Hibernate I still had a lot op problems creating the sample. Damn this is not easy. So what do you do when you are stuck? You start reading, I already had some books that could help me out. Still I like the Java Persistence with Hibernate book the best. The similarities between hibernate and JPA enabled me to quicker learn the basics. So I started reading, I came to the conclusion I had or wanted to start using annotations. It struck me how well Intellij was helping me again.<br />
<br />
Just a few tips when developing with intellij, maven, jpa, spring, etc.<br />
<br />
Create a new project based on an external model, click next and choose maven. Click next again and browse to the folter containing the master pom file. Click next and you have the option to select the project. The finish will create your new project with all modules present.<br />
<br />
<!-- s9ymdb:40 --><img width='500' height='302' style="border: 0px; padding-left: 5px; padding-right: 5px;" src="http://www.gridshore.nl/blog/uploads/jpaspring/createnewintellijproject.jpg" alt="" /><br />
<br />
<!-- s9ymdb:44 --><img width='500' height='302' style="border: 0px; padding-left: 5px; padding-right: 5px;" src="http://www.gridshore.nl/blog/uploads/jpaspring/createnewintellijproject2.jpg" alt="" /><br />
<br />
By default the spring and jpa facets are not present. You need to add them to the modules. Open the module settings (right mouse click and select menu item) and add the plus sign for adding a facet. The following screen shows the result of adding the spring facet and creating a new File Set. Another cool thing is that you can create a datasource to a database and connect this to a persistent unit. Columns and tables are then checked when creating your annotations.<br />
<br />
<!-- s9ymdb:43 --><img width='600' height='266' style="border: 0px; padding-left: 5px; padding-right: 5px;" src="http://www.gridshore.nl/blog/uploads/jpaspring/addfacettomodule.jpg" alt="" /><br />
<br />
I like the intellij way of creating new projects, but still I am a maven adept, so I wanted to have it all running with maven. You can find the sample online again. Beware, it is work in progress. I am adding a front end and more logic the coming weeks. Check:<br />
<a href="http://gridshore.googlecode.com/svn/trunk/RaffleApp/"  title="sources">http://gridshore.googlecode.com/svn/trunk/RaffleApp/</a><br />
<br />
If you want to start with jpa, spring and maven I can recommend the following archetype:<br />
<a href="http://www.rateyourwriting.com/downloads/jpa-hibernate-archetype.tar.gz"  title="maven archetype">http://www.rateyourwriting.com/downloads/jpa-hibernate-archetype.tar.gz</a><br />
I did not try it out myself, but it looks very good. It is create by Chris Maki (<a href="http://www.jroller.com/cmaki/category/JPA+101"  title="blog">http://www.jroller.com/cmaki/category/JPA+101</a>)<br />
<br />
In the reference manual of the springframework I found a sentence that for new applications they prefer not to use the JpaDaoSuppor class. There is another way based on the special bean PersistenceAnnotationBeanPostProcessor. Using this bean you can use annotations like :  @Entity, @PersistenceContext from within the spring container.<br />
<br />
Back to my problem, for some reason my tests using the AbstractJpaTests did not work with the separate jars for domain and data access (dao). I started by combining them in one module. But I was not satisfied. So I went back to my friend Google. I typed in a query for information about using modules with jpa and springframework. To my surprise I got back a lot of articles about the debate between using DAOs or not. Yes we are back to the  discussion about DDD or Domain Driven Design. After reading a lot of posts I guess the following sentence found on a blog item from Craig Wickesser but written by Adam Bien:<br />
<br />
<strong><em>I would say: it depends. It depends how complex your application really is.</em></strong> <br />
<br />
Now back to the original problem, how to design a application using JPA?<br />
<br />
Some of the choices you have to make:<ul><li>Use annotations or XML or both?</li><li>Use JpaTemplate or annotations and (org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor)</li><li>Create one or multiple modules<br />
Use a DAO layer or step into the DDD world and use the Persistence class.</li></ul><br />
<br />
In the end I did manage to get back to my so well known structure of a DAO layer and domain objects. What I had to do? We will check the persistence.xml file later on. I had to add the specific classes in this file.<br />
<br />
<strong>Every problem needs a sample</strong><br />
Let me first explain a bit about the example that I am going to use. For a technology evening at my company I had some books that I could give away to the people present. Since it was an evening about the Google Web Toolkit I created a nice front end application using a file as storage to a Raffle application. Check the following application if you want to see it:<br />
<a href="http://gridshore.googlecode.com/svn/trunk/Raffle/"  title="google web toolkit sample">http://gridshore.googlecode.com/svn/trunk/Raffle/</a><br />
<br />
I decided this file thing was not really optimal, so I wanted to create a database backed application. What to use? Well lets try it out JPA, hibernate started to get boring and I wanted to move on. So what is in the raffle applications domain model<br />
<br />
<!-- s9ymdb:45 --><img width='646' height='364' style="border: 0px; padding-left: 5px; padding-right: 5px;" src="http://www.gridshore.nl/blog/uploads/jpaspring/domainclassdiagram.jpeg" alt="" /><br />
<br />
Some rules:<ul><li>A raffle has multiple prices and multiple participants.</li><li>A price has a winner</li><li>A winner is a participant, or has a participant and a price.</li></ul><br />
<br />
We begin with the project setup using maven:<br />
First the dependencies that you need in your pom:<br />
spring-aop, spring-dao, spring-jpa, spring-hibernate3, hibernate-entitymanager, c3p0, mysql-connector-java, concurrent, spring-mock<br />
<br />
Thats about it, put that in the pom.xml, create the structure and do a mvn clean install, or ...<br />
<br />
Fire up intelij, create a new project based on this pom.xml and you can do the same things as I showed before.<br />
<br />
Well begin with the domain objects:<br />
<pre><br />
@MappedSuperclass<br />
public class BaseDomain {<br />
    @Id<br />
    @GeneratedValue<br />
    private Long id;<br />
}<br />
<br />
@Entity<br />
@Table (name = "participants")<br />
public class Participant extends BaseDomain {<br />
    private String name;<br />
    @ManyToOne<br />
    @JoinColumn(name = "raffle_id")<br />
    private Raffle raffle;<br />
}<br />
<br />
@Entity<br />
@Table(name = "prices")<br />
public class Price extends BaseDomain {<br />
    private String title;<br />
    private String description;<br />
    @ManyToOne<br />
    @JoinColumn(name = "raffle_id")<br />
    private Raffle raffle;<br />
    @OneToOne (mappedBy = "price")<br />
    private Winner winner;<br />
}<br />
<br />
@Entity<br />
@Table (name = "winners")<br />
public class Winner extends BaseDomain {<br />
    @OneToOne<br />
    @JoinColumn(name = "price_id")<br />
    private Price price;<br />
    @ManyToOne<br />
    @JoinColumn(name = "participant_id")<br />
    private Participant participant;<br />
}<br />
</pre><br />
Next step is to create a DAO interface that does not have anything to do with JPA, I use the interface like this:<br />
<pre><br />
public interface BaseDao<T extends BaseDomain> {<br />
    T save(T entity);<br />
    T loadByExample(T entity);<br />
    T loadById(Long entityId);<br />
    List<T> loadAll();<br />
    List<T> loadByFilter(T entityFilter);<br />
}<br />
</pre><br />
For now I will not focus on the implementation, I am not a JPA expert yet <img src="http://www.gridshore.nl/blog/templates/gridshore/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" />. One thing I want to mention is the EntityManager. Using a special annotation we make sure the EntityManager is injected by the container, the spring container in our case.<br />
<pre><br />
public abstract class BaseDaoJpa<T extends BaseDomain> implements BaseDao<T> {<br />
    @PersistenceContext<br />
    private EntityManager entityManager;<br />
...<br />
}<br />
</pre><br />
Next step is to configure the spring beans:<br />
<pre><br />
&lt;bean id="raffleDao" class="nl.gridshore.samples.raffle.dao.jpa.RaffleDaoJpa"/><br />
<br />
    &lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><br />
        &lt;property name="persistenceUnitName" value="raffle"/><br />
        &lt;property name="jpaVendorAdapter"><br />
            &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><br />
                &lt;property name="databasePlatform" value="${hibernate.sql.dialect}"/><br />
            &lt;/bean><br />
        &lt;/property><br />
        &lt;property name="dataSource" ref="dataSource"/><br />
    &lt;/bean><br />
<br />
    &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><br />
        &lt;property name="entityManagerFactory" ref="entityManagerFactory"/><br />
    &lt;/bean><br />
<br />
    &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/><br />
<br />
    &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><br />
        &lt;property name="driverClassName" value="${jdbc.driverclass}"/><br />
        &lt;property name="url" value="${jdbc.url}"/><br />
        &lt;property name="username" value="${jdbc.username}"/><br />
        &lt;property name="password" value="${jdbc.password}"/><br />
    &lt;/bean><br />
</pre><br />
Finally we need to configure the the entity manager, this is done with a special file named persistence.xml which is displayed beneath.<br />
<pre><br />
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"><br />
    &lt;persistence-unit name="raffle" transaction-type="RESOURCE_LOCAL"><br />
        &lt;provider>org.hibernate.ejb.HibernatePersistence&lt;/provider><br />
        &lt;class>nl.gridshore.samples.raffle.domain.BaseDomain&lt;/class><br />
        &lt;class>nl.gridshore.samples.raffle.domain.Raffle&lt;/class><br />
        &lt;class>nl.gridshore.samples.raffle.domain.Price&lt;/class><br />
        &lt;class>nl.gridshore.samples.raffle.domain.Participant&lt;/class><br />
        &lt;class>nl.gridshore.samples.raffle.domain.Winner&lt;/class><br />
        &lt;properties><br />
            &lt;property name="hibernate.archive.autodetection" value="class"/><br />
            &lt;property name="hibernate.show_sql" value="true"/><br />
            &lt;property name="hibernate.format_sql" value="true"/><br />
            &lt;property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/><br />
        &lt;/properties><br />
    &lt;/persistence-unit>    <br />
&lt;/persistence><br />
</pre><br />
<br />
That is enough to start using the application. However, there is one thing I forget. What about testing this application. Spring comes with a special class for testing called AbstractJpaTests. This is class had familiar functionality, auto dependency injection and rolling back a transaction after the test.<br />
<br />
Using this test you still need a database. For the data access tests I am using a combination of dbunit, springframework and hsqldb. Most important part of the test class is the injection of the dao:<br />
<pre><br />
public class RaffleDaoJpaTest extends AbstractJpaTests {<br />
    private RaffleDaoJpa raffleDao;<br />
<br />
    public void setRaffleDao(RaffleDaoJpa raffleDao) {<br />
        this.raffleDao = raffleDao;<br />
    }<br />
<br />
	...<br />
<br />
    protected String[] getConfigLocations() {<br />
        return new String[] {"classpath:test-dao-spring.xml","classpath:dao-config.xml"};<br />
    }<br />
}<br />
</pre><br />
The following beans are in the special test spring config file together with the datasource for the test database.<br />
<pre><br />
    &lt;bean id="dbUnitInsertOperation" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"<br />
            depends-on="transactionManager"><br />
        &lt;property name="targetObject"><br />
            &lt;bean class="org.dbunit.operation.RefreshOperation" /><br />
        &lt;/property><br />
        &lt;property name="targetMethod" value="execute" /><br />
        &lt;property name="arguments"><br />
            &lt;list><br />
                &lt;ref bean="dbUnitConnection" /><br />
                &lt;bean id="dbUnitDataSet" class="org.dbunit.dataset.xml.FlatXmlDataSet"><br />
                    &lt;constructor-arg><br />
                        &lt;bean id="refDataFile" factory-bean="referenceData" factory-method="getInputStream" /><br />
                    &lt;/constructor-arg><br />
                &lt;/bean><br />
            &lt;/list><br />
        &lt;/property><br />
    &lt;/bean><br />
<br />
    &lt;bean id="referenceData" class="org.springframework.core.io.ClassPathResource"><br />
        &lt;constructor-arg value="testdata.xml"/><br />
    &lt;/bean><br />
<br />
    &lt;bean id="dbUnitConnection"	class="util.CustomDatabaseConnection"><br />
        &lt;constructor-arg><br />
            &lt;bean id="connection" factory-bean="dataSource"	factory-method="getConnection" /><br />
        &lt;/constructor-arg><br />
    &lt;/bean><br />
</pre><br />
That is about it, again, check the source code, everything is runnable by maven2 and tested on tomcat 5.5. If you want to read more, I used the following resources while creating learning about jpa and the other topics.<br />
<br />
Links:<br />
<a href="http://www.infoq.com/news/2007/09/jpa-dao" >http://www.infoq.com/news/2007/09/jpa-dao</a><br />
<a href="http://debasishg.blogspot.com/" >http://debasishg.blogspot.com/</a><br />
<a href="http://www.vitarara.org/cms/struts_2_cookbook/integration_testing" >http://www.vitarara.org/cms/struts_2_cookbook/integration_testing</a><br />
<a href="http://dev2dev.bea.com/pub/a/2006/03/jpa-spring-medrec.html?page=6" >http://dev2dev.bea.com/pub/a/2006/03/jpa-spring-medrec.html?page=6</a><br />
<a href="http://www.jroller.com/cmaki/entry/domain_model_revisited" >http://www.jroller.com/cmaki/entry/domain_model_revisited</a><br />
<br />
<br />
<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/71-Loading-properties-using-JNDI-within-the-springframework-deployed-on-tomcat.html" rel="alternate" title="Loading properties using JNDI within the springframework deployed on tomcat" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-11-16T22:32:54Z</published>
        <updated>2007-11-16T22:32:54Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=71</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=71</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/71-guid.html</id>
        <title type="html">Loading properties using JNDI within the springframework deployed on tomcat</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Hai All,<br />
finally a new technical item. It is a short item, but I have been struggling to get this to work. Therefore I want to share this so other can use it to configure there properties in a flexible way.<br />
<br />
<strong>Problem:</strong><br />
Properties like database url's, userid's and pasword's are different in your test environment and your production environment. There are other items you might want to configure.<br />
<br />
<strong>Solution:</strong><br />
You can make complicated deployment scripts that get the right property files for the right environment. But you need to create different packages for different environments. I think a more elegant solution is to use the JNDI parameters to load the specific environmental values. If there are a lot a good way might be to store them in a database and only configure the database access parameters using JNDI.<br />
<br />
The following solution is based on two posts in different forums:<br />
<a href="http://forum.java.sun.com/thread.jspa?threadID=647327&messageID=3810991" >http://forum.java.sun.com/thread.jspa?threadID=647327&messageID=3810991</a> - gives details about the configuration of tomcat.<br />
<a href="http://forum.springframework.org/showthread.php?t=30991" >http://forum.springframework.org/showthread.php?t=30991</a> - gives details about the spring configuration<br />
<br />
Now the code, we start with the tomcat configuration. The server.xml file contains all the actual values connected to the exposed JNDI parameter names.<br />
<br />
<strong>server.xml</strong><br />
<pre style="width:600px"><br />
  &lt;!-- Global JNDI resources --><br />
  &lt;GlobalNamingResources><br />
    &lt;!-- Test entry for demonstration purposes --><br />
    &lt;Environment name="jdbc/username" value="myUser" type="java.lang.String"/><br />
    &lt;Environment name="jdbc/password" value="myPwd" type="java.lang.String"/><br />
    &lt;Environment name="jdbc/url" value="jdbc:mysql://servername/schema" type="java.lang.String"/><br />
    &lt;Environment name="jdbc/drivername" value="com.mysql.jdbc.Driver" type="java.lang.String"/><br />
  &lt;/GlobalNamingResources><br />
</pre><br />
We need to tell the application the names of the parameters that are available. We must add the following items to the web configuration file.<br />
<br />
<strong>web.xml</strong><br />
<pre style="width:600px"><br />
&lt;resource-env-ref><br />
    &lt;resource-env-ref-name>jdbc/username</resource-env-ref-name><br />
    &lt;resource-env-ref-type>java.lang.String</resource-env-ref-type><br />
&lt;/resource-env-ref><br />
</pre><br />
Of course you need to do this for all four parameters. Then the tricky part. This is the one I missed while getting this to work. You need to add a tomcat specific deployment configuration with the following lines<br />
<br />
<strong>META-INF/context.xml</strong><br />
<pre  style="width:600px" ><br />
&lt;Context path="/webapp"><br />
    &lt;ResourceLink name="jdbc/username" global="jdbc/username" type="java.lang.String"/><br />
    &lt;ResourceLink name="jdbc/password" global="jdbc/password" type="java.lang.String"/><br />
    &lt;ResourceLink name="jdbc/url" global="jdbc/url" type="java.lang.String"/><br />
    &lt;ResourceLink name="jdbc/drivername" global="jdbc/drivername" type="java.lang.String"/><br />
&lt;/Context><br />
</pre><br />
Thats is all we need to do to make these values available to the spring beans. So the last part is the spring configuration. We are going to create a PropertyPlaceHolderConfigurer. That way you can access the properties just like properties from a file.<br />
<br />
<strong>spring-config.xml</strong><br />
<pre  style="width:600px" ><br />
    &lt;bean id="databaseprops" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><br />
        &lt;property name="properties"><br />
            &lt;bean class="java.util.Properties"><br />
                &lt;constructor-arg><br />
                    &lt;map><br />
                        &lt;entry key="database.username"><br />
                            &lt;jee:jndi-lookup jndi-name="java:comp/env/jdbc/username"/><br />
                        &lt;/entry><br />
                        &lt;entry key="database.password"><br />
                            &lt;jee:jndi-lookup jndi-name="java:comp/env/jdbc/password"/><br />
                        &lt;/entry><br />
                        &lt;entry key="database.url"><br />
                            &lt;jee:jndi-lookup jndi-name="java:comp/env/jdbc/url"/><br />
                        &lt;/entry><br />
                        &lt;entry key="database.drivername"><br />
                            &lt;jee:jndi-lookup jndi-name="java:comp/env/jdbc/drivername"/><br />
                        &lt;/entry><br />
                    &lt;/map><br />
                &lt;/constructor-arg><br />
            &lt;/bean><br />
        &lt;/property><br />
    &lt;/bean><br />
    &lt;bean id="sampleConfigBean" class="nl.gridshore.samples.config.SampleConfiguredBean"><br />
        &lt;property name="username" value="${database.username}"/><br />
        &lt;property name="password" value="${database.password}"/><br />
        &lt;property name="url" value="${database.url}"/><br />
        &lt;property name="drivername" value="${database.drivername}"/><br />
    &lt;/bean><br />
</pre><br />
This made my deployment life a lot easier, hope you will find some good use of it. Thanks again to contributers on the forum for making the different parts clear to me.<br />
<br />
Till next time, which is going to be a piece about JPA.<br />
<br />
greetz Jettro Coenradie 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/70-I-have-a-Mac.html" rel="alternate" title="I have a Mac" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-11-04T23:49:48Z</published>
        <updated>2007-11-06T06:57:57Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=70</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=70</wfw:commentRss>
    
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/70-guid.html</id>
        <title type="html">I have a Mac</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Wow, I have finally made the decision, I bought a Mac. Now I am the proud owner of a MacBook pro. So the next blog entries will be written on my new Mac. I think I will loose time at first, new key board, new mouse, new platform. But IntelliJ is running already. I have my mail setup, importing i-tunes now. To bad it is time to go to bed. I understood, I need to read the following website <a href="http://www.macmiep.nl"  title="http://www.macmiep.nl">http://www.macmiep.nl</a>, if you have better options, please let me know.<br />
<br />
Now I say, goodnight, I am off with a very big smile. 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/69-Rowing-the-Google-Web-Toolkit-boat-with-intellij.html" rel="alternate" title="Rowing the Google Web Toolkit boat with intellij" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-10-14T07:11:49Z</published>
        <updated>2007-10-14T07:11:49Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=69</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=69</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/12-ajax" label="ajax" term="ajax" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/69-guid.html</id>
        <title type="html">Rowing the Google Web Toolkit boat with intellij</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                The last month(s) I have been working on multiple <a href="http://code.google.com/webtoolkit/"  title="gwt">Google Web Toolkit</a> implementations. I must admit that the implementations are not very big. They are mostly small applications I needed for some reason. One of them is a Raffle system, there is one with a large amount of data on a screen that should be editable as well. In this blog item I will share some experiences I have gained using the Google Web Toolkit with <a href="http://code.google.com/p/gwt-maven/"  title="maven gwt">maven2</a>, <a href="http://www.jetbrains.com/idea/nextversion/"  title="intellij">JetBrains IntelliJ</a>. The applications can interact with a standard GWT servlet, or with the springframework and security via spring security (acegi). I also experimented with a nice GUI framework called <a href="http://code.google.com/p/gwt-ext/"  title="gwt-ext">gwt-ext</a>. Finally, I also used the Google Web Toolkit in a sample we created for spring osgi. So please continue reading, most sources can be found in in my<a href="http://code.google.com/p/gridshore/"  title="google code for gridshore"> code repository </a>at google.<br />
In this blog item I will mostly look at IntelliJ, I will create new blog items about using eclipse and maven as well.<br />
<br />
<strong>Step 1 - Creating a project skeleton</strong><br />
<p><div class="serendipity_imageComment_left" style="width: 110px"><div class="serendipity_imageComment_img"><a class='serendipity_image_link' href='http://www.gridshore.nl/blog/uploads/gwt/intellijmodulesettingsgwt.jpg' onclick="F1 = window.open('/blog/uploads/gwt/intellijmodulesettingsgwt.jpg','Zoom','height=444,width=615,top=185.5,left=340,toolbar=no,menubar=no,location=no,resize=1,resizable=1,scrollbars=yes'); return false;"><!-- s9ymdb:28 --><img width='110' height='79'  src="http://www.gridshore.nl/blog/uploads/gwt/intellijmodulesettingsgwt.serendipityThumb.jpg" alt="" /></a></div><div class="serendipity_imageComment_txt">new gwt module wizzard</div></div>If you just want to play around and you have IntelliJ, I recommend to use the new project wizzard from intellij. Just create a new Java Project and select Google Web Toolkit in the desired technologies section. Go to the module settings and point to the right direction of you gwt install. Now you can start adding modules, remote services, etc.</p><br />
<br />
<strong>Step 2 - Adding the module and entry point</strong><br />
<div class="serendipity_imageComment_right" style="width: 74px"><div class="serendipity_imageComment_img"><a class='serendipity_image_link' href='http://www.gridshore.nl/blog/uploads/gwt/intellijstructurenewmodule.jpg' onclick="F1 = window.open('/blog/uploads/gwt/intellijstructurenewmodule.jpg','Zoom','height=479,width=327,top=168,left=484,toolbar=no,menubar=no,location=no,resize=1,resizable=1,scrollbars=yes'); return false;"><!-- s9ymdb:29 --><img width='74' height='110'  src="http://www.gridshore.nl/blog/uploads/gwt/intellijstructurenewmodule.serendipityThumb.jpg" alt="" /></a></div><div class="serendipity_imageComment_txt">generated gwt module files</div></div>Start by adding a package, select src and alt+insert. Select package, enter the package name. Then select that package and again alt-insert. Now choose the gwt>gwt module. Give the name you think is right for your project, in my case <em>Raffle</em>. This step generates multiple files:<br />
Raffle.gwt.xml - the configuration file for the module with a reference to the entry point.<br />
Raffle.java - in the client package, this is the entry point for the gwt application.<br />
Raffle.html - html file in the public folder that is called by the browser with a javascript that starts the gwt application.<br />
Raffle.css - stylesheet referenced by the html file that is also in the public folder.<br />
<br />
Everthing in the client folder is compiled to JavaScript, be sure there is nog Java 5 features in here, this is not (yet) supported. The public folder is exposed using the webserver as static files. Nothing happens to them. You can put images in here as well. Finally there is a server folder. This is in the end a plain java folder that contains the implementations of remote services. More on that later.<br />
<br />
<strong>Step 3 - Test the setup we have created</strong><br />
<div class="serendipity_imageComment_left" style="width: 110px"><div class="serendipity_imageComment_img"><a class='serendipity_image_link' href='http://www.gridshore.nl/blog/uploads/gwt/intellijaddgwtrunconfiguration.jpg' onclick="F1 = window.open('/blog/uploads/gwt/intellijaddgwtrunconfiguration.jpg','Zoom','height=522,width=615,top=146.5,left=340,toolbar=no,menubar=no,location=no,resize=1,resizable=1,scrollbars=yes'); return false;"><!-- s9ymdb:30 --><img width='110' height='93'  src="http://www.gridshore.nl/blog/uploads/gwt/intellijaddgwtrunconfiguration.serendipityThumb.jpg" alt="" /></a></div><div class="serendipity_imageComment_txt">create new run configuration</div></div>Time to start the test. We need to create a configuration. Press alt+shift+f10 and 'edit configurations'. In the next screen add the + sign to create a new configuration and choose GWT Configuration. Give the configuration a good name. Other than that, the defaults should be fine. Now you can run the application by clicking the green run arrow or shift + f10. You can see the result in the icon on the right.<div class="serendipity_imageComment_right" style="width: 110px"><div class="serendipity_imageComment_img"><a class='serendipity_image_link' href='http://www.gridshore.nl/blog/uploads/gwt/intellijgwtrunfirst.jpg' onclick="F1 = window.open('/blog/uploads/gwt/intellijgwtrunfirst.jpg','Zoom','height=515,width=815,top=150,left=240,toolbar=no,menubar=no,location=no,resize=1,resizable=1,scrollbars=yes'); return false;"><!-- s9ymdb:34 --><img width='110' height='69'  src="http://www.gridshore.nl/blog/uploads/gwt/intellijgwtrunfirst.serendipityThumb.jpg" alt="" /></a></div><div class="serendipity_imageComment_txt">running the application</div></div><br />
<br />
<strong>Step 4 - Adding stuff to the screen.</strong><br />
<strong>Step 4.1 - Add the menu</strong><br />
The total screen will consist of two panels, one containing the menu, the other is the content panel in which all menu actions take place.<br />
<pre><br />
public void onModuleLoad() {<br />
  ScrollPanel contentContent = new ScrollPanel();<br />
  MenuBar menuBar = createMenuBar(contentContent);<br />
  RootPanel.get().add(menuBar);<br />
  RootPanel.get().add(contentPanel);<br />
}<br />
<br />
private MenuBar createMenuBar(final ScrollPanel contentPanel) {<br />
  ...<br />
    menuBar.addItem("List Names", new Command() {<br />
      public void execute() {<br />
        contentPanel.setWidget(createListNames(contentPanel));<br />
      }<br />
    });<br />
  ...<br />
}<br />
private Panel createListNames(final ScrollPanel contentPanel) {<br />
  ...<br />
}<br />
</pre><br />
The code shows how to create the MenuBar and how to add an item. This is not a very thorough example and as you can see I did not implement the method createListNames. Before I do this I need to explain remoting which I will do next. The sample up till now does show how to add an a menu and how to add items to the menu. Look at the way to create a command when the menu item is clicked. By using the method setWidget on the content panel we can change the content on the page when clicking a menu item.<br />
<br />
<strong>Step 4.2 - Doing some remoting</strong><br />
<div class="serendipity_imageComment_left" style="width: 110px"><div class="serendipity_imageComment_img"><a class='serendipity_image_link' href='http://www.gridshore.nl/blog/uploads/gwt/intellijcreateremoteservice.jpg' onclick="F1 = window.open('/blog/uploads/gwt/intellijcreateremoteservice.jpg','Zoom','height=515,width=815,top=150,left=240,toolbar=no,menubar=no,location=no,resize=1,resizable=1,scrollbars=yes'); return false;"><!-- s9ymdb:36 --><img width='110' height='69'  src="http://www.gridshore.nl/blog/uploads/gwt/intellijcreateremoteservice.serendipityThumb.jpg" alt="" /></a></div><div class="serendipity_imageComment_txt">Create a new remote service</div></div>This is the moment Intellij will also help you a lot. Select the package where you stored your client gwt module. alt + insert will popup a menu. Select the Google Web Toolkit > GWT Remote Service. The following file will be generated when you create the RaffleRemoteService:<br />
<br />
In the client package<br />
RaffleRemoteService - Interface containing a static internal class <strong>App</strong> with a utility method getInstance to get a RaffleRemoteServiceAsync. Check the code later on.<br />
RaffleRemoteServiceAsync - Interface that has the same methods as the RaffleRemoteService with one extra parameter of type AsyncCallback.<br />
<br />
In the server package<br />
RaffleRemoteServiceImpl that implements RaffleRemoteService and is a subclass of RemoteServiceServlet, a google web toolkit provided servlet. This servlet is also automatically configured in the module configuration file 'Raffle.gwt.xml'. The following lines are added.<br />
<br />
&#160;servlet path="/nl.gridshore.samples.gwt.simple.Raffle/RaffleRemoteService"<br />
    class="nl.gridshore.samples.gwt.simple.server.RaffleRemoteServiceImpl"/><br />
<br />
Want to see some intellij magic? Let's add a method to the RaffleRemoteService for obtaining a list of names.<br />
<!-- s9ymdb:38 --><img width='775' height='209' style="border: 0px; padding-left: 5px; padding-right: 5px;" src="http://www.gridshore.nl/blog/uploads/gwt/intellijaddingmethodtoremoteservice.jpg" alt="" /><br />
As you can see on the image there is an error. Intellij asks you if you want to synchronise the remote service with the asynchronous service. Click ant + enter and the interfaces are in sync again. There is more in the image. Check the return argument <em>ArrayList</em>. This is not a java 5 collection, gwt cannot handle that. But we do need to tell what kind of objects are in the ArrayList. This is why we need the annotation @gwt.typeArgs <java.lang.String>.<br />
<br />
<strong>Step 4.3 - Doing some styling</strong><br />
You can add styling via the style sheet. Almost every widget has it's own styling and of course you can add a style name to every widget you create. Some of the basic styles are:<br />
<pre><br />
.gwt-Button {}<br />
.gwt-Label {}<br />
.gwt-TextBox {margin-left:20}<br />
.gwt-TextBox-readonly {}<br />
<br />
.gwt-MenuBar {}<br />
.gwt-MenuBar .gwt-MenuItem {}<br />
.gwt-MenuBar .gwt-MenuItem-selected {}<br />
</pre><br />
<br />
That is about it for now, hope this helps, you can extract the important information if you want to use eclipse. Next time I will write something about using maven2 and a special toolkit called gwt-ext. You can find the complete source code online: <a href="http://gridshore.googlecode.com/svn/trunk/Raffle/"  title="code">http://gridshore.googlecode.com/svn/trunk/Raffle/</a> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html" rel="alternate" title="Web service versioning in the java world" />
        <author>
            <name>Allard Buijze</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-08-20T11:04:00Z</published>
        <updated>2007-09-18T09:17:40Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=68</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/11-Webservices" label="Webservices" term="Webservices" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/68-guid.html</id>
        <title type="html">Web service versioning in the java world</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>There are many blog entries and articles out there about web service versioning. So why write another? In my day-to-day work, I am often asked about how to solve web service versioning issues. The articles on the web provide different ways to do it, but do not take the impact on the codebase, deployment and testing into consideration. Now that's exactly what I'll be trying to do in this article.</p><p>First, I'll briefly describe what I mean with Web Service versioning. Then, I'll shed some light on different possible solutions. Finally, I'll compare all of these solutions in terms of complexity, codebase, deployment and testing.<br /></p><br />
<br />
<h4>Web service versioning, real or just a myth?</h4><p>Many, maybe even all, projects that involve web services will encounter a problem they call "web service versioning". But what is it? And does it really exist?<br /><br />A web service is a piece of code, published under a more or less strict contract (WSDL and XSD), that can be called by other pieces of code across the web. This contract poses a problem, because your users depend on this contract to communicate with your application. If your request or response message format changes, it will most probably break the contract, causing your clients to send invalid messages and being unable to parse your responses.<br /><br />So, if you change the contract, are we still talking about the same service? Or is it just another service you are providing? In terms of web services, it will be just another service. However, developers think in terms of code and classes. Since the major part of the codebase will be the same for the new service, we like to think of it as a new version. So, web service versioning doesn't really exist, but we want our classes to be reused. Now we've put our finger on the sore spot.</p><h4>Why versioning web services is an issue</h4><p>Web Service versioning doesn't exist. So why is it an issue? Because developers (myself included) want to be able to reuse existing classes for new versions of a service. So, in our Version Control System (VCS, e.g. Subversion or CVS) repository weÂ?ll want to create a branch for the old version, and continue development in our main branch. We'd want to deploy our application with our old JAR and the new one and provide some mechanism for selecting either the old classes or the new ones.<br /><br />That's when class loading comes in to play and ruin our day. Java isn't able to load the two different classes with the same name, at least, not in this case. It will load class com.mycompany.MyService from only one of both jars, whichever is first on the classpath. For java to accept different implementations of a same class, you'd have to do some class loader tricks.<br /></p><p /><h4>Solutions for service versioning</h4><p>The web is full of solutions for versioning. I'll mention each solution briefly, and explain how it is set up. At the end of this blog entry, I will compare these solutions in terms of codebase, deployment and testing.<br /><br /><strong>1. Don't do versioning. Force clients to migrate to the newest version available.</strong>This is often tried as the first solution, but will most likely fail. Often, client applications are managed by another project, not in the area of influence of the project developing the web service provider. The cons are mostly financial: who's going to pay for the migration of the client? I'm not going into more detail on this solution, as it doesn't solve the versioning problem.<br /><br /><strong>2. Deploy another EAR file containing the new version of the web service, leaving the old application untouched.</strong>In terms of development and maintenance of the codebase, this is the easiest solution. Just create a branch in your VCS for the old version and continue the development in the main branch. Since the old application is totally unmodified, it doesn't have to be tested when a new version is created. However, your deployers will have to deploy and maintain one applications per supported version.<br />In case of bug fixes, there is another choice to be made. Will the bug be fixed in each version, or just in the latest one. In the first case, the code has to be changed in several locations in you repository. Fortunately, today's VCS tools (e.g. TortoiseSVN) allow you to easily merge changes across branches. Then, testers have to test each modified application and the deployer has to redeploy them.<br /><br />In conclusion, this solution is easy for the developers, but has more impact on testers and deployers.<br /><br /><strong>3. Deploy a single EAR file, with a WAR file per version</strong>Beware! For this solution to work, all version specific code should be placed in the WEB-INF/lib dir of your WAR file, and each WAR file must have its own class loader.<br /><br />Just like the previous solution, you can create a branch in your VCS and merge changes across branches. However, a change in one version of the code will change the composition of the entire EAR file, and thus affect other versions, even if the specifications of that version haven't changed. This means that there is no way to guarantee that old versions are unaffected by changes in newer versions. This puts some extra load on the testers. The deployers however will only have to deploy and maintain a single application, regardless of the number of versions it supports.<br /><br /><strong>4. Use different package names for each version</strong>On several blog sites, this solution is provided as &quot;the one&quot; to use. If you take java out of the equation, it might be very interesing, because your request and response messages are very clear about the version of the service. However, in the real world, developers use binding frameworks such as jaxb or augis. This would mean different package names (and rewriting code) for each version. This makes solutionÂ the worst of all for developers, as the entire codebase has to be changed for each new version.<br /><br />I am not going into detail about this solution, because it is not a solution to the "versioning" problem. Here, we are just creating a completely new service, with all new classes. No resuse. However, do take this option into consideration for at least a few minutes. Depending on the size of your codebase, it might just not be such a bad solution.<br /><br /><strong>5. Use a framework that supports advanced class loading</strong>People who know me would probable wonder by now: "When will he mention OSGi"?. Well, just about now. Frameworks that implement the OSGi specification (e.g. Equinox, Knoplerfish and Felix), are able to load different implementations of the same class, and understand the difference between them. Jettro Coenradie and I have given a presentation on Web Service versioning using OSGi that the Spring 2007 conference (see <a href="http://www.nljug.org/pages/events/content/jspring_2007/sessions/00003/">http://www.nljug.org/pages/events/content/jspring_2007/sessions/00003/</a>). We've also dedicated a website to provide information on the subject: <a href="http://www.osgisamples.com/">http://www.osgisamples.com</a>.<br /><br />This solution is probably the most difficult one to implement. It is most likely that neither the developers, nor the testers and deployers have knowledge about OSGi and the impact on their work. However, if this knowledge is available to your project, make sure to consider this solution.</p><h4>Comparing the solutions</h4><p>Now that I have mentioned each solution briefly, it is time to put them in the ring to compete against each other. Here we go:</p><h4><table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1"><tbody><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt" /></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1"><strong>EAR versioning</strong><br />(endpoint versioning)</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1"><strong>WAR versioning</strong><br />(endpoint versioning)</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1"><strong>Package versioning</strong><br />(namespace versioning)</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1"><strong>OSGi</strong><br />(any type of versioning you like)</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">How the versions are recognized</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">By endpoint</font></span></p><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Either the EARs will be deployed on different app servers, or the WARs inside will have different contexts</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">By endpoint</font></span></p><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Each WAR in the ear wil have a different context (e.g. /services/v1 and /services/v2)</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">By namespace</font></span></p><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">We're talking about different services here. The dispatching process will send each service to the appropriate class</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Any way you like. You have complete influence on the dispatching process.</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Complexity to set up</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">No specific set up to be done. Make sure to use a VCS.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Slightly complex. Use e.g. maven to build the WAR files and include the necessary versions in your EAR. Make sure version specific classes and jars are included inside the WAR.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Not complex at all to set up, but each new version will require you to create new classes or rename the old ones.</font></span></p><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Consider each new version as a completely new service in your web service dispatcher</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Very complex for beginners. OSGi introduces some extra features and a different mindset than Â?normalÂ? java programming.</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Impact on codebase, bug fixing and maintenance</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Little impact. Keep in mind that each fixed version will have to be redeployed. Use your VCS tools to merge changes across branches.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Little impact. Each modified version will have to be rebuilt and each WAR included in the EAR file. Use your VCS tools to merge changes across branches.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Huge impact. The amount of classes will double with each version. Merging across branches is no longer possible, since class names are different.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">You application will have to be set up in a modular fashion. If it already is, the impact on your codebase is small. You can use VCS tools to merge changes, since class names donÂ?t change.</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Impact on deployment effort</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Highest impact on deployers. Each version requires an extra EAR to be maintained.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Small impact on deployers. There is only a single EAR file to deploy and maintain.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Small impact on deployers. There is only a single EAR file to deploy and maintain.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Small impact on deployers. There is only a single EAR file to deploy and maintain.</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Impact on testers</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Small impact. Old versions are remained intact when deploying new versions.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Big impact. It is hard to guarantee that old versions are remained intact upon deployment of a new version.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Big impact. It is hard to guarantee that old versions are remained intact upon deployment of a new version.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Big impact. It is hard to guarantee that old versions are remained intact upon deployment of a new version.</font></span></p></td></tr><tr><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Flexibility</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Very high. Since versions are completely separate, changes in one version do not affect the other.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">High. Because all versions share a common (EAR) class loader, there are some limitations. Especially when using native code.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Low. All versions must use the same shared libraries, as all versions share a single class loader.</font></span></p></td><td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 99.65pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="133"><p style="MARGIN-BOTTOM: 12pt"><span style="FONT-SIZE: 10pt; FONT-FAMILY: "><font face="verdana,arial,helvetica,sans-serif" color="#000000" size="1">Very high. The versioning and dispatching mechanism is completely configurable to your projects needs. Each version of the web service can depend on different versions of external libraries. </font></span></p></td></tr></tbody></table></h4> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/67-Java-Generics-almost-seem-like-puzzlers-from-Joshua-Bloch.html" rel="alternate" title="Java Generics almost seem like puzzlers from Joshua Bloch" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-07-16T20:01:56Z</published>
        <updated>2007-08-28T07:00:21Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=67</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=67</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/67-guid.html</id>
        <title type="html">Java Generics almost seem like puzzlers from Joshua Bloch</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Hai, today I have a short blog item. This is just because I am having fun with java generics. Check out the following piece of code. Will it compile? If you think it will compile, what will it print? If you think it won't compile, why not?<br />
<br />
Use the comment option at the end of each blog item to give me your answer.<br />
<br />
<pre><br />
package generics.method.withinterface;<br />
public interface Converter {<br />
    &lt;E,T> E convert (T toBeConverted);<br />
}<br />
<br />
package generics.method.withinterface;<br />
public class ExampleConverter implements Converter {<br />
	public &lt;String, Integer> String convert(Integer toBeConverted) {<br />
		String retVal = "";<br />
		retval = toBeConverted.toString();<br />
		return retval;<br />
	}<br />
}<br />
package generics.method.withinterface;<br />
public class Executer {<br />
	public static void main(String[] args) {<br />
		ExampleConverter converter = new ExampleConverter();<br />
		System.out.println(converter.convert(5));<br />
	}<br />
<br />
}<br />
</pre><br />
After a few weeks I'll give the answer <img src="http://www.gridshore.nl/blog/templates/gridshore/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" /> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/66-Using-Spring-ws-for-creating-a-webservice.html" rel="alternate" title="Using Spring-ws for creating a webservice" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-07-04T18:33:52Z</published>
        <updated>2007-07-04T18:33:52Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=66</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=66</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/11-Webservices" label="Webservices" term="Webservices" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/66-guid.html</id>
        <title type="html">Using Spring-ws for creating a webservice</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                My previous post was about creating a client with the spring-ws project. This dis take me some time to grasp. But without a published webservice a client is of no much use. Therefore I also had a look at the server side. To my surprise this was even easier than expected. I did have some requirements for the sample:<br />
<ul><li>wsdl generation</li><li>marshalling/unmarshalling using jaxb2</li></ul><br />
That does not sound to bad does it? Well try to do it with axis and you'll be surprised. If you know a little bid about spring-webmvc and the use of the dispatcher, you know you need one configuration file for spring. For the webservice I had to provide the spring config file and one class, yes really, just one class. I used maven to generate the jaxb stuff and this is wat I did:<br />
<pre><br />
<strong>web.xml</strong><br />
&lt;servlet><br />
  &lt;servlet-name>spring-ws&#160;/servlet-name><br />
  &lt;servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet&lt;/servlet-class><br />
&lt;/servlet><br />
&lt;servlet-mapping><br />
  &lt;servlet-name>spring-ws&#160;/servlet-name><br />
  &lt;url-pattern>/*&#160;/url-pattern><br />
&lt;/servlet-mapping><br />
</pre><br />
The spring-ws framework provides a special servlet that receives the requests. No the really hard part, the spring configuration for the endpoint:<br />
<pre><br />
&lt;bean class="org.springframework.ws.server.endpoint.mapping.SimpleMethodEndpointMapping"><br />
  &lt;property name="endpoints" ref="congressRegistrationEndpoint"/><br />
&lt;/bean><br />
&lt;bean id="congressRegistrationEndpoint"  class="nl.gridshore.samples.springws.server.JaxbMarshallingMethodEndpoint"><br />
  &lt;property name="marshaller" ref="marshaller"/><br />
  &lt;property name="unmarshaller" ref="unmarshaller"/><br />
&lt;/bean><br />
&lt;bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><br />
  &lt;property name="contextPath" value="nl.gridshore.samples.jaxb"/><br />
&lt;/bean><br />
&lt;bean id="unmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><br />
  &lt;property name="contextPath" value="nl.gridshore.samples.jaxb"/><br />
&lt;/bean><br />
</pre><br />
First check the endpoint mapping, this class <em>SimpleMethodEndpointMapping</em> is found by the dispatcher to map all incoming requests to endpoints. In our case we map to our only endpoint called the congressRegistrationEndpoint. This class has a special super class that needs a marshaller and unmarshaller. Other than that it needs nothing. By convention the name of the Request is used by the super class to know which method to call. In our case we have a CongressRegistrationRequest. Therefore we need to implement to method handleCongressRegistrationRequest as you can see in the following coded block.<br />
<pre><br />
public CongressRegistrationResponse handleCongressRegistrationRequest(CongressRegistrationRequest request) {<br />
  ObjectFactory objectFactory = new ObjectFactory();<br />
  CongressRegistrationResponse response = objectFactory.createCongressRegistrationResponse();<br />
  response.setRegistrationCode("code333");<br />
  return response;<br />
}<br />
</pre><br />
In this code the argument and the return value are JAXB objects. I created the most easy method, do nothing with the request and always return the same response. Bu as you can see the code itself is very clean. I do not need to do a lot of conding. I think this is probably one of the easiest implementations I have seen that works in java 1.4 as well.<br />
<br />
That is it for one of the requirements. Now I also wanted a solution for generating the wsdl. In the end this is only some springframework configuration. You also need an xsd, but you have already used this to generate the jaxb classes with maven. So we can reuse it. Check the following configuration<br />
<pre><br />
&lt;bean id="service" class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition"><br />
  &lt;property name="builder"><br />
    &lt;bean class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder"><br />
      &lt;property name="schema" value="/WEB-INF/classes/congressregistration.xsd"/><br />
      &lt;property name="portTypeName" value="services"/><br />
      &lt;property name="locationUri" value="http://localhost:8080/spring-ws-sample-server/"/><br />
      &lt;property name="targetNamespace" value="http://www.gridshore.nl/samples/definitions"/><br />
    &lt;/bean><br />
  &lt;/property><br />
&lt;/bean><br />
</pre><br />
So you need the location of the xsd, the name of the bean is used to find the wsdl. The locationUri locates the endpoint and the targetNamespace is the namespace used in the xsd. By entering the following url you can find the wsdl.<br />
http://localhost:8080/spring-ws-sample-server/service.wsdl<br />
<br />
You can check the code at the <a href="http://gridshore.googlecode.com/svn/trunk/spring-ws-sample/spring-ws-sample-server/">google code project</a>.<br />
<br />
I know it is pretty short, but with the code you should be able to understand it.<br />
<br />
greetz Jettro 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/65-Creating-a-webservice-client-using-Spring-ws-and-maven2.html" rel="alternate" title="Creating a webservice client using Spring-ws and maven2" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-06-30T19:25:00Z</published>
        <updated>2007-06-27T10:06:49Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=65</wfw:comment>
    
        <slash:comments>14</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=65</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/11-Webservices" label="Webservices" term="Webservices" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/65-guid.html</id>
        <title type="html">Creating a webservice client using Spring-ws and maven2</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Last week I attended the <a href="http://www.springone.com">SpringOne Congress</a> in Antwerp. Just one or two days before the congress I wanted to create a proof of concept for a client connecting to a webservice. I have been using the proxy way (spring-remote), but I did not really like the way this works. Therefore I was looking for something else. I stumbled upon the  <a href="http://static.springframework.org/spring-ws/site/">Spring Webservices</a> project. I did try this out before, but not for clients. I started working and it did not look very complicated. I must admit I needed the help from Arjen Poutsma himself to make it work, but now I have a very light weight solution. I like the approach very much, therefore I will briefly describe the solution I have created. You can of course find the sources online as well. Check the <a href="http://gridshore.googlecode.com/svn/trunk/spring-ws-sample/">google code subversion repo for gridshore</a>.<br />
<h2>Overview of application</h2><ul><li>Build application using maven2</li><br />
<li>Web application build using spring webmvc</li><br />
<li>Webservice client created using spring-ws</li><br />
<li>Mapping between objects and xml using jaxb2 and spring-oxm</li><br />
</ul><br />
<h2>Maven 2 for building</h2>This time not much details about the maven2 part. There are some things interesting though. Most important part is the creation of the jaxb generated classes using the <a href="https://maven-jaxb2-plugin.dev.java.net/">maven2 jaxb2 plugin</a>.<br />
<h2>Using spring-webmv for web project</h2>I do not think it is really interesting to talk a long time about this. There can be found a lot (better) resources online. I used the spring webmvc project to make the client i18n compatible, used the form controllers from spring to help with the error messages and validation stuff. For the webservices part the most interesting thing starts in the file <strong>service-applicationcontext.xml</strong>. This spring configurtion file contains the webservice client, the converters for jaxb (using generics to abstract the technique marshalling technique).<br />
<h2>Webservice client created using spring-ws</h2>Let's start by having a look at the configuration:<br />
<pre><br />
&lt;bean id="congressRegistrationDAO"<br />
    class="nl.gridshore.samples.springws.integration.wsclient.impl.CongressRegistrationGateway"><br />
  &lt;property name="defaultUri" value="${cr.endpoint}" /><br />
  &lt;property name="marshaller" ref="marshaller"/><br />
  &lt;property name="unmarshaller" ref="unmarshaller"/><br />
  &lt;constructor-arg index="0" ref="congressRegistrationRequestConverter"/><br />
  &lt;constructor-arg index="1" ref="congressRegistrationResponseConverter"/><br />
&lt;/bean><br />
&lt;bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><br />
  &lt;property name="contextPath" value="nl.gridshore.samples.jaxb"/><br />
&lt;/bean><br />
&lt;bean id="unmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><br />
  &lt;property name="contextPath" value="nl.gridshore.samples.jaxb"/><br />
&lt;/bean><br />
<br />
</pre>This configured class is the class that knows how to connect to the webservice. It uses a few values and classes to do it's work. The defaultUri is used to find the endpoint to connect to (we obtain it from a property file). Since we use JAXB2 to marshall and unmarshall the request we need the marshaller and unmarshaller. These (un)marshallers are provided by spring-ws as well. Actually they are provided by spring-oxm. The interface for the marshaller is the same as for the unmarshaller. The only thing you need to provide is the package where the jaxb files are generatd in. The other two references are converters used to convert the application specific components to JAXB2 components. More on this later as well. So the most important class is the Gateway class. Let's have a look at that now.<br />
<pre><br />
package nl.gridshore.samples.springws.integration.wsclient.impl;<br />
<br />
import nl.gridshore.samples.springws.domain.RegistrationDetails;<br />
import nl.gridshore.samples.springws.integration.converter.Converter;<br />
import nl.gridshore.samples.springws.integration.wsclient.CongressRegistrationDAO;<br />
<br />
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;<br />
import org.springframework.ws.soap.client.core.SoapActionCallback;<br />
<br />
public class CongressRegistrationGateway extends WebServiceGatewaySupport implements CongressRegistrationDAO {<br />
  private final Converter<Object,RegistrationDetails> requestConverter;<br />
  private final Converter<String,Object> responseConverter;<br />
	<br />
  public CongressRegistrationGateway(Converter<Object,RegistrationDetails> requestConverter,  <br />
      Converter<String,Object> responseConverter) {<br />
    this.requestConverter = requestConverter;<br />
    this.responseConverter = responseConverter;<br />
  }<br />
	<br />
  public String registerForCongress(final RegistrationDetails registrationDetails) {<br />
    Object request = requestConverter.convert(registrationDetails);<br />
    <strong>Object response = getWebServiceTemplate().marshalSendAndReceive(request);</strong><br />
    return responseConverter.convert(response);<br />
  }<br />
}<br />
</pre><br />
This is it, really. I show you the complete class, but in the end the most important works takes place in one line. That's the one in bold. Here we use the special webServiceTemplate class and ask it to marshall our request object and send it as a soap message to the configured endpoint. Ofcourse you can do a lot more, but for most situations this is all it takes. Do not forget to extend the <strong>WebServiceGatewaySupport</strong> class. <br />
<h2>Mapping between objects and xml using jaxb2 and spring-oxm</h2>Not much to tell here as well. I keep saying this, but that's because it is true. We have configured the marshaller and the unmarshaller which are provided by spring-oxm. We also call the right method from the template adapter called marshalSendAndReceive. I did create an interface and some implementations that enable the gateway to be ignorand to the type of marshalling and unmarshalling we use. This is my first try to do something with generics. There can be a better way, if you know one, please let me know as well <img src="http://www.gridshore.nl/blog/templates/gridshore/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" />. Let's start with the generic interface.<br />
<pre><br />
public interface Converter<E,T> {<br />
  public E convert(T toBeConverted);<br />
}<br />
</pre><br />
So we have an interface specifying we have a object as a parameter and an object as a return type. Then there is a method called convert that uses these generic types. At the moment I have two concrete implementations for creating the JAXB request and handling the JAXB Response. One of them is presented below.<br />
<pre><br />
public class CongressRegistrationResponseConverter implements Converter<String, CongressRegistrationResponse> {<br />
  public String convert(CongressRegistrationResponse toBeConverted) {<br />
    String response = toBeConverted.getRegistrationCode();<br />
      return response;<br />
  }<br />
}<br />
</pre><br />
As you can see we now have a concrete implementation for the generic interface. The returned object is a String and the parameter is a JAXB object called CongressRegistrationResponse. Now look back at the gateway code, check that there is no jaxb reference in that code.<br />
<br />
Again check out the code at <a href="http://gridshore.googlecode.com/svn/trunk/spring-ws-sample/">google code subversion repo for gridshore</a>. You can already find the code for a server implementation there as well. The next blog will deal with the server. I am also working on a sample about the Rule engine called Drools. so stay tuned. 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/64-Book-reading-time-The-myths-of-innovation.html" rel="alternate" title="Book reading time - The myths of innovation" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-06-11T19:48:56Z</published>
        <updated>2007-06-11T19:48:56Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=64</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=64</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/3-Books" label="Books" term="Books" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/64-guid.html</id>
        <title type="html">Book reading time - The myths of innovation</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Man, have I been busy the last few weeks. So much to do, so much to learn, so much to try. Within two days it is time for our presentation at the dutch NLJug. I have been setting up the <a href="http://www.osgisamples.com"  title="osgisamples">osgisamples</a> website. Upgraded the <a href="http://www.coenradie.com"  title="family website">family website</a>. For my current employer we are finishing a webservices project at a big client. After about 1 1/2 year it is time to go to a new client. The time to relax is starting to come back. I want to use more time to start reading books. Ofcourse no thrillers :-), but interesting books. So from now on you will see some book reviews on the website again. I hope you will get enthousiastic about the books. If you decide to buy the books, you can support me by clicking on the link on this website. This also gives me an indication if people like what I write about the books.<br />
<br />
This time I want to write something about the following book:<br />
<iframe src="http://rcm.amazon.com/e/cm?t=gridshore-20&o=1&p=8&l=as1&asins=0596527055&fc1=000000&IS2=1&lt1=_blank&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
<br />
This is not a programming book, no you won't find java in here, no webservices, but a lot of technology. The book is about innovations. How can you be innovative. Is it something you can learn? Was the gravity moment of Newton an epiphany, or is that not possible. Does the eureka moment exist when your innovative, or do you need a lot of time to prepare that euraka moment. The book uses a nice historical introduction and a lot of links to resources on the web to read more. Sometimes it is just fun to follow the links and continue reading there. The biggest problem is that you need some sleep. You can really get lost in all that interesting reading on the web. Just for the fun two examples of interesting links.<br />
<a href="http://www.ideafinder.com/"  title="ideafinder">http://www.ideafinder.com/</a> - look for good initiatives and learn from the past<br />
<a href="http://www.goodyear.com/corporate/history/history_overview.html"  title="goodyear history">http://www.goodyear.com/corporate/history/history_overview.html</a> - nice story about how something simple can influence the world. 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/63-New-blog-writer.html" rel="alternate" title="New blog writer" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-06-08T07:08:57Z</published>
        <updated>2007-06-08T07:08:57Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=63</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=63</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/2-News" label="News" term="News" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/63-guid.html</id>
        <title type="html">New blog writer</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Today I agreed with Allard buijze (Some of you allready know him due to our <a href="http://www.osgisamples.com"  title="osgisamples">osgisamples</a> initiative) that he will also write down his knowledge in this blog. So welcome Allard and I hope we will find a lot of interesting posts from you in this blog.<br />
<br />
greetz Jettro 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/61-NLJUG,-the-dutch-java-user-group.html" rel="alternate" title="NLJUG, the dutch java user group" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-05-16T18:45:03Z</published>
        <updated>2007-05-16T18:45:03Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=61</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=61</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/10-Announcements" label="Announcements" term="Announcements" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/5-Java" label="Java" term="Java" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/61-guid.html</id>
        <title type="html">NLJUG, the dutch java user group</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                We did it, Allard and I have been choosen to give a presentation at the <a href="www.nljug.org" target="_blank">NLJUG JSpring</a> the 13th of June 2007. We are going to give a presentation about <a href="http://www.nljug.org/pages/events/content/jspring_2007/sessions/00003/" target="_blank">Webservice versioning using osgi</a>.<br />
<br />
<em>A lot of companies are using or starting to use webservices and/or a Service Oriented Architecture. For each of these companies there comes a time to think about backwards compatibility and versioning. The solution is not always obvious. There are multiple options, we will discuss some of them and explain the concerns we have with them at our current projects. Our presentation deals mostly with a solution based on apache axis and  the eclipse equinox implementation of the OSGi framework. The presentation uses a case of a congress registration system for demonstrating the problem of a plain webservice project. We will present our osgi based solution to the versioning problem.  In a demo, we show that we can solve the versioning problem within one deployment with one ear/war file. Even better, we can do it at runtime, so no need to redeploy, no downtime. We can do an upgrade and roll it back without one second downtime. At the end of the presentation you will have basic understanding of osgi concepts. You will have the ambition to try it out yourself, that is when you take out your notes, go to <a href="www.osgisamples.com">our website</a> and download all our material. This is when the real fun part starts.</em> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/60-Where-have-I-been.html" rel="alternate" title="Where have I been" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-04-02T21:18:22Z</published>
        <updated>2007-04-02T21:27:13Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=60</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=60</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/2-News" label="News" term="News" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/60-guid.html</id>
        <title type="html">Where have I been</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Hai All,<br />
just a short non technical message. It is quiet around this blog. Not that nothing is happening, but it is temporarily happening somewhere else. Together with a colleague of mine I am working on knowledge and samples around OSGi. We are creating a nice sample that proves we can create web service versioning within one application. So we deploy (at runtime) multiple versions of the same component (or bundle) in a way we can set multiple versions of the same web service live. Sounds interesting? Go to our website http://www.osgisamples.com.<br />
<br />
see you next time 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://www.gridshore.nl/blog/index.php?/archives/59-Spring-osgi-an-evaluation-using-maven-2-and-the-special-spring-osgi-archetype.html" rel="alternate" title="Spring osgi - an evaluation using maven 2 and the special spring osgi archetype" />
        <author>
            <name>Jettro Coenradie</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2007-01-03T20:20:43Z</published>
        <updated>2007-01-03T20:20:43Z</updated>
        <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=59</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=59</wfw:commentRss>
    
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/13-spring-osgi" label="spring-osgi" term="spring-osgi" />
            <category scheme="http://www.gridshore.nl/blog/index.php?/categories/6-Springframework" label="Springframework" term="Springframework" />
    
        <id>http://www.gridshore.nl/blog/index.php?/archives/59-guid.html</id>
        <title type="html">Spring osgi - an evaluation using maven 2 and the special spring osgi archetype</title>
        <content type="xhtml" xml:base="http://www.gridshore.nl/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                A few months a go I was reading the website of the springframework. One article subject supprised me. I had never heard of it, OSGi. Curious enough to want to know what it was about I opened the article and started reading. The more I read the more I was certain, this is going to be the next big thing. Then in December I attended <a href="http://www.thespringexperience.com" >The SpringExperience in Miami</a> and of course there was one presentation I had to attend. It turned out I was not the only one interested in spring-OSGi. Adrian Colyer gave a very interesting presentation and almost the complete interface21 team was there. They all think OSGi is going to be the next big thing. If you do a google on spring osgi you will get a lot of hits. Of course none of these is as technical as mine <img src="http://www.gridshore.nl/blog/templates/gridshore/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" /><br />
<br />
If you want to read more about the event look at <a href="http://accenturetechnologysolutions.blogspot.com/index.html" >this blog</a>.<br />
<br />
Now a few weeks later I had finally found some time to experiment, and of course I want to share what I have learned. This blog item is a step by step approach of creating your own spring-osgi bundle. Later I will add some more complicated bundles with references, listeners and maybe a webserver.<br />
<br />
So, how do we start? Well first download all code and install it using maven. Hmm, maybe I should tell you first that you need to install maven 2 and subversion. So, please install subversion and maven2. Then checkout all sources:<br />
<pre><br />
svn checkout https://svn.sourceforge.net/svnroot/springframework/spring-osgi/trunk spring-osgi<br />
</pre><br />
Than step into the root folder and do a mvn install. You can ofcourse have a look at the samples that come with spring-osgi. Please go to the <a href="http://www.springframework.org/osgi" >spring-osgi website</a> and see the tutorials there. We arfe going to create a new bundle using the maven archetype.<br />
<br />
If you want to have a look at the complete source code, do a checkout from the following google code website or <a href="http://gridshore.googlecode.com/svn/trunk/SpringOsgiSample/" >browse it online</a><br />
<pre><br />
svn checkout http://gridshore.googlecode.com/svn/trunk/SpringOsgiSample gridshore<br />
</pre><br />
<strong>Using the archetype</strong><br />
<pre><br />
mvn archetype:create \<br />
  -DarchetypeGroupId=org.springframework.osgi \<br />
  -DarchetypeArtifactId=spring-osgi-bundle-archetype \<br />
  -DarchetypeVersion=1.0-SNAPSHOT \<br />
  -DgroupId=nl.gridshore.samples.springosgi \<br />
  -DartifactId=bookreview-service \<br />
  -Dversion=1.0-SNAPSHOT \<br />
  -DremoteRepositories=http://static.springframework.org/maven2-snapshots<br />
</pre><br />
Have a look at the generated pom.xml file and check mine. There are some things I altered that are important.<br />
- I added the scope - test to the dependencies that did not have it<br />
- I added the following dependencies : jcl104-over-slf4j.osgi, slf4j-log4j-full and log4j.osgi<br />
- removed the dependecy for commons-logging<br />
Check the pom.xml file of the provided samples by spring-osgi, that is where I got it from.<br />
<br />
The archetype also provides a .project and .classpath file for eclipse. I had problems when I did a mvn eclipse:clean eclipse:eclipse. Some lines are not added that were in place when the files were provided by the archetype.<br />
<pre><br />
    &lt;buildCommand><br />
      &lt;name>org.eclipse.pde.ManifestBuilder&lt;/name><br />
    &lt;/buildCommand><br />
    &lt;buildCommand><br />
      &lt;name>org.eclipse.pde.SchemaBuilder&lt;/name><br />
    &lt;/buildCommand><br />
    &lt;nature>org.eclipse.pde.PluginNature&lt;/nature><br />
</pre><br />
Not sure whether these are absolutely necessary. I do know a bundle within eclipse is a plugin, therefore you need the plugin nature.<br />
<br />
<strong>Start coding</strong><br />
The framework of the project is in place and should compile (mvn install). Now it is time to start creating the bundle. We'll start by creating the BookReviewService, the unit test and the implementation of this service. This is pure java code, check the sources if you like. Now add a bean that we can expose as a service to the spring context file. There are two context files out of the box. You can find them in the src/main/resources/META-INF/spring folder. <br />
bundle-context.xml : contains the normal spring configuration<br />
bundle-context-osgi.xml : contains all beans that use the osgi namespace<br />
<br />
We have created the spring bean myBookReviewService:<br />
<pre><br />
&lt;bean name="myBookReviewService" <br />
    class="nl.gridshore.samples.springosgi.impl.BookReviewServiceImpl" /><br />
</pre><br />
Then we expose this bean as a special osgi service<br />
<pre><br />
&lt;osgi:service id="bookReviewServiceOSGi" ref="myBookReviewService"<br />
    interface="nl.gridshore.samples.springosgi.BookReviewService" /><br />
</pre><br />
And now we are done, no not really. First we need to create an integration test. We use the special super class <u>AbstractDependencyInjectionSpringContextTests</u>. This test uses the spring config file to configure and start an application context. From the context we obtain our bean and test it to see if it works.<br />
<strong>Alter the manifest file</strong><br />
Next step is to alter the manifest file, you can find this file in the  META-INF folder at the same level of the src folder. You need to add an export package and the Bundle-classpath<br />
<pre><br />
Bundle-Version: 1.0<br />
Bundle-SymbolicName: nl.gridshore.samples.springosgi.bookreviewservice<br />
Bundle-Name: nl.gridshore.samples.springosgi.bookreview-service<br />
<strong>Export-Package: nl.gridshore.samples.springosgi<br />
Bundle-ClassPath: .,<br />
 target/classes/<br />
</strong></pre><br />
Now we are ready to package our bundle. By using one of the tutorials from the spring-osgi website you can use eclipse/equinox to install and start this bundle. There is however not much to see. Wouldn't it be nice to be able to test within an exsiting osgi container whether your hard labor was wurth it? You can, the next steps will describe how you can create an in container test.<br />
<br />
<strong>Creating the in container test</strong><br />
Again the framework provides a number of super classes that makes life a lot easier. I am not going to explain in detail what these classes are doing. Still I think one thing is important to know. Your test projects is being transformed into a bundle at runtime with a reference to the bundle under test. But lets start with the creation of the normal jar file that will contain our test.<br />
<pre><br />
mvn archetype:create \<br />
  -DgroupId=nl.gridshore.samples.springosgi \<br />
  -DartifactId=bookreview-service-integration-test \<br />
  -Dversion=1.0-SNAPSHOT \<br />
</pre><br />
Alter the pom, it should use the parent and have a lot of dependencies. There are two I would like to mention is special:<br />
bookreview-service : this is our own project that we are gonna test<br />
org.springframework.osgi.test : utilit classes for our own test class<br />
<br />
The manifest file for the bundle that is created on the fly comes from the test/resources directory and looks like this.<br />
<pre><br />
Manifest-Version: 1.0<br />
Bundle-Name: simple-service-integration-tests<br />
Bundle-SymbolicName: nl.gridshore.samples.springosgi.test<br />
Bundle-Activator: org.springframework.osgi.test.JUnitTestActivator<br />
Import-Package: junit.framework,<br />
 org.osgi.framework;specification-version="1.3.0",<br />
 org.springframework.core.io;specification-version="2.1.0",<br />
 org.springframework.osgi.test,<br />
 org.springframework.osgi.test.runner,<br />
 nl.gridshore.samples.springosgi<br />
</pre><br />
Now we can create the test, use the <u>ConfigurableBundleCreatorTests</u> as a super class and implement the method to locate your MANIFEST.MF file. You also must implement a method that defines all the dependencies that can be obtained from your local maven repository. Finally you need to add your test methods.<br />
<pre><br />
public void testOSGiStartedOk() {<br />
   BundleContext bundleContext = getBundleContext();<br />
   assertNotNull(bundleContext);<br />
}<br />
</pre><br />
This test checks if the context for the created bundle can be obtained.<br />
<pre><br />
public void testSimpleServiceExported() {<br />
  waitOnContextCreation("nl.gridshore.samples.springosgi.bookreviewservice");<br />
  BundleContext context = getBundleContext();<br />
  ServiceReference ref = context.getServiceReference(BookReviewService.class.getName());<br />
  assertNotNull("Service Reference is null", ref);<br />
  try {<br />
    BookReviewService bookReviewService = (BookReviewService) context.getService(ref);<br />
    assertNotNull("Cannot find the service", bookReviewService);<br />
    List bookreviews = bookReviewService.findBookReviewByKeyword("habits"); <br />
    assertEquals(1, bookreviews.size());<br />
  } finally {<br />
    context.ungetService(ref);<br />
  }<br />
}<br />
</pre><br />
This test first checks if the osgi service can be obtained from the bundle context. Then the obtained service is used and the result is checked. In my case we are looking for a book and if all is well we should be able to find exactly one.<br />
<br />
Now do a mvn install on the highest level and you should have a tested spring osgi module<br />
<br />
<strong>Conclusion</strong><br />
That is about it, I hope this will help some of you, do not hesitate to ask questions if something is not clear. You can find a lot of information on the spring osgi website, there is a google group and google lists about thousands of hits.  
            </div>
        </content>
        
    </entry>

</feed>