<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1059181725962492104</id><updated>2012-01-26T20:54:19.122-05:00</updated><category term='ruby'/><category term='AOP'/><category term='jquery'/><category term='AspectJ'/><category term='Scala'/><category term='Spring MVC'/><category term='STS'/><category term='javascript'/><category term='IndyJug'/><category term='Maven'/><category term='Web Services'/><category term='Ext-JS'/><category term='sqlite'/><category term='SBT'/><category term='jackson'/><category term='Spring'/><category term='Spring-WS'/><category term='Spring Integration'/><category term='Java'/><category term='json'/><category term='netbeans'/><title type='text'>all and sundry</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-2907485659945481959</id><published>2012-01-25T20:35:00.002-05:00</published><updated>2012-01-25T20:35:23.908-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IndyJug'/><title type='text'>NoSQL at IndyJug</title><content type='html'>I attended a session on NoSQL databases at IndyJUG today. Tom Hunter, the presenter, had done a very extensive research last year on the entire NoSQL landscape for his personal project, and the presentation was a aggregation of this information - he managed to give a good overview of the different NoSQL databases and had a very interesting way of classifying them, if I remember correctly:&lt;br /&gt;1. Column type databases - Hadoop, Big Table&lt;br /&gt;2. Key/Value type - Memcache,..&lt;br /&gt;3. Document type - MongoDB, Couch DB&lt;br /&gt;4. Graph type - Neo4J&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-2907485659945481959?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/2907485659945481959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=2907485659945481959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2907485659945481959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2907485659945481959'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/nosql-at-indyjug.html' title='NoSQL at IndyJug'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6119290338239006793</id><published>2012-01-24T21:32:00.002-05:00</published><updated>2012-01-24T21:38:11.973-05:00</updated><title type='text'>(-14)%3 and 14%(-3)</title><content type='html'>Never really thought about it before, if I offhand look at -14%3 and 14%-3, I would have guessed the result to be the same in both cases...but it is -2 in the first case and 2 in the second case.&lt;br /&gt;&lt;br /&gt;the rule is a = (a/b)*b + a%b, &lt;br /&gt;&lt;pre&gt;(-14) = (-4)*( 3) + (-14)%3&lt;br /&gt;( 14) = (-4)*(-3) + ( 14)%3&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6119290338239006793?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6119290338239006793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6119290338239006793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6119290338239006793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6119290338239006793'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/143-and-14-3.html' title='(-14)%3 and 14%(-3)'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8849438098536818618</id><published>2012-01-22T20:26:00.001-05:00</published><updated>2012-01-22T20:26:25.017-05:00</updated><title type='text'>New way of looking at VIM</title><content type='html'>I am a long time &lt;a href="http://www.vim.org/"&gt;VIM&lt;/a&gt; user, but never thought of it &lt;a href="http://yanpritzker.com/2011/12/16/learn-to-speak-vim-verbs-nouns-and-modifiers/"&gt;this&lt;/a&gt; way - http://yanpritzker.com/2011/12/16/learn-to-speak-vim-verbs-nouns-and-modifiers/ &lt;br /&gt;&lt;br /&gt;Highly recommended if you are planning to take a second look at vim.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8849438098536818618?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8849438098536818618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8849438098536818618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8849438098536818618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8849438098536818618'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/new-way-of-looking-at-vim.html' title='New way of looking at VIM'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6551463676280372726</id><published>2012-01-15T11:25:00.001-05:00</published><updated>2012-01-26T20:54:19.133-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring Custom Property Editor - Convert String to Calendar</title><content type='html'>Continuing on a previous &lt;a href="http://biju-allandsundry.blogspot.com/2011/10/spring-custom-date-editor.html"&gt;entry&lt;/a&gt;: &lt;br /&gt;&lt;br /&gt;The previous blog entry was about a custom property editor to convert a string representation of a date to a java.util.Date field. The approach here is a little different, to convert a string representation to a "java.util.Calendar" type, which is a little more complicated.&lt;br /&gt;&lt;br /&gt;Say if I have a bean defined this way:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean name="project1" class="org.bk.simplygtd.domain.GtdProject" p:name="project1" p:startDate="2010-01-01T12:00:00.000-0800" p:completedDate="2010-01-04T12:08:56.235-0800" p:isDone="true" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the class has startDate and completedDate of type java.util.Calendar type.&lt;br /&gt;&lt;br /&gt;If no custom property editors are registered this error will be returned when trying to start up the container:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'completedDate': no matching editors or conversion strategy found&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is perfectly reasonable as the container does not know how to transform the Calendar string to Calendar type.&lt;br /&gt;&lt;br /&gt;The approach that has best worked for me is to actually write a custom property editor and register it with the container.&lt;br /&gt;&lt;br /&gt;This is how my property editor looks:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;import java.beans.PropertyEditorSupport;&lt;br /&gt;import java.util.Calendar;&lt;br /&gt;&lt;br /&gt;import org.joda.time.DateTime;&lt;br /&gt;import org.joda.time.format.DateTimeFormatter;&lt;br /&gt;import org.joda.time.format.ISODateTimeFormat;&lt;br /&gt;import org.springframework.util.StringUtils;&lt;br /&gt;&lt;br /&gt;public class CustomCalendarEditor extends PropertyEditorSupport {&lt;br /&gt;    private final DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime();&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public String getAsText() {&lt;br /&gt;        Calendar value = (Calendar) getValue();&lt;br /&gt;        DateTime dateTime = new DateTime(value);&lt;br /&gt;        return (value != null ? dateTime.toString(this.dateTimeFormatter) : "");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void setAsText(String text) throws IllegalArgumentException {&lt;br /&gt;        if (!StringUtils.hasText(text)) {&lt;br /&gt;            setValue(null);&lt;br /&gt;        } else {&lt;br /&gt;            DateTime dateTime = this.dateTimeFormatter.parseDateTime(text);&lt;br /&gt;            setValue(dateTime.toGregorianCalendar());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that I have used &lt;a href="http://joda-time.sourceforge.net/"&gt;joda time &lt;/a&gt; as bridge between the string representation and java.util.Calendar and have assumed a ISO-8601 format for date.&lt;br /&gt;&lt;br /&gt;Now, to register this property editor:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"&amp;gt;&lt;br /&gt;        &amp;lt;property name="customEditors"&amp;gt;&lt;br /&gt;            &amp;lt;map&amp;gt;&lt;br /&gt;                &amp;lt;entry key="java.util.Calendar"&amp;gt;&lt;br /&gt;                    &amp;lt;bean class="org.bk.simplygtd.spring.CustomCalendarEditor"/&amp;gt;&lt;br /&gt;                &amp;lt;/entry&amp;gt;&lt;br /&gt;            &amp;lt;/map&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's it, now the conversion between string to Calendar and back should work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6551463676280372726?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6551463676280372726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6551463676280372726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6551463676280372726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6551463676280372726'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/spring-property-editor-convert-string.html' title='Spring Custom Property Editor - Convert String to Calendar'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-1271131895095833535</id><published>2012-01-12T20:28:00.001-05:00</published><updated>2012-01-12T20:29:06.224-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Spring integration and version 2.0 schema files</title><content type='html'>Something to note when upgrading &lt;a href="http://www.springsource.org/spring-integration"&gt;Spring Integration&lt;/a&gt; from version 2.0 to 2.1.0 - &lt;br /&gt;&lt;br /&gt;Schema location to the custom namespace used to be specified this way:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt; xmlns:int=&amp;quot;http://www.springframework.org/schema/integration&amp;quot;&lt;br /&gt; xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This either has to be explicitly the 2.1 version schema or version less, otherwise the start-up of the container aborts:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt; xmlns:int=&amp;quot;http://www.springframework.org/schema/integration&amp;quot;&lt;br /&gt; xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;More details &lt;a href="https://github.com/SpringSource/spring-integration/wiki/Spring-Integration-2.0-to-2.1-Migration-Guide"&gt;here&lt;/a&gt;: https://github.com/SpringSource/spring-integration/wiki/Spring-Integration-2.0-to-2.1-Migration-Guide&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-1271131895095833535?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/1271131895095833535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=1271131895095833535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1271131895095833535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1271131895095833535'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/spring-integration-and-version-20.html' title='Spring integration and version 2.0 schema files'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-4866082080221801577</id><published>2012-01-01T11:10:00.001-05:00</published><updated>2012-01-04T21:06:48.926-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jackson'/><category scheme='http://www.blogger.com/atom/ns#' term='Ext-JS'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Ext-JS, Json -  Date/time mapping in Spring MVC with Jackson</title><content type='html'>The default date/time handling with &lt;a href="http://jackson.codehaus.org/"&gt;Jackson &lt;/a&gt;and Spring is:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;To serialize dates as a Unix epoch time - number of millseconds since Jan 1, 1970 (UTC).&amp;nbsp;&lt;/li&gt;&lt;li&gt;To always use GMT as the timezone, irrespective of the default timezone on the server.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I prefer to see the dates in a string format with &lt;a href="http://en.wikipedia.org/wiki/ISO_8601"&gt;ISO-8601&lt;/a&gt; standard. The way to handle this in Spring MVC with version 3.1 of the Spring framework is to provide a custom Jackson ObjectMapper, to handle the date serialization differently. A custom Object Mapper would be along these lines:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;import org.codehaus.jackson.map.ObjectMapper;&lt;br /&gt;import org.codehaus.jackson.map.SerializationConfig.Feature;&lt;br /&gt;&lt;br /&gt;public class CustomObjectMapper extends ObjectMapper {&lt;br /&gt;    public CustomObjectMapper(){&lt;br /&gt;        super.configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now &lt;b&gt;Spring 3.1&lt;/b&gt; has made it really simple to register this Custom Object Mapper with the Handler Adapters:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;mvc:annotation-driven &amp;gt; &lt;br /&gt;    &amp;lt;mvc:message-converters register-defaults="false"&amp;gt;&lt;br /&gt;        &amp;lt;bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" &amp;gt;&lt;br /&gt;            &amp;lt;property name="objectMapper"&amp;gt;&lt;br /&gt;                &amp;lt;bean class="org.bk.simplygtd.web.spring.CustomObjectMapper"/&amp;gt;&lt;br /&gt;            &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;    &amp;lt;/mvc:message-converters&amp;gt;&lt;br /&gt; &amp;lt;/mvc:annotation-driven&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Prior to Spring 3.1&lt;/b&gt;, a way to register this Custom Object Mapper would have been to write a custom&amp;nbsp;&lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html"&gt;BeanPostProcessor&lt;/a&gt;, to iterate through the handler adapters, find the relevant message converter(&lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/http/converter/json/MappingJacksonHttpMessageConverter.html"&gt;MappingJacksonHttpMessageConverter&lt;/a&gt;) and register the custom object mapper, something along these lines:&lt;br /&gt;&lt;pre class="brush:java"&gt;import org.springframework.beans.BeansException;&lt;br /&gt;import org.springframework.beans.factory.config.BeanPostProcessor;&lt;br /&gt;import org.springframework.http.converter.HttpMessageConverter;&lt;br /&gt;import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;&lt;br /&gt;import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;&lt;br /&gt;&lt;br /&gt;public class CustomObjectMapperBeanPostProcessor implements BeanPostProcessor{&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {&lt;br /&gt;        return bean;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {&lt;br /&gt;        if (bean instanceof AnnotationMethodHandlerAdapter){&lt;br /&gt;            AnnotationMethodHandlerAdapter methodHandlerAdapter = (AnnotationMethodHandlerAdapter)bean;&lt;br /&gt;            for (HttpMessageConverter&amp;lt;?&amp;gt; messageConverter: methodHandlerAdapter.getMessageConverters()){&lt;br /&gt;                if (messageConverter instanceof MappingJacksonHttpMessageConverter){&lt;br /&gt;                    ((MappingJacksonHttpMessageConverter)messageConverter).setObjectMapper(new CustomObjectMapper());&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return bean;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the json responses from Spring MVC should be formatted correctly in this format:&amp;nbsp;&lt;span style="-webkit-text-size-adjust: none; background-color: white; font-family: Consolas, 'Lucida Console', monospace; font-size: 12px; white-space: pre;"&gt;&lt;i&gt;2011-12-06T00:00:00.000+0000&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Consolas, 'Lucida Console', monospace;"&gt;&lt;span style="-webkit-text-size-adjust: none; font-size: 12px; white-space: pre;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;If the user interface is using created using Ext-JS, the model for Ext-JS can be customized to use this date format along these lines - date format of 'c' indicates that the date string should be interpreted using ISO-8601 standard:&lt;br /&gt;&lt;pre class="brush:java"&gt;Ext.define('CUSTOM.model.Proj',{&lt;br /&gt;    extend: 'Ext.data.Model',&lt;br /&gt;    fields:[{name:'id', type:'string'},{name:'name', type:'string'}, &lt;br /&gt;            {name:'startDate', type:'date', dateFormat:'c'}, {name:'completedDate', type:'date', dateFormat:'c'},&lt;br /&gt;            {name:'isDone', type:'boolean'}, {name:'version', type:'string'}]&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There is still one problem, when submitting this date Ext-JS still does not format the date string correctly - it would, by default, send the date without the timezone offset(eg. 2011-12-25T00:15:00), which would be interpreted by the JSON deserializer as &amp;nbsp;a GMT date/time. To fix this just have this global function:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;Ext.JSON.encodeDate = function(o)&lt;br /&gt;{&lt;br /&gt;   return '"' + Ext.Date.format(o, 'c') + '"';&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the dates should be correctly posted to the server with timezone offsets also eg. 2011-12-25T01:15:00-05:00&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;Jackson JSON Processing:&amp;nbsp;&lt;a href="http://jackson.codehaus.org/"&gt;http://jackson.codehaus.org/&lt;/a&gt; &lt;br /&gt;Jackson Date Handling FAQ:&amp;nbsp;&lt;a href="http://wiki.fasterxml.com/JacksonFAQDateHandling"&gt;http://wiki.fasterxml.com/JacksonFAQDateHandling&lt;/a&gt;&lt;br /&gt;Some ideas from this blog entry: &lt;a href="http://magicmonster.com/kb/prg/java/spring/webmvc/jackson_custom.html"&gt;http://magicmonster.com/kb/prg/java/spring/webmvc/jackson_custom.html&lt;/a&gt;&lt;br /&gt;Date type in Ext-JS:&amp;nbsp;&lt;a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.Date"&gt;http://docs.sencha.com/ext-js/4-0/#!/api/Ext.Date&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-4866082080221801577?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/4866082080221801577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=4866082080221801577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4866082080221801577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4866082080221801577'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2012/01/ext-js-json-datetime-mapping-in-spring.html' title='Ext-JS, Json -  Date/time mapping in Spring MVC with Jackson'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-1517641105241743496</id><published>2011-12-27T10:30:00.001-05:00</published><updated>2011-12-27T10:38:23.116-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Debugging with Maven</title><content type='html'>&lt;div&gt;&lt;b&gt;For Non-Forked Process&lt;/b&gt;&lt;/div&gt;The way to debug any project using maven is to use "mvndebug" command line tool instead of "mvn". So, if I want to debug a tomcat based project, I would do:&lt;br /&gt;&lt;div&gt;mvndebug tomcat:run&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;which would enable the debugging on the JVM and would wait for the debugger to connect to the vm:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-l5FIlbk6xG4/Tvnf3tjZW2I/AAAAAAAAA_E/RZEZnnfBa8M/s1600/mvndebug.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-l5FIlbk6xG4/Tvnf3tjZW2I/AAAAAAAAA_E/RZEZnnfBa8M/s1600/mvndebug.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;By default, the &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html"&gt;JDWP &lt;/a&gt;port that mvndebug listens is on 8000.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next step is to connect to this vm through the debugger in Eclipse -&amp;nbsp;&lt;/div&gt;&lt;div&gt;Go to Run-&amp;gt;Debug Configurations-&amp;gt;Remote Java Application and create a new "launch configuration" along these lines:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XSjf9aaWWiU/TvnhWjUtPDI/AAAAAAAAA_Q/78s0fPFeRGo/s1600/EclipseDebug.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="313" src="http://2.bp.blogspot.com/-XSjf9aaWWiU/TvnhWjUtPDI/AAAAAAAAA_Q/78s0fPFeRGo/s640/EclipseDebug.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Click on debug and eclipse should connect to the maven vm and the tomcat should start up at this point.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;For Forked Process&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The above approach will however not work for forked processes like JUnit tests - tests by default are forked by maven.&amp;nbsp;&lt;/div&gt;&lt;div&gt;There are two workarounds for debugging JUnit tests:&lt;/div&gt;&lt;div&gt;To prevent forking of Junit tests, this can be done using a forkMode parameter this way:&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;mvndebug test -Dtest=GtdProjectDaoIntegrationTest -DforkMode=never&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The second workaround is to use the "maven.surefire.debug" property:&lt;br /&gt;&lt;pre class="brush:java"&gt;mvn -Dmaven.surefire.debug test -Dtest=GtdProjectDaoIntegrationTest&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This would, by default, start up the debugger at port 5005. A variation of this is to explicitly specify the port where the debugger is to be started and with additional JDWP options:&lt;br /&gt;&lt;pre class="brush:java"&gt;mvn -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE" test&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;&lt;a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html"&gt;http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-1517641105241743496?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/1517641105241743496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=1517641105241743496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1517641105241743496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1517641105241743496'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/12/debugging-with-maven.html' title='Debugging with Maven'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-l5FIlbk6xG4/Tvnf3tjZW2I/AAAAAAAAA_E/RZEZnnfBa8M/s72-c/mvndebug.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6268266703832040202</id><published>2011-12-19T22:21:00.000-05:00</published><updated>2011-12-27T09:48:25.696-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Concurrency - Executors and Spring Integration</title><content type='html'>&lt;div&gt;This is a follow up to a &lt;a href="http://biju-allandsundry.blogspot.com/2011/12/concurrency-sequential-and-raw-thread.html"&gt;previous blog entry&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Thread Pool/Executors Based Implementation&lt;/b&gt;&lt;br /&gt;A better approach than the raw thread version, is a Thread pool based one, where an appropriate thread pool size is defined based on the system where the task is running - Number of CPU's/(1-Blocking Coefficient of Task). Venkat Subramaniams book has more details: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/193435676X/ref=as_li_ss_il?ie=UTF8&amp;amp;tag=allandsun-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=193435676X"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;Format=_SL110_&amp;amp;ASIN=193435676X&amp;amp;MarketPlace=US&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;tag=allandsun-20&amp;amp;ServiceVersion=20070822" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=allandsun-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=193435676X" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;First I defined a custom task to generate the Report Part, given the Report Part Request, this is implemented as a &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Callable.html"&gt;Callable&lt;/a&gt;:&lt;/div&gt;&lt;pre class="brush:java"&gt;public class ReportPartRequestCallable implements Callable&amp;lt;ReportPart&amp;gt; {&lt;br /&gt; private final ReportRequestPart reportRequestPart;&lt;br /&gt; private final ReportPartGenerator reportPartGenerator;&lt;br /&gt;&lt;br /&gt; public ReportPartRequestCallable(ReportRequestPart reportRequestPart, ReportPartGenerator reportPartGenerator) {&lt;br /&gt;     this.reportRequestPart = reportRequestPart;&lt;br /&gt;     this.reportPartGenerator = reportPartGenerator;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt;    public ReportPart call() {&lt;br /&gt;    return this.reportPartGenerator.generateReportPart(reportRequestPart);&lt;br /&gt;    } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;public class ExecutorsBasedReportGenerator implements ReportGenerator {&lt;br /&gt;    private static final Logger logger = LoggerFactory.getLogger(ExecutorsBasedReportGenerator.class);&lt;br /&gt;&lt;br /&gt;    private ReportPartGenerator reportPartGenerator;&lt;br /&gt;&lt;br /&gt;    private ExecutorService executors = Executors.newFixedThreadPool(10);&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Report generateReport(ReportRequest reportRequest) {&lt;br /&gt;        List&amp;lt;Callable&amp;lt;ReportPart&amp;gt;&amp;gt; tasks = new ArrayList&amp;lt;Callable&amp;lt;ReportPart&amp;gt;&amp;gt;();&lt;br /&gt;        List&amp;lt;ReportRequestPart&amp;gt; reportRequestParts = reportRequest.getRequestParts();&lt;br /&gt;        for (ReportRequestPart reportRequestPart : reportRequestParts) {&lt;br /&gt;            tasks.add(new ReportPartRequestCallable(reportRequestPart, reportPartGenerator));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        List&amp;lt;Future&amp;lt;ReportPart&amp;gt;&amp;gt; responseForReportPartList;&lt;br /&gt;        List&amp;lt;ReportPart&amp;gt; reportParts = new ArrayList&amp;lt;ReportPart&amp;gt;();&lt;br /&gt;        try {&lt;br /&gt;            responseForReportPartList = executors.invokeAll(tasks);&lt;br /&gt;            for (Future&amp;lt;ReportPart&amp;gt; reportPartFuture : responseForReportPartList) {&lt;br /&gt;                reportParts.add(reportPartFuture.get());&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            logger.error(e.getMessage(), e);&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;        return new Report(reportParts);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt; ......&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Here a thread pool is created using the Executors.newFixedThreadPool(10) call, with a pool size of 10, a callable task is generated for each of the report request parts, and handed over to the threadpool using the ExecutorService abstraction - &lt;br /&gt;&lt;pre class="brush:java"&gt;responseForReportPartList = executors.invokeAll(tasks);&lt;/pre&gt;this call returns a List of Futures, which support a get() method which is a blocking call on the response to be available.&lt;br /&gt;&lt;br /&gt;This is clearly a much better implementation compared to the raw thread version, the number of threads is constrained to a manageable number under load.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Spring Integration Based Implementation&lt;/b&gt;&lt;br /&gt;The approach that I personally like the most is using &lt;a href="http://www.springsource.org/spring-integration"&gt;Spring Integration&lt;/a&gt;, the reason is that with Spring Integration I focus on the components doing the different tasks and leave it upto Spring Integration to wire the flow together, using a xml based or annotation based configuration. Here I will be using a XML based configuration :&lt;br /&gt;&lt;br /&gt;The components in my case are:&lt;br /&gt;1. The component to generate the report part, given the report part request, which I had &lt;a href="http://biju-allandsundry.blogspot.com/2011/12/concurrency-sequential-and-raw-thread.html"&gt;shown earlier&lt;/a&gt;.&lt;br /&gt;2. A component to split the report request to report request parts:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class DefaultReportRequestSplitter implements ReportRequestSplitter{&lt;br /&gt; @Override&lt;br /&gt; public List&amp;lt;ReportRequestPart&amp;gt; split(ReportRequest reportRequest) {&lt;br /&gt;  return reportRequest.getRequestParts();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. A component to assemble/aggregate the report parts into a whole report:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class DefaultReportAggregator implements ReportAggregator{&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Report aggregate(List&amp;lt;ReportPart&amp;gt; reportParts) {&lt;br /&gt;        return new Report(reportParts);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that is all the java code that is required with Spring Integration, the rest of the is wiring - here I have used a Spring integration configuration file:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans ....&lt;br /&gt;&lt;br /&gt;    &amp;lt;int:channel id="report.partsChannel"/&amp;gt;&lt;br /&gt;    &amp;lt;int:channel id="report.reportChannel"/&amp;gt;&lt;br /&gt;    &amp;lt;int:channel id="report.partReportChannel"&amp;gt;&lt;br /&gt;        &amp;lt;int:queue capacity="50"/&amp;gt;&lt;br /&gt;    &amp;lt;/int:channel&amp;gt;  &lt;br /&gt;    &amp;lt;int:channel id="report.joinPartsChannel"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;int:splitter id="splitter" ref="reportsPartSplitter" method="split" &lt;br /&gt;        input-channel="report.partsChannel" output-channel="report.partReportChannel"/&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;task:executor id="reportPartGeneratorExecutor" pool-size="10" queue-capacity="50" /&amp;gt;&lt;br /&gt;    &lt;br /&gt; &amp;lt;int:service-activator id="reportsPartServiceActivator"  ref="reportPartReportGenerator" method="generateReportPart" &lt;br /&gt;            input-channel="report.partReportChannel" output-channel="report.joinPartsChannel"&amp;gt;&lt;br /&gt;    &amp;lt;int:poller task-executor="reportPartGeneratorExecutor" fixed-delay="500"&amp;gt;&lt;br /&gt;    &amp;lt;/int:poller&amp;gt;&lt;br /&gt; &amp;lt;/int:service-activator&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;int:aggregator ref="reportAggregator" method="aggregate" &lt;br /&gt;            input-channel="report.joinPartsChannel" output-channel="report.reportChannel" &amp;gt;&amp;lt;/int:aggregator&amp;gt; &lt;br /&gt;&lt;br /&gt;    &amp;lt;int:gateway id="reportGeneratorGateway" service-interface="org.bk.sisample.springintegration.ReportGeneratorGateway" &lt;br /&gt;           default-request-channel="report.partsChannel" default-reply-channel="report.reportChannel"/&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;bean name="reportsPartSplitter" class="org.bk.sisample.springintegration.processors.DefaultReportRequestSplitter"&amp;gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;    &amp;lt;bean name="reportPartReportGenerator" class="org.bk.sisample.processors.DummyReportPartGenerator"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="reportAggregator" class="org.bk.sisample.springintegration.processors.DefaultReportAggregator"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="reportGenerator" class="org.bk.sisample.springintegration.SpringIntegrationBasedReportGenerator"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.springsource.com/developer/sts"&gt;Spring Source Tool Suite &lt;/a&gt; provides a great way of visualizing this file:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-jffRNY2LIkQ/Tu_8Ngq0gTI/AAAAAAAAA-o/78evBMbIX2o/s1600/SpringIntegrationFlow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="121" src="http://3.bp.blogspot.com/-jffRNY2LIkQ/Tu_8Ngq0gTI/AAAAAAAAA-o/78evBMbIX2o/s640/SpringIntegrationFlow.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;this matches perfectly with my original view of the user flow:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-tqfMl5SyhcE/Tu_r2FSCtuI/AAAAAAAAA-g/atk_alIiv64/s1600/SampleReportFlow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="196" src="http://2.bp.blogspot.com/-tqfMl5SyhcE/Tu_r2FSCtuI/AAAAAAAAA-g/atk_alIiv64/s640/SampleReportFlow.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In the Spring Integration version of the code, I have defined the different components to handle the different parts of the flow:&lt;br /&gt;1. A splitter to convert a report request to report request parts:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;int:splitter id="splitter" ref="reportsPartSplitter" method="split" &lt;br /&gt;        input-channel="report.partsChannel" output-channel="report.partReportChannel"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. A service activator component to generate a report part from a report part request:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;int:service-activator id="reportsPartServiceActivator"  ref="reportPartReportGenerator" method="generateReportPart" &lt;br /&gt;            input-channel="report.partReportChannel" output-channel="report.joinPartsChannel"&amp;gt;&lt;br /&gt;    &amp;lt;int:poller task-executor="reportPartGeneratorExecutor" fixed-delay="500"&amp;gt;&lt;br /&gt;    &amp;lt;/int:poller&amp;gt;&lt;br /&gt; &amp;lt;/int:service-activator&amp;gt;&lt;/pre&gt;3. An aggregator to join the report parts back to a report, and is intelligent enough to correlate the original split report requests appropriately without any explicit coding required for it:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;int:aggregator ref="reportAggregator" method="aggregate" &lt;br /&gt;            input-channel="report.joinPartsChannel" output-channel="report.reportChannel" &amp;gt;&amp;lt;/int:aggregator&amp;gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What is interesting in this code is that, like in the executors based sample, the number of threads that services each of these components is completely configurable using the xml file, by using appropriate channels to connect the different components together and by using &lt;a href="http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/scheduling.html"&gt;task executors&lt;/a&gt; with the thread pool size set as attribute of the executor.&lt;br /&gt;&lt;br /&gt;In this code, I have defined a queue channel where the report request parts come in:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;int:channel id="report.partReportChannel"&amp;gt;&lt;br /&gt;        &amp;lt;int:queue capacity="50"/&amp;gt;&lt;br /&gt;    &amp;lt;/int:channel&amp;gt;  &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and is serviced by the service activator component, using a task executor with a thread pool of size 10, and a capacity of 50:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;task:executor id="reportPartGeneratorExecutor" pool-size="10" queue-capacity="50" /&amp;gt;&lt;br /&gt;    &lt;br /&gt; &amp;lt;int:service-activator id="reportsPartServiceActivator"  ref="reportPartReportGenerator" method="generateReportPart" &lt;br /&gt;            input-channel="report.partReportChannel" output-channel="report.joinPartsChannel"&amp;gt;&lt;br /&gt;    &amp;lt;int:poller task-executor="reportPartGeneratorExecutor" fixed-delay="500"&amp;gt;&lt;br /&gt;    &amp;lt;/int:poller&amp;gt;&lt;br /&gt; &amp;lt;/int:service-activator&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;All this through configuration!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The entire codebase for this sample is available at this github location:&amp;nbsp;&lt;a href="https://github.com/bijukunjummen/si-sample"&gt;https://github.com/bijukunjummen/si-sample&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6268266703832040202?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6268266703832040202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6268266703832040202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6268266703832040202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6268266703832040202'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/12/concurrency-executors-and-spring.html' title='Concurrency - Executors and Spring Integration'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-jffRNY2LIkQ/Tu_8Ngq0gTI/AAAAAAAAA-o/78evBMbIX2o/s72-c/SpringIntegrationFlow.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-916620997507425803</id><published>2011-12-17T07:14:00.000-05:00</published><updated>2011-12-27T09:47:23.636-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Concurrency - Sequential and Raw Thread</title><content type='html'>I worked on a project a while back, where the report flow was along these lines:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-tqfMl5SyhcE/Tu_r2FSCtuI/AAAAAAAAA-g/atk_alIiv64/s1600/SampleReportFlow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="195" src="http://2.bp.blogspot.com/-tqfMl5SyhcE/Tu_r2FSCtuI/AAAAAAAAA-g/atk_alIiv64/s640/SampleReportFlow.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;User would request for a report&lt;/li&gt;&lt;li&gt;The report request would be translated into smaller parts/sections&lt;/li&gt;&lt;li&gt;The report for each part, based on the type of the part/section would be generated by a report generator&lt;/li&gt;&lt;li&gt;The constituent report parts would be reassembled into a final report and given back to the user&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My objective is to show how I progressed from a bad implementation to a fairly good implementation:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some of the basic building blocks that I have is best demonstrated by a unit test:&lt;/div&gt;&lt;div&gt;This is a test helper which generates a sample report request, with constituent report request parts:&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;public class FixtureGenerator {&lt;br /&gt;    public static ReportRequest generateReportRequest(){&lt;br /&gt;        List&amp;lt;ReportRequestPart&amp;gt; requestParts = new ArrayList&amp;lt;ReportRequestPart&amp;gt;();&lt;br /&gt;        Map&amp;lt;String, String&amp;gt; attributes = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;        attributes.put("user","user");&lt;br /&gt;        Context context = new Context(attributes );&lt;br /&gt;    &lt;br /&gt;        ReportRequestPart part1 = new ReportRequestPart(Section.HEADER, context);&lt;br /&gt;        ReportRequestPart part2 = new ReportRequestPart(Section.SECTION1, context);&lt;br /&gt;        ReportRequestPart part3 = new ReportRequestPart(Section.SECTION2, context);&lt;br /&gt;        ReportRequestPart part4 = new ReportRequestPart(Section.SECTION3, context);&lt;br /&gt;        ReportRequestPart part5 = new ReportRequestPart(Section.FOOTER, context);   &lt;br /&gt;        &lt;br /&gt;        requestParts.add(part1);        &lt;br /&gt;        requestParts.add(part2);&lt;br /&gt;        requestParts.add(part3);&lt;br /&gt;        requestParts.add(part4);&lt;br /&gt;        requestParts.add(part5);&lt;br /&gt;        &lt;br /&gt;        ReportRequest reportRequest  = new ReportRequest(requestParts );&lt;br /&gt;        return reportRequest;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;And the test for the report generation:&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;public class FixtureGenerator {&lt;br /&gt; @Test&lt;br /&gt; public void testSequentialReportGeneratorTime(){&lt;br /&gt;  long startTime = System.currentTimeMillis();&lt;br /&gt;  Report report = this.reportGenerator.generateReport(FixtureGenerator.generateReportRequest());&lt;br /&gt;  long timeForReport = System.currentTimeMillis()-startTime;&lt;br /&gt;  assertThat(report.getSectionReports().size(), is (5));&lt;br /&gt;  logger.error(String.format("Sequential Report Generator : %s ms", timeForReport));&lt;br /&gt; } &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The component which generates a part of the report is a dummy implementation with a 2 second delay to simulate a IO intensive call:&lt;br /&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;public class DummyReportPartGenerator implements ReportPartGenerator{&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public ReportPart generateReportPart(ReportRequestPart reportRequestPart) {&lt;br /&gt;  try {&lt;br /&gt;   //Deliberately introduce a delay&lt;br /&gt;   Thread.sleep(2000);&lt;br /&gt;  } catch (InterruptedException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt;  return new ReportPart(reportRequestPart.getSection(), "Report for " + reportRequestPart.getSection());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Sequential Implementation&lt;/b&gt;&lt;br /&gt;Given these base set of classes, my first naive sequential implementation is the following:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class SequentialReportGenerator implements ReportGenerator {&lt;br /&gt; private ReportPartGenerator reportPartGenerator;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Report generateReport(ReportRequest reportRequest){&lt;br /&gt;  List&amp;lt;ReportRequestPart&amp;gt; reportRequestParts = reportRequest.getRequestParts();&lt;br /&gt;  List&amp;lt;ReportPart&amp;gt; reportSections = new ArrayList&amp;lt;ReportPart&amp;gt;();&lt;br /&gt;  for (ReportRequestPart reportRequestPart: reportRequestParts){&lt;br /&gt;   reportSections.add(reportPartGenerator.generateReportPart(reportRequestPart));&lt;br /&gt;  }&lt;br /&gt;  return new Report(reportSections);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;......&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Obviously, for a report request with 5 parts in it, each part taking 2 seconds to be fulfilled this report takes about 10 seconds for it to be returned back to the user.&lt;br /&gt;&lt;br /&gt;It begs to be made concurrent. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Raw Thread Based Implementation&lt;/b&gt;&lt;br /&gt;The first concurrent implementation, not good but better than sequential is the following, where a thread is spawned for every report request part, waiting on the reportparts to be generated(using thread.join() method), and aggregating the pieces as they come in.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;public class RawThreadBasedReportGenerator implements ReportGenerator {&lt;br /&gt;    private static final Logger logger = LoggerFactory.getLogger(RawThreadBasedReportGenerator.class);&lt;br /&gt;&lt;br /&gt;    private ReportPartGenerator reportPartGenerator;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Report generateReport(ReportRequest reportRequest) {&lt;br /&gt;        List&amp;lt;ReportRequestPart&amp;gt; reportRequestParts = reportRequest.getRequestParts();&lt;br /&gt;        List&amp;lt;Thread&amp;gt; threads = new ArrayList&amp;lt;Thread&amp;gt;();&lt;br /&gt;        List&amp;lt;ReportPartRequestRunnable&amp;gt; runnablesList = new ArrayList&amp;lt;ReportPartRequestRunnable&amp;gt;();&lt;br /&gt;        for (ReportRequestPart reportRequestPart : reportRequestParts) {&lt;br /&gt;            ReportPartRequestRunnable reportPartRequestRunnable = new ReportPartRequestRunnable(reportRequestPart, reportPartGenerator);&lt;br /&gt;            runnablesList.add(reportPartRequestRunnable);&lt;br /&gt;            Thread thread = new Thread(reportPartRequestRunnable);&lt;br /&gt;            threads.add(thread);&lt;br /&gt;            thread.start();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        for (Thread thread : threads) {&lt;br /&gt;            try {&lt;br /&gt;                thread.join();&lt;br /&gt;            } catch (InterruptedException e) {&lt;br /&gt;                logger.error(e.getMessage(), e);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        List&amp;lt;ReportPart&amp;gt; reportParts = new ArrayList&amp;lt;ReportPart&amp;gt;();&lt;br /&gt;&lt;br /&gt;        for (ReportPartRequestRunnable reportPartRequestRunnable : runnablesList) {&lt;br /&gt;            reportParts.add(reportPartRequestRunnable.getReportPart());&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return new Report(reportParts);&lt;br /&gt;&lt;br /&gt;    }    &lt;br /&gt;    .....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The danger with this approach is that a new thread is being created for every report part, so in a real world scenario if a 100 simultaneous request comes in with each request spawning 5 threads, this can potentially end up creating 500 costly threads in the vm!!&lt;br /&gt;&lt;br /&gt;So thread creation has to be constrained in some way. I will go through two more approaches where threads are controlled, in the next blog entry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-916620997507425803?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/916620997507425803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=916620997507425803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/916620997507425803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/916620997507425803'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/12/concurrency-sequential-and-raw-thread.html' title='Concurrency - Sequential and Raw Thread'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-tqfMl5SyhcE/Tu_r2FSCtuI/AAAAAAAAA-g/atk_alIiv64/s72-c/SampleReportFlow.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-5892233925626188086</id><published>2011-12-16T18:16:00.000-05:00</published><updated>2011-12-27T10:31:15.669-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>jquery maphilight</title><content type='html'>&lt;a href="http://davidlynch.org/projects/maphilight/docs/"&gt;jquery maphilight&lt;/a&gt; is a fantastic jquery plugin to overlay an image with highlights, based on information from an&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Image_map"&gt;imagemap&lt;/a&gt;. &lt;br /&gt;I recently used it for one of my work projects and it worked out beautifully - highly recommended for overlay highlights.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-5892233925626188086?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/5892233925626188086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=5892233925626188086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5892233925626188086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5892233925626188086'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/12/jquery-maphilight.html' title='jquery maphilight'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-5648025478531289737</id><published>2011-12-03T06:29:00.001-05:00</published><updated>2012-01-15T10:13:45.624-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>SimpleDateFormat and TimeZone</title><content type='html'>Recently I was stumped by a simple concept - I needed to transform a timestamp in a Europe/London timezone to a yyyyMMdd format. So I had a code along this lines to do this:&lt;br /&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");&lt;br /&gt;Calendar date = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));&lt;br /&gt;date.set(Calendar.YEAR, 2011);&lt;br /&gt;date.set(Calendar.MONTH, 10);&lt;br /&gt;date.set(Calendar.DAY_OF_MONTH, 15);&lt;br /&gt;date.set(Calendar.HOUR_OF_DAY, 3);&lt;br /&gt;int aDateName = Integer.valueOf(formatter.format(date.getTime()));&lt;br /&gt;System.out.println(aDateName);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I was expecting it to print 20111115 as the output. &lt;br /&gt;&lt;br /&gt;However, the output was 20111114(when executing from US EST Timezone) - this is because I am transforming Calendar to a date using getTime() API, and as soon as I do this the timezone is set to UTC. The workaround is to somehow set the the timezone attribute at the point where it is printed back to a string, this can be done by setting the timezone attribute of SimpleDateFormat, otherwise it tends to format it based on the default timezone where the code is run - &lt;br /&gt;&lt;br /&gt;This is what fixed the code for me:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:java"&gt;.....&lt;br /&gt;formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));&lt;br /&gt;.....&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-5648025478531289737?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/5648025478531289737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=5648025478531289737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5648025478531289737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5648025478531289737'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/12/simpledateformat-and-timezone.html' title='SimpleDateFormat and TimeZone'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-7286677322315092238</id><published>2011-11-11T19:49:00.001-05:00</published><updated>2011-11-25T08:23:10.127-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><title type='text'>Enabling Proxy server for CXF Client</title><content type='html'>If you ever have the need to enable proxy server for a CXF based webservice client, this is the way to go about it:&lt;br /&gt;&lt;br /&gt;Assuming a Spring based application, add this new namespace to the Spring configuration file:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt; xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"&lt;br /&gt;....&lt;br /&gt; xsi:schemaLocation="...&lt;br /&gt;    http://cxf.apache.org/transports/http/configuration&lt;br /&gt;    http://cxf.apache.org/schemas/configuration/http-conf.xsd"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, if all outbound requests are via a proxy server then make the following entry in your Spring configuration:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt; &amp;lt;http-conf:conduit name="*.http-conduit"&amp;gt;&lt;br /&gt;  &amp;lt;http-conf:client ProxyServer="${proxy.server}" ProxyServerPort="${proxy.port}" /&amp;gt;  &lt;br /&gt; &amp;lt;/http-conf:conduit&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you need to disable the proxy server, just provide an empty proxy.server parameter.&lt;br /&gt;&lt;br /&gt;If you need to enable it only for specific WS requests, then the conduit name has to be modified to the specific services portType:&lt;br /&gt;&lt;pre class="brush:xml"&gt;http-conf:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;More information &lt;a href="http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html#ClientHTTPTransport%28includingSSLsupport%29-The%7B%7Bconduit%7D%7Delement"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-7286677322315092238?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/7286677322315092238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=7286677322315092238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7286677322315092238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7286677322315092238'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/11/enabling-proxy-server-for-cxf-client.html' title='Enabling Proxy server for CXF Client'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6491027476004657823</id><published>2011-10-19T21:01:00.000-04:00</published><updated>2011-10-20T07:50:40.478-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>SOAP-Fault for a Contract First service using Spring-WS</title><content type='html'>This is a follow up to the simple webservice described in &lt;a href="http://biju-allandsundry.blogspot.com/2011/05/sample-contract-first-service-using.html"&gt;this post&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Just to recap, my webservice was responsible for returning the details of a "member" given the identifier for the member. If a member was not found for the identifier, the service did not return a member.&lt;br /&gt;&lt;br /&gt;For this request, which matches a member in the system:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mem="http://bk.org/memberservice/"&amp;gt;&lt;br /&gt;   &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;   &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;      &amp;lt;mem:MemberDetailsRequest xmlns:mem="http://bk.org/memberservice/"&amp;gt;&lt;br /&gt;         &amp;lt;mem:id&amp;gt;1&amp;lt;/mem:id&amp;gt;&lt;br /&gt;      &amp;lt;/mem:MemberDetailsRequest&amp;gt;&lt;br /&gt;   &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;&amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;this is the response:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Header/&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;      &amp;lt;ns2:MemberDetailsResponse xmlns:ns2="http://bk.org/memberservice/"&amp;gt;&lt;br /&gt;         &amp;lt;ns2:memberdetail&amp;gt;&lt;br /&gt;            &amp;lt;ns2:id&amp;gt;1&amp;lt;/ns2:id&amp;gt;&lt;br /&gt;            &amp;lt;ns2:name&amp;gt;john doe&amp;lt;/ns2:name&amp;gt;&lt;br /&gt;            &amp;lt;ns2:phone&amp;gt;111-111-1111&amp;lt;/ns2:phone&amp;gt;&lt;br /&gt;            &amp;lt;ns2:city&amp;gt;City&amp;lt;/ns2:city&amp;gt;&lt;br /&gt;            &amp;lt;ns2:state&amp;gt;State&amp;lt;/ns2:state&amp;gt;&lt;br /&gt;         &amp;lt;/ns2:memberdetail&amp;gt;&lt;br /&gt;      &amp;lt;/ns2:MemberDetailsResponse&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and for a case where there is no match, this is the response:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Header/&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;      &amp;lt;ns2:MemberDetailsResponse xmlns:ns2="http://bk.org/memberservice/"/&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, what I want to do is, instead of giving a response of this form, I want my contract to explicitly declare a Fault, in case a member is not found. &lt;br /&gt;&lt;br /&gt;There are a couple of different ways of doing it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The first way&lt;/b&gt; is to simply throw a RuntimeException, this would be trapped by the Spring-WS stack(using a &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/apidocs/org/springframework/ws/client/core/SimpleFaultMessageResolver.html"&gt;SimpleFaultMessageResolver&lt;/a&gt;) and returned as a Soap fault.&lt;br /&gt;So now my endpoint implementation is:&lt;br /&gt;&lt;pre class="brush:java"&gt;...&lt;br /&gt;@Endpoint&lt;br /&gt;public class GetMemberDetailsEndpoint {&lt;br /&gt; @Autowired private MemberManager memberManager;&lt;br /&gt;&lt;br /&gt; @PayloadRoot(namespace = "http://bk.org/memberservice/", localPart = "MemberDetailsRequest")&lt;br /&gt; @ResponsePayload&lt;br /&gt; public MemberDetailsResponse getMemberDetails(@RequestPayload MemberDetailsRequest request) throws Exception {&lt;br /&gt;  MemberDetail memberDetail = memberManager.findByMemberId(request.getId());&lt;br /&gt;  if (memberDetail==null){&lt;br /&gt;   throw new RuntimeException("Member Not Found");&lt;br /&gt;  }&lt;br /&gt;  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);&lt;br /&gt;  return response;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the response for a case where a member is not found is a clean Soap fault with the message set in the exception as the fault detail:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Header/&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;      &amp;lt;SOAP-ENV:Fault&amp;gt;&lt;br /&gt;         &amp;lt;faultcode&amp;gt;SOAP-ENV:Server&amp;lt;/faultcode&amp;gt;&lt;br /&gt;         &amp;lt;faultstring xml:lang=&amp;quot;en&amp;quot;&amp;gt;Member Not Found&amp;lt;/faultstring&amp;gt;&lt;br /&gt;      &amp;lt;/SOAP-ENV:Fault&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The second way&lt;/b&gt; is to define a custom exception class, and throw this custom exception from the endpoint:&lt;br /&gt;&lt;pre class="brush:java"&gt;@PayloadRoot(namespace = &amp;quot;http://bk.org/memberservice/&amp;quot;, localPart = &amp;quot;MemberDetailsRequest&amp;quot;)&lt;br /&gt; @ResponsePayload&lt;br /&gt; public MemberDetailsResponse getMemberDetails(@RequestPayload MemberDetailsRequest request) throws Exception {&lt;br /&gt;  MemberDetail memberDetail = memberManager.findByMemberId(request.getId());&lt;br /&gt;  if (memberDetail==null){&lt;br /&gt;   throw new MemberDetailsFault(&amp;quot;Member Not Found&amp;quot;);&lt;br /&gt;  }&lt;br /&gt;  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);&lt;br /&gt;  return response;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and define a &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/apidocs/org/springframework/ws/soap/server/endpoint/SoapFaultMappingExceptionResolver.html"&gt;resolver&lt;/a&gt;, which will map exceptions of this new type(MemberDetailsFault) to a more descriptive text:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean class=&amp;quot;org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;defaultFault&amp;quot; value=&amp;quot;SERVER&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;exceptionMappings&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;&lt;br /&gt;                org.bk.memberservice.message.MemberDetailsFault=SERVER,No Member-message from application context&lt;br /&gt;            &amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the exceptionresolver is discovered by type, so there is no need to give the bean a name. With this in place, the Soap fault, will have the fault detail based on the exceptionMapping:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Header/&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;      &amp;lt;SOAP-ENV:Fault&amp;gt;&lt;br /&gt;         &amp;lt;faultcode&amp;gt;SOAP-ENV:Server&amp;lt;/faultcode&amp;gt;&lt;br /&gt;         &amp;lt;faultstring xml:lang=&amp;quot;en&amp;quot;&amp;gt;No Member-message from application context&amp;lt;/faultstring&amp;gt;&lt;br /&gt;      &amp;lt;/SOAP-ENV:Fault&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;A third way&lt;/b&gt;, is to annotate the custom exception class with a @SoapFault annotation, describing the exception to be returned as part of the faultdetail:&lt;br /&gt;&lt;pre class="brush:java"&gt;@SoapFault(faultCode = FaultCode.SERVER, faultStringOrReason = &amp;quot;No Member Found - From @SoapFault annotation&amp;quot;)&lt;br /&gt;public class MemberDetailsFault extends RuntimeException{&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A new resolver is required to interpret exception with annotations to a Soap Fault, &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/apidocs/org/springframework/ws/soap/server/endpoint/SoapFaultAnnotationExceptionResolver.html"&gt;SoapFaultAnnotationExceptionResolver&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean class=&amp;quot;org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this in place, the response is:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Header/&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;      &amp;lt;SOAP-ENV:Fault&amp;gt;&lt;br /&gt;         &amp;lt;faultcode&amp;gt;SOAP-ENV:Server&amp;lt;/faultcode&amp;gt;&lt;br /&gt;         &amp;lt;faultstring xml:lang=&amp;quot;en&amp;quot;&amp;gt;No Member Found - From @SoapFault annotation&amp;lt;/faultstring&amp;gt;&lt;br /&gt;      &amp;lt;/SOAP-ENV:Fault&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I personally prefer the third approach, it is a little more concise.&lt;br /&gt;&lt;br /&gt;Sample available at this location: &lt;a href="https://github.com/bijukunjummen/memberservice-contractfirst"&gt;git://github.com/bijukunjummen/memberservice-contractfirst.git&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6491027476004657823?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6491027476004657823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6491027476004657823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6491027476004657823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6491027476004657823'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/10/soap-fault-for-contract-first-service.html' title='SOAP-Fault for a Contract First service using Spring-WS'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6743537445743382246</id><published>2011-10-03T22:32:00.000-04:00</published><updated>2011-10-18T20:29:12.949-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring Custom Date Editor</title><content type='html'>Recently I had a need to convert a date specified in this sample format "10/01/2010 01:05:20" into java.util.Date, with the date specified in a spring configuration file:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean name="aBean" p:id="1" class="org.bk.BeanClass" p:fromDate="01/10/2011 01:05:00" p:toDate="01/10/2011 02:05:00" p:counterId="1"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The hour and second part of the date was however being dropped by Spring.&lt;br /&gt;&lt;br /&gt;The fix is simple, register a custom date editor, which understands the appropriate date format:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt; &amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.CustomEditorConfigurer&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;customEditors&amp;quot;&amp;gt;&lt;br /&gt;     &amp;lt;map&amp;gt;&lt;br /&gt;       &amp;lt;entry key=&amp;quot;java.util.Date&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;bean class=&amp;quot;org.springframework.beans.propertyeditors.CustomDateEditor&amp;quot;&amp;gt;&lt;br /&gt;           &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;        &amp;lt;bean class=&amp;quot;java.text.SimpleDateFormat&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;constructor-arg&amp;gt;&amp;lt;value&amp;gt;MM/dd/yyyy hh:mm:ss&amp;lt;/value&amp;gt;&amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;                  &amp;lt;/bean&amp;gt;           &lt;br /&gt;           &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;           &amp;lt;constructor-arg index=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;          &amp;lt;/bean&amp;gt;&lt;br /&gt;       &amp;lt;/entry&amp;gt;&lt;br /&gt;     &amp;lt;/map&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6743537445743382246?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6743537445743382246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6743537445743382246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6743537445743382246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6743537445743382246'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/10/spring-custom-date-editor.html' title='Spring Custom Date Editor'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8894586722090893376</id><published>2011-09-29T06:46:00.000-04:00</published><updated>2012-01-25T20:27:04.358-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IndyJug'/><title type='text'>Indianapolis Java User Group - Presentation on Clojure</title><content type='html'>I attended a session on &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;&amp;nbsp;at &lt;a href="http://www.indyjug.net/index.shtml"&gt;Indianapolis JUG&lt;/a&gt;&amp;nbsp;yesterday. The session was conducted by &lt;a href="http://www.gigasquidsoftware.com/"&gt;Carin Meier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have wanted to look at Clojure for sometime now, but have been put off by the different looking LISP syntax. Instead I have been learning Scala as the functional JVM based language this year&lt;br /&gt;&lt;br /&gt;The session was great, it was about the basics of Clojure but presented in a fun way - it has provided me sufficient amount of motivation to have a second look at Clojure.&lt;br /&gt;&lt;br /&gt;The presentation slides are available at &lt;a href="https://github.com/gigasquid/Presentations"&gt;Carin Meier's Github account&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8894586722090893376?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8894586722090893376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8894586722090893376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8894586722090893376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8894586722090893376'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/09/indianapolis-java-user-group.html' title='Indianapolis Java User Group - Presentation on Clojure'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6087041913821836415</id><published>2011-09-10T19:13:00.000-04:00</published><updated>2011-09-12T08:21:05.345-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='SBT'/><title type='text'>Using SBT 0.10.1, Eclipsify for a new Scala project</title><content type='html'>Run sbt(0.10.1) in a new folder:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;D:\samplescala&amp;gt;sbt&lt;br /&gt;&lt;br /&gt;D:\samplescala&amp;gt;set SCRIPT_DIR=C:\util\sbt\&lt;br /&gt;&lt;br /&gt;D:\samplescala&amp;gt;java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar "C:\util\sbt\sbt&lt;br /&gt;-launch.jar"&lt;br /&gt;Getting net.java.dev.jna jna 3.2.3 ...&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-app&lt;br /&gt;        confs: [default]&lt;br /&gt;        1 artifacts copied, 0 already retrieved (838kB/46ms)&lt;br /&gt;Getting Scala 2.8.1 (for sbt)...&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-scala&lt;br /&gt;        confs: [default]&lt;br /&gt;        3 artifacts copied, 0 already retrieved (15178kB/235ms)&lt;br /&gt;Getting org.scala-tools.sbt sbt_2.8.1 0.10.1 ...&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-app&lt;br /&gt;        confs: [default]&lt;br /&gt;        36 artifacts copied, 0 already retrieved (6414kB/965ms)&lt;br /&gt;[info] Set current project to default-097978 (in build file:/D:/samplescala/)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following folders will show up under the root folder:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-YYI5RndUpkM/TmvoJuqSNYI/AAAAAAAAA-A/pji4ppS-mhU/s1600/sbtfolders.GIF" imageanchor="1"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-YYI5RndUpkM/TmvoJuqSNYI/AAAAAAAAA-A/pji4ppS-mhU/s1600/sbtfolders.GIF" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Create the default source/test/resource structure:&lt;br /&gt;&lt;pre class="brush:java"&gt;mkdir src\main\resources&lt;br /&gt;mkdir src\main\scala&lt;br /&gt;mkdir src\main\java&lt;br /&gt;mkdir src\test\resources&lt;br /&gt;mkdir src\test\scala&lt;br /&gt;mkdir src\test\java&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Create a build configuration file &lt;b&gt;build.sbt&lt;/b&gt;, and place it in the root of the project with the following content:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;name:="samplescala"&lt;br /&gt;&lt;br /&gt;version:="1.0"&lt;br /&gt;&lt;br /&gt;scalaVersion := "2.9.0-1"&lt;br /&gt;&lt;br /&gt;libraryDependencies ++= Seq(&lt;br /&gt;    "junit" % "junit" % "4.8" % "test",&lt;br /&gt;    "org.scalatest" % "scalatest_2.9.0" % "1.6.1"&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;defaultExcludes ~= (filter =&amp;gt; filter || "*~")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Add, one sample test in the file src\test\scala\gcdtests.scala, just to test out the sbt configuration:&lt;br /&gt;&lt;pre class="brush:scala"&gt;package com.sample&lt;br /&gt;&lt;br /&gt;object Gcd{&lt;br /&gt;    def gcd(a:Int, b:Int):Int = if (b==0) a else gcd(b, a%b)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;import org.scalatest.FlatSpec&lt;br /&gt;import org.scalatest.matchers.ShouldMatchers&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class GcdTests extends FlatSpec with ShouldMatchers{&lt;br /&gt;    "GCD of 1440, 408" should  "be 24" in {&lt;br /&gt;        Gcd.gcd(1440, 408) should equal (24)&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Invoke sbt, and run &lt;b&gt;test, &lt;/b&gt;if everything is configured correctly the following output will be displayed:&lt;br /&gt;&lt;pre class="brush:java"&gt;D:\samplescala&amp;gt;sbt&lt;br /&gt;&lt;br /&gt;D:\samplescala&amp;gt;set SCRIPT_DIR=C:\util\sbt\&lt;br /&gt;&lt;br /&gt;D:\samplescala&amp;gt;java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar "C:\util\sbt\sbt&lt;br /&gt;-launch.jar"&lt;br /&gt;[info] Set current project to default-097978 (in build file:/D:/samplescala/)&lt;br /&gt;&amp;gt; test&lt;br /&gt;[info] Updating {file:/D:/samplescala/}default-097978...&lt;br /&gt;[info] Done updating.&lt;br /&gt;[info] GcdTests:&lt;br /&gt;[info] GCD of 1440, 408&lt;br /&gt;[info] - should be 24&lt;br /&gt;[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0&lt;br /&gt;[success] Total time: 1 s, completed Sep 10, 2011 7:00:28 PM&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, to import this project into eclipse. Create a build.sbt file with the following contents and place in the project/plugins folder:&lt;br /&gt;&lt;pre class="brush:scala"&gt;libraryDependencies &amp;lt;+= (libraryDependencies, sbtVersion) { (deps, version) =&amp;gt; &lt;br /&gt;    "de.element34" %% "sbt-eclipsify" % "0.10.0-SNAPSHOT"&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Restart sbt, if the plugin is configured correctly, eclipse will be a valid task in sbt, running this will create the .project and .classpath files for Eclipse:&lt;br /&gt;&lt;pre class="brush:scala"&gt;&amp;gt; eclipse&lt;br /&gt;[info] Starting eclipse&lt;br /&gt;[info] written .project for samplescala&lt;br /&gt;[info] written .classpath for samplescala&lt;br /&gt;[info] * Don't forget to install the Scala IDE Plugin from http://www.scalaide.org/&lt;br /&gt;[info] You may now import your projects in Eclipse&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Assuming that &lt;a href="http://www.scala-ide.org/"&gt;Scala IDE for Eclipse&lt;/a&gt; is installed, import this new project into Eclipse:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-4B-4AAzKdKs/TmvuHGXAWBI/AAAAAAAAA-E/GzU_Yl6kNOw/s1600/samplescalaproject.GIF" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="http://2.bp.blogspot.com/-4B-4AAzKdKs/TmvuHGXAWBI/AAAAAAAAA-E/GzU_Yl6kNOw/s640/samplescalaproject.GIF" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6087041913821836415?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6087041913821836415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6087041913821836415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6087041913821836415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6087041913821836415'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/09/using-sbt-0101-eclipsify-for-new-scala.html' title='Using SBT 0.10.1, Eclipsify for a new Scala project'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-YYI5RndUpkM/TmvoJuqSNYI/AAAAAAAAA-A/pji4ppS-mhU/s72-c/sbtfolders.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-5109791597158589510</id><published>2011-09-08T20:57:00.000-04:00</published><updated>2011-09-12T08:21:57.123-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AspectJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Simple Introduction to AOP - Session 5</title><content type='html'>This will be a wrap up of the AOP intro, with an example that will comprehensively exercise the concepts introduced in the previous sessions.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The use case is simple, I am going to define a custom annotation, PerfLog, I expect the calls to methods annotated with this annotation to be timed and logged.&lt;/div&gt;&lt;div&gt;Let me start by defining the annotation:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.annotations;&lt;br /&gt;import java.lang.annotation.ElementType;&lt;br /&gt;import java.lang.annotation.Retention;&lt;br /&gt;import java.lang.annotation.RetentionPolicy;&lt;br /&gt;import java.lang.annotation.Target;&lt;br /&gt;&lt;br /&gt;@Target({ElementType.TYPE, ElementType.METHOD})&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;public @interface PerfLog {&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Now to annotate some service methods with this annotation:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;@Service&lt;br /&gt;public class DefaultInventoryService implements InventoryService{&lt;br /&gt;    &lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(InventoryService.class);&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public Inventory create(Inventory inventory) {&lt;br /&gt;        logger.info("Create Inventory called");&lt;br /&gt;        inventory.setId(1L);&lt;br /&gt;        return inventory; &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public List&amp;lt;Inventory&amp;gt; list() {&lt;br /&gt;        return new ArrayList&amp;lt;Inventory&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    @PerfLog&lt;br /&gt;    public Inventory update(Inventory inventory) {&lt;br /&gt;        return inventory;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public boolean delete(Long id) {&lt;br /&gt;        logger.info("Delete Inventory called");&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    @PerfLog&lt;br /&gt;    public Inventory findByVin(String vin) {&lt;br /&gt;        logger.info("find by vin called");&lt;br /&gt;        return new Inventory("testmake", "testmodel","testtrim","testvin" );&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    @PerfLog&lt;br /&gt;    public Inventory compositeUpdateService(String vin, String newMake) {&lt;br /&gt;        logger.info("composite Update Service called");&lt;br /&gt;        Inventory inventory = findByVin(vin);&lt;br /&gt;        inventory.setMake(newMake);&lt;br /&gt;        update(inventory);&lt;br /&gt;        return inventory;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here three methods of DefaultInventoryService have been annotated with @PerfLog annotation - update, findByVin, compositeUpdateService which internally invokes the methods findByVin and update.&lt;br /&gt;&lt;br /&gt;Now for the Aspect which will intercept all calls to methods annotated with @PerfLog and log the time taken for the method call:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.inventory.aspect;&lt;br /&gt;&lt;br /&gt;import org.aspectj.lang.ProceedingJoinPoint;&lt;br /&gt;import org.aspectj.lang.annotation.Around;&lt;br /&gt;import org.aspectj.lang.annotation.Aspect;&lt;br /&gt;import org.aspectj.lang.annotation.Pointcut;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;@Aspect&lt;br /&gt;public class AuditAspect {&lt;br /&gt;&lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);&lt;br /&gt;&lt;br /&gt;    @Pointcut(&amp;quot;execution(@org.bk.annotations.PerfLog * *.*(..))&amp;quot;)&lt;br /&gt;    public void performanceTargets(){}&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;    @Around(&amp;quot;performanceTargets()&amp;quot;)&lt;br /&gt;    public Object logPerformanceStats(ProceedingJoinPoint joinpoint) {&lt;br /&gt;        try {&lt;br /&gt;            long start = System.nanoTime();&lt;br /&gt;            Object result = joinpoint.proceed();&lt;br /&gt;            long end = System.nanoTime();&lt;br /&gt;            logger.info(String.format(&amp;quot;%s took %d ns&amp;quot;, joinpoint.getSignature(), (end - start)));&lt;br /&gt;            return result;&lt;br /&gt;        } catch (Throwable e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here the pointcut expression - &lt;pre class="brush:java"&gt;@Pointcut(&amp;quot;execution(@org.bk.annotations.PerfLog * *.*(..))&amp;quot;)&lt;/pre&gt;selects all methods annotated with @PerfLog annotation, and the aspect method logPerformanceStats logs the time taken by the method calls.&lt;br /&gt;&lt;br /&gt;To test this:&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.inventory;&lt;br /&gt;&lt;br /&gt;import static org.hamcrest.CoreMatchers.*;&lt;br /&gt;import static org.junit.Assert.*;&lt;br /&gt;&lt;br /&gt;import org.bk.inventory.service.InventoryService;&lt;br /&gt;import org.bk.inventory.types.Inventory;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;import org.junit.runner.RunWith;&lt;br /&gt;import org.springframework.beans.factory.annotation.Autowired;&lt;br /&gt;import org.springframework.test.context.ContextConfiguration;&lt;br /&gt;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;&lt;br /&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@ContextConfiguration(&amp;quot;classpath:/testApplicationContextAOP.xml&amp;quot;)&lt;br /&gt;public class AuditAspectTest {&lt;br /&gt;&lt;br /&gt;    @Autowired &lt;br /&gt;    InventoryService inventoryService;&lt;br /&gt;        &lt;br /&gt;    @Test&lt;br /&gt;    public void testInventoryService() {&lt;br /&gt;        Inventory inventory = this.inventoryService.create(new Inventory(&amp;quot;testmake&amp;quot;, &amp;quot;testmodel&amp;quot;,&amp;quot;testtrim&amp;quot;,&amp;quot;testvin&amp;quot; ));&lt;br /&gt;        assertThat(inventory.getId(), is(1L));&lt;br /&gt;        &lt;br /&gt;        assertThat(this.inventoryService.delete(1L), is(true));&lt;br /&gt;        assertThat(this.inventoryService.compositeUpdateService(&amp;quot;vin&amp;quot;,&amp;quot;newmake&amp;quot;).getMake(),is(&amp;quot;newmake&amp;quot;));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When this test is invoked the output is the following:&lt;br /&gt;&lt;pre class="brush:java"&gt;2011-09-08 20:54:03,521 org.bk.inventory.service.InventoryService - Create Inventory called&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - Delete Inventory called&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - composite Update Service called&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - find by vin called&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.findByVin(String) took 64893 ns&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.update(Inventory) took 1833 ns&lt;br /&gt;2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.compositeUpdateService(String, String) took 1371171 ns&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the advice is correctly invoked for findByVin, update and compositeUpdateService.&lt;br /&gt;&lt;br /&gt;This sample is available at : git://github.com/bijukunjummen/AOP-Samples.git&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-5109791597158589510?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/5109791597158589510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=5109791597158589510' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5109791597158589510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5109791597158589510'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/09/simple-introduction-to-aop-session-5.html' title='Simple Introduction to AOP - Session 5'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-7098389036438418493</id><published>2011-09-02T22:05:00.000-04:00</published><updated>2011-09-12T08:22:03.029-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AspectJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Simple Introduction to AOP - Session 4</title><content type='html'>Yet another way to define an aspect - this time using native aspectj notation.  &lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.inventory.aspect;&lt;br /&gt;&lt;br /&gt;import org.bk.inventory.types.Inventory;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;public aspect AuditAspect {&lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);&lt;br /&gt;&lt;br /&gt;    pointcut serviceMethods() : execution(* org.bk.inventory.service.*.*(..));&lt;br /&gt;&lt;br /&gt;    pointcut serviceMethodsWithInventoryAsParam(Inventory inventory) : execution(* org.bk.inventory.service.*.*(Inventory)) &amp;amp;&amp;amp; args(inventory);&lt;br /&gt;&lt;br /&gt;    before() : serviceMethods() {&lt;br /&gt;        logger.info(&amp;quot;before method&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    Object around() : serviceMethods() {&lt;br /&gt;        long start = System.nanoTime();&lt;br /&gt;        Object result = proceed();&lt;br /&gt;        long end = System.nanoTime();&lt;br /&gt;        logger.info(String.format(&amp;quot;%s took %d ns&amp;quot;, thisJoinPointStaticPart.getSignature(),&lt;br /&gt;                (end - start)));&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    Object around(Inventory inventory) : serviceMethodsWithInventoryAsParam(inventory) {&lt;br /&gt;        Object result = proceed(inventory);&lt;br /&gt;        logger.info(String.format(&amp;quot;WITH PARAM: %s&amp;quot;, inventory.toString()));&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;    after() : serviceMethods() {&lt;br /&gt;        logger.info(&amp;quot;after method&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This maps to the &lt;a href="http://biju-allandsundry.blogspot.com/2011/08/simple-introduction-to-aop-session-3.html"&gt;previously defined&lt;/a&gt; @AspectJ notation  &lt;br /&gt;&lt;br /&gt;Since this is a DSL specifically for defining Aspects, it is not understood by the java compiler. AspectJ provides a &lt;a href="http://www.eclipse.org/aspectj/doc/released/devguide/ajc-ref.html"&gt;tool(ajc)&lt;/a&gt; to compile these native aspectj files and to weave the aspects into the targeted pointcuts.  Maven provides a plugin which seamlessly invokes ajc at the point of compilation: &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;			&amp;lt;plugin&amp;gt;&lt;br /&gt;				&amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;				&amp;lt;artifactId&amp;gt;aspectj-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;				&amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;				&amp;lt;dependencies&amp;gt;&lt;br /&gt;					&amp;lt;dependency&amp;gt;&lt;br /&gt;						&amp;lt;groupId&amp;gt;org.aspectj&amp;lt;/groupId&amp;gt;&lt;br /&gt;						&amp;lt;artifactId&amp;gt;aspectjrt&amp;lt;/artifactId&amp;gt;&lt;br /&gt;						&amp;lt;version&amp;gt;${aspectj.version}&amp;lt;/version&amp;gt;&lt;br /&gt;					&amp;lt;/dependency&amp;gt;&lt;br /&gt;					&amp;lt;dependency&amp;gt;&lt;br /&gt;						&amp;lt;groupId&amp;gt;org.aspectj&amp;lt;/groupId&amp;gt;&lt;br /&gt;						&amp;lt;artifactId&amp;gt;aspectjtools&amp;lt;/artifactId&amp;gt;&lt;br /&gt;						&amp;lt;version&amp;gt;${aspectj.version}&amp;lt;/version&amp;gt;&lt;br /&gt;					&amp;lt;/dependency&amp;gt;&lt;br /&gt;				&amp;lt;/dependencies&amp;gt;&lt;br /&gt;				&amp;lt;executions&amp;gt;&lt;br /&gt;					&amp;lt;execution&amp;gt;&lt;br /&gt;						&amp;lt;goals&amp;gt;&lt;br /&gt;							&amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;							&amp;lt;goal&amp;gt;test-compile&amp;lt;/goal&amp;gt;&lt;br /&gt;						&amp;lt;/goals&amp;gt;&lt;br /&gt;					&amp;lt;/execution&amp;gt;&lt;br /&gt;				&amp;lt;/executions&amp;gt;&lt;br /&gt;				&amp;lt;configuration&amp;gt;&lt;br /&gt;					&amp;lt;outxml&amp;gt;true&amp;lt;/outxml&amp;gt;&lt;br /&gt;					&amp;lt;aspectLibraries&amp;gt;&lt;br /&gt;						&amp;lt;aspectLibrary&amp;gt;&lt;br /&gt;							&amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;							&amp;lt;artifactId&amp;gt;spring-aspects&amp;lt;/artifactId&amp;gt;&lt;br /&gt;						&amp;lt;/aspectLibrary&amp;gt;&lt;br /&gt;					&amp;lt;/aspectLibraries&amp;gt;&lt;br /&gt;					&amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;&lt;br /&gt;					&amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;&lt;br /&gt;				&amp;lt;/configuration&amp;gt;&lt;br /&gt;			&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-7098389036438418493?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/7098389036438418493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=7098389036438418493' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7098389036438418493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7098389036438418493'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/09/simple-introduction-to-aop-session-4.html' title='Simple Introduction to AOP - Session 4'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8050423107978097396</id><published>2011-08-20T19:45:00.000-04:00</published><updated>2011-09-12T08:22:09.754-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AspectJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Simple Introduction to AOP - Session 3</title><content type='html'>Another way of defining an Aspect is using @AspectJ annotaions - which is natively understood by Spring:  &lt;pre class="brush:java"&gt;package org.bk.inventory.aspect;&lt;br /&gt;&lt;br /&gt;import org.aspectj.lang.ProceedingJoinPoint;&lt;br /&gt;import org.aspectj.lang.annotation.After;&lt;br /&gt;import org.aspectj.lang.annotation.Around;&lt;br /&gt;import org.aspectj.lang.annotation.Aspect;&lt;br /&gt;import org.aspectj.lang.annotation.Before;&lt;br /&gt;import org.aspectj.lang.annotation.Pointcut;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;@Aspect&lt;br /&gt;public class AuditAspect {&lt;br /&gt;&lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);&lt;br /&gt;&lt;br /&gt;    @Pointcut(&amp;quot;execution(* org.bk.inventory.service.*.*(..))&amp;quot;)&lt;br /&gt;    public void serviceMethods(){&lt;br /&gt;        //&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    @Before(&amp;quot;serviceMethods()&amp;quot;)&lt;br /&gt;    public void beforeMethod() {&lt;br /&gt;        logger.info(&amp;quot;before method&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Around(&amp;quot;serviceMethods()&amp;quot;)&lt;br /&gt;    public Object aroundMethod(ProceedingJoinPoint joinpoint) {&lt;br /&gt;        try {&lt;br /&gt;            long start = System.nanoTime();&lt;br /&gt;            Object result = joinpoint.proceed();&lt;br /&gt;            long end = System.nanoTime();&lt;br /&gt;            logger.info(String.format(&amp;quot;%s took %d ns&amp;quot;, joinpoint.getSignature(), (end - start)));&lt;br /&gt;            return result;&lt;br /&gt;        } catch (Throwable e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;      &lt;br /&gt;    @After(&amp;quot;serviceMethods()&amp;quot;)&lt;br /&gt;    public void afterMethod() {&lt;br /&gt;        logger.info(&amp;quot;after method&amp;quot;);&lt;br /&gt;    }    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The @Aspect annotation on the class identifies it as an aspect definition. It starts by defining the pointcuts: &lt;pre class="brush:java"&gt;@Pointcut(&amp;quot;execution(* org.bk.inventory.service.*.*(..))&amp;quot;)&lt;br /&gt;    public void serviceMethods(){}&lt;br /&gt;&lt;/pre&gt;The above basically identifies all the methods of all types in org.bk.inventory.service package, this pointcut is identified by the name of the method on which the annotation is placed - in this case "serviceMethods".  Next, the advice is defined using the @Before(serviceMethods()), @After(serviceMethods()) and @Around(serviceMethods()) annotation and the specifics of what needs to happen is the body of the methods with those annotations.  Spring AOP natively understands the @AspectJ annotations, if this Aspect is defined as a bean: &lt;pre class="brush:java"&gt;&amp;lt;bean id=&amp;quot;auditAspect&amp;quot; class=&amp;quot;org.bk.inventory.aspect.AuditAspect&amp;quot; /&amp;gt;&lt;br /&gt;&lt;/pre&gt;Spring would create a dynamic proxy to apply the advice on all the target beans identified as part of the pointcut notation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8050423107978097396?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8050423107978097396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8050423107978097396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8050423107978097396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8050423107978097396'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/08/simple-introduction-to-aop-session-3.html' title='Simple Introduction to AOP - Session 3'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-4651688772189716737</id><published>2011-08-13T20:31:00.000-04:00</published><updated>2011-09-12T08:22:15.760-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AspectJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Simple Introduction to AOP - Session 2</title><content type='html'>Here, I will show how the cross-cutting concern that was introduced in the previous &lt;a href="http://biju-allandsundry.blogspot.com/2011/08/simple-introduction-to-aop-session-1.html"&gt;session&lt;/a&gt;, can be implemented using Spring AOP - Spring offers multiple ways of implementing Aspects - XML configuration based, @AspectJ based. In this specific example, I will use XML configuration file based way of defining the aspect&lt;br /&gt;&lt;br /&gt;Spring AOP works in the context of a Spring container, so the service implementation that was defined in the previous session needs to be a Spring bean, I am defining it using the @Service annotation:  &lt;br /&gt;&lt;pre class="brush:java"&gt;@Service&lt;br /&gt;public class DefaultInventoryService implements InventoryService{&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now, I want to record the time taken for each of the method calls of my DefaultInventoryService - I am first going to modularize this as an "advice": &lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.inventory.aspect;&lt;br /&gt;&lt;br /&gt;import org.aspectj.lang.ProceedingJoinPoint;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;public class AuditAdvice {&lt;br /&gt;&lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(AuditAdvice.class);&lt;br /&gt;&lt;br /&gt;    public void beforeMethod() {&lt;br /&gt;        logger.info("before method");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void afterMethod() {&lt;br /&gt;        logger.info("after method");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object aroundMethod(ProceedingJoinPoint joinpoint) {&lt;br /&gt;        try {&lt;br /&gt;            long start = System.nanoTime();&lt;br /&gt;            Object result = joinpoint.proceed();&lt;br /&gt;            long end = System.nanoTime();&lt;br /&gt;            logger.info(String.format("%s took %d ns", joinpoint.getSignature(), (end - start)));&lt;br /&gt;            return result;&lt;br /&gt;        } catch (Throwable e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;        &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This advice is expected to capture the time taken by the methods in DefaultInventoryService. So now to wire this advice to the DefaultInventoryService spring bean: &lt;br /&gt;&lt;pre class="brush:xml"&gt;	&amp;lt;bean id="auditAspect" class="org.bk.inventory.aspect.AuditAdvice" /&amp;gt;&lt;br /&gt;&lt;br /&gt;	&amp;lt;aop:config&amp;gt;&lt;br /&gt;		&amp;lt;aop:aspect ref="auditAspect"&amp;gt;&lt;br /&gt;			&amp;lt;aop:pointcut id="serviceMethods" expression="execution(* org.bk.inventory.service.*.*(..))" /&amp;gt;&lt;br /&gt;&lt;br /&gt;			&amp;lt;aop:before pointcut-ref="serviceMethods" method="beforeMethod" /&amp;gt;  &lt;br /&gt;			&amp;lt;aop:around pointcut-ref="serviceMethods" method="aroundMethod" /&amp;gt;&lt;br /&gt;			&amp;lt;aop:after-returning pointcut-ref="serviceMethods" method="afterMethod" /&amp;gt; &lt;br /&gt;		&amp;lt;/aop:aspect&amp;gt;&lt;br /&gt;	&amp;lt;/aop:config&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This works by first defining the "pointcut" - the places(in this example, the service methods) to add the cross cutting concern(capturing the method execution time in this example) to. Here I have defined it using a pointcut expression -&lt;pre class="brush:xml"&gt;execution(* org.bk.inventory.service.*.*(..))&lt;/pre&gt;, which is essentially selecting all methods of all the types in the org.bk.inventory.service package.  Once the pointcut is defined, it defines what needs to be done around the pointcut(the advice), using the expression: &lt;pre class="brush:xml"&gt;&amp;lt;aop:around pointcut-ref="serviceMethods" method="aroundMethod" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;This basically says, that around every method of any service type, execute the aroundMethod of AspectAdvice that was defined earlier.  Now, if the service methods are executed, I would see the advice getting invoked during the method execution, the following is a sample output if DefaultInventoryService, createInventory method is called:  &lt;pre&gt;org.bk.inventory.service.InventoryService - Create Inventory called&lt;br /&gt;org.bk.inventory.aspect.AuditAdvice - Inventory org.bk.inventory.service.InventoryService.create(Inventory) took 82492 ns&lt;br /&gt;&lt;/pre&gt;Spring's AOP implementation works by generating a dynamic proxy at runtime for all the target beans, based on the defined pointcut. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-4651688772189716737?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/4651688772189716737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=4651688772189716737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4651688772189716737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4651688772189716737'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/08/simple-introduction-to-aop-session-2.html' title='Simple Introduction to AOP - Session 2'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8236706933243483577</id><published>2011-08-09T20:18:00.000-04:00</published><updated>2011-09-12T08:22:21.753-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AspectJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>A simple introduction to AOP - Session 1</title><content type='html'>Why use AOP, a simple way to answer this question is to show an implementation of a cross cutting concern without using AOP.  &lt;br /&gt;&lt;br /&gt;Consider a simple service and it's implementation:&lt;br /&gt;&lt;pre class="brush:java"&gt;public interface InventoryService {&lt;br /&gt;    public Inventory create(Inventory inventory);&lt;br /&gt;    public List&lt;inventory&gt; list();&lt;br /&gt;    public Inventory findByVin(String vin);&lt;br /&gt;    public Inventory update(Inventory inventory);&lt;br /&gt;    public boolean delete(Long id);&lt;br /&gt;    public Inventory compositeUpdateService(String vin, String newMake);&lt;br /&gt;}&lt;br /&gt;&lt;/inventory&gt;&lt;/pre&gt;&lt;br /&gt;and its default implementation: &lt;br /&gt;&lt;pre class="brush:java"&gt;public class DefaultInventoryService implements InventoryService{&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public Inventory create(Inventory inventory) {&lt;br /&gt;        logger.info("Create Inventory called");&lt;br /&gt;        inventory.setId(1L);&lt;br /&gt;        return inventory; &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public List&lt;inventory&gt; list() {&lt;br /&gt;        return new ArrayList&lt;inventory&gt;();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Inventory update(Inventory inventory) {&lt;br /&gt;        return inventory;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public boolean delete(Long id) {&lt;br /&gt;        logger.info("Delete Inventory called");&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;....&lt;br /&gt;&lt;/inventory&gt;&lt;/inventory&gt;&lt;/pre&gt;&lt;br /&gt;This is just one service. Assume that there are many more services in this project.&lt;br /&gt;&lt;br /&gt;So now, if there were a requirement to record the time taken by each of the service methods, the option without AOP would be something along the following lines. Create a decorator for the service: &lt;br /&gt;&lt;pre class="brush:java"&gt;public class InventoryServiceDecorator implements InventoryService{&lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(InventoryServiceDecorator.class);&lt;br /&gt;    private InventoryService decorated;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Inventory create(Inventory inventory) {&lt;br /&gt;        logger.info("before method: create");&lt;br /&gt;        long start = System.nanoTime();&lt;br /&gt;        Inventory inventoryCreated = decorated.create(inventory);&lt;br /&gt;        long end = System.nanoTime();&lt;br /&gt;        logger.info(String.format("%s took %d ns", "create", (end-start)) );&lt;br /&gt;        return inventoryCreated;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;This decorator would essentially intercept the call on behalf of the decorated, record the time  taken for the method call while delegating the call to the decorated object.&lt;br /&gt;&lt;br /&gt;Imagine doing this for all the methods and all the services in the project. This is the scenario that AOP addresses, it provides a way for the cross cutting concerns(Recording time for the service method calls for eg.) to be modularized - to be packaged up separately without polluting the core of the classes.&lt;br /&gt;&lt;br /&gt;To end the session, a different way to implement the decorator would be using the &lt;a href="http://download.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/InvocationHandler.html"&gt;dynamic proxy&lt;/a&gt; feature of Java:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;public class AuditProxy implements java.lang.reflect.InvocationHandler {&lt;br /&gt;    &lt;br /&gt;    private static Logger logger = LoggerFactory.getLogger(AuditProxy.class);&lt;br /&gt;    private Object obj;&lt;br /&gt;&lt;br /&gt;    public static Object newInstance(Object obj) {&lt;br /&gt;        return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj&lt;br /&gt;                .getClass().getInterfaces(), new AuditProxy(obj));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private AuditProxy(Object obj) {&lt;br /&gt;        this.obj = obj;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {&lt;br /&gt;        Object result;&lt;br /&gt;        try {&lt;br /&gt;            logger.info("before method " + m.getName());&lt;br /&gt;            long start = System.nanoTime();&lt;br /&gt;            result = m.invoke(obj, args);&lt;br /&gt;            long end = System.nanoTime();&lt;br /&gt;            logger.info(String.format("%s took %d ns", m.getName(), (end-start)) );&lt;br /&gt;        } catch (InvocationTargetException e) {&lt;br /&gt;            throw e.getTargetException();&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());&lt;br /&gt;        } finally {&lt;br /&gt;            logger.info("after method " + m.getName());&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now, when creating an instance of InventoryService, I would create it through the AuditProxy dynamic proxy: &lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;/pre&gt;&lt;pre class="brush:java"&gt;InventoryService inventoryService = (InventoryService)AuditProxy.newInstance(new DefaultInventoryService());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the overridden invoke method of java.lang.reflect.InvocationHandler would intercept all calls to the InventoryService created in this manner, where the cross cutting concern of auditing the method call time is recorded.  This way the cross cutting concern is modularized to one place(AuditProxy), but still needs to be explicitly known by the clients of InventoryService, when instantiating InventoryService.&lt;br /&gt;&lt;br /&gt;In the next few sessions, I will demonstrate how this can be more cleanly accomplished using Spring AOP, Spring AOP with @AspectJ, AspectJ, @AspectJ with compile time weaving and finish it off with a comprehensive example.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8236706933243483577?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8236706933243483577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8236706933243483577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8236706933243483577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8236706933243483577'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/08/simple-introduction-to-aop-session-1.html' title='A simple introduction to AOP - Session 1'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8490857226450957764</id><published>2011-07-26T23:47:00.000-04:00</published><updated>2011-07-26T23:47:50.200-04:00</updated><title type='text'>"n" slots - continued..</title><content type='html'>A different java implementation, closer to being a good functional implementation, but not quite there:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;    public List&amp;lt;String&amp;gt; fillNSlots(int n){&lt;br /&gt;        return fillNSlotsWithPrefix(0, n, "");&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private List&amp;lt;String&amp;gt; fillNSlotsWithPrefix(int counter, int  n, String prefix){&lt;br /&gt;        if (counter==n-1){&lt;br /&gt;            return new ArrayList&amp;lt;String&amp;gt;(Arrays.asList(new String[]{prefix + "0", prefix + "1"})); &lt;br /&gt;        }else{&lt;br /&gt;            List&amp;lt;String&amp;gt; result1 = fillNSlotsWithPrefix(counter+1, n , prefix + "0");&lt;br /&gt;            result1.addAll(fillNSlotsWithPrefix(counter+1, n , prefix + "1"));&lt;br /&gt;            return result1;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is not quite there, as there is still a need to hold an intermediate state with a temporary variable, result1 above, which could have been avoided had List supported an API which adds an element and returns itself or returns a new list.&lt;br /&gt;&lt;br /&gt;The following is an equivalent implementation in scala:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;   def fillNSlots(n:Int):List[String] = {&lt;br /&gt;        fillNSlotsWithPrefix(0,n,&amp;quot;&amp;quot;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def fillNSlotsWithPrefix(counter:Int, n: Int, prefix:String): List[String] = {&lt;br /&gt;        if (counter==(n-1))&lt;br /&gt;            (prefix+&amp;quot;0&amp;quot;)::(prefix+&amp;quot;1&amp;quot;)::List()&lt;br /&gt;        else&lt;br /&gt;            fillNSlotsWithPrefix(counter+1, n, prefix+&amp;quot;0&amp;quot;):::fillNSlotsWithPrefix(counter+1, n, prefix+&amp;quot;1&amp;quot;)&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8490857226450957764?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8490857226450957764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8490857226450957764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8490857226450957764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8490857226450957764'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/07/n-slots-continued.html' title='&quot;n&quot; slots - continued..'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-3333704280000215565</id><published>2011-07-24T21:33:00.000-04:00</published><updated>2011-07-24T21:33:46.052-04:00</updated><title type='text'>"n" slots - different ways of filling it</title><content type='html'>The problem is simple - Given "n" slots, find all possible different configurations to fill the slots:&lt;br /&gt;For "2" slots, the possible configurations are - [00, 01, 10, 11]&lt;br /&gt;For "3" slots, the possible configurations are - [000, 001, 010, 011, 100, 101, 110, 111]&lt;br /&gt;&lt;br /&gt;Here is a test for any solution:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;    @Test&lt;br /&gt;    public void test2Slots() {&lt;br /&gt;        String[] slotsAnswer = {"00","01", "10", "11"};&lt;br /&gt;        assertThat(fillNSlots(2), hasItems(slotsAnswer));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void test3Slots() {&lt;br /&gt;        String[] slotsAnswer = {"000", "001", "010", "011", "100", "101", "110", "111"};&lt;br /&gt;        assertThat(fillNSlots(3), hasItems(slotsAnswer));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void test5Slots() {&lt;br /&gt;        String[] slotsAnswer = {"00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111"};&lt;br /&gt;        assertThat(fillNSlots(5), hasItems(slotsAnswer));&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have a naive solution to start with:&lt;br /&gt;&lt;pre class="brush:java"&gt;    &lt;br /&gt;    public List&amp;lt;String&amp;gt; fillNSlots(int n){&lt;br /&gt;        List&amp;lt;String&amp;gt; result = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;        fillNSlotsWithPrefix(result, n, "");&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private void fillNSlotsWithPrefix(List&amp;lt;String&amp;gt; result, int n, String prefix){&lt;br /&gt;        if (n==0){&lt;br /&gt;            result.add(prefix);&lt;br /&gt;        }else{&lt;br /&gt;            fillNSlotsWithPrefix(result, n-1, prefix + "0");&lt;br /&gt;            fillNSlotsWithPrefix(result, n-1, prefix + "1");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;This solution works, however state is being passed(an arraylist of result) with each of the "fillNSlotsWithPrefix" methods recursive calls. A pure functional method, however would not have had this side effect. I will fix this implementation to be more functional over the course of next week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-3333704280000215565?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/3333704280000215565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=3333704280000215565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3333704280000215565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3333704280000215565'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/07/n-slots-different-ways-of-filling-it.html' title='&quot;n&quot; slots - different ways of filling it'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6655328682039020900</id><published>2011-06-20T21:57:00.000-04:00</published><updated>2011-09-12T08:23:15.441-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>Writing Integration tests for Spring WS endpoints</title><content type='html'>Writing Integration tests for Spring WS endpoints is easy, based on &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e1500"&gt;this&lt;/a&gt; resource from Spring-WS reference site. Spring WS provides a &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/apidocs/org/springframework/ws/test/server/MockWebServiceClient.html"&gt;MockWebServiceClient&lt;/a&gt;&amp;nbsp;class to test the Spring-WS endpoints.&lt;br /&gt;&lt;br /&gt;My endpoint has the following signature:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;@Endpoint&lt;br /&gt;public class GetMemberDetailsEndpoint {&lt;br /&gt;&lt;br /&gt; @Resource private MemberManager memberManager;&lt;br /&gt;&lt;br /&gt; @PayloadRoot(namespace = "http://bk.org/memberservice/", localPart = "MemberDetailsRequest")&lt;br /&gt; @ResponsePayload&lt;br /&gt; public MemberDetailsResponse getMemberDetails(@RequestPayload MemberDetailsRequest request) throws Exception {&lt;br /&gt;  MemberDetail memberDetail = memberManager.findByMemberId(request.getId());&lt;br /&gt;                ......&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have a memberManager bean dependency in my endpoint, I mock this up using easymock first: &lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean name="memberManager" class="org.easymock.EasyMock" factory-method="createMock"&amp;gt;&lt;br /&gt;  &amp;lt;constructor-arg value="org.bk.memberservice.service.MemberManager"/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;this way Spring will wire it to the endpoint when starting up the bean factory. Record the easymock with appropriate expectations: &lt;br /&gt;&lt;pre class="brush:java"&gt;MemberDetail memberDetail = new MemberDetail("john doe", "111-111-1111", "City", "State");&lt;br /&gt;        memberDetail.setId(1L);&lt;br /&gt;        expect(memberManager.findByMemberId(1L)).andReturn(memberDetail);&lt;br /&gt;        replay(memberManager);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Initialize MockWebserviceClient, set up the test: &lt;br /&gt;&lt;pre class="brush:java"&gt;mockClient = MockWebServiceClient.createClient(applicationContext);&lt;br /&gt;        Source requestPayload = new StringSource(&lt;br /&gt;                "&amp;lt;mem:MemberDetailsRequest xmlns:mem=\"http://bk.org/memberservice/\"&amp;gt;"&lt;br /&gt;                        + "&amp;lt;mem:id&amp;gt;1&amp;lt;/mem:id&amp;gt;" &lt;br /&gt;                        + "&amp;lt;/mem:MemberDetailsRequest&amp;gt;");&lt;br /&gt;        Source responsePayload = new StringSource(&lt;br /&gt;                "&amp;lt;ns3:MemberDetailsResponse xmlns:ns3=\"http://bk.org/memberservice/\"&amp;gt;"&lt;br /&gt;          + "&amp;lt;memberDetail&amp;gt;" &lt;br /&gt;          + "&amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;"&lt;br /&gt;          + "&amp;lt;name&amp;gt;john doe&amp;lt;/name&amp;gt;"&lt;br /&gt;          + "&amp;lt;phone&amp;gt;111-111-1111&amp;lt;/phone&amp;gt;"&lt;br /&gt;          + "&amp;lt;city&amp;gt;City&amp;lt;/city&amp;gt;"&lt;br /&gt;          + "&amp;lt;state&amp;gt;State&amp;lt;/state&amp;gt;"&lt;br /&gt;          + "&amp;lt;/memberDetail&amp;gt;"&lt;br /&gt;      + "&amp;lt;/ns3:MemberDetailsResponse&amp;gt;");&lt;br /&gt;&lt;br /&gt;        mockClient.sendRequest(withPayload(requestPayload)).andExpect(payload(responsePayload));&lt;br /&gt;        verify(this.memberManager);&lt;br /&gt;&lt;/pre&gt;This completes the test, MockWebserviceClient would take care of  packaging up the raw xml request, dispatching it the appropriate WS endpoint, getting the response and validating it. Updated codesample with integration test available at: &lt;a href="https://github.com/bijukunjummen/memberservice-contractfirst"&gt;git://github.com/bijukunjummen/memberservice-contractfirst.git&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6655328682039020900?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6655328682039020900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6655328682039020900' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6655328682039020900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6655328682039020900'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/06/writing-integration-tests-for-spring-ws.html' title='Writing Integration tests for Spring WS endpoints'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-994361371399841808</id><published>2011-06-18T16:37:00.000-04:00</published><updated>2011-09-12T08:23:28.261-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>Supporting Spring-WS and Spring MVC integration in a project</title><content type='html'>Spring WS and Spring MVC provide different &lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html"&gt;front controlle&lt;/a&gt;r implementations as a gateway to the webservice and the MVC functionality respectively. The Dispatcher Servlet used by Spring-WS is :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;org.springframework.ws.transport.http.MessageDispatcherServlet&lt;br /&gt;&lt;/pre&gt;and the one used by Spring MVC is :&lt;br /&gt;&lt;pre class="brush:java"&gt;org.springframework.web.servlet.DispatcherServlet&lt;br /&gt;&lt;/pre&gt;To have a combined Spring MVC and Spring-WS project, it is possible to configure these front controllers based on the URI pattern of the request, in the following way:  &lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;member-ws&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.springframework.ws.transport.http.MessageDispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;classpath:/META-INF/spring/applicationContext-ws.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;member-web&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;/WEB-INF/spring/webmvc-config.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;    &lt;br /&gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;member-ws&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;member-ws&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;*.wsdl&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;member-web&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;/web/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this specific instance, all requests to /web/ is handled by the Spring MVC DispatcherServlet whereas all requests to /services is handled by Spring-WS DispatcherServlet. Further, each dispatcher servlet is configured with its custom Spring configuration file, the one for Spring MVC loads up the contollers, the one for Spring WS loads up the Webservice endpoints.  &lt;br /&gt;&lt;br /&gt;I am not sure if this is a optimal configuration, but it works for me in this project available at: git://github.com/bijukunjummen/memberservice-contractfirst.git&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OR An alternate way to hook up DispatcherServlet to handle Spring-WS requests is described here!: &lt;a href="http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e884"&gt;http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e884&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-994361371399841808?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/994361371399841808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=994361371399841808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/994361371399841808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/994361371399841808'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/06/supporting-spring-ws-and-spring-mvc.html' title='Supporting Spring-WS and Spring MVC integration in a project'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-1129930300213087259</id><published>2011-06-12T10:31:00.000-04:00</published><updated>2011-09-12T08:22:50.225-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='SBT'/><title type='text'>IntelliJ IDEA for Scala/SBT projects</title><content type='html'>I have found it easier to use &lt;a href="http://www.jetbrains.com/idea/"&gt;Intellij IDEA&lt;/a&gt; with &lt;a href="http://plugins.jetbrains.net/plugin/?id=1347"&gt;Scala plugins&lt;/a&gt;, for Scala learnings. This is the way I normally spin up a scala project.&lt;br /&gt;&lt;br /&gt;1. Use &lt;a href="http://code.google.com/p/simple-build-tool/"&gt;sbt &lt;/a&gt;to first create a shell of a project:&lt;br /&gt;&lt;pre&gt;D:\learn\shell-project&amp;gt;sbt&lt;br /&gt;&lt;br /&gt;D:\learn\shell-project&amp;gt;set SCRIPT_DIR=C:\util\sbt\&lt;br /&gt;&lt;br /&gt;D:\learn\shell-project&amp;gt;java -Xmx512M -jar "C:\util\sbt\sbt-launch-0.7.5.jar"&lt;br /&gt;Project does not exist, create new project? (y/N/s) y&lt;br /&gt;Name: shellproject&lt;br /&gt;Organization: org.bk&lt;br /&gt;......&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. Add eclipsify plugin - this is done by creating a sbt ProjectDefinition under project/plugins folder:&lt;br /&gt;&lt;pre class="brush:java"&gt;import sbt._&lt;br /&gt;&lt;br /&gt; class MySbtProjectPlugins(info: ProjectInfo) extends PluginDefinition(info) {&lt;br /&gt;       lazy val eclipse = "de.element34" % "sbt-eclipsify" % "0.7.0"&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3. Add scalatest to the dependency - this is done by creating a file of the following type under project/build folder:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;import sbt._&lt;br /&gt;import de.element34.sbteclipsify._&lt;br /&gt;&lt;br /&gt;class MySbtProject(info: ProjectInfo) extends DefaultProject(info) with Eclipsify {&lt;br /&gt;    override def libraryDependencies = Set(&lt;br /&gt;       "org.scalatest" % "scalatest" % "1.3" % "test-&amp;gt;default"&lt;br /&gt;    ) ++ super.libraryDependencies&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4. reload sbt(run "reload" in the sbt console)&lt;br /&gt;&lt;br /&gt;5. A new action "eclipse" should now be available. Run "eclipse"&lt;br /&gt;&lt;br /&gt;6. That's it. Now a new project should be available for IntelliJ idea to import as a project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-1129930300213087259?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/1129930300213087259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=1129930300213087259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1129930300213087259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1129930300213087259'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/06/intellij-idea-for-scalasbt-projects.html' title='IntelliJ IDEA for Scala/SBT projects'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6247507017016112345</id><published>2011-06-06T22:17:00.000-04:00</published><updated>2011-06-06T22:18:46.031-04:00</updated><title type='text'>Lucene Search on Numeric Long field</title><content type='html'>Something new to me, I have previously enabled Lucene search using pure text fields, but stumbled recently when trying to search using a Long field:&lt;pre class="brush:java"&gt;&lt;br /&gt;IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_30,  new StandardAnalyzer(Version.LUCENE_30));&lt;br /&gt;IndexWriter indexWriter = new IndexWriter(directory, indexConfig );&lt;br /&gt;&lt;br /&gt;Document doc = new Document();&lt;br /&gt;doc.add(new NumericField("id", Store.YES, true).setLongValue(123L));&lt;br /&gt;&lt;/pre&gt;and to search on this field:&lt;pre class="brush:java"&gt;&lt;br /&gt;IndexSearcher is = new IndexSearcher(dir);&lt;br /&gt;Query query = new TermQuery(new Term("id", NumericUtils.longToPrefixCoded(123L)));&lt;br /&gt;TopDocs hits = is.search(query, 10);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6247507017016112345?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6247507017016112345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6247507017016112345' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6247507017016112345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6247507017016112345'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/06/lucene-search-on-numeric-long-field.html' title='Lucene Search on Numeric Long field'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-2641629360900413735</id><published>2011-05-31T19:27:00.000-04:00</published><updated>2011-05-31T19:27:49.627-04:00</updated><title type='text'>Tower of Hanoi in Scala</title><content type='html'>Had a little fun with scala after 2 months, an &lt;a href="http://en.wikipedia.org/wiki/Tower_of_Hanoi"&gt;implementation of Tower of Hanoi&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush:scala"&gt;object Hanoi{&lt;br /&gt;    def move(n:Int, fromTower:String, toTower:String, usingTower:String):Unit = {&lt;br /&gt;        if (n==0) return&lt;br /&gt;        move(n-1, fromTower, usingTower, toTower);&lt;br /&gt;        println("Moving from " + fromTower + " to " + toTower)&lt;br /&gt;        move(n-1, usingTower, toTower, fromTower);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-2641629360900413735?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/2641629360900413735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=2641629360900413735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2641629360900413735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2641629360900413735'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/tower-of-hanoi-in-scala.html' title='Tower of Hanoi in Scala'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-3960955222738184388</id><published>2011-05-26T09:14:00.000-04:00</published><updated>2012-01-25T20:26:29.222-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IndyJug'/><title type='text'>Drools session at Indianapolis Java User Group</title><content type='html'>I attended a &lt;a href="http://www.jboss.org/drools"&gt;JBoss Drools&lt;/a&gt; session at the &lt;a href="http://www.indyjug.net/index.shtml"&gt;Indianapolis JUG&lt;/a&gt; yesterday evening. The session was presented by Ray Ploski, a Principal Solution Architect with Redhat.&lt;br /&gt;Ray went over the breadth of product offerings within the Drools Umbrella -&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Drools Expert(the Rule engine)&lt;/li&gt;&lt;li&gt;Drools Guvnor(Rules Hosting/Management)&lt;/li&gt;&lt;li&gt;Drools Fusion(Complex Event Processing)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Drools Planner(Planning)&lt;/li&gt;&lt;li&gt;Drools Flow(Process Flow)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;All these product offerings is together referred to as the "Drools Business Logic Integration Platform".&amp;nbsp;&lt;/div&gt;&lt;div&gt;I had gone into the meeting with the mistaken assumption that Drools is just a rule engine and came out &amp;nbsp;a little wiser.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some notes that I have from the meeting are the following:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Ray has hosted the presentation, samples at this location -&amp;nbsp;&lt;a href="http://bit.ly/cjug-drools-2011"&gt;http://bit.ly/cjug-drools-2011&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Drools Flow is being merged into jBPM5 - with support for Graphical process flows tightly integrated with Drools Expert.&lt;/li&gt;&lt;li&gt;Rules and other artifacts can be versioned within Guvnor - internally it uses JCR as the API for versioning with &lt;a href="http://jackrabbit.apache.org/"&gt;Jack Rabbit&lt;/a&gt; as the implementation&lt;/li&gt;&lt;li&gt;Java code can implement a pull based model, to pull in rules from Guvnor - at a specified schedule pull in the latest rules from Guvnor, thus reflecting the rule changes without needing to restart application&lt;/li&gt;&lt;li&gt;Drools Expert uses a MVEL dialect to express the condition(LHS) part of the rule&lt;/li&gt;&lt;li&gt;One of the largest Drools users has Million and a half rules defined!&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;PS: &lt;a href="http://www.e-gineering.com/"&gt;E-gineerin&lt;/a&gt;g hosted this meeting at their great new office location.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-3960955222738184388?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/3960955222738184388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=3960955222738184388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3960955222738184388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3960955222738184388'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/drools-session-at-indianapolis-java.html' title='Drools session at Indianapolis Java User Group'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-1090585745455528223</id><published>2011-05-25T11:31:00.000-04:00</published><updated>2011-05-25T11:31:42.165-04:00</updated><title type='text'>java.lang.ClassCastException: org.apache.cxf.transport.servlet.CXFServlet cannot be cast to javax.servlet.Servlet</title><content type='html'>I was getting this exception:&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;java.lang.ClassCastException: org.apache.cxf.transport.servlet.CXFServlet cannot be cast to javax.servlet.Servlet&lt;br /&gt;        at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1116)&lt;br /&gt;        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:993)&lt;br /&gt;        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4350)&lt;br /&gt;        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4659)&lt;br /&gt;        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)&lt;br /&gt;        at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)&lt;br /&gt;&lt;/pre&gt;when trying to start up Tomcat using maven command - &lt;pre&gt;mvn tomcat:run&lt;/pre&gt;on this application - &lt;pre&gt;git://github.com/bijukunjummen/memberservice-codefirst.git&lt;/pre&gt;It turns out that the issue is related to a dependency that CXF pulls in which conflicts with Tomcats version of Servlet class. The fix is to change the maven dependency from:&lt;pre class="brush:xml"&gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.apache.cxf&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;apache-cxf&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;${cxf.version}&amp;lt;/version&amp;gt;&lt;br /&gt;   &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;to the specific set of CXF libs:&lt;pre class="brush:xml"&gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.apache.cxf&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;cxf-rt-frontend-jaxws&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;${cxf.version}&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.apache.cxf&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;cxf-rt-transports-http&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;${cxf.version}&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.apache.cxf&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;cxf-rt-transports-http&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;${cxf.version}&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.apache.cxf&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;cxf-rt-ws-security&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;${cxf.version}&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;      &amp;lt;groupId&amp;gt;org.apache.ws.security&amp;lt;/groupId&amp;gt;&lt;br /&gt;      &amp;lt;artifactId&amp;gt;wss4j&amp;lt;/artifactId&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.6.0&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt; &lt;br /&gt;&lt;/pre&gt;Now &lt;pre&gt;mvn tomcat:run&lt;/pre&gt; should run through just fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-1090585745455528223?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/1090585745455528223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=1090585745455528223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1090585745455528223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1090585745455528223'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/javalangclasscastexception.html' title='java.lang.ClassCastException: org.apache.cxf.transport.servlet.CXFServlet cannot be cast to javax.servlet.Servlet'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-5516174463751446255</id><published>2011-05-22T20:47:00.000-04:00</published><updated>2011-09-12T08:23:47.172-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>Enabling WS-Security Username Token Profile for Apache CXF service</title><content type='html'>This article describes how to&lt;a href="http://biju-allandsundry.blogspot.com/2011/05/contract-first-and-code-first.html"&gt; create a code first webservice&lt;/a&gt;. I am going to extend the sample provided to support &lt;a href="http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf"&gt;WS-Security Username Token profile&lt;/a&gt;. It is a way for the callers of the service to prove their identity by providing username and a password.&lt;br /&gt;&lt;br /&gt;To recap the previous article, it is very simple to expose a code first webservice using Apache CXF with Spring. Apache CXF provides a custom Spring namespace to easily configure the endpoint:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"&lt;br /&gt; xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt; xmlns:jaxws="http://cxf.apache.org/jaxws"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&lt;br /&gt;        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd&lt;br /&gt;        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&lt;br /&gt;        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;import resource="classpath:META-INF/cxf/cxf.xml"/&amp;gt;&lt;br /&gt; &amp;lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/&amp;gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &amp;lt;bean id="memberendpoint" class="org.bk.memberservice.endpoint.DefaultMemberEndpoint"/&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;jaxws:endpoint address="/memberservice" id="memberservicehttp" implementor="#memberendpoint" &amp;gt;&lt;br /&gt; &amp;lt;/jaxws:endpoint&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This exposes the memberendpoint bean above as a fully configured webservice.&lt;br /&gt;&lt;br /&gt;To secure this service using usernametoken, first implement a callback for CXF to invoke to validate the credentials passed by the user:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.memberservice.endpoint;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.security.auth.callback.Callback;&lt;br /&gt;import javax.security.auth.callback.CallbackHandler;&lt;br /&gt;import javax.security.auth.callback.UnsupportedCallbackException;&lt;br /&gt;&lt;br /&gt;import org.apache.ws.security.WSPasswordCallback;&lt;br /&gt;&lt;br /&gt;public class UsernameTokenCallback implements CallbackHandler {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void handle(Callback[] callbacks) throws IOException,&lt;br /&gt;   UnsupportedCallbackException {&lt;br /&gt;  Callback callback = callbacks[0];&lt;br /&gt;  WSPasswordCallback pc = (WSPasswordCallback) callback;&lt;/pre&gt;&lt;pre class="brush:java"&gt;//              Retrieve and set the real password..which will be validated &lt;/pre&gt;&lt;pre class="brush:java"&gt;//              by CXF validator against the digest password&lt;/pre&gt;&lt;pre class="brush:java"&gt;pc.setPassword("test");&lt;br /&gt;  System.out.println("Received cred: " + pc.getIdentifier() + " : " + pc.getPassword());&lt;br /&gt;//  validate the credentials&lt;br /&gt;//              boolean isValid = true;&lt;br /&gt;//              throw IO Exception if the credentials are not valid&lt;br /&gt;//  if (!isValid) {&lt;br /&gt;//   throw new IOException("Bad Credentials");&lt;br /&gt;//  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To wire this Callback handler with the service endpoint, CXF uses a concept called the interceptor, basically the webservice call is handled by the interceptors before being handed over to the service.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;jaxws:endpoint address="/memberservice" id="memberservicehttp"&lt;br /&gt;  implementor="#memberendpoint"&amp;gt;&lt;br /&gt;  &amp;lt;jaxws:inInterceptors&amp;gt;&lt;br /&gt;   &amp;lt;bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"&amp;gt;&lt;br /&gt;    &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;     &amp;lt;map&amp;gt;&lt;br /&gt;      &amp;lt;entry key="action" value="UsernameToken" /&amp;gt;&lt;br /&gt;      &amp;lt;entry key="passwordType" value="PasswordDigest" /&amp;gt;&lt;br /&gt;      &amp;lt;entry key="passwordCallbackRef"&amp;gt;&lt;br /&gt;       &amp;lt;ref bean="usernameTokenCallback" /&amp;gt;&lt;br /&gt;      &amp;lt;/entry&amp;gt;&lt;br /&gt;     &amp;lt;/map&amp;gt;&lt;br /&gt;    &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;   &amp;lt;/bean&amp;gt;&lt;br /&gt;  &amp;lt;/jaxws:inInterceptors&amp;gt;&lt;br /&gt; &amp;lt;/jaxws:endpoint&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;That's it!! the endpoint is now secured using UsernameToken profile. To test this, bring up the endpoint, use SOAP UI to send a normal request, it will fail with the message that a ws-security header is required - this is the username token soap header that is expected as part of the request.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-7mU65k6LQ2M/Tdmjdx3SYbI/AAAAAAAAA8E/u4HQ6u658ao/s1600/SoapUiWithUserNameToken.GIF" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="365" src="http://4.bp.blogspot.com/-7mU65k6LQ2M/Tdmjdx3SYbI/AAAAAAAAA8E/u4HQ6u658ao/s640/SoapUiWithUserNameToken.GIF" width="640" /&gt;&lt;/a&gt;&amp;nbsp;Fix this by adding the username and password, select "digest" as the password type and the service invocation should just work.&lt;br /&gt;Updated Sample available at:&amp;nbsp;git://github.com/bijukunjummen/memberservice-codefirst.git&lt;br /&gt;Reference:&lt;br /&gt;1. WS-Security reference in Wikipedia:&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/WS-Security"&gt;http://en.wikipedia.org/wiki/WS-Security&lt;/a&gt;&lt;br /&gt;2. WS-Secuirty usernametoken profile specs at OASIS:&amp;nbsp;&lt;a href="http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf"&gt;http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf&lt;/a&gt;&lt;br /&gt;3. Apache CXF reference:&amp;nbsp;&lt;a href="http://cxf.apache.org/docs/ws-security.html"&gt;http://cxf.apache.org/docs/ws-security.html&lt;/a&gt;&lt;br /&gt;4. New changes as part of WSS4J -&amp;nbsp;&lt;a href="http://coheigea.blogspot.com/2011/02/wspasswordcallback-changes-in-wss4j-16.html"&gt;http://coheigea.blogspot.com/2011/02/wspasswordcallback-changes-in-wss4j-16.html&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-DOYXPM_-V3s/Tdms_viFXTI/AAAAAAAAA8I/y9ReWB2AYIY/s1600/SoapUiWithUserNameTokenDigest.GIF" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="330" src="http://2.bp.blogspot.com/-DOYXPM_-V3s/Tdms_viFXTI/AAAAAAAAA8I/y9ReWB2AYIY/s640/SoapUiWithUserNameTokenDigest.GIF" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-5516174463751446255?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/5516174463751446255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=5516174463751446255' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5516174463751446255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5516174463751446255'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/enabling-ws-security-username-token.html' title='Enabling WS-Security Username Token Profile for Apache CXF service'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-7mU65k6LQ2M/Tdmjdx3SYbI/AAAAAAAAA8E/u4HQ6u658ao/s72-c/SoapUiWithUserNameToken.GIF' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-9075154322444282013</id><published>2011-05-19T21:15:00.000-04:00</published><updated>2011-05-19T21:15:30.516-04:00</updated><title type='text'>Quick and Dirty fixtures for tests</title><content type='html'>This is a quick and dirty approach that I use to quickly add fixtures for a entity test, say if I am testing an entity of the following type:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@Entity&lt;br /&gt;@Table(name="gtdcontexts")&lt;br /&gt;public class GtdContext {&lt;br /&gt;    @Size(min = 1, max = 50)&lt;br /&gt;    private String name;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;In my test Spring context file, I have entries to instantiate beans of the type:&lt;br /&gt;&lt;pre class="brush:xml"&gt; &amp;lt;bean name="context1" class="org.bk.simplygtd.domain.GtdContext"  p:name="context1"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="context2" class="org.bk.simplygtd.domain.GtdContext"  p:name="context2"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="context3" class="org.bk.simplygtd.domain.GtdContext"  p:name="context3"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="context4" class="org.bk.simplygtd.domain.GtdContext"  p:name="context4"/&amp;gt;&lt;br /&gt;    &amp;lt;bean name="context5" class="org.bk.simplygtd.domain.GtdContext"  p:name="context5"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Now in my test class, I autowire in a Map in the following way:&lt;pre class="brush:java"&gt; &lt;br /&gt; @Autowired&lt;br /&gt; Map&amp;lt;String, GtdContext&amp;gt; gtdContextsMap;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Spring in this case autowires in all the GtdContexts instances into this Map, with the key as the bean name and the value being the instance. So now that the map is populated, a test embedded database can be populated with these fixtures:&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;jdbc:embedded-database type=&amp;quot;H2&amp;quot; id=&amp;quot;dataSource&amp;quot;&amp;gt;&amp;lt;/jdbc:embedded-database&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;  for (Map.Entry&amp;lt;String, GtdContext&amp;gt; entry:gtdContextsMap.entrySet()){&lt;br /&gt;   this.gtdContextDao.persist(entry.getValue());&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;That is it! an embedded h2 database with some sample entries will be ready for tests&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-9075154322444282013?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/9075154322444282013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=9075154322444282013' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/9075154322444282013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/9075154322444282013'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/quick-and-dirty-fixtures-for-tests.html' title='Quick and Dirty fixtures for tests'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6655664037368752514</id><published>2011-05-14T10:11:00.000-04:00</published><updated>2011-09-12T08:24:00.462-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>Sample Contract First Service using Spring-WS 2.0</title><content type='html'>I have now updated the sample for &lt;a href="http://java.dzone.com/articles/spring-ws-how"&gt;this article&lt;/a&gt;, to use Spring WS 2.0, which now provides a annotation based model for Webservice endpoints. The amount of configuration required to define a Webservice endpoint has reduced considerably between Spring WS 1.x and Spring WS 2.0 &amp;nbsp;- most of the routine boilerplate to define an endpoint has moved from configuration to an annotation: &lt;br /&gt;Whereas earlier, the endpoint would have been defined by a code of the following signature:  &lt;br /&gt;&lt;pre class="brush:java"&gt;public class GetMemberDetailsEndpoint extends&lt;br /&gt;  AbstractMarshallingPayloadEndpoint {&lt;br /&gt; private MemberManager memberManager;&lt;br /&gt; protected Object invokeInternal(Object requestObject) throws Exception {&lt;br /&gt;  MemberDetailsRequest request = (MemberDetailsRequest) requestObject;&lt;br /&gt;  MemberDetail memberDetail = memberManager.getMemberDetails(request&lt;br /&gt;    .getId());&lt;br /&gt;  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);&lt;br /&gt;  return response;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;......&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;With Spring-WS 2.0 the endpoint can be more intuitively defined with the following signature:  &lt;br /&gt;&lt;pre class="brush:java"&gt;@Endpoint&lt;br /&gt;public class GetMemberDetailsEndpoint {&lt;br /&gt;&lt;br /&gt; @Autowired private MemberManager memberManager;&lt;br /&gt;&lt;br /&gt; @PayloadRoot(namespace = "http://bk.org/memberservice/", localPart = "MemberDetailsRequest")&lt;br /&gt; @ResponsePayload&lt;br /&gt; public MemberDetailsResponse getMemberDetails(@RequestPayload MemberDetailsRequest request) throws Exception {&lt;br /&gt;  MemberDetail memberDetail = memberManager.getMemberDetails(request&lt;br /&gt;    .getId());&lt;br /&gt;  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);&lt;br /&gt;  return response;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;.....&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;Updated code available at:&lt;br /&gt;git://github.com/bijukunjummen/memberservice-contractfirst.git&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6655664037368752514?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6655664037368752514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6655664037368752514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6655664037368752514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6655664037368752514'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/sample-contract-first-service-using.html' title='Sample Contract First Service using Spring-WS 2.0'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8646706076674166970</id><published>2011-05-14T00:47:00.000-04:00</published><updated>2011-09-12T08:24:16.070-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-WS'/><title type='text'>Contract First and Code First Webservice Development</title><content type='html'>There are generally two styles for Webservice Development - Contract First and Code First.&lt;br /&gt;&lt;br /&gt;Contract First is an approach where the developer starts from defining a contract for the webservice using a WSDL and then goes about generating/developing the codebase - typically using stacks that allow code to be generated from the wsdl.&lt;br /&gt;&lt;br /&gt;Code First on the other hand is an approach where the developer starts by defining an interface, then generates the contract for the webservice using tools that allow translating an interface to wsdl.&lt;br /&gt;&lt;br /&gt;I have used both approaches now for different projects over time and but am not very opinionated about either of the approaches. A purist approach would be to start with the contract, which I have &lt;a href="http://java.dzone.com/articles/spring-ws-how"&gt;personally advocated&lt;/a&gt;&amp;nbsp;in the past, however in some real world projects I have tended to go with a code first approach, for a few reasons:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Good tool support is required to define a reasonably involved wsdl - Eclipse is not good enough to create a quality wsdl - I would recommend IBM RAD or &lt;a href="http://www.altova.com/xmlspy/wsdl-editor.html"&gt;XML Spy&lt;/a&gt; for creating wsdl's&lt;/li&gt;&lt;li&gt;A very deep knowledge of XML schema language is required to generate good constructs&lt;/li&gt;&lt;li&gt;Development time is generally slower - &amp;nbsp;as creating a wsdl takes a good amount of time&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Code First Approach on the other hand is quick. Let me illustrate by changing my &lt;a href="http://java.dzone.com/articles/spring-ws-how"&gt;DZone Example&lt;/a&gt;&amp;nbsp;which is a Contract First example to a Code First using &lt;a href="http://cxf.apache.org/"&gt;Apache CXF&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;The contract for the service was:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&amp;lt;wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ms="http://bk.org/memberservice/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="memberservice" targetNamespace="http://bk.org/memberservice/"&amp;gt;&lt;br /&gt; &amp;lt;wsdl:types&amp;gt;&lt;br /&gt;  &amp;lt;xsd:schema targetNamespace="http://bk.org/memberservice/" elementFormDefault="qualified"&amp;gt;&lt;br /&gt;   &amp;lt;xsd:complexType name="MemberDetailType"&amp;gt;&lt;br /&gt;    &amp;lt;xsd:sequence&amp;gt;&lt;br /&gt;     &amp;lt;xsd:element name="name" type="xsd:string"/&amp;gt;&lt;br /&gt;     &amp;lt;xsd:element name="phone" type="xsd:string"/&amp;gt;&lt;br /&gt;     &amp;lt;xsd:element name="city" type="xsd:string"/&amp;gt;&lt;br /&gt;     &amp;lt;xsd:element name="state" type="xsd:string"/&amp;gt;&lt;br /&gt;    &amp;lt;/xsd:sequence&amp;gt;&lt;br /&gt;   &amp;lt;/xsd:complexType&amp;gt;&lt;br /&gt;   &amp;lt;xsd:element name="MemberDetailsRequest"&amp;gt;&lt;br /&gt;    &amp;lt;xsd:complexType&amp;gt;&lt;br /&gt;     &amp;lt;xsd:sequence&amp;gt;&lt;br /&gt;      &amp;lt;xsd:element name="id" type="xsd:string"/&amp;gt;&lt;br /&gt;     &amp;lt;/xsd:sequence&amp;gt;&lt;br /&gt;    &amp;lt;/xsd:complexType&amp;gt;&lt;br /&gt;   &amp;lt;/xsd:element&amp;gt;&lt;br /&gt;   &amp;lt;xsd:element name="MemberDetailsResponse"&amp;gt;&lt;br /&gt;    &amp;lt;xsd:complexType&amp;gt;&lt;br /&gt;     &amp;lt;xsd:sequence&amp;gt;&lt;br /&gt;      &amp;lt;xsd:element name="memberdetail" type="ms:MemberDetailType"/&amp;gt;&lt;br /&gt;     &amp;lt;/xsd:sequence&amp;gt;&lt;br /&gt;    &amp;lt;/xsd:complexType&amp;gt;&lt;br /&gt;   &amp;lt;/xsd:element&amp;gt;&lt;br /&gt;  &amp;lt;/xsd:schema&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:types&amp;gt;&lt;br /&gt; &amp;lt;wsdl:message name="MemberDetailsRequest"&amp;gt;&lt;br /&gt;  &amp;lt;wsdl:part element="ms:MemberDetailsRequest" name="parameters"/&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt; &amp;lt;wsdl:message name="MemberDetailsResponse"&amp;gt;&lt;br /&gt;  &amp;lt;wsdl:part element="ms:MemberDetailsResponse" name="parameters"/&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt; &amp;lt;wsdl:portType name="memberservice"&amp;gt;&lt;br /&gt;  &amp;lt;wsdl:operation name="GetMemberDetails"&amp;gt;&lt;br /&gt;   &amp;lt;wsdl:input message="ms:MemberDetailsRequest"/&amp;gt;&lt;br /&gt;   &amp;lt;wsdl:output message="ms:MemberDetailsResponse"/&amp;gt;&lt;br /&gt;  &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:portType&amp;gt;&lt;br /&gt; &amp;lt;wsdl:binding name="memberserviceSOAP" type="ms:memberservice"&amp;gt;&lt;br /&gt;  &amp;lt;soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/&amp;gt;&lt;br /&gt;  &amp;lt;wsdl:operation name="GetMemberDetails"&amp;gt;&lt;br /&gt;   &amp;lt;soap:operation soapAction="http://bk.org/memberservice/GetMemberDetails"/&amp;gt;&lt;br /&gt;   &amp;lt;wsdl:input&amp;gt;&lt;br /&gt;    &amp;lt;soap:body use="literal"/&amp;gt;&lt;br /&gt;   &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;   &amp;lt;wsdl:output&amp;gt;&lt;br /&gt;    &amp;lt;soap:body use="literal"/&amp;gt;&lt;br /&gt;   &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;  &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:binding&amp;gt;&lt;br /&gt; &amp;lt;wsdl:service name="memberservice"&amp;gt;&lt;br /&gt;  &amp;lt;wsdl:port binding="ms:memberserviceSOAP" name="memberserviceSOAP"&amp;gt;&lt;br /&gt;   &amp;lt;soap:address location="http://localhost:8081/memberservice/services/MemberDetailsRequest"/&amp;gt;&lt;br /&gt;  &amp;lt;/wsdl:port&amp;gt;&lt;br /&gt; &amp;lt;/wsdl:service&amp;gt;&lt;br /&gt;&amp;lt;/wsdl:definitions&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let us start by defining a java interface that can sufficiently mimic this WSDL:&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.memberservice.endpoint;&lt;br /&gt;&lt;br /&gt;import javax.jws.WebMethod;&lt;br /&gt;import javax.jws.WebParam;&lt;br /&gt;import javax.jws.WebResult;&lt;br /&gt;import javax.jws.WebService;&lt;br /&gt;&lt;br /&gt;import org.bk.memberservice.message.MemberDetailsRequest;&lt;br /&gt;import org.bk.memberservice.message.MemberDetailsResponse;&lt;br /&gt;&lt;br /&gt;@WebService&lt;br /&gt;public interface MemberEndpoint {&lt;br /&gt; @WebMethod(operationName = "MemberDetailsRequest")&lt;br /&gt; @WebResult(name = "MemberDetailsResponse", targetNamespace = "http://bk.org/memberservice/")&lt;br /&gt; MemberDetailsResponse getMemberDetails(&lt;br /&gt;   @WebParam(name = "MemberDetailsRequest") MemberDetailsRequest memberDetailsRequest);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the JAXB2 annotations on the request and response types:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.bk.memberservice.message;&lt;br /&gt;&lt;br /&gt;import javax.xml.bind.annotation.XmlAccessType;&lt;br /&gt;import javax.xml.bind.annotation.XmlAccessorType;&lt;br /&gt;import javax.xml.bind.annotation.XmlRootElement;&lt;br /&gt;&lt;br /&gt;@XmlAccessorType(XmlAccessType.FIELD)&lt;br /&gt;@XmlRootElement(name = "MemberDetailsRequest", namespace="http://bk.org/memberservice/")&lt;br /&gt;public class MemberDetailsRequest {&lt;br /&gt;&lt;br /&gt; public MemberDetailsRequest() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public MemberDetailsRequest(String id) {&lt;br /&gt;  this.id = id;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private String id;&lt;br /&gt;&lt;br /&gt; public String getId() {&lt;br /&gt;  return id;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setId(String id) {&lt;br /&gt;  this.id = id;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="brush:java"&gt;package org.bk.memberservice.message;&lt;br /&gt;&lt;br /&gt;import javax.xml.bind.annotation.XmlAccessType;&lt;br /&gt;import javax.xml.bind.annotation.XmlAccessorType;&lt;br /&gt;import javax.xml.bind.annotation.XmlElement;&lt;br /&gt;import javax.xml.bind.annotation.XmlRootElement;&lt;br /&gt;&lt;br /&gt;import org.bk.memberservice.types.MemberDetail;&lt;br /&gt;&lt;br /&gt;@XmlAccessorType(XmlAccessType.FIELD)&lt;br /&gt;@XmlRootElement(name = "MemberDetailsResponse", namespace="http://bk.org/memberservice/")&lt;br /&gt;public class MemberDetailsResponse {&lt;br /&gt;&lt;br /&gt; public MemberDetailsResponse() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @XmlElement(name="memberdetail", namespace="http://bk.org/memberservice/")&lt;br /&gt; private MemberDetail memberDetail;&lt;br /&gt;&lt;br /&gt; public MemberDetailsResponse(MemberDetail memberDetail) {&lt;br /&gt;  this.memberDetail = memberDetail;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public MemberDetail getMemberDetail() {&lt;br /&gt;  return memberDetail;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setMemberDetail(MemberDetail memberDetail) {&lt;br /&gt;  this.memberDetail = memberDetail;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This generates a wsdl fairly close to the manually generated one, but not quite there - there does not seem to be a good way of controlling the namespace of operation name, and the wrappers around the request and the response xml structures.&lt;br /&gt;&lt;br /&gt;So considering these factors, a rule that I have used is:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If a service is consumed only by a known internal client(say for cases where the same team is the producer AND the consumer) then go for code first, for the speed of development&lt;/li&gt;&lt;li&gt;If a service is expected to be more widely used, then go for contract first, with careful wsdl design&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Sample code used here is available at :&lt;br /&gt;git://github.com/bijukunjummen/memberservice-codefirst.git&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8646706076674166970?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8646706076674166970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8646706076674166970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8646706076674166970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8646706076674166970'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/contract-first-and-code-first.html' title='Contract First and Code First Webservice Development'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-4091863300474857170</id><published>2011-05-05T20:09:00.000-04:00</published><updated>2011-05-05T20:09:19.493-04:00</updated><title type='text'>Layered vs Big Ball of Mud</title><content type='html'>&lt;br /&gt;&lt;div class="MsoNormal"&gt;Layered arch vs &lt;a href="http://www.laputan.org/mud/mud.html#BigBallOfMud"&gt;Big Ball Of Mud&lt;/a&gt;:&amp;nbsp;&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .25in; mso-list: l0 level1 lfo1; tab-stops: list .25in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Separationof concerns -&amp;nbsp; Each layer encapsulates distinct functions –eg Presentation, Business Logic, Data Access in traditional three-tiered architecture. &lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .75in; mso-list: l0 level2 lfo1; tab-stops: list .75in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Ifmultiple presentation technology needs to be supported – say Mobile and Webbased views, only the presentation tier is affected&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .75in; mso-list: l0 level2 lfo1; tab-stops: list .75in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Ifa different kind of data access pattern needs to be supported – say Memcachebased caching, only the data tier is affected&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .25in; mso-list: l0 level1 lfo1; tab-stops: list .25in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;AllowsReuse – lower layers can be re-used by the layers above it.&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .25in; mso-list: l0 level1 lfo1; tab-stops: list .25in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Testability– Each layer can be tested independently. &lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .25in; mso-list: l0 level1 lfo1; tab-stops: list .25in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Maintainable– if view breaks, look in the presentation tier. If data seems wrong, look inthe data access tier, if business logic seems wrong, look at the business tier&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: .25in; mso-list: l0 level1 lfo1; tab-stops: list .25in; text-indent: -.25in;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings;"&gt;&lt;span style="mso-list: Ignore;"&gt;§&lt;span style="font: 7.0pt &amp;quot;Times New Roman&amp;quot;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;FostersDeveloper specialization – UI developers looking at Presentation layer&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-4091863300474857170?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/4091863300474857170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=4091863300474857170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4091863300474857170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4091863300474857170'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/layered-vs-big-ball-of-mud.html' title='Layered vs Big Ball of Mud'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-2691837173956347243</id><published>2011-05-01T13:06:00.000-04:00</published><updated>2011-05-14T13:45:23.127-04:00</updated><title type='text'>Learning - How do you learn a new technology area</title><content type='html'>This is the way I ( or for that matter anyone!) picks up a new technology area - a representation using &lt;a href="http://www.simplediagrams.com/"&gt;Simplediagrams&lt;/a&gt;&amp;nbsp;:&lt;br /&gt;&lt;br /&gt;Say I am learning something about the new version of Spring Core -&lt;br /&gt;I would first download Spring Core, play around with the reference applications(the "10 minute test"), try my own application by copying the reference and trying out more variations, until one day I can claim a level of expertise!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-U5lDQPsTWxI/Tb2Se-QJBiI/AAAAAAAAA7s/fTl8f0G3LxM/s1600/NewTech.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="277" src="http://4.bp.blogspot.com/-U5lDQPsTWxI/Tb2Se-QJBiI/AAAAAAAAA7s/fTl8f0G3LxM/s400/NewTech.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-2691837173956347243?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/2691837173956347243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=2691837173956347243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2691837173956347243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2691837173956347243'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/05/learning-how-do-you-learn-new.html' title='Learning - How do you learn a new technology area'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-U5lDQPsTWxI/Tb2Se-QJBiI/AAAAAAAAA7s/fTl8f0G3LxM/s72-c/NewTech.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-7100582547027166023</id><published>2011-02-05T21:23:00.000-05:00</published><updated>2011-05-14T13:47:22.525-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='STS'/><title type='text'>STS Graph view for Spring Integration Configuration</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The Spring Integration Graph View packaged with &lt;a href="http://www.springsource.com/developer/sts"&gt;Spring Source Tool Suite (STS 2.5.2.RELEASE)&lt;/a&gt; is brilliant.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The xml configuration for Spring Integration tends to get a little involved over time, the graphical view helps with visualizing the configuration well. Any high level gaps - no listener on a channel etc(bridge to nowhere?) will stand out in the graphical view -&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_qhxEfsM90zs/TU4D0FTOHOI/AAAAAAAAA6E/UcKBNpymYmI/s1600/SpringIntegrationGraphView.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="215" src="http://3.bp.blogspot.com/_qhxEfsM90zs/TU4D0FTOHOI/AAAAAAAAA6E/UcKBNpymYmI/s400/SpringIntegrationGraphView.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I have faced one issue though and I have heard of one other in the forums:&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;If I compose multiple flows into a single Spring configuration file (using import tags), the Graphical view cannot display the composed flow.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Different Spring Integration components can be created using annotations - these are also not reflected in the Visual view.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-7100582547027166023?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/7100582547027166023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=7100582547027166023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7100582547027166023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/7100582547027166023'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/02/spring-integration-graph-view-packaged.html' title='STS Graph view for Spring Integration Configuration'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_qhxEfsM90zs/TU4D0FTOHOI/AAAAAAAAA6E/UcKBNpymYmI/s72-c/SpringIntegrationGraphView.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-607742127312951929</id><published>2011-01-24T14:53:00.000-05:00</published><updated>2011-01-24T14:58:07.598-05:00</updated><title type='text'>org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for http://schemas.xmlsoap.org/wsdl/soap/</title><content type='html'>If you see the following at runtime:&lt;pre class="brush: java"&gt;org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for http://schemas.xmlsoap.org/wsdl/soap/&lt;br /&gt;&lt;/pre&gt;add the following spring resources in your Spring context file:&lt;pre class="brush: xml"&gt;&lt;br /&gt; &amp;lt;import resource=&amp;quot;classpath:META-INF/cxf/cxf.xml&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;import resource=&amp;quot;classpath:META-INF/cxf/cxf-extension-http.xml&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;import resource=&amp;quot;classpath:META-INF/cxf/cxf-extension-soap.xml&amp;quot; /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-607742127312951929?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/607742127312951929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=607742127312951929' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/607742127312951929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/607742127312951929'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/01/orgapachecxfservicefactoryserviceconstr.html' title='org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for http://schemas.xmlsoap.org/wsdl/soap/'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-3867939043348376767</id><published>2011-01-24T12:31:00.000-05:00</published><updated>2011-01-24T13:09:17.445-05:00</updated><title type='text'>Gradle JDK 1.6 source compatibility</title><content type='html'>To configure JDK 1.6 compatibility in the generated eclipse JDT preferences file using gradle, add this to the build.gradle file:&lt;pre&gt;eclipseJdt{&lt;br /&gt; whenConfigured { domain -&amp;gt;&lt;br /&gt;  domain.sourceCompatibility=org.gradle.api.JavaVersion.toVersion("1.6")&lt;br /&gt;  domain.targetCompatibility=org.gradle.api.JavaVersion.toVersion("1.6")&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Or something simpler, add the following to the build.gradle file:&lt;pre&gt;&lt;br /&gt;sourceCompatibility=1.6&lt;br /&gt;targetCompatibility=1.6&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-3867939043348376767?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/3867939043348376767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=3867939043348376767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3867939043348376767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/3867939043348376767'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2011/01/to-configure-jdk-1.html' title='Gradle JDK 1.6 source compatibility'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8665949285449072245</id><published>2010-09-12T18:42:00.000-04:00</published><updated>2011-09-12T08:24:35.911-04:00</updated><title type='text'>Karate Chop - An Imperative and Functional implementation</title><content type='html'>&lt;a href="http://codekata.pragprog.com/2007/01/kata_two_karate.html"&gt;Karate Chop&lt;/a&gt; is a Kata about implementing binary search five different ways. I could come up with 2 obvious ways - an imperative style with iteration and a functional style based on the solution inspired by &lt;a href="http://rosettacode.org/wiki/Binary_search#Scala"&gt;this site&amp;nbsp;&lt;/a&gt;. So here goes:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Imperative:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java"&gt;package org.bk.karatechop&lt;br /&gt;&lt;br /&gt;class KarateChop {&lt;br /&gt; def chop(aNumber:Int, anArray:Array[Int]):Int = {&lt;br /&gt;  var minIndex=0&lt;br /&gt;  var maxIndex = anArray.length-1&lt;br /&gt;  while(minIndex&amp;lt;=maxIndex){&lt;br /&gt;   var midIndex = (minIndex+maxIndex)/2&lt;br /&gt;   var atMidIndex = anArray(midIndex)&lt;br /&gt;   if (aNumber&amp;gt;atMidIndex){&lt;br /&gt;    minIndex=midIndex+1&lt;br /&gt;   }else if(aNumber&amp;lt;atMidIndex){&lt;br /&gt;    maxIndex=midIndex-1&lt;br /&gt;   }else{&lt;br /&gt;    return midIndex&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  -1&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Functional:&amp;nbsp;&lt;/div&gt;&lt;pre class="brush: java"&gt;package org.bk.karatechop&lt;br /&gt;&lt;br /&gt;class KarateChopRecursive {&lt;br /&gt; def chop(aNumber:Int, anArray:Array[Int]):Int = {&lt;br /&gt;  &lt;br /&gt;  def recurse(low:Int, high:Int):Option[Int] = { &lt;br /&gt;   (low + high)/2 match {&lt;br /&gt;    case _ if high &amp;lt; low =&amp;gt; None&lt;br /&gt;    case mid if aNumber &amp;lt; anArray(mid)  =&amp;gt; recurse(low, mid - 1)&lt;br /&gt;    case mid if aNumber &amp;gt; anArray(mid)  =&amp;gt; recurse(mid + 1, high)&lt;br /&gt;    case mid =&amp;gt; Some(mid)&lt;br /&gt;   }   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  recurse(0,anArray.length-1).getOrElse(-1)&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8665949285449072245?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8665949285449072245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8665949285449072245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8665949285449072245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8665949285449072245'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2010/09/karate-chop-imperative-and-functional.html' title='Karate Chop - An Imperative and Functional implementation'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6398912538335532480</id><published>2010-09-07T11:42:00.000-04:00</published><updated>2010-09-07T12:03:10.414-04:00</updated><title type='text'>Perfect Number implementation using Scala Actor, Spring Integration, Java Executors, Kilim based Actor</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A Simple non-threaded (and non-optimized) java implementation for figuring out if a number is a &lt;a href="http://en.wikipedia.org/wiki/Perfect_number"&gt;perfect number&lt;/a&gt; is the following:&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java"&gt;public class SimplePerfectNumberUtil implements PerfectNumberUtil{&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public boolean isPerfect(int aNumber) {&lt;br /&gt;  return sumOfFactors(aNumber)==2*aNumber;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt; private int sumOfFactors(int aNumber){&lt;br /&gt;  int sum = 0;&lt;br /&gt;  for (int i=1;i&amp;lt;=aNumber;i++){&lt;br /&gt;   if (aNumber%i==0){&lt;br /&gt;    sum+=i;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return sum;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;div style="font-family: 'Times New Roman'; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;a href="http://pragprog.com/titles/vsscala/programming-scala"&gt;Programming Scala&lt;/a&gt;&amp;nbsp;book provides a sample scala actor implementation for this by breaking up the task of determining whether a large number is a perfect number by&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;breaking up the large number into a range of smaller numbers - eg. a number like 3000 can be split up into say 0-1000, 1001-2000, 2001-3000, with a task responsible for summing up the factors in each of these ranges and summing up the result.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: 'Times New Roman'; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: 'Times New Roman'; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A slightly modified implementation based on the Programming Scala book is the following:&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;class PerfectUtilScala {&lt;br /&gt;&lt;br /&gt;  def isPerfect(candidate: Int) = {&lt;br /&gt;    val RANGE = 10000000&lt;br /&gt;    val numberOfPartitions = (candidate.toDouble / RANGE).ceil.toInt&lt;br /&gt;    val caller = self&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    val sumoffactorsActor = actor{&lt;br /&gt;     loop {&lt;br /&gt;      react {&lt;br /&gt;    case msg:FactorsRangeForCandidate =&amp;gt;&lt;br /&gt;     caller ! sumOfFactorsInRange(msg.lower, msg.upper, msg.candidate)&lt;br /&gt;   }  &lt;br /&gt;  } &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    for (i &amp;lt;- 0 until numberOfPartitions) {&lt;br /&gt;      val lower = i * RANGE + 1;&lt;br /&gt;      val upper = candidate min (i + 1) * RANGE&lt;br /&gt;      &lt;br /&gt;      sumoffactorsActor ! new FactorsRangeForCandidate(lower, upper, candidate)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val sum = (0 /: (0 until numberOfPartitions)) { (partialSum, i) =&amp;gt;&lt;br /&gt;      receive {&lt;br /&gt;        case sumInRange: Int =&amp;gt; partialSum + sumInRange&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    2 * candidate == sum&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private def sumOfFactorsInRange(lower: Int, upper: Int, number: Int) = {&lt;br /&gt;    (0 /: (lower to upper)) { (sum, i) =&amp;gt; if (number % i == 0) sum + i else sum }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class FactorsRangeForCandidate(val lower:Int, val upper:Int, val candidate:Int)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A Java Executors based implementation is the following:&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ThreadPoolPerfectNumberUtil implements PerfectNumberUtil{ &lt;br /&gt; private ExecutorService threadpool = Executors.newFixedThreadPool(3);&lt;br /&gt; @SuppressWarnings("unchecked")&lt;br /&gt;    public boolean isPerfect(int aNumber) {&lt;br /&gt;     int RANGE = Constants.RANGE;&lt;br /&gt;     int numberOfPartitions = new Double(Math.ceil(aNumber * 1.0 / RANGE)).intValue();&lt;br /&gt;     Future&lt;integer&gt;[] sumOfFactors = new Future[numberOfPartitions];&lt;br /&gt;     &lt;br /&gt;     for (int i=0;i&lt;numberofpartitions;i++) (anumber="" *="" +="" 1;="" if="" int="" lower="i" range;="" range="" upper="(i+1)*" {=""&gt;&lt;upper) (exception="" (int="" (sum="=2*aNumber)" +="sumOfFactors[i].get();" callable="" catch="" class="" e)="" false;="" for="" i="0;i&amp;lt;numberOfPartitions;i++)" if="" implements="" int="" new="" return="" runtimeexception(e);="" sum="0;" sumoffactors[i]="threadpool.submit(new" sumoffactorstask(lower,upper,anumber));="" sumoffactorstask="" throw="" true;="" try="" upper="aNumber;" {="" }=""&gt;&lt;integer&gt;{&lt;br /&gt;&lt;br /&gt; private final int lower;&lt;br /&gt; private final int upper;&lt;br /&gt; private final int anumber;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; public SumOfFactorsTask(int lower, int upper, int anumber){&lt;br /&gt;  this.lower = lower;&lt;br /&gt;  this.upper = upper;&lt;br /&gt;  this.anumber = anumber;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt;    public Integer call() {&lt;br /&gt;  int sum=0;&lt;br /&gt;  for (int i=lower;i&amp;lt;=upper;i++){&lt;br /&gt;   if (anumber%i==0){&lt;br /&gt;    sum+=i;&lt;br /&gt;   }&lt;br /&gt;  }  &lt;br /&gt;  &lt;br /&gt;  return sum;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/integer&gt;&lt;/upper)&gt;&lt;/numberofpartitions;i++)&gt;&lt;/integer&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;And a &lt;a href="http://www.malhar.net/sriram/kilim/"&gt;Kilim&lt;/a&gt; based actor implementation:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ActorsPerfectNumberUtil extends Task implements PerfectNumberUtil {&lt;br /&gt;&lt;br /&gt; private Mailbox&lt;factorsrange&gt; mailbox;&lt;br /&gt; private Mailbox&lt;integer&gt; resultmailbox;&lt;br /&gt; private SumOfFactorsActor sumOfFactors;&lt;br /&gt;&lt;br /&gt; public ActorsPerfectNumberUtil() {&lt;br /&gt;  mailbox = new Mailbox&lt;factorsrange&gt;();&lt;br /&gt;  resultmailbox = new Mailbox&lt;integer&gt;();&lt;br /&gt;  sumOfFactors = new SumOfFactorsActor(mailbox, resultmailbox);&lt;br /&gt;  sumOfFactors.start();&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isPerfect(int aNumber) {&lt;br /&gt;  int RANGE = Constants.RANGE;&lt;br /&gt;  int numberOfPartitions = new Double(Math.ceil(aNumber * 1.0 / RANGE)).intValue();&lt;br /&gt;&lt;br /&gt;  for (int i = 0; i &amp;lt; numberOfPartitions; i++) {&lt;br /&gt;   int lower = i * RANGE + 1;&lt;br /&gt;   int upper = (i + 1) * RANGE;&lt;br /&gt;   if (aNumber &amp;lt; upper)&lt;br /&gt;    upper = aNumber;&lt;br /&gt;   mailbox.putnb(new FactorsRange(lower, upper, aNumber));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  int sum = 0;&lt;br /&gt;  for (int i = 0; i &amp;lt; numberOfPartitions; i++) {&lt;br /&gt;    sum += resultmailbox.getb();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (sum == 2*aNumber)&lt;br /&gt;   return true;&lt;br /&gt;&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/integer&gt;&lt;/factorsrange&gt;&lt;/integer&gt;&lt;/factorsrange&gt;&lt;/pre&gt;The codebase along with the Spring Integration based implementation is available at this Git location:&lt;br /&gt;&lt;pre&gt;git://github.com/bijukunjummen/Perfect-Number.git&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6398912538335532480?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6398912538335532480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6398912538335532480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6398912538335532480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6398912538335532480'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2010/09/perfect-number-implementation-using.html' title='Perfect Number implementation using Scala Actor, Spring Integration, Java Executors, Kilim based Actor'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6199992036535730995</id><published>2010-01-30T15:58:00.000-05:00</published><updated>2010-02-01T23:06:58.102-05:00</updated><title type='text'>Windows 7 and Ubuntu - My perspective</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A screenshot of my desktop under Ubuntu:&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_qhxEfsM90zs/S2SdLIl16vI/AAAAAAAAA0Y/6YgoEaOmqPQ/s1600-h/Ubuntu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;img border="0" height="360" src="http://4.bp.blogspot.com/_qhxEfsM90zs/S2SdLIl16vI/AAAAAAAAA0Y/6YgoEaOmqPQ/s640/Ubuntu.png" width="640" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;and, a screenshot of the similar set of applications in Windows 7:&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_qhxEfsM90zs/S2SdZV3y7tI/AAAAAAAAA0g/oNYKc6S7r2s/s1600-h/Windows.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;img border="0" height="360" src="http://2.bp.blogspot.com/_qhxEfsM90zs/S2SdZV3y7tI/AAAAAAAAA0g/oNYKc6S7r2s/s640/Windows.PNG" width="640" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A constant battle that plays out everyday in my mind - to use Ubuntu or Windows as my primary development box&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I use both interchangeably in my dual boot laptop, most of my work related files is kept in a shared partition, this way I can use either Ubuntu or Windows any time. I could use a virtual machine hosting Windows or Ubuntu but I don't like the idea of allocating a good chunk of resources to run a Virtual machine in my "not a high end" laptop.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I will continue to use both for the&amp;nbsp;foreseeable future, the following is just an attempt to list down the specific reasons why I like/hate Ubuntu and Windows and prevents me from sticking to one or the other:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;What do &lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt; really love about Ubuntu:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The super clean desktop, once I have changed the default Ubuntu look by adjusting the DPI settings using this article(https://wiki.ubuntu.com/X/Troubleshooting/HugeFonts) and changed the theme to Murrina Gilouche(http://gnome-look.org/content/show.php/MurrinaGilouche?content=44510)&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Terminal - For controlling the small scripts that I have &amp;nbsp;- to start subversion, confluence, bamboo, run maven scripts&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Package Management tools - Synaptic, aptitude and apt-get make software install a cinch.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;What do &lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt; really hate about Ubuntu:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Lack of a good pdf reader plugin support in Google Chrome/Firefox. &amp;nbsp;I know Adobe provides a pdf reader for Linux but it does not work well with Google Chrome/Firefox&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Lack of ITunes port for Linux. Yes there is Rhythmbox, but it does not for some reason synch my iPod Nano.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Picasa - I know a port using Wine is available, but I would have preferred a native version.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Flash experience is buggy - It works but there are bugs - for eg, I have issues in watching videos in full screen mode at TED, if I go into a fullscreen mode there are times when I hear the sound but no window.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Java applications like Netbeans, JEdit with default look and feel(typically Metal) look very bad in Ubuntu, if the L&amp;amp;F is changed to GTK then it is passable.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Hibernate and Resume is very slow(order of minutes) in Ubuntu.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;What do&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&amp;nbsp;really love about Windows:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Default Windows Aero based desktop is very clean and I like the new taskbar in Windows 7&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Flash, Pdf Reader(and plugin!), Itunes, Picasa work well on Windows&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Office suite - some of my work related documents does not open up correctly using Open office, and there is no equivalent of Visio in Open office.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Very fast Hibernate and Resume&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;What do&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&amp;nbsp;really hate about Windows:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The command shell and Powershell are not as good and intuitive as the Linux terminal(tab completion, color support etc). Yes there is Cygwin, but I do have problems in some applications related to the different way paths are handled(forward vs backward slash and the default "Program Files" space resolution)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6199992036535730995?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6199992036535730995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6199992036535730995' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6199992036535730995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6199992036535730995'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2010/01/windows-7-and-ubuntu.html' title='Windows 7 and Ubuntu - My perspective'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_qhxEfsM90zs/S2SdLIl16vI/AAAAAAAAA0Y/6YgoEaOmqPQ/s72-c/Ubuntu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-4473201892737132244</id><published>2009-12-29T20:25:00.000-05:00</published><updated>2009-12-31T19:06:31.239-05:00</updated><title type='text'>Spring Integration and Apache Camel</title><content type='html'>&lt;h2&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Spring Integration and Apache Camel are open source frameworks providing a simpler solution for the Integration problems in the enterprise, to quote from their respective websites:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Apache Camel -&lt;/p&gt;&lt;blockquote&gt;Apache Camel is a powerful open source integration framework based on known Enterprise Integration Patterns with powerful Bean Integration.&lt;/blockquote&gt;&lt;br /&gt;Spring Integration -&lt;blockquote&gt;It provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns while building on the Spring Framework's existing support for enterprise integration.&lt;/blockquote&gt;&lt;p&gt;Essentially Spring Integration and Apache Camel enable applications to integrate with other systems. &lt;/p&gt;&lt;p&gt;This article seeks to provide an implementation for an integration problem using both Spring Integration and Apache Camel. The objective is to show how easy it is to use these frameworks for a fairly complicated integration problem and to recommend either of these great products for your next Integration challenge.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Problem:&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;To illustrate the use of these frameworks consider a simple integration scenario, described using EIP terminology:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center"&gt;&lt;a style="margin-left: 1em; margin-right: 1em" href="EIPFlowForArticleV2.gif"&gt;&lt;img src="http://java.dzone.com/sites/all/files/EIPFlowForArticleV2.gif" border="0" alt="" width="657" height="295" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;The application needs to get a &amp;quot;Report&amp;quot; by aggregating &amp;quot;Sections&amp;quot; from a Section XML over http service. Each request for Report consists of a set of request for sections – in this specific example there are requests for three sections, the header, body and footer. The XML over http service returns a Section for the Section Request. The responses need to be aggregated into a single report.A sample test for this scenario is of the following type:&lt;/p&gt;&lt;pre class="brush: java"&gt;        ReportGenerator reportGenerator = reportGeneratorFactory.createReportGenerator();&lt;br /&gt;        List&amp;lt;SectionRequest&amp;gt; sectionRequests = new ArrayList&amp;lt;SectionRequest&amp;gt;();&lt;br /&gt;        &lt;br /&gt;        String entityId=&amp;quot;A Company&amp;quot;;&lt;br /&gt;        &lt;br /&gt;        sectionRequests.add(new SectionRequest(entityId,&amp;quot;header&amp;quot;));&lt;br /&gt;        sectionRequests.add(new SectionRequest(entityId,&amp;quot;body&amp;quot;));&lt;br /&gt;        sectionRequests.add(new SectionRequest(entityId,&amp;quot;footer&amp;quot;));        &lt;br /&gt;&lt;br /&gt;        ReportRequest reportRequest = new ReportRequest(sectionRequests);&lt;br /&gt;&lt;br /&gt;        Report report = reportGenerator.generateReport(reportRequest);&lt;br /&gt;        List&amp;lt;Section&amp;gt; sectionOfReport = report.getSections();&lt;br /&gt;        System.out.println(report);&lt;br /&gt;        assertEquals(3, sectionOfReport.size());&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The “ReportGenerator” is the messaging gateway, hiding the details of the underlying messaging infrastructure and in this specific case also the integration API – Apache Camel or Spring Integration.To start with, let us implement a solution to this integration problem using Spring Integration as the Framework, followed by Apache Camel. The complete working code using Spring Integration and Apache Camel is also available with the article.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;!--pagebreak--&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Solution Using Spring Integration:&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The Gateway component is easily configured using the following entry in the Spring Configuration. Internally Spring Integration uses AOP to hook up a component which routes the requests from an internal input channel and waits for the response in the response channel.&lt;/p&gt;&lt;pre class="brush: java"&gt;&amp;lt;si:gateway default-reply-channel=&amp;quot;exit&amp;quot; default-request-channel=&amp;quot;enter&amp;quot; id=&amp;quot;reportGenerator&amp;quot; service-interface=&amp;quot;org.bk.report.ReportGenerator&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/si:gateway&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The component to Split the Input Report Request to Section Request is fairly straightforward:&lt;pre class="brush: java"&gt;public class SectionRequestSplitter {    &lt;br /&gt;    public List split(ReportRequest reportRequest){&lt;br /&gt;        return reportRequest.getSectionRequests();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and to hook this splitter with Spring Integration:&lt;pre class="brush: java"&gt;&amp;lt;bean class=&amp;quot;org.bk.report.common.SectionRequestSplitter&amp;quot; id=&amp;quot;sectionRequestSplitterBean&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;si:splitter id=&amp;quot;sectionRequestSplitter&amp;quot; input-channel=&amp;quot;enter&amp;quot; method=&amp;quot;split&amp;quot; output-channel=&amp;quot;sectionRequestToXMLChannel&amp;quot; ref=&amp;quot;sectionRequestSplitterBean&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/si:splitter&amp;gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;Next, to transform the Section Request to an XML format - The component is the following:&lt;pre class="brush: java"&gt;public class SectionRequestToXMLTransformer {&lt;br /&gt;    public String transform(SectionRequest sectionRequest){&lt;br /&gt; //this needs to be optimized...purely for demonstration of the concept&lt;br /&gt;        String sectionRequestAsString = &amp;quot;&amp;lt;section&amp;gt;&amp;lt;meta&amp;gt;&amp;lt;entityId&amp;gt;&amp;quot; + sectionRequest.getEntityId()&lt;br /&gt;        + &amp;quot;&amp;lt;/entityId&amp;gt;&amp;lt;sectionName&amp;gt;&amp;quot; + sectionRequest.getSectionId()&lt;br /&gt;        + &amp;quot;&amp;lt;/sectionName&amp;gt;&amp;lt;/meta&amp;gt;&amp;lt;/section&amp;gt;&amp;quot;;&lt;br /&gt;        &lt;br /&gt;        return sectionRequestAsString;&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and is hooked up in the Spring Integration configuration file in the following way:&lt;pre class="brush: java"&gt;&amp;lt;bean id=&amp;quot;sectionRequestToXMLBean&amp;quot; class=&amp;quot;org.bk.report.common.SectionRequestToXMLTransformer&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;si:transformer input-channel=&amp;quot;sectionRequestToXMLChannel&amp;quot; ref=&amp;quot;sectionRequestToXMLBean&amp;quot; method=&amp;quot;transform&amp;quot; output-channel=&amp;quot;sectionRequestChannel&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;To send an XML over http request using the Section Request XML to a section Service:&lt;pre class="brush: xml"&gt;&amp;lt;http:outbound-gateway id=&amp;quot;httpHeaderGateway&amp;quot;&lt;br /&gt;  request-channel=&amp;quot;sectionRequestChannel&amp;quot; reply-channel=&amp;quot;sectionResponseChannel&amp;quot;&lt;br /&gt;  default-url=&amp;quot;${sectionBaseURL}/section&amp;quot; extract-request-payload=&amp;quot;true&amp;quot;&lt;br /&gt;  charset=&amp;quot;UTF-8&amp;quot; request-timeout=&amp;quot;1200&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;To transform the Section Response XML to a Section Object - The component is the following:&lt;pre class="brush: java"&gt;public class SectionResponseXMLToSectionTransformer {&lt;br /&gt; public Section transform(String sectionXML) {&lt;br /&gt;  SAXReader saxReader = new SAXReader();&lt;br /&gt;  Document document;&lt;br /&gt;  String sectionName = &amp;quot;&amp;quot;;&lt;br /&gt;  String entityId = &amp;quot;&amp;quot;;&lt;br /&gt;  try {&lt;br /&gt;   document = saxReader.read(new StringReader(sectionXML));&lt;br /&gt;&lt;br /&gt;   sectionName = document&lt;br /&gt;     .selectSingleNode(&amp;quot;/section/meta/sectionName&amp;quot;).getText();&lt;br /&gt;   entityId = document.selectSingleNode(&amp;quot;/section/meta/entityId&amp;quot;)&lt;br /&gt;     .getText();&lt;br /&gt;  } catch (DocumentException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt;  return new Section(entityId, sectionName, sectionXML);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and is hooked up in the Spring Integration configuration file in the following way:&lt;pre class="brush: xml"&gt;&amp;lt;bean id=&amp;quot;sectionResponseXMLToSectionBean&amp;quot; class=&amp;quot;org.bk.report.common.SectionResponseXMLToSectionTransformer&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;si:transformer input-channel=&amp;quot;sectionXMLResponseChannel&amp;quot;&lt;br /&gt;  ref=&amp;quot;sectionResponseXMLToSectionBean&amp;quot; method=&amp;quot;transform&amp;quot; output-channel=&amp;quot;sectionResponseChannel&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;To aggregate the Sections together into a report, the component is the following::&lt;pre class="brush: java"&gt;public class SectionResponseAggregator {&lt;br /&gt;&lt;br /&gt;    public Report aggregate(List&amp;lt;Section&amp;gt; sections) {&lt;br /&gt;        return new Report(sections);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;and is hooked up in the Spring Integration configuration file in the following way:&lt;pre class="brush: xml"&gt;&amp;lt;bean id=&amp;quot;sectionResponseAggregator&amp;quot; class=&amp;quot;org.bk.report.common.SectionResponseAggregator&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;si:aggregator input-channel=&amp;quot;sectionResponseChannel&amp;quot; output-channel=&amp;quot;exit&amp;quot; ref=&amp;quot;sectionResponseAggregator&amp;quot; method=&amp;quot;aggregate&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This completes the Spring Integration implementation for this Integration Problem. The following is the complete Spring Integration configuration file:&lt;/p&gt;&lt;pre class="brush:xml"&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt; xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot; xmlns:si=&amp;quot;http://www.springframework.org/schema/integration&amp;quot;&lt;br /&gt; xmlns:http=&amp;quot;http://www.springframework.org/schema/integration/http&amp;quot;&lt;br /&gt; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt; xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&lt;br /&gt; http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd &lt;br /&gt; http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd&lt;br /&gt; http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-1.0.xsd&lt;br /&gt; &amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;context:property-placeholder /&amp;gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;enter&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;exit&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:gateway id=&amp;quot;reportGenerator&amp;quot; default-request-channel=&amp;quot;enter&amp;quot;&lt;br /&gt;  default-reply-channel=&amp;quot;exit&amp;quot; service-interface=&amp;quot;org.bk.report.ReportGenerator&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;sectionRequestToXMLChannel&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;si:splitter id=&amp;quot;sectionRequestSplitter&amp;quot; input-channel=&amp;quot;enter&amp;quot;&lt;br /&gt;  ref=&amp;quot;sectionRequestSplitterBean&amp;quot; method=&amp;quot;split&amp;quot; output-channel=&amp;quot;sectionRequestToXMLChannel&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;sectionRequestChannel&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;si:transformer input-channel=&amp;quot;sectionRequestToXMLChannel&amp;quot;&lt;br /&gt;  ref=&amp;quot;sectionRequestToXMLBean&amp;quot; method=&amp;quot;transform&amp;quot; output-channel=&amp;quot;sectionRequestChannel&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;sectionXMLResponseChannel&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;http:outbound-gateway id=&amp;quot;httpHeaderGateway&amp;quot;&lt;br /&gt;  request-channel=&amp;quot;sectionRequestChannel&amp;quot; reply-channel=&amp;quot;sectionXMLResponseChannel&amp;quot;&lt;br /&gt;  default-url=&amp;quot;${sectionBaseURL}/section&amp;quot; extract-request-payload=&amp;quot;true&amp;quot;&lt;br /&gt;  charset=&amp;quot;UTF-8&amp;quot; request-timeout=&amp;quot;1200&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:channel id=&amp;quot;sectionResponseChannel&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;si:transformer input-channel=&amp;quot;sectionXMLResponseChannel&amp;quot;&lt;br /&gt;  ref=&amp;quot;sectionResponseXMLToSectionBean&amp;quot; method=&amp;quot;transform&amp;quot; output-channel=&amp;quot;sectionResponseChannel&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;si:aggregator input-channel=&amp;quot;sectionResponseChannel&amp;quot;&lt;br /&gt;  output-channel=&amp;quot;exit&amp;quot; ref=&amp;quot;sectionResponseAggregator&amp;quot; method=&amp;quot;aggregate&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;bean id=&amp;quot;sectionRequestSplitterBean&amp;quot; class=&amp;quot;org.bk.report.common.SectionRequestSplitter&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;bean id=&amp;quot;sectionRequestToXMLBean&amp;quot; class=&amp;quot;org.bk.report.common.SectionRequestToXMLTransformer&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;bean id=&amp;quot;sectionResponseXMLToSectionBean&amp;quot; class=&amp;quot;org.bk.report.common.SectionResponseXMLToSectionTransformer&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;bean id=&amp;quot;sectionResponseAggregator&amp;quot; class=&amp;quot;org.bk.report.common.SectionResponseAggregator&amp;quot; /&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;A working sample is provided with the article(Download, extract and run &amp;quot;mvn test&amp;quot;)&lt;!--pagebreak--&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Solution using Apache Camel:&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Apache Camel allows the route to be defined using multiple DSL implementations – Java DSL, Scala DSL and an XML based DSL. The recommended approach is to use Spring CamelContext as a runtime and the Java DSL for route development.The following is to build the Spring Camel Context:&lt;/p&gt;&lt;pre class="brush: xml"&gt;&amp;lt;camelContext id=&amp;quot;camel&amp;quot; xmlns=&amp;quot;http://camel.apache.org/schema/spring&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;template id=&amp;quot;camelTemplate&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;routeBuilder ref=&amp;quot;routeBuilder&amp;quot;/&amp;gt;&lt;br /&gt; &amp;lt;/camelContext&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The route is configured by the Java based DSL:&lt;pre class="brush: java"&gt;public class CamelRouteBuilder extends RouteBuilder {&lt;br /&gt; private String serviceURL;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void configure() throws Exception {&lt;br /&gt;  &lt;br /&gt;  from(&amp;quot;direct:start&amp;quot;)&lt;br /&gt;  .split().method(&amp;quot;sectionRequestSplitterBean&amp;quot;, &amp;quot;split&amp;quot;)&lt;br /&gt;  .aggregationStrategy(new ReportAggregationStrategy())&lt;br /&gt;  .transform().method(&amp;quot;sectionRequestToXMLBean&amp;quot;, &amp;quot;transform&amp;quot;)&lt;br /&gt;  .to(serviceURL)&lt;br /&gt;  .transform().method(&amp;quot;sectionResponseXMLToSectionBean&amp;quot;, &amp;quot;transform&amp;quot;);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setServiceURL(String serviceURL) {&lt;br /&gt;  this.serviceURL = serviceURL;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Apache Camel does not provide an out of the box Message Gateway feature, however it is fairly easy to create a wrapper component that can hide the underlying details in the following way:&lt;pre class="brush: java"&gt;public class CamelReportGenerator implements ReportGenerator {&lt;br /&gt; private ProducerTemplate producer;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Report generateReport(ReportRequest reportRequest) {&lt;br /&gt;  Report report = (Report)producer.requestBody(&amp;quot;direct:start&amp;quot;, reportRequest);  &lt;br /&gt;  return report;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setProducer(ProducerTemplate producer) {&lt;br /&gt;  this.producer = producer;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This is a simple wrapper around Apache Camel's Producer Template which is essentially a handle to Apache Camel's route for this specific integration problem.The component to Split the Input Report Request to Section Request is exactly same as Spring Integration component:&lt;pre class="brush: java"&gt;public class SectionRequestSplitter {&lt;br /&gt;    &lt;br /&gt;    public List&amp;lt;SectionRequest&amp;gt; split(ReportRequest reportRequest){&lt;br /&gt;        return reportRequest.getSectionRequests();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;To hook the component with Apache Camel:&lt;pre class="brush: java"&gt;&amp;lt;bean id=&amp;quot;sectionRequestSplitterBean&amp;quot; class=&amp;quot;org.bk.report.si.SectionRequestSplitter&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;from(&amp;quot;direct:start&amp;quot;)&lt;br /&gt;.split().method(&amp;quot;sectionRequestSplitterBean&amp;quot;, &amp;quot;split&amp;quot;)&lt;br /&gt;....&lt;br /&gt;&lt;/pre&gt;Next to transform the Section Request to an XML format, again this is exactly same as the implementation for Spring Integration, with hook being provided in the following manner:&lt;pre class="brush: java"&gt;......&lt;br /&gt;.transform().method(&amp;quot;sectionRequestToXMLBean&amp;quot;, &amp;quot;transform&amp;quot;)&lt;br /&gt;......&lt;br /&gt;&lt;/pre&gt;To send an XML over http request using the Section Request XML to a section Service:&lt;pre class="brush: java"&gt;......&lt;br /&gt;.transform().method(&amp;quot;sectionRequestToXMLBean&amp;quot;, &amp;quot;transform&amp;quot;)&lt;br /&gt;.to(serviceURL)&lt;br /&gt;.........&lt;br /&gt;&lt;/pre&gt;To transform the Section Response XML to a Section object, the component is exactly same as the one used with Spring Integration, with the following highlighted hook in the Camel route:&lt;pre class="brush: java"&gt;......&lt;br /&gt;.transform().method(&amp;quot;sectionResponseXMLToSectionBean&amp;quot;, &amp;quot;transform&amp;quot;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;To aggregate the Section responses together into a report, the component is a bit more complicated than Spring Integration. Apache Camel supports a Scatter/Gather pattern using a route of the following type:&lt;pre class="brush: java"&gt;......&lt;br /&gt;.split().method(&amp;quot;sectionRequestSplitterBean&amp;quot;, &amp;quot;split&amp;quot;)&lt;br /&gt;.aggregationStrategy(new ReportAggregationStrategy())&lt;br /&gt;&lt;/pre&gt;with an aggregation strategy being passed on to the Splitter, the aggregation strategy implementation is the following:&lt;pre class="brush: java"&gt;public class ReportAggregationStrategy implements AggregationStrategy {&lt;br /&gt; @Override&lt;br /&gt; public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {&lt;br /&gt;  if (oldExchange == null) {&lt;br /&gt;   Section section = newExchange.getIn().getBody(Section.class);&lt;br /&gt;   Report report = new Report();&lt;br /&gt;   report.addSection(section);&lt;br /&gt;   newExchange.getIn().setBody(report);&lt;br /&gt;   return newExchange;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Report report = oldExchange.getIn().getBody(Report.class);&lt;br /&gt;  Section section = newExchange.getIn().getBody(Section.class);&lt;br /&gt;  report.addSection(section);&lt;br /&gt;  oldExchange.getIn().setBody(report);&lt;br /&gt;  return oldExchange;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This completes the Apache Camel based implementation. A working sample for Camel is provided with the article - just download, extract and run &amp;quot;mvn test&amp;quot;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/h2&gt;Spring Integration and Apache Camel provide a simple and clean approach for the Integration problems in a typical enterprise. They are lightweight frameworks – Spring Integration builds on top of Spring portfolio and extends the familiar programming model for the Integration domain and is easy to pick up, Apache camel provides a good Java based DSL and integrates well with Spring Core, with a fairly gentle learning curve.  The article does not recommend one product over the other but encourages the reader to evaluate and learn from both these frameworks.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/h2&gt;Spring Integration Website: &lt;a href="http://www.springsource.org/spring-integration"&gt;http://www.springsource.org/spring-integration&lt;/a&gt;&lt;br /&gt;Apache Camel Website: &lt;a href="http://camel.apache.org/"&gt;http://camel.apache.org/&lt;/a&gt;&lt;br /&gt;Spring Integration Reference: &lt;a href="http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html"&gt;http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html&lt;/a&gt;&lt;br /&gt;Apache Camel User Guide: &lt;a href="http://camel.apache.org/user-guide.html"&gt;http://camel.apache.org/user-guide.html&lt;/a&gt;&lt;br /&gt;Plug for my blog: &lt;a href="http://biju-allandsundry.blogspot.com/"&gt;http://biju-allandsundry.blogspot.com/&lt;/a&gt;&lt;br /&gt;Spring Integration Implementation for the Problem: &lt;a href="http://sites.google.com/site/bijukunjummen/reportgenerator-springintegration.zip"&gt;http://sites.google.com/site/bijukunjummen/reportgenerator-springintegration.zip&lt;/a&gt;&lt;br /&gt;Apache Camel Implementation for the Problem: &lt;a href="http://sites.google.com/site/bijukunjummen/reportgenerator-camel.zip"&gt;http://sites.google.com/site/bijukunjummen/reportgenerator-camel.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-4473201892737132244?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/4473201892737132244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=4473201892737132244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4473201892737132244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4473201892737132244'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/12/spring-integration-and-apache-camel.html' title='Spring Integration and Apache Camel'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-4956489034227012073</id><published>2009-12-20T08:26:00.000-05:00</published><updated>2009-12-20T08:26:26.546-05:00</updated><title type='text'>Useful Java Development setup instructions for Ubuntu</title><content type='html'>&lt;a href="https://help.ubuntu.com/community/EclipseIDE"&gt;https://help.ubuntu.com/community/EclipseIDE&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-4956489034227012073?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/4956489034227012073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=4956489034227012073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4956489034227012073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/4956489034227012073'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/12/useful-java-development-setup.html' title='Useful Java Development setup instructions for Ubuntu'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-6648021546480585823</id><published>2009-12-14T21:35:00.000-05:00</published><updated>2009-12-14T21:36:08.407-05:00</updated><title type='text'>Lumosity and Physical Exercise</title><content type='html'>I am a subscriber of &lt;a href="http://www.lumosity.com"&gt;Lumosity&lt;/a&gt;, it is a website which has a wonderful set of small games designed to improve and test memory, attention and other cognitive functions. &lt;br /&gt;&lt;br /&gt;I have found that whenever I exercise a bit, I get a jump in my scores!!&lt;br /&gt;&lt;br /&gt;I know this is well known, but experiencing this for myself vs just reading about it are two different things. Now that I KNOW that exercise helps, this is a nice little feedback loop for me to pull myself up these winter days and hit the Gym more often&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-6648021546480585823?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/6648021546480585823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=6648021546480585823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6648021546480585823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/6648021546480585823'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/12/lumosity-and-physical-exercise.html' title='Lumosity and Physical Exercise'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-5698776756279096540</id><published>2009-12-04T20:30:00.000-05:00</published><updated>2009-12-25T19:01:52.356-05:00</updated><title type='text'>Ubuntu: Problem during "gem install" - /usr/bin/ruby1.8 extconf.rb</title><content type='html'>If you get this when installing sqlite3-ruby:&lt;br /&gt;&lt;pre class="brush: xml"&gt;biju@ubhome:~$ sudo gem install sqlite3-ruby&lt;br /&gt;Building native extensions.  This could take a while...&lt;br /&gt;ERROR:  Error installing sqlite3-ruby:&lt;br /&gt; ERROR: Failed to build gem native extension.&lt;br /&gt;&lt;br /&gt;/usr/bin/ruby1.8 extconf.rb&lt;br /&gt;extconf.rb:1:in `require': no such file to load -- mkmf (LoadError)&lt;br /&gt; from extconf.rb:1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gem files will remain installed in /var/lib/gems/1.8/gems/sqlite3-ruby-1.2.5 for inspection.&lt;br /&gt;Results logged to /var/lib/gems/1.8/gems/sqlite3-ruby-1.2.5/ext/sqlite3_api/gem_make.out&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then solution gleaned from Google is to run:&lt;br /&gt;&lt;pre class="brush: xml"&gt;biju@ubhome:~$ sudo apt-get install ruby1.8-dev&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If it says:&lt;br /&gt;&lt;pre class="brush: xml"&gt;biju@ubhome:~/notes$ sudo gem install sqlite3-ruby&lt;br /&gt;Building native extensions.  This could take a while...&lt;br /&gt;ERROR:  Error installing sqlite3-ruby:&lt;br /&gt; ERROR: Failed to build gem native extension.&lt;br /&gt;&lt;br /&gt;/usr/bin/ruby1.8 extconf.rb&lt;br /&gt;checking for fdatasync() in -lrt... yes&lt;br /&gt;checking for sqlite3.h... no&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then solution is to run:&lt;br /&gt;&lt;pre class="brush: xml"&gt;biju@ubhome:~/notes$ sudo apt-get install libsqlite3-dev&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"sudo gem install sqlite3-ruby" should just run with these libraries in place.&lt;br /&gt;&lt;br /&gt;If you see the following while starting the rails application:&lt;br /&gt;&lt;pre class="brush: xml"&gt;./script/../config/../vendor/rails/railties/lib/initializer.rb:259:in `require_frameworks': no such file to load -- openssl (RuntimeError)&lt;br /&gt; from ./script/../config/../vendor/rails/railties/lib/initializer.rb:133:in `process'&lt;br /&gt; from ./script/../config/../vendor/rails/railties/lib/initializer.rb:112:in `send'&lt;br /&gt; from ./script/../config/../vendor/rails/railties/lib/initializer.rb:112:in `run'&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;then run:&lt;br /&gt;&lt;pre class="brush: xml"&gt;sudo apt-get install libopenssl-ruby&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-5698776756279096540?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/5698776756279096540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=5698776756279096540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5698776756279096540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/5698776756279096540'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/12/ubuntu-problem-during-gem-install.html' title='Ubuntu: Problem during &quot;gem install&quot; - /usr/bin/ruby1.8 extconf.rb'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-2901949260439716820</id><published>2009-10-31T13:38:00.000-04:00</published><updated>2011-09-10T18:39:51.231-04:00</updated><title type='text'>Scala Maven projects with multiple source folders</title><content type='html'>I had a need on a recent scala based maven project to be able to support multiple source folders - to hold the scala and java source and tests separately."Build Helper" Maven plugin perfectly fit this need, the following is a sample pom.xml configured using this plugin:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are two sources - src/main/java holding the java code, and src/main/scala holding the scala code&lt;/div&gt;&lt;div&gt;and two test sources - src/test/java, src/test/scala.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;org.bk&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;trainroute&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;build&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;sourceDirectory&amp;gt;src/main/scala&amp;lt;/sourceDirectory&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;testSourceDirectory&amp;gt;src/test/scala&amp;lt;/testSourceDirectory&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;plugins&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;artifactId&amp;gt;maven-scala-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;executions&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goal&amp;gt;testCompile&amp;lt;/goal&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;scalaVersion&amp;gt;${scala.version}&amp;lt;/scalaVersion&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;#160; &amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;version&amp;gt;1.3&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;executions&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;id&amp;gt;add-source&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goal&amp;gt;add-source&amp;lt;/goal&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;sources&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;source&amp;gt;src/main/java&amp;lt;/source&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/sources&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;id&amp;gt;add-test-source&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;goal&amp;gt;add-test-source&amp;lt;/goal&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/goals&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;sources&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;source&amp;gt;src/test/java&amp;lt;/source&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/sources&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/execution&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;#160; &amp;lt;/plugin&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;dependencies&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;artifactId&amp;gt;scala-library&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;version&amp;gt;${scala.version}&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;version&amp;gt;${junit.version}&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;lt;properties&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;scala.version&amp;gt;2.7.6&amp;lt;/scala.version&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;junit.version&amp;gt;4.6&amp;lt;/junit.version&amp;gt;&lt;br /&gt;&amp;lt;/properties&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;repositories&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;repository&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/repository&amp;gt;&lt;br /&gt;&amp;lt;/repositories&amp;gt;&lt;br /&gt;&amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;&amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-2901949260439716820?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/2901949260439716820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=2901949260439716820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2901949260439716820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/2901949260439716820'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/10/scala-maven-projects-with-multiple.html' title='Scala Maven projects with multiple source folders'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-9060197173057909577</id><published>2009-08-29T11:25:00.000-04:00</published><updated>2009-08-29T11:28:54.828-04:00</updated><title type='text'>Spring Web Services - How to - Article contributed to Javalobby - http://java.dzone.com/articles/spring-ws-how</title><content type='html'>&lt;p&gt;Spring Webservices encourages a contract first, message oriented approach to creating Webservices. The underlying details are completely under developer control starting from the contract to the marshalling/unmarshalling details to the endpoint handling the request.  &lt;/p&gt;  &lt;p&gt;Let us start by an example of a simple service to expose as a webservice -  call it the MemberService. MemberService exposes one operation “Get Member Details” which returns the details of a member/person, given an identifier.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;   	 	 	 	 	 	  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Creating the contract:&lt;/strong&gt;&lt;/p&gt;   	 	 	 	 	 	  &lt;p&gt;The Contract/WSDL for this service is fairly simple. Let us start by defining the messages and type :&lt;/p&gt;&lt;div id="highlighter_205680" class="syntaxhighlighter "&gt;&lt;div class="lines"&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:schema&lt;/code&gt; &lt;code class="color1"&gt;targetNamespace&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;"&lt;/code&gt; &lt;code class="color1"&gt;elementFormDefault&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"qualified"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailType"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;            &lt;/code&gt;&lt;span class="block" style="margin-left: 72px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"name"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"xsd:string"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;         &lt;/code&gt;&lt;span class="block" style="margin-left: 54px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"phone"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"xsd:string"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;            &lt;/code&gt;&lt;span class="block" style="margin-left: 72px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"city"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"xsd:string"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;         &lt;/code&gt;&lt;span class="block" style="margin-left: 54px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"state"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"xsd:string"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;10.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailsRequest"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;11.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;12.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;         &lt;/code&gt;&lt;span class="block" style="margin-left: 54px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;13.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;                &lt;/code&gt;&lt;span class="block" style="margin-left: 96px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"id"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"xsd:string"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;14.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;           &lt;/code&gt;&lt;span class="block" style="margin-left: 66px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;15.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;16.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;17.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailsResponse"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;18.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;19.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;         &lt;/code&gt;&lt;span class="block" style="margin-left: 54px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;20.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;                &lt;/code&gt;&lt;span class="block" style="margin-left: 96px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"memberdetail"&lt;/code&gt; &lt;code class="color1"&gt;type&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"ms:MemberDetailType"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;21.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;            &lt;/code&gt;&lt;span class="block" style="margin-left: 72px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:sequence&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;22.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:complexType&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;23.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:element&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;24.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;xsd:schema&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;MemberRequest message comprises of an id to represent the requested members identifier&lt;/p&gt; &lt;p&gt;MemberResponse message comprises of MemberDetail type to represent the details of a member.&lt;/p&gt;  &lt;p&gt;A sample payload over the wire would look like this:&lt;/p&gt; &lt;div id="highlighter_273685" class="syntaxhighlighter "&gt;&lt;div class="lines"&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;1.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;code class="keyword"&gt;xml&lt;/code&gt; &lt;code class="color1"&gt;version&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"1.0"&lt;/code&gt;&lt;code class="plain"&gt;?&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;2.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:MemberDetailsRequest&lt;/code&gt; &lt;code class="color1"&gt;xmlns:ms&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;3.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;  &lt;/code&gt;&lt;span class="block" style="margin-left: 12px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:id&lt;/code&gt;&lt;code class="plain"&gt;&gt;SAMPLE&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:id&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;4.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:MemberDetailsRequest&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;and a sample response:&lt;/p&gt;&lt;div id="highlighter_339542" class="syntaxhighlighter "&gt;&lt;div class="lines"&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;1.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:MemberDetailsResponse&lt;/code&gt; &lt;code class="color1"&gt;xmlns:ms&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;2.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:memberdetail&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;3.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:name&lt;/code&gt;&lt;code class="plain"&gt;&gt;testname&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:name&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;4.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:city&lt;/code&gt;&lt;code class="plain"&gt;&gt;testcity&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:city&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;5.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:phone&lt;/code&gt;&lt;code class="plain"&gt;&gt;testphone&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:phone&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;6.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;ms:state&lt;/code&gt;&lt;code class="plain"&gt;&gt;teststate&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:state&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;7.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;  &lt;/code&gt;&lt;span class="block" style="margin-left: 12px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:memberdetail&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;8.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;ms:MemberDetailsResponse&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;   	 	 	 	 	 	  &lt;/p&gt;&lt;p&gt;The sample request and response can be easily generated by using a tool like SOAP UI –  &lt;/p&gt;&lt;p&gt;&lt;img src="http://java.dzone.com/sites/all/files/Screenshot-soapUI%202.5.1.png" alt="SOAP UI" height="600" width="800" /&gt; &lt;/p&gt;&lt;p&gt;&lt;img src="http://java.dzone.com/Screenshot-soapUI%202.5.1.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;   	 	 	 	 	 	  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Creating an Endpoint:&lt;/strong&gt;&lt;/p&gt;   	 	 	 	 	 	   &lt;p&gt;A Spring-WS endpoint processes the XML message and produces the XML response. Spring provides different Endpoints based on how the XML is to be handled. If you wish to handle raw xml you have the option of implementing AbstractDom4jPayloadEndpoint, AbstractDomPayloadEndpoint, AbstractJDomPayloadEndpoint etc, based on how the raw xml needs to be handled. If you wish to handle the XML message as an object representation then you can implement the AbstractMarshallingPayloadEndpoint, which is what I will be using for this example along with JIBX as the XML binding framework for its ease of use and performance. &lt;/p&gt;&lt;div id="highlighter_974754" class="syntaxhighlighter "&gt;&lt;div class="bar"&gt;&lt;div class="toolbar"&gt;&lt;a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="http://java.dzone.com/articles/spring-ws-how#viewSource"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a class="item about" style="width: 16px; height: 16px;" title="?" href="http://java.dzone.com/articles/spring-ws-how#about"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="lines"&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;package&lt;/code&gt; &lt;code class="plain"&gt;org.bk.memberservice.endpoint;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;import&lt;/code&gt; &lt;code class="plain"&gt;org.bk.memberservice.message.MemberDetailsRequest;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;import&lt;/code&gt; &lt;code class="plain"&gt;org.bk.memberservice.message.MemberDetailsResponse;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;import&lt;/code&gt; &lt;code class="plain"&gt;org.bk.memberservice.service.MemberManager;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;import&lt;/code&gt; &lt;code class="plain"&gt;org.bk.memberservice.types.MemberDetail;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;import&lt;/code&gt; &lt;code class="plain"&gt;org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="keyword"&gt;public&lt;/code&gt; &lt;code class="keyword"&gt;class&lt;/code&gt; &lt;code class="plain"&gt;GetMemberDetailsEndpoint &lt;/code&gt;&lt;code class="keyword"&gt;extends&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;10.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;AbstractMarshallingPayloadEndpoint {&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;11.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;12.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="keyword"&gt;private&lt;/code&gt; &lt;code class="plain"&gt;MemberManager memberManager;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;13.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;14.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="keyword"&gt;protected&lt;/code&gt; &lt;code class="plain"&gt;Object invokeInternal(Object requestObject) &lt;/code&gt;&lt;code class="keyword"&gt;throws&lt;/code&gt; &lt;code class="plain"&gt;Exception {&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;15.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;MemberDetailsRequest request = (MemberDetailsRequest) requestObject;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;16.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;MemberDetail memberDetail = memberManager.getMemberDetails(request&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;17.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;              &lt;/code&gt;&lt;span class="block" style="margin-left: 84px;"&gt;&lt;code class="plain"&gt;.getId());&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;18.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;MemberDetailsResponse response = &lt;/code&gt;&lt;code class="keyword"&gt;new&lt;/code&gt; &lt;code class="plain"&gt;MemberDetailsResponse(memberDetail);&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;19.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="keyword"&gt;return&lt;/code&gt; &lt;code class="plain"&gt;response;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;20.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;21.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;}&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;22.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;23.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="keyword"&gt;public&lt;/code&gt; &lt;code class="keyword"&gt;void&lt;/code&gt; &lt;code class="plain"&gt;setMemberManager(MemberManager memberManager) {&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;24.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="keyword"&gt;this&lt;/code&gt;&lt;code class="plain"&gt;.memberManager = memberManager;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;25.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt; &lt;/code&gt;&lt;span class="block" style="margin-left: 6px;"&gt;&lt;code class="plain"&gt;}&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;26.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;}&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;The structure of the Endpoint is very simple, it takes an Object which can be cast to MemberDetailsRequest a holder for the request, and the response is returned as an instance of MemberDetailsResponse, a holder for the response details.  &lt;p&gt;&lt;strong&gt;Writing the Object/XML binding:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;So we now have the endpoint to process the take in the request Message, process it and respond. The only missing piece is how to transform the raw request xml over the wire to the MemberDetailsRequest object, and on the way back to transform the MemberDetailsResponse object back to XML. This is where Springs Object/XML mapping support comes in. Spring Object/XML mapper provides a simple abstraction over the popular Java XML binding stacks like JAXB, Castor, JiBX, Xstream. In the current example, we will start by defining the binding file for JiBX:&lt;/p&gt;  &lt;div id="highlighter_227951" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;code class="keyword"&gt;xml&lt;/code&gt; &lt;code class="color1"&gt;version&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"1.0"&lt;/code&gt; &lt;code class="color1"&gt;encoding&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"UTF-8"&lt;/code&gt;&lt;code class="plain"&gt;?&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;binding&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt; &lt;/code&gt;&lt;span class="block" style="margin-left: 6px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;mapping&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailsRequest"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.message.MemberDetailsRequest"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;namespace&lt;/code&gt; &lt;code class="color1"&gt;prefix&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"ms"&lt;/code&gt; &lt;code class="color1"&gt;uri&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;"&lt;/code&gt; &lt;code class="color1"&gt;default&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"all"&lt;/code&gt;&lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;value&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"id"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"id"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;mapping&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;mapping&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailsResponse"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;10.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.message.MemberDetailsResponse"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;11.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;namespace&lt;/code&gt; &lt;code class="color1"&gt;prefix&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"ms"&lt;/code&gt; &lt;code class="color1"&gt;uri&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;"&lt;/code&gt; &lt;code class="color1"&gt;default&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"all"&lt;/code&gt;&lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;12.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;structure&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"memberdetail"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"memberDetail"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;13.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;          &lt;/code&gt;&lt;span class="block" style="margin-left: 60px;"&gt;&lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.types.MemberDetail"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;14.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;         &lt;/code&gt;&lt;span class="block" style="margin-left: 54px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;value&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"name"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"name"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;15.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;            &lt;/code&gt;&lt;span class="block" style="margin-left: 72px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;value&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"city"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"city"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;16.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;            &lt;/code&gt;&lt;span class="block" style="margin-left: 72px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;value&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"phone"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"phone"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;17.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;          &lt;/code&gt;&lt;span class="block" style="margin-left: 60px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;value&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"state"&lt;/code&gt; &lt;code class="color1"&gt;field&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"state"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;18.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;structure&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;19.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;  &lt;/code&gt;&lt;span class="block" style="margin-left: 12px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;mapping&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;20.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;binding&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;JiBX requires a compile step with the above binding file, this is very easily wired using Maven as the build tool.&lt;/p&gt; &lt;p&gt;   	 	 	 	 	 	  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Putting it together:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;So now all the pieces are in place -  &lt;/p&gt;  &lt;p&gt;To direct the request to the appropriate endpoint, Spring-WS requires a custom servlet to be set up:&lt;/p&gt; &lt;div id="highlighter_714662" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;servlet&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;servlet-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;memberservice&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;servlet-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;servlet-class&lt;/code&gt;&lt;code class="plain"&gt;&gt;org.springframework.ws.transport.http.MessageDispatcherServlet&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;servlet-class&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;init-param&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;param-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;contextConfigLocation&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;param-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;param-value&lt;/code&gt;&lt;code class="plain"&gt;&gt;classpath:/applicationContext-memberservice.xml&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;param-value&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;init-param&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;servlet&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;10.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;servlet-mapping&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;11.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;servlet-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;memberservice&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;servlet-name&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;12.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;    &lt;/code&gt;&lt;span class="block" style="margin-left: 24px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;url-pattern&lt;/code&gt;&lt;code class="plain"&gt;&gt;/services/*&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;url-pattern&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;13.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;servlet-mapping&lt;/code&gt;&lt;code class="plain"&gt;&gt; &lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="LEFT"&gt;This would direct all requests starting with serivces/* to be handled by Spring-WS.&lt;/p&gt;   &lt;p&gt;The MessageDispatcherServlet would look for a Spring bean with id of “payloadMapping” to direct the incoming XML to an appropriate endpoint, for the example the bean entry is the following: &lt;/p&gt;&lt;div id="highlighter_971394" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt; &lt;code class="color1"&gt;id&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"payloadMapping"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;property&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"endpointMap"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;map&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;          &lt;/code&gt;&lt;span class="block" style="margin-left: 60px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;entry&lt;/code&gt; &lt;code class="color1"&gt;key&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"{&lt;a href="http://bk.org/memberservice/"&gt;http://bk.org/memberservice/&lt;/a&gt;}MemberDetailsRequest"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;               &lt;/code&gt;&lt;span class="block" style="margin-left: 90px;"&gt;&lt;code class="color1"&gt;value-ref&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"getMemberDetailsEndpoint"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;map&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;property&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="LEFT"&gt; Essentially a request with MemberDetailsRequest as the element will be directed to getMemberDetailsEndpoint which is :&lt;/p&gt; &lt;div id="highlighter_184367" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;1.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt; &lt;code class="color1"&gt;id&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"getMemberDetailsEndpoint"&lt;/code&gt; &lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.endpoint.GetMemberDetailsEndpoint"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;2.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;property&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"marshaller"&lt;/code&gt; &lt;code class="color1"&gt;ref&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"marshaller"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;3.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;property&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"unmarshaller"&lt;/code&gt; &lt;code class="color1"&gt;ref&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"unmarshaller"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;4.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;      &lt;/code&gt;&lt;span class="block" style="margin-left: 36px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;property&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"memberManager"&lt;/code&gt; &lt;code class="color1"&gt;ref&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"memberManager"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;5.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="LEFT"&gt;The Endpoint needs the marshaller and unmarshaller to be injected to transform the request XML to request object and the response object to response XML. These are created as follows:&lt;/p&gt; &lt;div id="highlighter_898636" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;01.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;bean id="&lt;/code"&gt;&lt;code class="string"&gt;"marshaller"&lt;/code&gt; &lt;code class="plain"&gt;class=&lt;/code&gt;&lt;code class="string"&gt;"org.springframework.oxm.jibx.JibxMarshaller"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/bean&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;02.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;       &lt;/code&gt;&lt;span class="block" style="margin-left: 42px;"&gt;&lt;code class="plain"&gt;&lt;property&gt;&lt;code class="keyword"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"targetClass"&lt;/code&gt;&lt;/property&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;03.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;value=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.message.MemberDetailsResponse"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;04.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;05.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;06.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;  &lt;/code&gt;&lt;span class="block" style="margin-left: 12px;"&gt;&lt;code class="plain"&gt;&lt;bean id="&lt;/code"&gt;&lt;code class="string"&gt;"unmarshaller"&lt;/code&gt; &lt;code class="plain"&gt;class=&lt;/code&gt;&lt;code class="string"&gt;"org.springframework.oxm.jibx.JibxMarshaller"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/bean&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;07.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;     &lt;/code&gt;&lt;span class="block" style="margin-left: 30px;"&gt;&lt;code class="plain"&gt;&lt;property&gt;&lt;code class="keyword"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"targetClass"&lt;/code&gt;&lt;/property&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;08.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;        &lt;/code&gt;&lt;span class="block" style="margin-left: 48px;"&gt;&lt;code class="plain"&gt;value=&lt;/code&gt;&lt;code class="string"&gt;"org.bk.memberservice.message.MemberDetailsRequest"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;09.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;    	 	 	 	 	 	  &lt;/p&gt;&lt;p align="LEFT"&gt;&lt;strong&gt;Exposing the Webservice WSDL:&lt;/strong&gt;&lt;/p&gt; &lt;p align="LEFT"&gt;Since the WSDL was created from scratch, to expose this pre-canned wsdl requires a bit more configuration with Spring:&lt;/p&gt; &lt;div id="highlighter_296477" class="syntaxhighlighter "&gt;&lt;code class="number"&gt;1.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt; &lt;code class="color1"&gt;id&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"MemberDetailsRequest"&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="lines"&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;2.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;  &lt;/code&gt;&lt;span class="block" style="margin-left: 12px;"&gt;&lt;code class="color1"&gt;class&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition"&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt1"&gt;&lt;code class="number"&gt;3.&lt;/code&gt;&lt;span class="content"&gt;&lt;code class="spaces"&gt;   &lt;/code&gt;&lt;span class="block" style="margin-left: 18px;"&gt;&lt;code class="plain"&gt;&lt;&lt;/code&gt;&lt;code class="keyword"&gt;property&lt;/code&gt; &lt;code class="color1"&gt;name&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"wsdl"&lt;/code&gt; &lt;code class="color1"&gt;value&lt;/code&gt;&lt;code class="plain"&gt;=&lt;/code&gt;&lt;code class="string"&gt;"classpath:/memberservice.wsdl"&lt;/code&gt; &lt;code class="plain"&gt;/&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line alt2"&gt;&lt;code class="number"&gt;4.&lt;/code&gt;&lt;span class="content"&gt;&lt;span class="block" style="margin-left: 0px;"&gt;&lt;code class="plain"&gt;&lt;!--&lt;/code--&gt;&lt;code class="keyword"&gt;bean&lt;/code&gt;&lt;code class="plain"&gt;&gt;&lt;/code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="LEFT"&gt;Now, when the request comes in for the URI /memberservice/MemberDetailsRequest.wsdl, Spring-WS would serve out the static memberservice.wsdl.&lt;/p&gt; &lt;p align="LEFT"&gt; &lt;/p&gt;&lt;p align="LEFT"&gt;This completes the Webservice implementation. It can be further enhanced to handle the Exception scenarios, Security etc which is an exercise for another day.&lt;/p&gt;  &lt;p align="LEFT"&gt;The complete example can be run using the attached maven enabled code, which will download all dependencies, and can be run using the following command:&lt;/p&gt; &lt;p align="LEFT"&gt;mvn jetty:run&lt;/p&gt;    &lt;p align="LEFT"&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;   &lt;p&gt;Spring-WS provides a compelling way to create a webservice with a contract first approach. The amount of code appears extensive, however there is clean separation of the contract defined by the WSDL and the implementation, thus being able to change underlying implementation without affecting the contract. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-9060197173057909577?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/9060197173057909577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=9060197173057909577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/9060197173057909577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/9060197173057909577'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/08/spring-web-services-how-to-article.html' title='Spring Web Services - How to - Article contributed to Javalobby - http://java.dzone.com/articles/spring-ws-how'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-1793099531043880490</id><published>2009-05-19T00:40:00.000-04:00</published><updated>2009-10-31T17:17:20.057-04:00</updated><title type='text'>Font configuration in Ubuntu Jaunty Jackalope</title><content type='html'>This is the font configuration that has worked extremely well for me in my Dell Inspiron laptop:&lt;br /&gt;&lt;br /&gt;1. Font size of 9 across the board&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_qhxEfsM90zs/ShI52gU7tQI/AAAAAAAAAvQ/E7tPZ-mHQd4/s1600-h/Screenshot.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 278px;" src="http://2.bp.blogspot.com/_qhxEfsM90zs/ShI52gU7tQI/AAAAAAAAAvQ/E7tPZ-mHQd4/s320/Screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5337392116940911874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2. Entries in ~/.fonts.conf file, based on the recommendations from the following post -&lt;br /&gt;&lt;a href="http://www.kilobitspersecond.com/2009/04/17/ubuntu-font-hinting-you-a-cautionary-tale/"&gt;http://www.kilobitspersecond.com/2009/04/17/ubuntu-font-hinting-you-a-cautionary-tale/&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;fontconfig&amp;gt;&lt;br /&gt;  &amp;lt;match target="font"&amp;gt;&lt;br /&gt;      &amp;lt;edit mode="assign" name="antialias"&amp;gt;&lt;br /&gt;          &amp;lt;bool&amp;gt;true&amp;lt;/bool&amp;gt;&lt;br /&gt;      &amp;lt;/edit&amp;gt;&lt;br /&gt;      &amp;lt;edit mode="assign" name="hinting"&amp;gt;&lt;br /&gt;          &amp;lt;bool&amp;gt;true&amp;lt;/bool&amp;gt;&lt;br /&gt;      &amp;lt;/edit&amp;gt;&lt;br /&gt;      &amp;lt;edit mode="assign" name="hintstyle"&amp;gt;&lt;br /&gt;          &amp;lt;const&amp;gt;hintslight&amp;lt;/const&amp;gt;&lt;br /&gt;      &amp;lt;/edit&amp;gt;&lt;br /&gt;      &amp;lt;edit mode="assign" name="lcdfilter"&amp;gt;&lt;br /&gt;          &amp;lt;const&amp;gt;lcdlegacy&amp;lt;/const&amp;gt;&lt;br /&gt;      &amp;lt;/edit&amp;gt;&lt;br /&gt;      &amp;lt;edit mode="assign" name="rgba"&amp;gt;&lt;br /&gt;          &amp;lt;const&amp;gt;none&amp;lt;/const&amp;gt;&lt;br /&gt;      &amp;lt;/edit&amp;gt;&lt;br /&gt;  &amp;lt;/match&amp;gt;&lt;br /&gt;&amp;lt;/fontconfig&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. The fonts within firefox looked extremely tiny at the end of this exercise. This was improved by installing Microsoft Core fonts :&lt;br /&gt;&lt;pre&gt;sudo apt-get install msttcorefonts gsfonts-x11&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-1793099531043880490?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/1793099531043880490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=1793099531043880490' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1793099531043880490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/1793099531043880490'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/05/font-configuration-in-ubuntu-jaunty.html' title='Font configuration in Ubuntu Jaunty Jackalope'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_qhxEfsM90zs/ShI52gU7tQI/AAAAAAAAAvQ/E7tPZ-mHQd4/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-8310314412228403456</id><published>2009-01-01T21:38:00.001-05:00</published><updated>2009-01-01T21:41:09.847-05:00</updated><title type='text'>Grails - Musings</title><content type='html'>&lt;div&gt;I have long observed Grails passively, rejoiced that there is now a web  framework in Java that does not require jumping through hoops to get a basic  setup working. Free time has been a bit of a constraint through 2008, so I never  got enough time to spend exploring Grails.&lt;br /&gt;&lt;/div&gt; &lt;div&gt;When I heard about the release of &lt;a id="depi" title="Grails 1.1 Beta" href="http://graemerocher.blogspot.com/2008/12/grails-maven-kiss-and-make-up-with.html"&gt;Grails  1.1 Beta&lt;/a&gt; 2, around Christmas time, I decided I had enough of a free time  during the holidays to actually start learning Grails.&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt; &lt;div&gt;A good tutorial that I started following is a &lt;a id="rufg" title="Grails Web Album tutorial by John Leach" href="http://www.syger.it/Tutorials/GrailsWebAlbum.html"&gt;Grails Web Album  tutorial by John Leach&lt;/a&gt; - It is a fairly complex application about creating  an online photo album. I was easily able to follow the tutorial and at the end  was amazed by how simple it was to create a working application. A great thing  about the tutorial is that an equivalent &lt;a id="fpf3" title="Rails version is also available" href="http://www.jhl.it/Courses/LUGPC9.html"&gt;Rails version is also available&lt;/a&gt;  at John Leach's site, that allowed me to compare and contrast Rails with Grails.  I am already fairly proficient in Rails, so one thing that stood out in Grails  for me was that specifically for the Web Album application, all the image  manipulation libraries were available right within Java, whereas the Rails  version required using RMagick, which is fairly difficult to configure on a  Windows XP box. &lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;My conclusion is fairly simple - Both Grails and Rails are compelling Web  frameworks, both have a fairly flat learning curve and the underlying  languages(Groovy, Ruby) are delightful and fun to learn and use. I very much intend to continue exploring both Grails and Rails.&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-8310314412228403456?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/8310314412228403456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=8310314412228403456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8310314412228403456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/8310314412228403456'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2009/01/grails-musings.html' title='Grails - Musings'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-120511648408114278</id><published>2008-06-11T20:04:00.000-04:00</published><updated>2008-06-11T20:05:46.411-04:00</updated><title type='text'>My Java "Aha" moments - Article that I posted on Javalobby http://java.dzone.com/news/my-java-aha-moments</title><content type='html'>&lt;p&gt;The flood of technology choices in the Java world is overwhelming. I have an analogy that always comes to my mind for the developers who are faced with this flood of information - a python trying to gorge an elephant!!&lt;/p&gt;&lt;p&gt;Technologies like J2EE, JBI/SCA are massive and have a very steep learning curve. I attempted getting through the J2EE specification once and promptly lost my appetite for J2EE. I ended up using the simpler parts for the projects that I have worked on – the web application frameworks, the design blueprints etc and basically became proficient on the job. &lt;/p&gt;&lt;p&gt;There are technologies that have come up in the Java world that have helped manage the bloat considerably and have provided an aha moment for me - when something just clicks in the mind and has simplified the development process considerably for me. Here are my top 5:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Spring Framework&lt;/b&gt;: &lt;a href="http://www.springframework.org/"&gt;http://www.springframework.org&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Understanding the principles behind Dependency injection and its implementation in Spring Framework has been a great aha moment for me. Spring has helped me break out of the J2EE hell and has massively simplified the fundamental way in which I have considered projects by forcing some simple conventions like programming to interfaces, business logic as POJO’s. &lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Appfuse:&lt;/b&gt;  &lt;a href="http://appfuse.org/display/APF/Home"&gt;http://appfuse.org/display/APF/Home&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I have attempted developing web applications from scratch and have found it difficult to put a good structure in place with all the different myriad Java libraries integrated and working smoothly. Putting a modular structure from scratch also has been extremely. &lt;/p&gt;&lt;p&gt;And then came Matt Raible’s Appfuse and its successor Appfuse 2. Appfuse has been a Godsend. It made the initial ramp up time very smooth by providing a canned structure or a template based on good design and blueprints that any project can start from and move forward. &lt;/p&gt;&lt;p&gt;&lt;b&gt;3. JRuby and JRuby on Rails:&lt;/b&gt; &lt;a href="http://jruby.codehaus.org/"&gt;http://jruby.codehaus.org&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When Rails first came out it was an aha moment for me. I loved the Ruby language before rails was released – I was a smalltalk developer and Ruby as a language was the closest that I had seen to Smalltalk. Rails for the first time enabled me to quickly get up and running with developing a web application, no messing around with a mountain of libraries, everything just worked beautifully. I quickly picked it up, learned enough to create some small applications for myself. I was very pleased to see that the excellent JRuby contributors finally got the Rails framework working on JRuby and promptly now use it for all my internal work.&lt;/p&gt;&lt;p&gt;&lt;b&gt;4. OSGi, Equinox, Apache Felix :&lt;/b&gt; &lt;a href="http://www.osgi.org/Main/HomePage"&gt;http://www.osgi.org/Main/HomePage&lt;/a&gt;&lt;/p&gt;&lt;p&gt;OSGi promises modularization for Java – components can be developed as independent modules, and then put together in the OSGi runtime – like Equinox or Apache Felix, which takes care of hosting the component, resolving dependencies, versioning of the components etc.&lt;/p&gt;&lt;p&gt;OSGi was initially a bit of a difficult concept to get my head around, but then once I had tried a few examples, it quickly became an aha moment and see great promise for it in the Java world.&lt;/p&gt;&lt;p&gt;&lt;b&gt;5. Google Web Toolkit:&lt;/b&gt;  &lt;a href="http://code.google.com/webtoolkit/"&gt;http://code.google.com/webtoolkit/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Google Web Toolkit is amazing; it lets developers create, develop and test the UI with a Java Swing like constructs, and then internally does magic to convert the Java code to cross browser compatible Javascript for web application deployment. Getting a UI working with GWT was indeed an aha moment for me.&lt;/p&gt;&lt;p&gt;In conclusion, the developers in the Java and the broader software technology world are extremely innovative and I am indebted to these simpler technologies that finally present simpler meal options to the python in my analogy.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-120511648408114278?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/120511648408114278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=120511648408114278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/120511648408114278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/120511648408114278'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2008/06/my-java-aha-moments-article-that-i.html' title='My Java &quot;Aha&quot; moments - Article that I posted on Javalobby http://java.dzone.com/news/my-java-aha-moments'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-197169747849375944</id><published>2008-02-10T14:12:00.000-05:00</published><updated>2008-02-10T14:22:50.007-05:00</updated><title type='text'>JRuby on Rails - First project</title><content type='html'>I have been wanting to explore jruby on rails for sometime, I finally managed to scramble together a small working project and like what I am seeing.&lt;br /&gt;&lt;br /&gt;So this is what I did on my Windows box:&lt;br /&gt;&lt;br /&gt;1. Install JRuby. I have installed the latest RC available at this time - 1.1RC1&lt;br /&gt;&lt;br /&gt;2. Set the Environment variables -&lt;br /&gt;JRUBY_HOME&lt;br /&gt;PATH - to the bin directory of JRUBY_HOME&lt;br /&gt;&lt;br /&gt;3. Install Rails:&lt;br /&gt;jruby -S gem install rails --include-dependencies --no-ri --no-rdoc&lt;br /&gt;&lt;br /&gt;4. Install jdbc adapter:&lt;br /&gt;jruby -S gem install activerecord-jdbc-adapter&lt;br /&gt;&lt;br /&gt;5. Install Derby adapters:&lt;br /&gt;jruby -S gem install activerecord-jdbcderby-adapter&lt;br /&gt;&lt;br /&gt;6. Install Mongrel - To use Mongrel as the webserver instead of the default, download &lt;a href="http://rubyforge.org/frs/download.php/20097/mongrel-1.0.1-jruby.gem"&gt;http://rubyforge.org/frs/download.php/20097/mongrel-1.0.1-jruby.gem&lt;/a&gt; and,&lt;br /&gt;jruby -S gem install gem_plugin --no-ri --no-rdoc&lt;br /&gt;jruby -S gem install cgi_multipart_eof_fix --no-ri --no-rdoc&lt;br /&gt;jruby -S gem install mongrel-1.0.1-jruby  --no-ri --no-rdoc&lt;br /&gt;&lt;br /&gt;Now start up on the rails project - my project is to simply record my vehicle mileage:&lt;br /&gt;7. jruby -S rails mileage&lt;br /&gt;&lt;br /&gt;8. Modify config/database.yml to use derby:&lt;br /&gt;&lt;em&gt;development:&lt;br /&gt; adapter: jdbcderby&lt;br /&gt; database: db/development&lt;br /&gt; timeout: 5000&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;9. That's it, the rest of the steps are same as for rails. Once the application is ready, it can be run with the following command:&lt;br /&gt;jruby script/server&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-197169747849375944?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/197169747849375944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=197169747849375944' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/197169747849375944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/197169747849375944'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2008/02/jruby-on-rails-first-project.html' title='JRuby on Rails - First project'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1059181725962492104.post-913399412686884573</id><published>2007-11-15T21:57:00.000-05:00</published><updated>2007-11-15T22:17:15.716-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>Split 2 million records into 5000 groups of random lists</title><content type='html'>Problem:&lt;br /&gt;A list of 2 million names.&lt;br /&gt;Create 5000 groups of names with 51%(or 2550) having 100 names from the list, 29%(or 1450) with 500, 8%(400) with 1000, 6%(300) with 25000, 3%(150) with 50000, 3%(150) with 100000. The added complexity is that items in each group should have random set of names from the master list.&lt;br /&gt;&lt;br /&gt;My Solution:&lt;br /&gt;I used &lt;a href="http://www.ruby-lang.org/"&gt;Ruby &lt;/a&gt;to create a simple script:&lt;br /&gt;1. I dumped the list of 2 million names into &lt;a href="http://www.sqlite.org/"&gt;sqlite&lt;/a&gt; db.&lt;br /&gt;2. Created a script along the following lines:&lt;br /&gt;....&lt;br /&gt;db.execute("select duns, name from subject order by random() limit 100") do |row|&lt;br /&gt;       file.puts "#{row[0]}"&lt;br /&gt;end&lt;br /&gt;....&lt;br /&gt;&lt;br /&gt;This solution took about 10 hours to execute for my entire list. I wonder if there is a much simpler way to do this.&lt;br /&gt;&lt;br /&gt;BTB, my Ruby editor of choice is now &lt;a href="http://www.netbeans.org"&gt;Netbeans&lt;/a&gt;, it has neat features - code completion is my favourite and the ability to edit ad-hoc files is another. My previous editor of choice was Eclipse with ruby plugins&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1059181725962492104-913399412686884573?l=biju-allandsundry.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biju-allandsundry.blogspot.com/feeds/913399412686884573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1059181725962492104&amp;postID=913399412686884573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/913399412686884573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1059181725962492104/posts/default/913399412686884573'/><link rel='alternate' type='text/html' href='http://biju-allandsundry.blogspot.com/2007/11/split-2-million-records-into-5000.html' title='Split 2 million records into 5000 groups of random lists'/><author><name>Biju Kunjummen</name><uri>http://www.blogger.com/profile/09636436778807755643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
