<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Towards better software</title>
	<atom:link href="http://krzysztofadamczyk.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://krzysztofadamczyk.com</link>
	<description>About software development, domain driven design, code quality and IT in general</description>
	<lastBuildDate>Thu, 25 Aug 2011 06:26:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='krzysztofadamczyk.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Towards better software</title>
		<link>http://krzysztofadamczyk.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://krzysztofadamczyk.com/osd.xml" title="Towards better software" />
	<atom:link rel='hub' href='http://krzysztofadamczyk.com/?pushpress=hub'/>
		<item>
		<title>The Power of Value Objects</title>
		<link>http://krzysztofadamczyk.com/2010/02/10/the-power-of-value-objects/</link>
		<comments>http://krzysztofadamczyk.com/2010/02/10/the-power-of-value-objects/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 21:15:29 +0000</pubDate>
		<dc:creator>Krzysztof Adamczyk</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[code readability]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[measurement]]></category>
		<category><![CDATA[quantity]]></category>
		<category><![CDATA[unit]]></category>
		<category><![CDATA[value object]]></category>
		<category><![CDATA[whole value]]></category>

		<guid isPermaLink="false">http://www.krzysztofadamczyk.com/?p=88</guid>
		<description><![CDATA[Although Value Objects are still underestimated players in software design, they may have enormous impact on the quality of your code and flexibility of you domain model. When applied correctly, they increase readability and expressiveness of your code making development and future maintenance much easier. Therefore they should be an elementary tool in every software [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=88&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Although<strong> Value Objects</strong> are still underestimated players in software design, they may have enormous impact on the quality of your code and flexibility of you domain model. When applied correctly, they increase readability and expressiveness of your code making development and future maintenance much easier. Therefore they should be an elementary tool in every software craftsman&#8217;s toolbox.</p>
<p>In this article I want to show:</p>
<ul>
<li>when to use Value Objects</li>
<li>how to use Value Objects</li>
<li> what are the benefits of using Value Objects</li>
</ul>
<h2>Wrapping primitives</h2>
<p>Let&#8217;s assume that you have to write a batch tool which takes invoice data stored in DB, makes some complex processing and finally passes processed data to external system. A lot of conditions depend on the <em>invoice status </em>which is defined as INT in the database. According to business requirements, the following rules apply to the <em>invoice status</em>:</p>
<blockquote><p>Negative status of invoice is not allowed. Invoices with status of 0 to 9 are considered OPEN, and with status greater than 9 are considered CLOSED. Open/Closed classification has impact on processing workflow. Status should be passed to external system in original format (number).</p></blockquote>
<p>The first approach to modeling could be:<br />
<pre class="brush: java;">public class Invoice {

    private int status;

    public Invoice(int status, ....) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }
}</pre><br />
and when we need to use the flag:<br />
<pre class="brush: java;">Invoice invoice = new Invoice(2, ...);
        ....
        if (invoice.getStatus() &amp;lt; 0) {
            throw new IllegalStateException(
                    &quot;Negative invoice state is not allowed&quot;);
        } else if (invoice.getStatus() &amp;lt;= 9) {
            // invoice is OPEN
        } else {
            // invoice closed
        }</pre><br />
This solution has a few drawbacks. It promotes repetitions of code (checking the status value every time we want to use it) and therefore it leads to unmaintainable code. What&#8217;s more, each programmer in the team will probably write he&#8217;s own status-checking code. It is possible that each version will behave in a bit different way (especially in more complicated cases). How to avoid it? Let&#8217;s implement a value object which will wrap the status:<br />
<pre class="brush: java;">public class InvoiceStatus {

    private int status;

    public InvoiceStatus(int status) {
        if (status &amp;lt; 0) {
            throw new IllegalArgumentException(&quot;Negative status not allowed&quot;);
        }
        this.status = status;
    }

    public boolean isOpen() {
        return status &amp;gt; 9;
    }

    public boolean isClosed() {
        return !isOpen();
    }

    @Override
    public String toString() {
        return isOpen() ? &quot;OPEN&quot; : &quot;CLOSED&quot;;
    }

}</pre><br />
Here we have it all in one place, and anyone who will need to do the &#8220;&gt; 9&#8243; check will obviously use the provided method. Furthermore having a dedicated value object makes adding, extending and modifying functionality easier, because the code is not spread over the whole application.</p>
<p>This approach has also one positive side-effect. A method which needs an <em>invoice status</em> as an argument will look like this:<br />
<pre class="brush: java;">    public void doStuff(InvoiceStatus status) {
        ....
    }</pre><br />
Now you don&#8217;t have to worry if someone tries to invoke your method with -123 as an argument. It is guaranteed that you will get a valid invoice status. What&#8217;s more, readability increases because you know what to pass as an argument just by looking at the method signature.</p>
<p>Now let&#8217;s take a look at a similar example:<br />
<pre class="brush: java;">public class EmailAddress {

    private final String emailAddress;
    private final String domain;

    public EmailAddress(String email) {
        this.validate(email);

        this.emailAddress = email;
        domain = this.extractDomain(email);
    }

    public boolean isInDomain(String aDomain) {
        return domain.equals(aDomain);
    }

    public String getDomain() {
        return domain;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    private void validate(String phoneNumberToValidate) {
        // do some regexp, throw runtime exception if needed
    }

    private String extractDomain(String email) {
        // do string manipulation to extract email domain
        return null;
    }

}</pre><br />
Here we have a string data which contains complex information. When we need to extract this information from the String, a wrapping value object seems to be a good solution. Not only does it encapsulate the parsing and string manipulation logic but also takes care about validation.</p>
<h2>Arithmetic of Value Objects</h2>
<p>Value objects are particularly useful when your domain model includes some kind of arithmetic calculations on money, quantities, measurements etc. In such cases it is extremely useful to define methods which will play the role of operators in expression:<br />
<pre class="brush: java;">        Money salaryNet = new Money(20000, Money.EUR);
        Money tax = new Money(300, Money.EUR);

        Money salaryGross = salaryNet.plus(tax);</pre><br />
Now let&#8217;s imagine that we need to provide calculations for multiple currencies. We can model exchange rate as a smart value object:<br />
<pre class="brush: java;">    class ExchangeRate {
        private final Currency   sourceCurrency;
        private final Currency   targetCurrency;
        private final BigDecimal rate;

        public ExchangeRate(final Currency sourceCurrency, final Currency targetCurrency, final BigDecimal rate) {
            this.sourceCurrency = sourceCurrency;
            this.targetCurrency = targetCurrency;
            this.rate = rate;
        }

        public Money exchange(final Money money) {
            // do the computations
            return ........;
        }
    }</pre><br />
Now we can use it as follows:<br />
<pre class="brush: java;">    public Money computeSalaryInUSD() {
        Money salary = new Money(20000, Currency.EUR);
        ExchangeRate eurToUsd = new ExchangeRate(Currency.EUR, Currency.USD, new BigDecimal(1.5));

        return eurToUsd.exchange(salary);
    }</pre><br />
Quite intuitive, isn&#8217;t it?</p>
<p>Just like Money was implemented as a pair of amount and unit (currency), also quantities and measurements should be modeled as <a href="http://fit.c2.com/wiki.cgi?WholeValue">Whole Value</a>s since unit is their fundamental part. But Unit of Measure itself is a good candidate for a Value Object:<br />
<pre class="brush: java;">class LengthUnit {

        public final static LengthUnit METER     = new LengthUnit(&quot;meter&quot;, BigDecimal.ONE);
        public final static LengthUnit KILOMETER = new LengthUnit(&quot;kilometer&quot;, BigDecimal.valueOf(1000));

        private final String           name;
        private final BigDecimal       baseUnitMultiplier;

        public LengthUnit(final String name, final BigDecimal aBaseUnitMultiplier) {
            this.name = name;
            this.baseUnitMultiplier = aBaseUnitMultiplier;
        }

        public BigDecimal findRate(final LengthUnit otherLengthUnit) {
            return this.baseUnitMultiplier.divide(otherLengthUnit.baseUnitMultiplier);
        }

        @Override
        public String toString() {
            return this.name;
        }
    }</pre><br />
Like in example above, we can provide predefined constants to improve usability even more.<br />
Now we can create a full-blown Length model, which is NOT only a number, but a number with it&#8217;s unit:<br />
<pre class="brush: java;">class Length {
        private final BigDecimal quantity;
        private final LengthUnit unit;

        public Length(final BigDecimal quantity, final LengthUnit unit) {
            this.quantity = quantity;
            this.unit = unit;
        }

        public Length to(final LengthUnit targetUnit) {
            return new Length(this.quantity.multiply(this.unit.findRate(targetUnit)), targetUnit);
        }

        @Override
        public String toString() {
            return this.quantity + &quot; &quot; + this.unit;
        }
    }</pre><br />
Note how clear and lucid the code is when we need to use our classes:<br />
<pre class="brush: java;">        Length hundredMeters = new Length(new BigDecimal(100), LengthUnit.METER);
        Length oneKilometer = new Length(new BigDecimal(1), LengthUnit.KILOMETER);

        System.out.println(hundredMeters.to(LengthUnit.KILOMETER));
        System.out.println(oneKilometer.to(LengthUnit.METER));</pre><br />
We defined our own internal <em>language </em>of objects and operators. Everyone who will come to maintain this code will immediately catch the idea, because this <em>arithmetic of value objects </em>is built based on analogy to the real life. Everyone (at least every software engineer <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) learns at school how to add numbers, what are units and what means to convert between different units. Therefore when we need to model it in code, let&#8217;s make it <em>explicit</em>.</p>
<h2>When to use Value Objects?</h2>
<p>I will not even try to make a complete list of cases when Value Objects can be useful, partially because it all depends on the domain you are working in. But basing on examples above I can list a few cases when we should consider the need to create an explicit Object for some implicit concept.</p>
<p>If you are dealing with:</p>
<ul>
<li>primitives with limitations</li>
<li>primitives which carry some additional information</li>
<li>primitives as arguments and return values in service methods</li>
<li>money, time, amounts, units, quantities, measurements</li>
</ul>
<p>consider introducing <strong>explicit Value Object.</strong></p>
<p><strong>Further reading:<br />
</strong><a href="http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson">Power Use of Value Objects in DDD</a> by Dan Bergh Johnsson<br />
<a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design</a> by Eric Evans<br />
<a href="http://books.google.com/books?id=4V8pZmpwmBYC&amp;dq=Analysis+Patterns&amp;printsec=frontcover&amp;source=bn&amp;hl=pl&amp;ei=SWh0S8eHD4vgsAag1cWZCg&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=4&amp;ved=0CBwQ6AEwAw#v=onepage&amp;q=&amp;f=false">Alanysis Patterns</a> by Martin Fowler</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/krzysztofadamczyk.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/krzysztofadamczyk.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/krzysztofadamczyk.wordpress.com/88/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=88&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://krzysztofadamczyk.com/2010/02/10/the-power-of-value-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef9affbd5f509bd5d4d1ac20cf4651aa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">krzysztofadamczyk</media:title>
		</media:content>
	</item>
		<item>
		<title>Code readability: Uncover the conditions</title>
		<link>http://krzysztofadamczyk.com/2009/11/29/code-readability-uncover-the-conditions/</link>
		<comments>http://krzysztofadamczyk.com/2009/11/29/code-readability-uncover-the-conditions/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 14:24:48 +0000</pubDate>
		<dc:creator>Krzysztof Adamczyk</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[code readability]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[specification]]></category>

		<guid isPermaLink="false">http://krzysztofadamczyk.com/?p=42</guid>
		<description><![CDATA[In this article I want to show a few techniques that can make you code more expressive and readable especially when dealing with conditions and business rules. Let&#8217;s start with a simple example. Which of these two code snippets makes more sense to you ? or What are the magic numbers in the first example? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=42&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this article I want to show a few techniques that can make you code more expressive and readable especially when dealing with conditions and business rules.</p>
<p>Let&#8217;s start with a simple example. Which of these two code snippets makes more sense to you ?<br />
<pre class="brush: java;">        if (ratio &gt; 13 &amp;&amp; ratio &lt; 23) {
            doSomeStuff();
        } else if (ratio &lt;= 13) {
            doOtherStuff();
        }</pre><br />
or<br />
<pre class="brush: java;">        final boolean ratioInSafeRange = ratio &gt; 13 &amp;&amp; ratio &lt; 23;
        final boolean ratioTooLow = ratio &lt;= 13;

        if (ratioInSafeRange) {
            doSomeStuff();
        } else if (ratioTooLow) {
            doOtherStuff();
        }</pre><br />
What are the <em>magic numbers</em> in the first example? Why do we need to do one thing or the other depending on these numbers? Of course, second version does not explain everything. We still must know a bit about the domain to understand this code, but it tells us that there probably is some range of values which is <em>safe, </em>and when the ratio is outside of this range we should act in some different way.</p>
<p>In second version, we gave the conditions their  <em><strong>name</strong></em><strong>s, </strong>emphasising their meaning. Some would say that we can simply add comments that will explain what is going on. That&#8217;s true, but code changes quickly and comments become outdated and misleading in time. Comments are difficult to maintain and a false comment becomes rather an obstacle than help.</p>
<p>The solution presented above adds more expression to the code itself. It make the comment a part of the code, and therefore makes it more flexible. As the code evolves, developer can use refactoring techniques, bulk rename and so on to keep the comment-in-code up to date.</p>
<p>Now lets take a look at a bit more advanced example. Consider a banking system with the following domain interface:<br />
<pre class="brush: java;">interface Account {
    public Date creationDate();

    BigDecimal balance();

    BigDecimal avarageMonthlyBalance();

    void debit(BigDecimal amount);

    void credit(BigDecimal amount);
}</pre><br />
We also have a <strong>domain service</strong> to make fund transfers:<br />
<pre class="brush: java;">class TransferService {
    public void transfer(final Account source, final Account destination, final BigDecimal amount) {
        source.debit(amount);
        destination.credit(amount);
    }
}</pre><br />
Now the business comes with a new requirement:</p>
<blockquote><p>For every fund transfer from <strong>source</strong> <strong>account</strong> to destination account, a <strong>source account</strong> should pay a fee, unless the <strong>source account</strong> fulfills conditions of being a <strong>premium account</strong>. A <strong>premium account</strong> is an account which exists at least one year in the system and has an average monthly balance of $1000 or more for the last month.</p></blockquote>
<p>We decide to put this logic into the <em><strong>TransferService,</strong></em> since the fee is to be paid for <strong>transfer</strong> and not for <strong>debit</strong> transaction. Let&#8217;s take a look at the first draft:<br />
<pre class="brush: java;">class TransferService {
    private static final BigDecimal TRANSFER_FEE = BigDecimal.ONE;

    public void transfer(final Account source, final Account destination, final BigDecimal amount) {
        source.debit(amount);
        destination.credit(amount);

        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -1);
        if (!(source.creationDate().compareTo(calendar.getTime()) &lt;= 0 &amp;&amp; source.avarageMonthlyBalance().compareTo(BigDecimal.valueOf(1000L)) &gt; 0)) {
            source.debit(TRANSFER_FEE);
        }
    }
}</pre><br />
After extracting the date computation into utility class, and <strong>applying the </strong><em><strong>named condition</strong></em> pattern, we get the following:<br />
<pre class="brush: java;">    public void transfer(final Account source, final Account destination, final BigDecimal amount) {
        source.debit(amount);
        destination.credit(amount);

        final boolean accountExistsForAtLeatOneYear = source.creationDate().compareTo(DateTimeUtils.oneYearAgo()) &lt;= 0;
        final boolean monthlyBalanceGreaterThanRequired = source.avarageMonthlyBalance().compareTo(BigDecimal.valueOf(1000L)) &gt; 0;

        if (!(accountExistsForAtLeatOneYear &amp;amp;&amp;amp; monthlyBalanceGreaterThanRequired)) {
            source.debit(TRANSFER_FEE);
        }
    }</pre><br />
Just a small refactoring inside the <strong>if </strong>statement and here&#8217;s the final version of the method:<br />
<pre class="brush: java;">    public void transfer(final Account source, final Account destination, final BigDecimal amount) {
        source.debit(amount);
        destination.credit(amount);

        final boolean accountExistsForAtLeatOneYear = source.creationDate().compareTo(DateTimeUtils.oneYearAgo()) &lt;= 0;
        final boolean monthlyBalanceGreaterThanRequired = source.avarageMonthlyBalance().compareTo(BigDecimal.valueOf(1000L)) &gt; 0;

        if (!accountExistsForAtLeatOneYear || !monthlyBalanceGreaterThanRequired) {
            source.debit(TRANSFER_FEE);
        }
    }</pre><br />
Much better, isn&#8217;t it?</p>
<p>What we achieved is a code which is much more readable and expressive than before. It reveals concepts that were hidden in the first version in a form of complex comparisons and logical operators.</p>
<p>But we can go further. In this case being or not a premium account is a business rule, a <strong>specification</strong>. It&#8217;s not programmers job to define what are the conditions and rules for an account to become <strong>premium. </strong>If so, lets make it an explicit business rule with a name which we can use talking to business people. When discussing with domain experts we will not talk in terms of IFs, but we can talk in terms of specifications, policies etc.<br />
<pre class="brush: java;">class PremiumAccountSpecification {

    public boolean isSatisfiedBy(final Account candidate) {
        final boolean accountExistsForAtLeatOneYear = candidate.creationDate().compareTo(DateTimeUtils.oneYearAgo()) &lt;= 0;
        final boolean monthlyBalanceGreaterThanRequired = candidate.avarageMonthlyBalance().compareTo(BigDecimal.valueOf(1000L)) &gt;= 0;

        return accountExistsForAtLeatOneYear &amp;amp;&amp;amp; monthlyBalanceGreaterThanRequired;
    }
}</pre><br />
and the TransferService now looks like this:<br />
<pre class="brush: java;">    public void transfer(final Account source, final Account destination, final BigDecimal amount) {
        source.debit(amount);
        destination.credit(amount);

        PremiumAccountSpecification premiumAccountSpecification = new PremiumAccountSpecification();
        if (!premiumAccountSpecification.isSatisfiedBy(source)) {
            source.debit(TRANSFER_FEE);
        }
    }</pre><br />
When writing software, we are constantly facing problem of losing important concepts in the code. It is important for the model to hide details behind abstractions, but also to make important things explicit. Business rules are a good example where explicitness pays off. The patterns presented above are useful not only in small scale where they do their job for readability and ease of maintenance of methods and classes, but also in the scale of the domain model, where they are first-class citizens (in form of Specifications) and do their contribution to the domain <a href="http://domaindrivendesign.org/node/132">ubiquitous language</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/krzysztofadamczyk.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/krzysztofadamczyk.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/krzysztofadamczyk.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=42&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://krzysztofadamczyk.com/2009/11/29/code-readability-uncover-the-conditions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef9affbd5f509bd5d4d1ac20cf4651aa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">krzysztofadamczyk</media:title>
		</media:content>
	</item>
		<item>
		<title>Contract-first web services with JBoss 5, Metro &amp; Spring</title>
		<link>http://krzysztofadamczyk.com/2009/11/27/contract-first-web-services-with-jboss-5-metro-spring/</link>
		<comments>http://krzysztofadamczyk.com/2009/11/27/contract-first-web-services-with-jboss-5-metro-spring/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 18:00:15 +0000</pubDate>
		<dc:creator>Krzysztof Adamczyk</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[JAX-WS]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[Jboss]]></category>
		<category><![CDATA[Metro]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[WebServices]]></category>

		<guid isPermaLink="false">http://krzysztofadamczyk.com/?p=35</guid>
		<description><![CDATA[In this article I want to show how to build a simple application deployed on JBoss 5 using Metro web services stack and Spring. The main purpose of this article is to show the configuration that needs to be done in order to create project structure, define dependencies and prepare deployable artifacts. That&#8217;s why you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=35&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this article I want to show how to build a simple application deployed on JBoss 5 using Metro web services stack and Spring. The main purpose of this article is to show the configuration that needs to be done in order to create project structure, define dependencies and prepare deployable artifacts. That&#8217;s why you will find here much more XML than Java code (unfortunately). I chose to package the whole application as an EAR archive that in turn contains web application with our web services. Of course a WAR would be perfectly enough to show web services, but I want this project to be a base for future enhancement.</p>
<p>The complete source code from this example is available <a href="http://code.google.com/p/spring-metro-demo/">here</a>.</p>
<p>What you need?</p>
<ul>
<li><a href="http://www.jboss.org/jbossas/downloads/">JBoss 5</a></li>
<li><a href="http://maven.apache.org/download.html">Maven2</a></li>
<li><a href="http://eclipse.org/">Eclipse</a></li>
<li><a href="http://www.soapui.org/">SoapUI</a></li>
</ul>
<p><span style="font-size:14pt;"><strong>Step 1- Create Maven project</strong></span></p>
<p>First of all let&#8217;s create the main project using Maven</p>
<p><strong>mvn </strong>archetype:create <strong>-DgroupId</strong>=com.krzysztofadamczyk.playground.springmetrodemo -<strong>DartifactId</strong>=spring-metro-demo</p>
<p>Next we&#8217;ll changing packaging to &#8220;pom&#8221; in the main pom file</p>
<pre class="xml">&lt;packaging&gt;pom&lt;/packaging&gt;</pre>
<p>We also have to add <em>dependencyManagement</em> section, where we put our dependencies settings:</p>
<p>For Spring:</p>
<pre class="xml">		&lt;dependency&gt;
		   &lt;groupId&gt;org.springframework&lt;/groupId&gt;
		   &lt;artifactId&gt;spring&lt;/artifactId&gt;
		   &lt;version&gt;2.5.6.SEC01&lt;/version&gt;
		&lt;/dependency&gt;</pre>
<p>Metro:</p>
<pre class="xml">		&lt;dependency&gt;
			&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-rt&lt;/artifactId&gt;
			&lt;version&gt;1.5&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.sun.tools.ws&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-tools&lt;/artifactId&gt;
			&lt;version&gt;1.5&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;javax.xml&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-api&lt;/artifactId&gt;
			&lt;version&gt;1.5&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;javax.activation&lt;/groupId&gt;
			&lt;artifactId&gt;activation&lt;/artifactId&gt;
			&lt;version&gt;1.1&lt;/version&gt;
			&lt;scope&gt;provided&lt;/scope&gt;
		&lt;/dependency&gt;</pre>
<p>For JAXWS-Spring integration we will exclude transitive dependencies to JAX-WS, since we already have JAX-WS RI in Metro:</p>
<pre class="xml">		&lt;dependency&gt;
			&lt;groupId&gt;org.jvnet.jax-ws-commons.spring
			&lt;/groupId&gt;
			&lt;artifactId&gt;jaxws-spring&lt;/artifactId&gt;
			&lt;scope&gt;runtime&lt;/scope&gt;
			&lt;version&gt;1.8&lt;/version&gt;
			&lt;exclusions&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;
					&lt;artifactId&gt;jaxws-rt&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;
					&lt;artifactId&gt;jaxws-local-transport&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;javax.servlet&lt;/groupId&gt;
					&lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.springframework&lt;/groupId&gt;
					&lt;artifactId&gt;spring&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.springframework&lt;/groupId&gt;
					&lt;artifactId&gt;spring-core&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.springframework&lt;/groupId&gt;
					&lt;artifactId&gt;spring-context&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;junit&lt;/groupId&gt;
					&lt;artifactId&gt;junit&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;javax.jws&lt;/groupId&gt;
					&lt;artifactId&gt;jsr181-api&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.bind&lt;/groupId&gt;
					&lt;artifactId&gt;jaxb-impl&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;javax.xml.soap&lt;/groupId&gt;
					&lt;artifactId&gt;saaj-api&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.messaging.saaj&lt;/groupId&gt;
					&lt;artifactId&gt;saaj-impl&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.stream.buffer&lt;/groupId&gt;
					&lt;artifactId&gt;streambuffer&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.xml.stream&lt;/groupId&gt;
					&lt;artifactId&gt;sjsxp&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;com.sun.org.apache.xml.internal&lt;/groupId&gt;
					&lt;artifactId&gt;resolver&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.jvnet.staxex&lt;/groupId&gt;
					&lt;artifactId&gt;stax-ex&lt;/artifactId&gt;
				&lt;/exclusion&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;javax.activation&lt;/groupId&gt;
					&lt;artifactId&gt;activation&lt;/artifactId&gt;
				&lt;/exclusion&gt;
			&lt;/exclusions&gt;
		&lt;/dependency&gt;</pre>
<p>We must also declare repository for JAXWS-Spring integration:</p>
<pre class="xml">    &lt;repositories&gt;
        &lt;repository&gt;
            &lt;id&gt;maven2-repository.dev.java.net&lt;/id&gt;
            &lt;name&gt;Java.net Maven 2 Repository&lt;/name&gt;
            &lt;url&gt;http://download.java.net/maven/2&lt;/url&gt;
        &lt;/repository&gt;
    &lt;/repositories&gt;</pre>
<p><span style="font-size:14pt;"><strong>Step 2 &#8211; Create web application project</strong></span></p>
<p><strong>mvn </strong>archetype:create <strong>-DartifactId</strong>=services <strong>-DarchetypeArtifactId</strong>=maven-archetype-webapp</p>
<p>Add dependencies (dependencies are marked <em>optional</em>, because I don&#8217;t want them to go into WAR file &#8211; I&#8217;ll keep them on EAR level for future use by other modules):</p>
<pre class="xml">	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;!-- JAX-WS-Spring integration --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.jvnet.jax-ws-commons.spring&lt;/groupId&gt;
			&lt;artifactId&gt;jaxws-spring&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-rt&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;javax.xml&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-api&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.sun.tools.ws&lt;/groupId&gt;
			&lt;artifactId&gt;webservices-tools&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;javax.activation&lt;/groupId&gt;
			&lt;artifactId&gt;activation&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;junit&lt;/groupId&gt;
			&lt;artifactId&gt;junit&lt;/artifactId&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;</pre>
<p>We will also define ant task that will import our WSDL and create corresponding Java classes:</p>
<pre class="xml">			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-antrun-plugin&lt;/artifactId&gt;
				&lt;executions&gt;
					&lt;execution&gt;
						&lt;id&gt;generate-bindings&lt;/id&gt;
						&lt;phase&gt;generate-sources&lt;/phase&gt;
						&lt;configuration&gt;
							&lt;tasks&gt;
								&lt;mkdir dir="${basedir}/target/generated-sources"&gt;&lt;/mkdir&gt;
								&lt;mkdir dir="${basedir}/target/throwaway-classes"&gt;&lt;/mkdir&gt;

								&lt;taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport"&gt;
									&lt;classpath refid="maven.compile.classpath" /&gt;
									&lt;classpath refid="maven.plugin.classpath" /&gt;
								&lt;/taskdef&gt;

								&lt;wsimport
									wsdl="${basedir}/src/main/webapp/WEB-INF/wsdl/EchoService.wsdl"
									sourcedestdir="${basedir}/target/generated-sources"
									destdir="${basedir}/target/throwaway-classes" fork="true"
									extension="true"&gt;&lt;/wsimport&gt;

							&lt;/tasks&gt;
							&lt;sourceRoot&gt;${basedir}/target/generated-sources&lt;/sourceRoot&gt;
						&lt;/configuration&gt;
						&lt;goals&gt;
							&lt;goal&gt;run&lt;/goal&gt;
						&lt;/goals&gt;
					&lt;/execution&gt;
				&lt;/executions&gt;
			&lt;/plugin&gt;</pre>
<p>We don&#8217;t want to mix &#8220;hand-written&#8221; and generated classes, and therefore we will use separate source directories to keep them. As there can be only one <em>sourceDirectory </em>defined in <em>build </em>section, we have to use the following plug-in to define second source directory:</p>
<pre class="xml">	&lt;build&gt;
		&lt;sourceDirectory&gt;${basedir}/src/main/java&lt;/sourceDirectory&gt;
		&lt;plugins&gt;
             &lt;plugin&gt;
                &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
                &lt;artifactId&gt;build-helper-maven-plugin&lt;/artifactId&gt;
                &lt;executions&gt;
                  &lt;execution&gt;
                    &lt;id&gt;add-source&lt;/id&gt;
                    &lt;phase&gt;generate-sources&lt;/phase&gt;
                    &lt;goals&gt;
                      &lt;goal&gt;add-source&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;configuration&gt;
                      &lt;sources&gt;
                          &lt;source&gt;${basedir}/target/generated-sources&lt;/source&gt;
                      &lt;/sources&gt;
                    &lt;/configuration&gt;
                  &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;</pre>
<p>We have to configure our web application in web.xml. Things to notice here:</p>
<ul>
<li><em>org.springframework.web.context.ContextLoaderListener</em><br />
Which initializes Spring application context</li>
<li><em>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</em><br />
which handles requests and integrates JAX-WS with Spring</li>
</ul>
<pre class="xml">&lt;!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" &gt;

&lt;web-app&gt;
	&lt;display-name&gt;Spring + Metro on JBoss demo&lt;/display-name&gt;

	&lt;context-param&gt;
		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		&lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
	&lt;/context-param&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
	&lt;/listener&gt;

	&lt;servlet&gt;
		&lt;servlet-name&gt;jaxws-servlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;com.sun.xml.ws.transport.http.servlet.WSSpringServlet&lt;/servlet-class&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;jaxws-servlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/echoService&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;session-config&gt;
		&lt;session-timeout&gt;
			30
        &lt;/session-timeout&gt;
	&lt;/session-config&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;redirect.jsp&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
&lt;/web-app&gt;</pre>
<p><span style="font-size:14pt;"><strong>Step 3 &#8211; Create EAR project</strong></span></p>
<p><strong>mvn </strong>archetype:create <strong>-DartifactId</strong>=ear</p>
<p>Ear projects dependencies will be put into EAR file. The main parts of the pom file are shown below:</p>
<pre class="xml">....
  &lt;packaging&gt;ear&lt;/packaging&gt;
  &lt;dependencies&gt;
	&lt;dependency&gt;
		  &lt;groupId&gt;com.krzysztofadamczyk.playground.springmetrodemo&lt;/groupId&gt;
		  &lt;artifactId&gt;services&lt;/artifactId&gt;
		  &lt;type&gt;war&lt;/type&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework&lt;/groupId&gt;
		&lt;artifactId&gt;spring&lt;/artifactId&gt;
	&lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.jvnet.jax-ws-commons.spring&lt;/groupId&gt;
        &lt;artifactId&gt;jaxws-spring&lt;/artifactId&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;
		&lt;artifactId&gt;webservices-rt&lt;/artifactId&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.tools.ws&lt;/groupId&gt;
		&lt;artifactId&gt;webservices-tools&lt;/artifactId&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;javax.activation&lt;/groupId&gt;
		&lt;artifactId&gt;activation&lt;/artifactId&gt;
	&lt;/dependency&gt;

  &lt;/dependencies&gt;
  &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-ear-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;modules&gt;
            &lt;webModule&gt;
              &lt;groupId&gt;com.krzysztofadamczyk.playground.springmetrodemo&lt;/groupId&gt;
              &lt;artifactId&gt;services&lt;/artifactId&gt;
              &lt;contextRoot&gt;/spring-metro-webservices&lt;/contextRoot&gt;
            &lt;/webModule&gt;
          &lt;/modules&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;</pre>
<p><span style="font-size:14pt;"><strong>Step 4 &#8211; prepare contracts</strong></span></p>
<p>Now as our project structure is more or less done we can focus on preparing contracts for the web service. In this example we will create a simple echo service which simply returns the given string with &#8220;echo&#8221; prefix. Types are defined into EchoTypes.xsd file:</p>
<pre class="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://www.krzysztofadamczyk.com/echo/" xmlns:tns="http://www.krzysztofadamczyk.com/echo/"
	elementFormDefault="qualified"&gt;

	&lt;xs:element name="EchoRequest"&gt;
		&lt;xs:complexType&gt;
			&lt;xs:all&gt;
				&lt;xs:element name="text" type="xs:string" /&gt;
			&lt;/xs:all&gt;
		&lt;/xs:complexType&gt;
	&lt;/xs:element&gt;

	&lt;xs:element name="EchoResponse"&gt;
		&lt;xs:complexType&gt;
			&lt;xs:all&gt;
				&lt;xs:element name="text" type="xs:string" /&gt;
			&lt;/xs:all&gt;
		&lt;/xs:complexType&gt;
	&lt;/xs:element&gt;
&lt;/schema&gt;</pre>
<p>The WSDL file is presented below:</p>
<pre class="xml">&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
&lt;wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://www.krzysztofadamczyk.com/echo/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:echo="http://www.krzysztofadamczyk.com/echo/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	name="echo" targetNamespace="http://www.krzysztofadamczyk.com/echo/"&gt;
	&lt;wsdl:types&gt;
		&lt;xsd:schema&gt;
			&lt;xsd:import namespace="http://www.krzysztofadamczyk.com/echo/"
				schemaLocation="EchoTypes.xsd" /&gt;
		&lt;/xsd:schema&gt;
	&lt;/wsdl:types&gt;

	&lt;wsdl:message name="EchoRequest"&gt;
		&lt;wsdl:part name="EchoRequest" element="echo:EchoRequest" /&gt;
	&lt;/wsdl:message&gt;
	&lt;wsdl:message name="EchoResponse"&gt;
		&lt;wsdl:part name="EchoResponse" element="echo:EchoResponse"  /&gt;
	&lt;/wsdl:message&gt;

	&lt;wsdl:portType name="EchoPort"&gt;
		&lt;wsdl:operation name="sayEcho"&gt;
			&lt;wsdl:input message="tns:EchoRequest" /&gt;
			&lt;wsdl:output message="tns:EchoResponse" /&gt;
		&lt;/wsdl:operation&gt;
	&lt;/wsdl:portType&gt;

	&lt;wsdl:binding name="echoSOAP" type="tns:EchoPort"&gt;
		&lt;soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" /&gt;
		&lt;wsdl:operation name="sayEcho"&gt;
			&lt;soap:operation soapAction="http://www.krzysztofadamczyk.com/echo/SayEcho" /&gt;
			&lt;wsdl:input&gt;
				&lt;soap:body use="literal" /&gt;
			&lt;/wsdl:input&gt;
			&lt;wsdl:output&gt;
				&lt;soap:body use="literal" /&gt;
			&lt;/wsdl:output&gt;
		&lt;/wsdl:operation&gt;
	&lt;/wsdl:binding&gt;
	&lt;wsdl:service name="EchoService"&gt;
		&lt;wsdl:port binding="tns:echoSOAP" name="echoSOAP"&gt;
			&lt;soap:address location="http://www.example.org/" /&gt;
		&lt;/wsdl:port&gt;
	&lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;</pre>
<p><span style="font-size:14pt;"><strong>Step 5 &#8211; create service endpoint implementation</strong></span></p>
<p>After building the project with <strong>mvn install</strong> you can see a few Java classes generated in target\generated-sources\. EchoPort is our generated Service Endpoint Interface. We will now create the service implementation as follows:</p>
<pre class="java">package com.krzysztofadamczyk.playground.springmetrodemo;

import javax.jws.WebService;

import com.krzysztofadamczyk.echo.EchoPort;
import com.krzysztofadamczyk.echo.EchoRequest;
import com.krzysztofadamczyk.echo.EchoResponse;

@WebService(name = "EchoPort", targetNamespace = "http://www.krzysztofadamczyk.com/echo/",
endpointInterface = "com.krzysztofadamczyk.echo.EchoPort")
public class EchoServiceImpl implements EchoPort {

    public EchoResponse sayEcho(final EchoRequest echoRequest) {
        final EchoResponse result = new EchoResponse();
        result.setText("echo: " + echoRequest.getText());
        return result;
    }
}</pre>
<p><span style="font-size:14pt;"><strong>Step 6 &#8211; define application context</strong></span></p>
<p>Now it&#8217;s time to define application context. Here we take advantage of JAXWS-Spring integration using specialized schema to define our web service. Note that our endpoint implementation is a standard Spring bean and we can use here dependency injection or any other Spring technique.</p>
<pre class="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ws="http://jax-ws.dev.java.net/spring/core"
	xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
	xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

	http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd

http://jax-ws.dev.java.net/spring/servlet

        http://jax-ws.dev.java.net/spring/servlet.xsd"&gt;

	&lt;wss:binding url="/echoService"&gt;
		&lt;wss:service&gt;
			&lt;ws:service bean="#echoService" /&gt;
		&lt;/wss:service&gt;
	&lt;/wss:binding&gt;

	&lt;!-- this bean implements web service methods --&gt;
	&lt;bean id="echoService" class="com.krzysztofadamczyk.playground.springmetrodemo.EchoServiceImpl" /&gt;
&lt;/beans&gt;</pre>
<p><span style="font-size:14pt;"><strong>Step 7 &#8211; deploy and test project</strong></span></p>
<p>After successfull build, copy EAR file (which can be found in ear/target) into jboss_home/server/default/deploy, and start server. Run SoapUI and create new project with the following WSDL location:</p>
<pre class="plain">http://localhost:8080/spring-metro-webservices/echoService?wsdl</pre>
<p>Where:</p>
<ul>
<li>spring-metro-webservices &#8211; is the web application context root defined in EAR project pom</li>
<li>echoService &#8211; is an URL pattern (defined in web.xml, associated with WSSpringServlet), and also defined as binding URL in applicationContext.xml</li>
</ul>
<p>SoapUI will generate a sample request for you. The result looks as follows:</p>
<table style="width:auto;" border="0">
<tbody>
<tr>
<td><a href="http://picasaweb.google.com/lh/photo/_urXg7sNy54OiOMaDmPWUg?feat=embedwebsite"><img src="http://lh3.ggpht.com/_0zhWBYvrXoE/Suikb_aHriI/AAAAAAAAANc/XgDr8S3t5IY/s400/springmetro1.jpg" alt="" /></a></td>
</tr>
<tr>
<td style="font-family:arial,sans-serif;font-size:11px;text-align:right;">From <a href="http://picasaweb.google.com/krzysztof.adamczyk/Blog?feat=embedwebsite">Blog</a></td>
</tr>
</tbody>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/krzysztofadamczyk.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/krzysztofadamczyk.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/krzysztofadamczyk.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=35&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://krzysztofadamczyk.com/2009/11/27/contract-first-web-services-with-jboss-5-metro-spring/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef9affbd5f509bd5d4d1ac20cf4651aa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">krzysztofadamczyk</media:title>
		</media:content>

		<media:content url="http://lh3.ggpht.com/_0zhWBYvrXoE/Suikb_aHriI/AAAAAAAAANc/XgDr8S3t5IY/s400/springmetro1.jpg" medium="image" />
	</item>
		<item>
		<title>First steps with Groovy</title>
		<link>http://krzysztofadamczyk.com/2009/11/27/first-steps-with-groovy/</link>
		<comments>http://krzysztofadamczyk.com/2009/11/27/first-steps-with-groovy/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 16:42:42 +0000</pubDate>
		<dc:creator>Krzysztof Adamczyk</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://krzysztofadamczyk.com/?p=27</guid>
		<description><![CDATA[Inspired by Scott Davies and his great talk during Java Developers&#8217; Day in Krakow I decided to try out Groovy. As a first step I want to create a running application which contains both Java and Groovy classes talking to each other. I&#8217;ll also take Scott&#8217;s idea to use a Geocoding RESTful web service to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=27&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Inspired by Scott Davies and his great talk during <a href="http://09.jdd.org.pl/">Java Developers&#8217; Day</a> in Krakow I decided to try out Groovy. As a first step I want to create a running application which contains both Java and Groovy classes talking to each other. I&#8217;ll also take Scott&#8217;s idea to use a Geocoding RESTful web service to show how simple dealing with XML in Groovy is. So &#8211; let&#8217;s start.</p>
<ul>
<li><span style="font-size:14pt;"><strong>Step 0 &#8211; Download software</strong></span></li>
</ul>
<p><a href="http://groovy.codehaus.org/Download">Groovy</a>, <a href="http://groovy.codehaus.org/Eclipse+Plugin">Eclipse plug-in</a>,</p>
<ul>
<li><span style="font-size:14pt;"><strong>Step 1 &#8211; create Maven project with GMaven<br />
</strong></span></li>
</ul>
<p><strong>mvn archetype:generate</strong> <strong>-DarchetypeGroupId</strong>=org.codehaus.groovy.maven.archetypes <strong>-DarchetypeArtifactId</strong>=gmaven-archetype-basic <strong>-DarchetypeVersion</strong>=1.0-rc-5 <strong>-DgroupId</strong>=com.krzysztofadamczyk.playground.geocoder <strong>-DartifactId</strong>=geocoder<em></em></p>
<ul>
<li><span style="font-size:14pt;"><strong>Step 2 &#8211; build project &amp; import to Eclipse<br />
</strong></span></li>
</ul>
<p>Add &#8220;java&#8221; directories to both src/main and src/test directories</p>
<p><strong>mvn</strong> install</p>
<p><strong>mvn</strong> -Declipse.downloadSources <strong>eclipse:eclipse</strong></p>
<ul>
<li><span style="font-size:14pt;"><strong>Step 3 &#8211; implement domain class in Java</strong></span></li>
</ul>
<pre class="java">package com.krzysztofadamczyk.playground.geocoder.domain;

public class Location {

    private final double longitude;
    private final double latitude;

    public Location(final double longitude, final double latitude) {
        this.longitude = longitude;
        this.latitude = latitude;
    }

    public double getLongitude() {
        return this.longitude;
    }

    public double getLatitude() {
        return this.latitude;
    }

    public String toString() {
        return "Location [latitude=" + this.latitude + ", longitude=" + this.longitude + "]";
    }

}</pre>
<ul>
<li><span style="font-size:14pt;"><strong>Step 4 &#8211; </strong></span><span style="font-size:14pt;"><strong>implement web service client in Groovy</strong></span></li>
</ul>
<pre class="groovy">package com.krzysztofadamczyk.playground.geocoder

import com.krzysztofadamczyk.playground.geocoder.domain.Location
public class GroovyGeocoder{
	private final def BASEURL = "http://worldkit.org/geocoder/rest/?city=";

	public def Location getLocation(String city, String twoLetterCountryCode) {
		def wsAddress = BASEURL + city + "," + twoLetterCountryCode
		def geocoded = wsAddress.toURL().text
		def RDF = new XmlSlurper().parseText(geocoded)

		new Location(Double.valueOf(RDF.Point.long.text() ), Double.valueOf(RDF.Point.lat.text()))
	}

}</pre>
<ul>
<li><strong><span style="font-size:14pt;">Step 5 &#8211; Implement main class in Java</span></strong></li>
</ul>
<pre class="java">package com.krzysztofadamczyk.playground.geocoder.runner;

import com.krzysztofadamczyk.playground.geocoder.GroovyGeocoder;
import com.krzysztofadamczyk.playground.geocoder.domain.Location;

public class Runner {
    public static void main(final String[] args) {
        final GroovyGeocoder geocoder = new GroovyGeocoder();
        final Location location = geocoder.getLocation("Krakow", "PL");
        System.out.println(location);
    }

}</pre>
<p>Running this simple example produces the following output:</p>
<pre class="java">Location [latitude=50.0833333, longitude=19.9166667]</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/krzysztofadamczyk.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/krzysztofadamczyk.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/krzysztofadamczyk.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=krzysztofadamczyk.com&amp;blog=20688394&amp;post=27&amp;subd=krzysztofadamczyk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://krzysztofadamczyk.com/2009/11/27/first-steps-with-groovy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef9affbd5f509bd5d4d1ac20cf4651aa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">krzysztofadamczyk</media:title>
		</media:content>
	</item>
	</channel>
</rss>
