<?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/"
	>

<channel>
	<title>Java crumbs &#187; Spring</title>
	<atom:link href="http://blog.krecan.net/category/spring/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.krecan.net</link>
	<description>Short remarks from Java world</description>
	<lastBuildDate>Tue, 31 Jan 2012 20:13:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>WS testing</title>
		<link>http://blog.krecan.net/2011/03/08/on-ws-testing/</link>
		<comments>http://blog.krecan.net/2011/03/08/on-ws-testing/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 17:32:04 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Tests]]></category>
		<category><![CDATA[WS]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=836</guid>
		<description><![CDATA[This post recaps some results of my experiments with WS testing. In last few months I have been working on several projects – Spring WS Test, Spring WS 2.0 testing support and finally on Smock. All of them reflect different approaches to WS testing. Today I am going recapitulate my findings focusing on testing producer/server [...]]]></description>
			<content:encoded><![CDATA[<p>This post recaps some results of my experiments with WS testing. In last few months I have been working on several projects – <a href="http://javacrumbs.net/spring-ws-test/">Spring WS Test</a>, <a href="http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d0e3303">Spring WS 2.0 testing support</a> and finally on <a href="http://code.google.com/p/smock/">Smock</a>. All of them reflect different approaches to WS testing. Today I am going recapitulate my findings focusing on testing producer/server side code. Consumer/client side will be covered in a following post.</p>
<p><strong>Simple service, simple test</strong></p>
<p>You may wonder what's the problem? Testing web services is easy. We just need to call the endpoint end verify the response. For a simple web service we can write a simple test like this</p>
<pre name="code" class="java">
@Test
public void testPlus()
{
	assertEquals(3, endpoint.plus(1, 2));
}
</pre>
<p>The test is same as if I was testing a normal method. </p>
<p><strong>Web Services tend to be complex</strong></p>
<p>The trouble is that web services tend to be complex. Normal Java methods usually have few relatively simple parameters. On the other hand, web service request or response could be quite complicated which makes the service endpoint hard to test. </p>
<pre name="code" class="java">
GetFlightsRequest request = new GetFlightsRequest();
request.setFrom("PRG");
request.setTo("DUB");
request.setServiceClass(ServiceClass.BUSINESS);
request.setDepartureDate(DatatypeFactory.newInstance().newXMLGregorianCalendarDate(2011, 02, 23, 0));
//more setter calls could be here

GetFlightsResponse response = endpoint.getFlights(request);

List&lt;Flight&gt; flights = response.getFlight();
assertEquals(1, flights.size());
assertEquals(ServiceClass.BUSINESS, flights.get(0).getServiceClass());
//more assertions here
</pre>
<p>Such tests are bearable only until certain level of complexity. From certain level it's real pain. I really hate to call  twenty setters to construct several levels of nested XML hierarchy and then to call dozens of getters to validate the response. </p>
<p><strong>To define XML use ... the XML</strong><br />
The problem is that we want to create or validate an XML structure using wrong language. Java is just not suitable for the task. The best language to describe XML is, surprise, surprise, the XML. Would not it be easier to create XML files containing the request and response and just use them in the test?</p>
<pre name="code" class="java">
GetFlightsRequest request = JAXB.unmarshal(getStream("request1.xml"), GetFlightsRequest.class);

GetFlightsResponse response = endpoint.getFlights(request);

DOMResult domResponse = new DOMResult();
JAXB.marshal(response, domResponse);

XMLUnit.setIgnoreWhitespace(true);
XMLAssert.assertXMLEqual(getDocument("response1.xml"), (Document)domResponse.getNode());
</pre>
<p>It's much better. This test will look exactly the same way regardless the complexity of the service. But it still have some shortcomings. The biggest one is that usually testing using only one request is not sufficient. I'd like to test the service using different inputs. In such case I have to create lot of  XML files that differ just in few elements. It's a maintenance nightmare. If you change the service, you also have to change all the XML files. </p>
<p><strong>Smock comes to help</strong><br />
Up until now we managed to test without any special framework except <code>XMLUnit</code>. Now we will start to use my precious <a href="http://code.google.com/p/smock/">Smock</a> library. The test above can be rewritten to this form.</p>
<pre name="code" class="java">
Map&lt;String, Object&gt; params = new HashMap&lt;String, Object&gt;();
params.put("from", "DUB");
params.put("to", "JFK");
params.put("serviceClass", "economy");
GetFlightsRequest request = createRequest(
					withMessage("request-context-groovy.xml")
					.withParameters(params), GetFlightsRequest.class);

GetFlightsResponse response = endpoint.getFlights(request);

validate(response, request)
	.andExpect(message("response-context-groovy.xml")
	.withParameter("serviceClass", "economy"));
</pre>
<p>The test is quite similar as the previous one. The difference is that it uses statically imported method <code>createRequest</code> to create a request and <code>validate</code> method to validate the response. The main advantage is that Smock methods support templates. So we can set just values we want to, the rest can be driven by the template. Moreover we do not need to deal with the request structure, parameters can be set into a simple flat map.</p>
<pre name="code" class="xml">
&lt;ns1:GetFlightsRequest&gt;
	&lt;ns1:from&gt;${from}&lt;/ns1:from&gt;
	&lt;ns1:to&gt;${to}&lt;/ns1:to&gt;
	&lt;ns1:departureDate&gt;2001-01-01&lt;/ns1:departureDate&gt;
	&lt;ns1:serviceClass&gt;${serviceClass}&lt;/ns1:serviceClass&gt;
&lt;/ns1:GetFlightsRequest&gt;
</pre>
<p>Templates are even more useful when comparing the response</p>
<pre name="code" class="xml">
&lt;ns3:GetFlightsResponse&gt;
	&lt;ns3:flight&gt;
		&lt;ns2:number&gt;OK1324&lt;/ns2:number&gt;
		&lt;ns2:departureTime&gt;2011-02-19T10:00:00&lt;/ns2:departureTime&gt;
		&lt;ns2:from&gt;
			&lt;ns2:code&gt;${GetFlightsRequest.from}&lt;/ns2:code&gt;
			&lt;ns2:name&gt;${IGNORE}&lt;/ns2:name&gt;
			&lt;ns2:city&gt;${IGNORE}&lt;/ns2:city&gt;
		&lt;/ns2:from&gt;
		&lt;ns2:arrivalTime&gt;2011-02-19T12:00:00&lt;/ns2:arrivalTime&gt;
		&lt;ns2:to&gt;
			&lt;ns2:code&gt;${GetFlightsRequest.to}&lt;/ns2:code&gt;
			&lt;ns2:name&gt;${IGNORE}&lt;/ns2:name&gt;
			&lt;ns2:city&gt;${IGNORE}&lt;/ns2:city&gt;
		&lt;/ns2:to&gt;
		&lt;ns2:serviceClass&gt;${serviceClass}&lt;/ns2:serviceClass&gt;
	&lt;/ns3:flight&gt;
&lt;/ns3:GetFlightsResponse&gt;
</pre>
<p>We can ignore some elements, we can compare values based on the request elements and so on. Moreover, when we are using Smock library, we can leverage Spring WS 2.0 testing capabilities that Smock builds on. We can for example validate that the response is valid regarding to its schema.</p>
<pre name="code" class="java">
validate(response).andExpect(validPayload(resource("xsd/messages.xsd")));
</pre>
<p>Cool, isn't it?</p>
<p><strong>Testing the configuration</strong><br />
Sometimes unit test are not sufficient. Sometimes we want to test the configuration, interceptors, error handling and so on. No problem. If you are using Spring WS 2, you can use the built-in testing library. If you need templates or if you are using different framework like Axis 2, you can use Smock. The test looks similar.</p>
<pre name="code" class="java">
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring-ws-servlet.xml")
public class GroovyEndpointTest {

	private MockWebServiceClient wsMockClient;

	@Autowired
	public void setApplicationContext(ApplicationContext context)
	{
		wsMockClient = createClient(context);
	}

	@Test
	public void testResponseTemplate() throws Exception {
		Map&lt;String, Object&gt; params = new HashMap&lt;String, Object&gt;();
		params.put("from", "DUB");
		params.put("to", "JFK");
		params.put("serviceClass", "economy");
		wsMockClient.sendRequest(
			withMessage("request-context-groovy.xml")
			  .withParameters(params))
			.andExpect(message("response-context-groovy.xml")
			  .withParameter("serviceClass", "economy"));
	}
</pre>
<p>The only difference is that we have to bootstrap the application context. Having done this, we can use the mock web service client to call our services. Even though this kind of tests is more complicated, we can use it to test object-XML mapping, endpoint resolution, error handling and configuration in general.</p>
<p>We have seen several different methods of WS testing. Each of them have advantages and disadvantages. If you keep you services simple, your tests are simple too. If the service is more complex, it makes sense to use XML for the test. Either using your own helper methods, <a href="http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d0e3303">Spring WS 2.0 test support</a> or <a href="http://code.google.com/p/smock/">Smock</a>. </p>
<p><em>All the samples could be downloaded from <a href="http://code.google.com/p/smock/wiki/Samples">here</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2011/03/08/on-ws-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing fluent API</title>
		<link>http://blog.krecan.net/2010/07/10/writing-fluent-api/</link>
		<comments>http://blog.krecan.net/2010/07/10/writing-fluent-api/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 13:12:19 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[WS]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=603</guid>
		<description><![CDATA[In recent weeks I have been working with Arjen Poutsma on a brand new testing support for Spring Web Services. At least Arjen has been working, I have been just generating crazy ideas and he kept explaining me why we can't use them. But it was quite interesting experience and I have learned a lot [...]]]></description>
			<content:encoded><![CDATA[<p>In recent weeks I have been working with Arjen Poutsma on a brand new testing support for <a href="http://static.springsource.org/spring-ws/sites/1.5/">Spring Web Services</a>. At least Arjen has been working, I have been just generating crazy ideas and he kept explaining me why we can't use them.</p>
<p>But it was quite interesting experience and I have learned a lot about fluent API design. Since it was my first fluent API and I am not an API expert, please take everything I mention here with grain of salt.</p>
<p>The task is simple. We need a way how to configure a mock. This mock has to validate that requests generated by our application are correct and after that the mock has to return some response. We want to write something like this:</p>
<blockquote><p>Computer, when someone is trying to send a request, verify that the request contains value “a”, has header “header” and then respond with value “b”.</p></blockquote>
<p>The requirements for the API are following:</p>
<ul>
<li>It has to be simple for users. Mainly it has to be friendly to GUI addicts like me, that rely on code-completion all the time.</li>
<li>The library itself has to be simple</li>
<li>The API should be as fluent as possible</li>
<li>It has to be extensible</li>
</ul>
<p>In the next part, I will try to describe several variants of the solution, each of them fulfilling the requirements differently. Please keep in mind that the code is simplified, it focuses solely on the API, not on the implementation. Moreover, the classes have been renamed to show what their main purpose is. </p>
<blockquote><p>All characters appearing in this work are fictitious. Any resemblance to real persons, living or dead, is purely coincidental.</p></blockquote>
<h2>Interface based version</h2>
<p><a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/fluentapi/src/main/java/net/javacrumbs/fluentapi1/">code</a><br />
The first variant is based mainly on interfaces. The test itself looks like this</p>
<pre name="code" class="java">
	@Test
	public void testMock()
	{
		Mock mock = new Mock();
		mock.whenConnecting().expectValue("a").and().expectHeader("header").andRespondWithValue("b");

		//test code

		mock.verify();
	}
</pre>
<p>There is one entry point, class Mock</p>
<pre name="code" class="java">
public class Mock {

	public RequestExpectations whenConnecting()
	{
		return new MockInternal();
	}

	public void verify()
	{
		//do something
	}
}
</pre>
<p>It just returns an internal class that implements RequestExpectations interface. </p>
<pre name="code" class="java">
public interface RequestExpectations {

    ResponseActions expectValue(String value);

    ResponseActions expectHeader(String name);
}
</pre>
<p>All methods of this interface return ResponseActions interface </p>
<pre name="code" class="java">
public interface ResponseActions {

	RequestExpectations and();

	void andRespondWithValue(String value);

	void andRespondWithError();

}
</pre>
<p>Please note that and() method allows chaining of request expectation. </p>
<p>This API is really IDE friendly. Code completion works like a charm. It's quite simple both from outside and inside. But this API  has one big flaw. It's not extensible. Imagine that we would like to add an expectation that verifies a digital signature. We would have to add a method to the RequestExpectations interface. It is not possible neither for third parties nor for us, since this change would break backward compatibility. </p>
<h2>Static factory</h2>
<p><a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/fluentapi/src/main/java/net/javacrumbs/fluentapi2/">code</a><br />
We can split the functionality and allow others to provide their own validators and response generators. We just have to change the interfaces</p>
<pre name="code" class="java">
public interface RequestExpectations {

    ResponseActions expect(RequestMatcher matcher);
}
</pre>
<p>and</p>
<pre name="code" class="java">
public interface ResponseActions {

	RequestExpectations and();

	void andRespond(ResponseCallback callback);
}
</pre>
<p>Now we have made the API extensible, but we have to provide an easy way how to create RequestMatchers and ResponseCallbacks. One way how to do it is a statically imported static factory. </p>
<pre name="code" class="java">
public class StaticFactory {
	public static RequestMatcher value(String value)
	{
		return new RequestMatcher() {
			public void match(Object someParams) {
				//do something
			}
		};
	}
	public static ResponseCallback withValue(String value)
	{
		return new ResponseCallback() {
			public void doWithResponse(Object someParams) {
				//do something
			}
		};
	}
}
</pre>
<p>The test then can look like this.</p>
<pre name="code" class="java">
import static net.javacrumbs.fluentapi2.StaticFactory.*;

public class MockTest {

	@Test
	public void testMock()
	{
		Mock mock = new Mock();
		mock.whenConnecting().expect(value("a")).and().expect(header("header")).andRespond(withValue("b"));

		//test code

		mock.verify();
	}
}
</pre>
<p>Such API is also fluent. It even resembles <a href="http://easymock.org/">EasyMock</a> API. The issue here is that code completion does not work as well as before. In Eclipse you have to type first letter of the method name before Ctrl+Space starts working. In Idea you have to press Ctrl+Shift+Space. But the advantage is that everyone can provide their own factory and extend  the library seamlessly and consistently.</p>
<h2>Super-static variant</h2>
<p><a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/fluentapi/src/main/java/net/javacrumbs/fluentapi3/">code</a><br />
We can go event further. We can get rid of RequestExpectations interface, remove Mock class and do statically most of the stuff. The test can look like this</p>
<pre name="code" class="java">
import static net.javacrumbs.fluentapi3.StaticFactory.*;

public class MockTest {

	@Test
	public void testMock()
	{
		expect(value("a")).andExpect(header("header")).andRespond(withValue("b"));

		//test code

		verify();
	}
}
</pre>
<p>It's simple and elegant. We even got rid of the strange and() method. The downside is that we usually have to use some ThreadLocals internally. But it looks almost like EasyMock. Cool.</p>
<h2>Inheritance</h2>
<p><a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/fluentapi/src/main/java/net/javacrumbs/fluentapi4/">code</a><br />
Some people (like me) do not like static methods. It does not feel right, it's not object oriented programming. Can we do something similar, but dynamic? Yes, we can.</p>
<p>We just have to use inheritance. Just delete static keywords from the methods in StaticFactory class. We will also  rename the class itself because it's not static any more.</p>
<p>We get</p>
<pre name="code" class="java">
public class MockTest extends MockFactory{

	@Test
	public void testMock()
	{
		expect(value("a")).andExpect(header("header")).andRespond(withValue("b"));

		//test code

		verify();
	}
}
</pre>
<p>The downside is, that we have to extend our class from MockFactory. Sometimes it's not possible. No problem, we can use a trick I have seen in <a href="http://camel.apache.org/routes.html">Apache Camel DSL</a>.</p>
<pre name="code" class="java">
public class MockTest{
	@Test
	public void testMock()
	{
		MockFactory mockFactory = new MockFactory()
		{
			protected void configure() {
				expect(value("a")).andExpect(header("header")).andRespond(withValue("b"));
			};
		};

		//test code

		mockFactory.verify();
	}
}
</pre>
<p>It's not as elegant as the direct inheritance, but it works. If we are brave enough, we can even use a closure.</p>
<pre name="code" class="java">
public class MockTest extends MockFactory{
	@Test
	public void testMockClosure()
	{
		MockFactory mockFactory = new MockFactory()
		{{
				expect(value("a")).andExpect(header("header")).andRespond(withValue("b"));
		}};

		//test code

		mockFactory.verify();
	}
}
</pre>
<p>(I bet you did not know that Java has closures already). </p>
<p>So I have shown you four variants, which one is the best? I do not know, each of them has it's pros and cons. I personally like the last one the most. But the super static variant is not bad neither. Or the static? Or some mix between them? Some other? You have to make your own opinion.</p>
<p>References:<br />
<a href="http://martinfowler.com/bliki/FluentInterface.html">http://martinfowler.com/bliki/FluentInterface.html</a><br />
<a href="http://martinfowler.com/dslwip/InternalOverview.html">http://martinfowler.com/dslwip/InternalOverview.html</a><br />
<a href="http://camel.apache.org/routes.html">http://camel.apache.org/routes.html</a><br />
<a href="http://easymock.org/">http://easymock.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2010/07/10/writing-fluent-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring WS Security on both client and server</title>
		<link>http://blog.krecan.net/2010/06/07/spring-ws-security-on-both-client-and-server/</link>
		<comments>http://blog.krecan.net/2010/06/07/spring-ws-security-on-both-client-and-server/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 11:17:13 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[WS]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[spring-ws]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=578</guid>
		<description><![CDATA[Recently, I have been playing with Spring WS with WS-Security. I just want to write down how it works. Do not except anything special, just simple example of basic security operations. The example We want to implement both client and server side. The client will sign the message, encrypt some part of it and add [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I have been playing with Spring WS with WS-Security. I just want to write down how it works. Do not except anything special, just simple example of basic security operations.</p>
<h2>The example</h2>
<p>We want to implement both client and server side. The client will sign the message, encrypt some part of it and add a timestamp. To make it more complex and real-life like we will sign the message using private key with alias “client” and encrypt the message using public key called “server”. Server will validate that the request is valid and will just sign the response using his key called “server”. Please note that I have picked <a href="http://ws.apache.org/wss4j/">Wss4j</a> implementation because the configuration seemed to be easier than Xws.</p>
<h2>Client</h2>
<p>It's easy to do configure client interceptor like this (<a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/simple-server-test/branches/simple-server-test-security/simple-server-test/src/main/resources/spring/client/secured-client-config.xml">full configuration</a>).</p>
<pre name="code" class="xml">
&lt;bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"&gt;
	&lt;property name="interceptors"&gt;
		&lt;list&gt;
			&lt;ref local="wsClientSecurityInterceptor"/&gt;
		&lt;/list&gt;
	&lt;/property&gt;
	...
&lt;/bean&gt;

&lt;bean id="wsClientSecurityInterceptor"
	class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor"&gt;
	&lt;property name="securementActions" value="Timestamp Signature Encrypt" /&gt;
	&lt;!-- Key alias for signature --&gt;
	&lt;property name="securementUsername" value="client" /&gt;
	&lt;property name="securementPassword" value="" /&gt;
	&lt;property name="securementSignatureCrypto" ref="clientCrypto"/&gt;
	&lt;property name="securementEncryptionCrypto" ref="clientCrypto"/&gt;
	&lt;property name="securementEncryptionParts" value="{Content}{http://javacrumbs.net/calc}a"/&gt;
	&lt;!-- Key alias for encryption --&gt;
	&lt;property name="securementEncryptionUser" value="server"/&gt;

	&lt;!-- Validation config --&gt;
	&lt;property name="validationActions" value="Signature" /&gt;
	&lt;property name="validationSignatureCrypto" ref="clientCrypto"/&gt;
&lt;/bean&gt;

&lt;bean id="clientCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean"&gt;
    &lt;property name="keyStorePassword" value="mypasswd"/&gt;
    &lt;property name="keyStoreLocation" value="classpath:security/client-keystore.jks"/&gt;
&lt;/bean&gt;
</pre>
<p>As you can see, there is nothing special. We just define which actions to take and properties. The only confusing part is, that key alias is defined as “securementUsername”.</p>
<p>Whit this configuration we will get following SOAP message.</p>
<pre name="code" class="xml">
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
	xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&gt;
	&lt;SOAP-ENV:Header&gt;
		&lt;wsse:Security
			xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
			SOAP-ENV:mustUnderstand="1"&gt;
			&lt;xenc:EncryptedKey Id="EncKeyId-F5114C147B958E706212759086159355"
				xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&gt;
				&lt;xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /&gt;
				&lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
					&lt;wsse:SecurityTokenReference
						xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
						&lt;ds:X509Data&gt;
							&lt;ds:X509IssuerSerial&gt;
								&lt;ds:X509IssuerName&gt;CN=Test Server,OU=Test&lt;/ds:X509IssuerName&gt;
								&lt;ds:X509SerialNumber&gt;1275904530&lt;/ds:X509SerialNumber&gt;
							&lt;/ds:X509IssuerSerial&gt;
						&lt;/ds:X509Data&gt;
					&lt;/wsse:SecurityTokenReference&gt;
				&lt;/ds:KeyInfo&gt;
				&lt;xenc:CipherData&gt;
					&lt;xenc:CipherValue&gt;fwFM7ShJ1xd7dTGrkh0410sTmW92OPB1q1fpzB21XFIe36siDDJWGgbw5B94yjmGK2YaPOWLb7cpVTYPzc9VUDs7Jc42CtrhT2H6eZ7CDiA60Ugz+qi2UyyfMDK6Vrdj9J68rij5P12AiBeTnd2wlhI29+71XbUpD5weHDHjMtQ=
					&lt;/xenc:CipherValue&gt;
				&lt;/xenc:CipherData&gt;
				&lt;xenc:ReferenceList&gt;
					&lt;xenc:DataReference URI="#EncDataId-4" /&gt;
				&lt;/xenc:ReferenceList&gt;
			&lt;/xenc:EncryptedKey&gt;
			&lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
				Id="Signature-2"&gt;
				&lt;ds:SignedInfo&gt;
					&lt;ds:CanonicalizationMethod
						Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
					&lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
					&lt;ds:Reference URI="#id-3"&gt;
						&lt;ds:Transforms&gt;
							&lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
						&lt;/ds:Transforms&gt;
						&lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
						&lt;ds:DigestValue&gt;AU9utUgz5RylYCRDUAO0JWM48kM=&lt;/ds:DigestValue&gt;
					&lt;/ds:Reference&gt;
				&lt;/ds:SignedInfo&gt;
				&lt;ds:SignatureValue&gt;
					NHjjgpb9/alUOq50CqPKLcdYrp7edYdKJDNvIhh+2OAhYdDvZmD1qGsVKd1H9oKPF17uaF2Sv3aY
					0le6BrvzVx3n2+nYYlHwAWlzBk7wsBt4vLll6q6juLCP+siupTIb1PeZDf3WrAbHUQh5oqjD6cZB
					Sc89pDspWRABQ8wPxYE=
&lt;/ds:SignatureValue&gt;
				&lt;ds:KeyInfo Id="KeyId-F5114C147B958E706212759086157652"&gt;
					&lt;wsse:SecurityTokenReference
						xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
						wsu:Id="STRId-F5114C147B958E706212759086157673"
						xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
						&lt;ds:X509Data&gt;
							&lt;ds:X509IssuerSerial&gt;
								&lt;ds:X509IssuerName&gt;CN=Lukas Krecan,OU=Test&lt;/ds:X509IssuerName&gt;
								&lt;ds:X509SerialNumber&gt;1275900789&lt;/ds:X509SerialNumber&gt;
							&lt;/ds:X509IssuerSerial&gt;
						&lt;/ds:X509Data&gt;
					&lt;/wsse:SecurityTokenReference&gt;
				&lt;/ds:KeyInfo&gt;
			&lt;/ds:Signature&gt;
			&lt;wsu:Timestamp
				xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
				wsu:Id="Timestamp-1"&gt;
				&lt;wsu:Created&gt;2010-06-07T11:03:35.749Z&lt;/wsu:Created&gt;
				&lt;wsu:Expires&gt;2010-06-07T11:08:35.749Z&lt;/wsu:Expires&gt;
			&lt;/wsu:Timestamp&gt;
		&lt;/wsse:Security&gt;
	&lt;/SOAP-ENV:Header&gt;
	&lt;SOAP-ENV:Body
		xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
		wsu:Id="id-3"&gt;
		&lt;ns2:plusRequest xmlns:ns2="http://javacrumbs.net/calc"&gt;
			&lt;ns2:a&gt;
				&lt;xenc:EncryptedData Id="EncDataId-4"
					Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&gt;
					&lt;xenc:EncryptionMethod
						Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" /&gt;
					&lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
						&lt;wsse:SecurityTokenReference
							xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
							&lt;wsse:Reference URI="#EncKeyId-F5114C147B958E706212759086159355"
								xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" /&gt;
						&lt;/wsse:SecurityTokenReference&gt;
					&lt;/ds:KeyInfo&gt;
					&lt;xenc:CipherData&gt;
						&lt;xenc:CipherValue&gt;81TEtUhHXo6iZeAmYrtYlm2ObAqOBpjfzf2VOVUg4Hs=
						&lt;/xenc:CipherValue&gt;
					&lt;/xenc:CipherData&gt;
				&lt;/xenc:EncryptedData&gt;
			&lt;/ns2:a&gt;
			&lt;ns2:b&gt;2&lt;/ns2:b&gt;
		&lt;/ns2:plusRequest&gt;
	&lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
</pre>
<h2>Server config</h2>
<p>To configure server, you have to define Spring WS server interceptor like this (<a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/simple-server-test/branches/simple-server-test-security/simple-server-test/src/main/webapp/WEB-INF/secured-spring-ws-servlet.xml">full example</a>).</p>
<pre name="code" class="xml">
&lt;bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"&gt;
	&lt;property name="interceptors"&gt;
		&lt;list&gt;
			&lt;ref local="wsServerSecurityInterceptor" /&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="wsServerSecurityInterceptor"	class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor"&gt;
	&lt;!-- Validation part --&gt;
	&lt;property name="validationActions" value="Timestamp Signature Encrypt"/&gt;
	&lt;property name="validationSignatureCrypto" ref="serverCrypto"/&gt;
	&lt;property name="validationDecryptionCrypto" ref="serverCrypto"/&gt;
	&lt;property name="validationCallbackHandler"&gt;
		&lt;bean class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler"&gt;
			&lt;property name="keyStore"&gt;
				&lt;bean class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean"&gt;
				    &lt;property name="password" value="mypasswd"/&gt;
				&lt;/bean&gt;
			&lt;/property&gt;
			&lt;property name="privateKeyPassword" value=""/&gt;
		&lt;/bean&gt;
	&lt;/property&gt;
	&lt;!-- Sign the response --&gt;
	&lt;property name="securementActions" value="Signature" /&gt;
	&lt;property name="securementUsername" value="server" /&gt;
	&lt;property name="securementPassword" value="" /&gt;
	&lt;property name="securementSignatureCrypto" ref="serverCrypto"/&gt;
&lt;/bean&gt;

&lt;bean id="serverCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean"&gt;
    &lt;property name="keyStorePassword" value="mypasswd"/&gt;
    &lt;property name="keyStoreLocation" value="classpath:security/server-keystore.jks"/&gt;
&lt;/bean&gt;
</pre>
<p>No surprise here neither.  The response will look like this.</p>
<pre name="code" class="xml">
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
	&lt;SOAP-ENV:Header&gt;
		&lt;wsse:Security
			xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
			SOAP-ENV:mustUnderstand="1"&gt;
			&lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
				Id="Signature-6"&gt;
				&lt;ds:SignedInfo&gt;
					&lt;ds:CanonicalizationMethod
						Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
					&lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
					&lt;ds:Reference URI="#id-7"&gt;
						&lt;ds:Transforms&gt;
							&lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
						&lt;/ds:Transforms&gt;
						&lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
						&lt;ds:DigestValue&gt;hEdDfxM6Nfs62Jxe8EOsELCDtUk=&lt;/ds:DigestValue&gt;
					&lt;/ds:Reference&gt;
					&lt;ds:Reference URI="#SigConf-5"&gt;
						&lt;ds:Transforms&gt;
							&lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
						&lt;/ds:Transforms&gt;
						&lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
						&lt;ds:DigestValue&gt;TTSRri5KJqXeMJfjzXyVmUewPxc=&lt;/ds:DigestValue&gt;
					&lt;/ds:Reference&gt;
				&lt;/ds:SignedInfo&gt;
				&lt;ds:SignatureValue&gt;
					V5by3bOoGQNajfs7i9xQ+cbAqIkI0NS9N9FQlLb/dAuQfguE7jKRP9iypOeRLHCPr7g3BNg+NCrX
					6YcgDQ0TfXNhdL00AmoEfDmWSNvIVNE49kZEn3Ji/RW4VtdEiV79VD7Vuay0YAYGo9DSQvzq3FP6
					YEhfzfMqvfbWMdEKcO8=
&lt;/ds:SignatureValue&gt;
				&lt;ds:KeyInfo Id="KeyId-F5114C147B958E706212759086160837"&gt;
					&lt;wsse:SecurityTokenReference
						xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
						wsu:Id="STRId-F5114C147B958E706212759086160838"
						xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
						&lt;ds:X509Data&gt;
							&lt;ds:X509IssuerSerial&gt;
								&lt;ds:X509IssuerName&gt;CN=Test Server,OU=Test&lt;/ds:X509IssuerName&gt;
								&lt;ds:X509SerialNumber&gt;1275904530&lt;/ds:X509SerialNumber&gt;
							&lt;/ds:X509IssuerSerial&gt;
						&lt;/ds:X509Data&gt;
					&lt;/wsse:SecurityTokenReference&gt;
				&lt;/ds:KeyInfo&gt;
			&lt;/ds:Signature&gt;
			&lt;wsse11:SignatureConfirmation
				xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
				xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
				Value="NHjjgpb9/alUOq50CqPKLcdYrp7edYdKJDNvIhh+2OAhYdDvZmD1qGsVKd1H9oKPF17uaF2Sv3aY0le6BrvzVx3n2+nYYlHwAWlzBk7wsBt4vLll6q6juLCP+siupTIb1PeZDf3WrAbHUQh5oqjD6cZBSc89pDspWRABQ8wPxYE="
				wsu:Id="SigConf-5" /&gt;
		&lt;/wsse:Security&gt;
	&lt;/SOAP-ENV:Header&gt;
	&lt;SOAP-ENV:Body
		xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
		wsu:Id="id-7"&gt;
		&lt;ns2:plusResponse xmlns:ns2="http://javacrumbs.net/calc"&gt;
			&lt;ns2:result&gt;3&lt;/ns2:result&gt;
		&lt;/ns2:plusResponse&gt;
	&lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
</pre>
<p>As we have seen it's possible to configure WS-Security without much hassle. To learn more, visit the official <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/security.html">Spring WS reference</a>. You can download full example <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/simple-server-test/branches/simple-server-test-security/simple-server-test/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2010/06/07/spring-ws-security-on-both-client-and-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Spring WS Test</title>
		<link>http://blog.krecan.net/2009/09/02/spring-ws-test/</link>
		<comments>http://blog.krecan.net/2009/09/02/spring-ws-test/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 19:15:51 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Tests]]></category>
		<category><![CDATA[spring-ws]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=422</guid>
		<description><![CDATA[Last few weeks I have been working on one of my pet projects. Its name is Spring WS Test. As the name implies, its main purpose is to simplify Spring WS tests. Again, I am scratching my own itch. I am quite test infected and I have needed something that allows me to write functional [...]]]></description>
			<content:encoded><![CDATA[<p>Last few weeks I have been working on one of my pet projects. Its name is <a href="http://javacrumbs.net/spring-ws-test/">Spring WS Test</a>. As the name implies, its main purpose is to simplify Spring WS tests. </p>
<p>Again, I am scratching my own itch. I am quite test infected and I have needed something that allows me to write functional tests of my application without having to depend on an external server.  Until now, you basically had two options. This first one is to test WS client application using plain old JUnit together with a library like EasyMock. But usually this test are quite ugly and hard to read. Moreover this type of tests does not test your configuration. The second option is to create a functional test that calls an external mock service. But this solution requires you to have two JVM, its configuration is complicated and error prone.</p>
<p><img src="/files/spring-ws-test/seq1.png" alt="Classical WS test" /></p>
<p>I have been looking for something in between, for something that would allow me to write functional tests using JUnit and would be able to run in the same JVM as the test. Unfortunately I have not been able to find anything similar.</p>
<p><img src="/files/spring-ws-test/seq2.png" alt="Spring WS Test test" /></p>
<p>That's the reason why I have created Spring WS Test project. It's quite simple and easy even though I had to spent lot of my evenings getting it into a publishable state.</p>
<p>Basic configuration looks like this</p>
<pre name="code" class="xml">
&lt;beans ...&gt;
  &lt;!-- Creates mock message sender --&gt;
  &lt;bean id=&quot;messageSender&quot; class=&quot;net.javacrumbs.springws.test.MockWebServiceMessageSender&quot;/&gt;

  &lt;!-- Injects mock message sender into WebServiceTemplate --&gt;
  &lt;bean class=&quot;net.javacrumbs.springws.test.util.MockMessageSenderInjector&quot;/&gt;

  &lt;!-- Looks for responses on the disc based on the provided XPath --&gt;
  &lt;bean class=&quot;net.javacrumbs.springws.test.generator.DefaultResponseGeneratorFactoryBean&quot;&gt;
     &lt;property name=&quot;namespaceMap&quot;&gt;
         &lt;map&gt;
            &lt;entry key=&quot;soapenv&quot;
                value=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;/&gt;
            &lt;entry key=&quot;ns&quot;
                value=&quot;http://www.springframework.org/spring-ws/samples/airline/schemas/messages&quot;/&gt;
         &lt;/map&gt;
     &lt;/property&gt;
     &lt;property name=&quot;XPathExpressions&quot;&gt;
         &lt;list&gt;
             &lt;value&gt;
                 concat(local-name(//soapenv:Body/*[1]),'/default-response.xml')
             &lt;/value&gt;
         &lt;/list&gt;
     &lt;/property&gt;
 &lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p>Here we have MockWebServiceMessageSender that replaces standard Spring <a href="http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/transport/WebServiceMessageSender.html">WebServiceMessageSender</a>. The replacement is done by MockMessageSenderInjector. The only other thing you have to do is to define ResponseGenerator. It's main purpose is to look for files in you test classpath and return them as mock responses. </p>
<p>Of course it has to decide, which file to use. By default a XPath expression is used to determine the resource name. In our example it is <code>concat(local-name(//soapenv:Body/*[1]),'/default-response.xml')</code>. It takes name of the payload (first soap:Body child) and uses it as a directory name. File “default-response.xml” from this directory is used as the mock response. Simple isn't it? </p>
<p>Of course you can define more complicated XPaths, you can use XSLT templates to generate your responses, you can validate your requests etc. More details can be found in the <a href="http://javacrumbs.net/spring-ws-test/">documentation</a>.  </p>
<p>Now I am looking for some end-user feedback. So please, if you are using Spring WS on the client side do not hesitate and test it. It should be stable enough to be used although there might be a bug here and there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2009/09/02/spring-ws-test/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Spring WS fault detail</title>
		<link>http://blog.krecan.net/2009/05/23/spring-ws-fault-detail/</link>
		<comments>http://blog.krecan.net/2009/05/23/spring-ws-fault-detail/#comments</comments>
		<pubDate>Sat, 23 May 2009 13:59:07 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[soap error detail]]></category>
		<category><![CDATA[spring-ws]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=385</guid>
		<description><![CDATA[Spring WS project provides nice and versatile exception handling tools. But in some scenarios predefined Exception Resolvers are not sufficient. For example if you want to provide additional error info in the soap:fault detail like in this example: SOAP-ENV:Client Something wrong happened Error BigTrouble Fortunately it is quite easy to add similar behavior using Spring [...]]]></description>
			<content:encoded><![CDATA[<p>Spring WS project provides nice and versatile <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-endpoint-exception-resolver">exception handling tools</a>.  But in some scenarios predefined Exception Resolvers are not sufficient. For example if you want to provide additional error info in the soap:fault detail like in this example:</p>
<pre name="code" class="xml">
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring xml:lang="en">Something wrong happened</faultstring>
         <detail>
            <code>Error</code>
            <sub-code>BigTrouble</sub-code>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</pre>
<p>Fortunately it is quite easy to add similar behavior using Spring WS. You can easily extend existing <code>SoapFaultMappingExceptionResolver</code> and customize the fault (please note that <code>EndpointExeption</code> is project specific exception that provides necessary data):</p>
<pre name="code" class="java">
 public class EndpointExceptionResolver extends SoapFaultMappingExceptionResolver {
	private static final QName CODE = new QName("code");
	private static final QName SUB_CODE = new QName("sub-code");

	@Override
	protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) {
		logger.warn("Exception processed ",ex);
		if (ex instanceof EndpointException) {
			EndpointException ee = (EndpointException) ex;
			SoapFaultDetail detail = fault.addFaultDetail();
			detail.addFaultDetailElement(CODE).addText(ee.getCode());
			detail.addFaultDetailElement(SUB_CODE).addText(ee.getSubCode());
		}
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2009/05/23/spring-ws-fault-detail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Streaming a stream</title>
		<link>http://blog.krecan.net/2009/02/27/streaming-a-stream/</link>
		<comments>http://blog.krecan.net/2009/02/27/streaming-a-stream/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 10:53:01 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[HttpInvoker]]></category>
		<category><![CDATA[InputStream]]></category>
		<category><![CDATA[RMIIO]]></category>
		<category><![CDATA[Serializable]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=286</guid>
		<description><![CDATA[I have another dirty trick for you. Let's imagine that you have a document server with following sophisticated interface. public interface DocumentServer { /** * Stores a document. * @return document id */ public String storeDocument(InputStream in); /** * Loads document with given id. * @param id * @return */ public InputStream loadDocument(String id); } [...]]]></description>
			<content:encoded><![CDATA[<p>I have another dirty trick for you. Let's imagine that you have a document server with following sophisticated interface.</p>
<pre name="code" class="java">
public interface DocumentServer {
	/**
	 * Stores a document.
	 * @return document id
	 */
	public String storeDocument(InputStream in);

	/**
	 * Loads document with given id.
	 * @param id
	 * @return
	 */
	public InputStream loadDocument(String id);
}
</pre>
<p>It works well, until you realize, that you want to call the DocumentServer remotely, for example using Spring <a href="http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html#remoting-httpinvoker">HttpInvoker</a>. </p>
<p>HttpInvoker is a nice small tool, that lets you make remote method invocations over HTTP without much pain. It creates dynamic proxy, serializes all attributes using Java serialization, calls remote proxy, which deserializes arguments, calls the implementation and sends the result back in the same way. It is nice, simple and it works without any problem. You can configure it in five minutes. The downside is, that you have to have Spring Java application on both ends of the wire and all arguments that you send over the wire have to be Serializable.</p>
<p>And that's exactly the trouble we have with our DocumentServer. There is no standard InputStream implementation that implements serializable. Lets think about it. We need to have a stream that is able to stream itself into an <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectOutputStream.html">ObjectOutputStream</a>. Sounds strange, but it is quite easy. We can simply write a wrapper, that implements <a href="http://java.sun.com/developer/technicalArticles/Programming/serialization/">writeObject(ObjectOutputStream)</a> method and that takes all the bytes from the underlying stream and writes them to the ObjectOutputStream. It is simple and it does not consume much memory.</p>
<p>Deserialization is much harder. We have to implement readObject(ObjectInputStream in) method, load the data and store them somewhere for later use. We can store them in the memory or in a temporary file. If the streams are larger, temporary file is better choice but we have to delete them after use and the implementation gets messy. </p>
<p>The good news is, that we do not have to implement it, it's already done by <a href="http://openhms.sourceforge.net/rmiio/">RMIIO</a> library. They provide <a href="http://openhms.sourceforge.net/rmiio/apidocs/com/healthmarketscience/rmiio/SerializableInputStream.html">SerializableInputStream</a> class that does exactly what we need. You just have to ignore Javadoc comment saying:</p>
<blockquote><p>An additional layer around a RemoteInputStream which makes it Serializable and an InputStream. In general, this extra layer is not necessary and I do not recommend using this class. However, in the odd case where the callee really wants to get something which is already an InputStream, this class can be useful. </p></blockquote>
<p>The only thing we have to do is to wrap all the streams into SerializableInputStream like this</p>
<pre name="code" class="java">
new SerializableInputStream(new DirectRemoteInputStream(inputStream));
</pre>
<p>It can be done by hand written proxy, by dynamically generated proxy or by AOP.</p>
<p>Of course there are other alternatives. The easiest one is to create something like ByteArayInputStream that implements Serializable. If the streams are small enough, it's the best solution. </p>
<p>We can also try to use <a href="http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html#remoting-caucho-protocols-hessian">Hessian</a>, but I had some troubles when method signatures were more complicated. And of course there is still a possibility to implement own remoting mechanism. After all, HTTP is meant to transport streams. But it would require lot of boilerplate code and I do not like boilerplate code. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2009/02/27/streaming-a-stream/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spring managed Hibernate interceptor in JPA</title>
		<link>http://blog.krecan.net/2009/01/24/spring-managed-hibernate-interceptor-in-jpa/</link>
		<comments>http://blog.krecan.net/2009/01/24/spring-managed-hibernate-interceptor-in-jpa/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 16:29:27 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[injection]]></category>
		<category><![CDATA[interceptor]]></category>
		<category><![CDATA[JPA]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=261</guid>
		<description><![CDATA[I have been trying to teach Hibernate injecting dependencies into Entities (I know, there is magic @Configurable annotation, I wanted to try it without magic). It is quite easy to do it using Hibernate interceptor (for example like this). But there is one drawback. It is not straightforward to inject interceptor into Hibernate when JPA [...]]]></description>
			<content:encoded><![CDATA[<p>I have been trying to teach Hibernate injecting dependencies into Entities (I know, there is magic <a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable">@Configurable</a> annotation, I wanted to try it without magic). It is quite easy to do it using Hibernate interceptor (for example like <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/jpa-test/tags/jpa-test-3.0/jpa-test/src/main/java/net/krecan/javacrumbs/jpa/interceptor/SpringInjectingInterceptor.java">this</a>). But there is one drawback. It is not straightforward to inject interceptor into Hibernate when JPA abstraction is in the way. </p>
<p>It is simple to define interceptor in <code>persistence.xml</code> using <a href="http://www.hibernate.org/hib_docs/entitymanager/reference/en/html/configuration.html#setup-configuration-bootstrapping">hibernate.ejb.interceptor</a> property. But it is only possible to specify class name, you can not inject Spring bean. If you read documentation to Spring <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html">LocalContainerEntityManagerFactoryBean</a> there is no possibility to specify the interceptor bean there neither. But there is a way how to achieve it. First of all, you have to redefine Hibernate PersistenceProvider. </p>
<pre name="code" class="java">
public class ConfigurableHibernatePersistence extends HibernatePersistence {
	private Interceptor interceptor;
	public Interceptor getInterceptor() {
		return interceptor;
	}

	public void setInterceptor(Interceptor interceptor) {
		this.interceptor = interceptor;
	}

	@SuppressWarnings("unchecked")
	@Override
	public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
		Ejb3Configuration cfg = new Ejb3Configuration();
		Ejb3Configuration configured = cfg.configure( info, map );
		postprocessConfiguration(info, map, configured);
		return configured != null ? configured.buildEntityManagerFactory() : null;
	}

	@SuppressWarnings("unchecked")
	protected void postprocessConfiguration(PersistenceUnitInfo info, Map map, Ejb3Configuration configured) {
		if (this.interceptor != null)
		{
			if (configured.getInterceptor()==null || EmptyInterceptor.class.equals(configured.getInterceptor().getClass()))
			{
				configured.setInterceptor(this.interceptor);
			}
			else
			{
				throw new IllegalStateException("Hibernate interceptor already set in persistence.xml ("+configured.getInterceptor()+")");
			}
		}
	}
}
</pre>
<p>(<a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/jpa-test/tags/jpa-test-3.0/jpa-test/src/main/java/net/krecan/javacrumbs/jpa/interceptor/ConfigurableHibernatePersistence.java">source</a>)</p>
<p>Here we override method <code>createContainerEntityManagerFactory</code> in order to add <code>postprocessConfiguration</code> method call. In this method, it is possible to change Hibernate configuration as needed. Now the only thing to be done is configuring Spring to use our new PersistenceProvider. It is quite simple.</p>
<pre name="code" class="xml">
	&lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
		&lt;property name="persistenceUnitName" value="testPU" /&gt;
		&lt;property name="dataSource" ref="dataSource" /&gt;
		&lt;property name="persistenceProvider"&gt;
			&lt;bean class="net.krecan.javacrumbs.jpa.interceptor.ConfigurableHibernatePersistence"&gt;
				&lt;property name="interceptor"&gt;
					&lt;bean class="net.krecan.javacrumbs.jpa.interceptor.SpringInjectingInterceptor"/&gt;
				&lt;/property&gt;
			&lt;/bean&gt;
		&lt;/property&gt;
	&lt;/bean&gt;
</pre>
<p>And that all folks, we have Spring configured interceptor even when using JPA abstraction. It would be better if similar classes were in Spring or Hibernate, but it's just few lines of code so feel free to copy them if you need to. If you know easier way how to do it, please mention it in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2009/01/24/spring-managed-hibernate-interceptor-in-jpa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Skrytý drahokam Springu</title>
		<link>http://blog.krecan.net/2009/01/22/skryty-drahokam-springu/</link>
		<comments>http://blog.krecan.net/2009/01/22/skryty-drahokam-springu/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 19:25:16 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Annotation]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Configurable]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=243</guid>
		<description><![CDATA[Dnes jsem koukal na rozhovor s Rodem Johnsonem, v kterém mluvil o novinkách ve Springu 3.0. Mezi řečí se zmínil o anotaci @Configurable, která je už ve Springu 2.5 a označil ji za skrytý drahokam. Protože jsem o něčem takovém slyšel poprvé, tak jsem se podíval do dokumentace a docela mě to zaujalo. (Teda, teď [...]]]></description>
			<content:encoded><![CDATA[<p>	Dnes jsem koukal na <a href="http://www.infoq.com/interviews/Spring-3.0-Rod-Johnson">rozhovor s Rodem Johnsonem</a>, v kterém mluvil o novinkách ve Springu 3.0. Mezi řečí se zmínil o anotaci <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/Configurable.html">@Configurable</a>, která je už ve Springu 2.5 a označil ji za skrytý drahokam. Protože jsem o něčem takovém slyšel poprvé, tak jsem se podíval do <a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable">dokumentace</a> a docela mě to zaujalo. (Teda, teď koukám, že jsem se o něčem podobném zmiňoval už před půl rokem <a href="http://blog.krecan.net/2007/06/03/uz-tam-budem/">zde</a>, ach ta paměť). V zásadě jde o to, že obvykle funguje dependency injection jen u bean, které spravuje Spring. Takže například nejde použít u JPA entit a podobně. Což je docela škoda, protože pak musíme dělat umělou servisní vrstvu a objektový model tím docela trpí. Máme na jednu stranu třídy, které drží stav (entity) a na druhou stranu servisní třídy, v kterých je jen kód a stavu mají pomálu. Ale ve správném objektovém programování bychom měli mít třídy, které kombinují oboje. Takže například objekt <code>User</code> by měl mít metodu <code>remove()</code>, která by ho smazala z databáze. Jenže to by znamenalo, že by každá instance této třídy musela mít v sobě odkaz na <code>EntityManager</code> nebo ještě lépe DAO, což neumíme injektnout. </p>
<p>Možná si říkáte, že jsem se zbláznil, že to je ošklivé. Musím se přiznat, že mi je tento přístup taky cizí, ale asi je to jen otázka zvyku. Nejspíš jsem jen zvyklý na to procedurální programování, kde mám servisní procedury v singletonu a jim předhazuji hloupé datové objekty, které se o sebe neumějí postarat samy. </p>
<p>	Anotace <code>@Configurable</code> je tu právě od toho, aby nám usnadnila injektování i do bean, které nejsou spravovány Springem. Předvedu na příkladu. Mám třídu <code>Bean</code>, které se dá podstrčit nějaký text.</p>
<pre name="code" class="java">
@Configurable
public class Bean {
	private String text;
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
}
</pre>
<p>Mým cílem je zprovoznit tento test.</p>
<pre name="code" class="java">
	public void testIt()
	{
		Bean bean = new Bean();
		assertEquals("Hallo",bean.getText());
	}
</pre>
<p>Všimněte si, že vytvářím novou instanci a koukám se, co je v ní nastaveno za text. Podle všeho by tam mělo být <code>null</code>. Ale pokud správně poladím Spring, tak tam může být cokoliv. </p>
<p>	Prvním krokem je samozřejmě anotace <code>@Configurable</code>, která označí beanu jako kandidáta na injektování. V druhém kroku musím nastavit, co chci injektnout. Mohu například zvolit klasickou XML konfiguraci.</p>
<pre name="code" class="xml">
	&lt;bean class="net.krecan.configurable.Bean" scope="prototype"&gt;
		&lt;property name="text" value="Hallo"/&gt;
	&lt;/bean&gt;

	&lt;context:spring-configured/&gt;

	&lt;context:load-time-weaver/
</pre>
<p>	Zde si všimněme několika věcí. Například toho, že Spring pozná to kam má co injektnout automaticky, podle jména třídy. Nicméně dají se použít i vlastní jména. Pak si všimněme použití rozsahu „<code>protoype</code>“. To dává smysl, já mohu new zavolat kolikrát chci (i když tam to <code>protoype</code> nedáte, tak se to chová stejně, takhle je to jen hezčí).  No a pak už nám zbývá jen magie. Pomocí prvního kouzelného slůvka <code>&lt;context:spring-configured/&gt;</code> zařídíme, aby se použil AspectJ aspekt, který to všechno zařídí. Ano, musí se použít AspectJ, zázraky ani Spring nedovede. Zatím.  </p>
<p>	Druhé kouzelné slůvko <code>&lt;context:load-time-weaver/&gt;</code> nastaví AspectJ, tak aby si podle potřeby při startu aplikace upravil třídy. Aby to totiž všechno fungovalo, tak je potřeba upravit bytecode. A to buď při kompilaci nebo při startu aplikace. Já jsem zvolil druhou variantu, která bohužel také vyžaduje, abyste to celé spouštěli s atributem virtuálního stroje <code>-javaagent:spring-agent-2.5.6.jar</code>. Pokud si kód budete zkoušet sami, tak na to prosím nezapomeňte.</p>
<p>	A to je vše, testy projdou bez problému. Vidíme, že Spring umí injektovat i do tříd, nad kterými na první pohled nemá kontrolu. A to aniž bychom nějak zvlášť museli študovat AspectJ. Všechno už máme pěkně připraveno. Samozřejmě, uvedený příklad je umělý, ale pokud bychom našli dost odvahy, tak můžeme bez problémů injektnout EntityManager přímo do entit. A to může být docela užitečné.</p>
<p>	Zdrojový kód je ke stažení <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/trunk/spring-configurable">zde</a>, obzvláště doporučuji extra zvrhlou třídu <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/trunk/spring-configurable/src/main/java/net/krecan/configurable/MagicBean.java">MagicBean</a>. No a pokud chcete umět Spring tak skvěle jako já, tak se mi ozvěte, můžu vás to naučit <img src='http://blog.krecan.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2009/01/22/skryty-drahokam-springu/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Webové služby à la Spring</title>
		<link>http://blog.krecan.net/2008/11/25/webove-sluzby-a-la-spring/</link>
		<comments>http://blog.krecan.net/2008/11/25/webove-sluzby-a-la-spring/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 19:57:15 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=157</guid>
		<description><![CDATA[V poslední době docela často používal knihovnu Spring WS. Chtěl bych se s vámi podělit o zkušenosti, které jsem s tímto modulem udělal. Nejdřív bych měl ale upozornit, že nejsem expert na webové služby. O tom co je to port nebo binding mám jen mlhavou představu. Na druhou stranu jsem to nikdy vědět nepotřeboval. Nečekejte [...]]]></description>
			<content:encoded><![CDATA[<p>V poslední době docela často používal knihovnu <a href="http://static.springsource.org/spring-ws/sites/1.5/">Spring WS</a>. Chtěl bych se s vámi podělit o zkušenosti, které jsem s tímto modulem udělal. Nejdřív bych měl ale upozornit, že nejsem expert na webové služby. O tom co je to port nebo binding mám jen mlhavou představu. Na druhou stranu jsem to nikdy vědět nepotřeboval. Nečekejte také žádný návod jak to používat. Původně jsem ho sice chtěl napsat, ale pak mi došlo, že bych jen kopíroval existující <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/index.html">dokumentaci</a>.<br />
	Než se ale pustíme do Spring-WS, začnu trochu zeširoka. Na webové služby se můžeme dívat ze dvou úhlů. Můžeme je vnímat jako trochu lepší vzdálené volání metod (RPC). Prostě označím metodu vhodně zvolenou anotací a nějaký framework se mi postará o to, aby tato metoda byla vzdáleně volatelná. Nijak zvlášť mě nezajímá to, jak bude komunikace probíhat. Prostě beru webové služby jako takovou trochu modernější Corbu nebo RMI.<br />
	Druhý přístup se na webové služby dívá z druhé strany. Bere je jako trochu vylepšený způsob výměny XML dokumentů. Při tomto přístupu je pro mě důležitý formát výměny dat, od něj se pak odvíjí způsob volání.<br />
	Samozřejmě oba přístupy nakonec skončí obdobně, liší se jen tím, co je pro mě důležitější. Spousta lidí se shoduje v tom, že druhý přístup dává větší smysl. Obvykle se dočtete, že při návrhu webové služby by se mělo začít u definice XML dokumentů, které budou sloužit pro výměnu dat (contract first). Dává to smysl. Definice dat je to, kde se budeme střetávat s konzumenty naší webové služby, XSD je to, co vidí a proti čemu programují. Nikoho nezajímá, jakou signaturu má naše metoda, konzumenty zajímá co všechno nám musí poslat a co my jim na oplátku pošleme jako odpověď.<br />
	Spring WS je postaven právě kolem contract-first přístupu.  A musím přiznat, že je postaven docela dobře. Nečekejte super kvalitu, na kterou jste zvyklí od Springu. Spring WS je psán jinou partou lidí a občas člověk narazí na místa, která by šla udělat lépe. Nicméně i tak je to kvalitní knihovna a pokud jste zvyklí na Spring, konfigurace Spring WS vám přijde přímočará.<br />
	Než se vrhnu do popisu toho, jako co všechno Spring WS umí, zamysleme se nad tím, co  si od takové knihovny představujeme. Já od ní chci několik věcí. Chci, abych se nemusel starat o mydlinky kolem SOAPu, chci se zabývat pouze zpracováním nákladu (payloadu), který mi v těch mýdlových bublinách přišel. Takže od WS knihovny chci, aby mi zpracovala SOAP, vybalila náklad a předala mi ho k zpracování. Protože nerad pracuji s XML, chci, aby mi pomohla s převodem z XML  do objektů. U odpovědi chci aby udělala to samé, ale pozpátku. Pak by se také hodilo, aby mi pomohla s vygenerováním WSDL a pokud je to nutné s WS-Security. Když se na tyto požadavky podívám, zjistím, že už to všechno je vyřešeno. Zpracování SOAPu umí <a href="https://saaj.dev.java.net/">SAAJ</a>, na serializaci XML máme taky hromadu frameworků. Stačí to všechno jenom pospojovat. A přesně to dělá Spring WS.<br />
	Co se mi na něm líbí je jednoduchá konfigurovatelnost. Nestalo se mi, že bych narazil na něco, co bych neuměl nakonfigurovat. Všechno je možné nastavit, snadno přeprogramovat a podobně.<br />
	Samozřejmostí je volba způsobu serializace z a do XML. Máte na výběr <a href="https://jaxb.dev.java.net/">JAXB2</a>, <a href="http://www.castor.org/">Castor</a>, <a href="http://xstream.codehaus.org/">XStream</a>, moje oblíbené <a href="http://xmlbeans.apache.org/">XMLBeans</a> a několik dalších. Vytvoření vlastního způsobu serializace je jen otázkou implementace dvou rozhraní.<br />
	Pokud potřebujete něco pokročilejšího, můžete použít <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-endpoint-interceptor">interceptory</a>. Ty fungují obdobně jako filtry u HTTP requestu, jsou ale spouštěny na úrovni SOAP dotazu a odpovědi. Spring WS obsahuje interceptor pro logování dotazů a odpovědí, který je docela užitečný. Navíc obsahuje interceptor, který umí spustit XSLT transformaci nad příchozím dotazem. To je super, pokud potřebujete upravovat formát dat. Například přidáte element do odpovědi. Ale v mezidobí, než všichni vaši klienti přejdou na novou verzi, musíte některým z nich vracet odpověď bez tohoto elementu. Není nic snazšího než napsat příslušnou XSLT šablonu, která ho z odpovědi vyhodí.  To vám ušetří starosti s údržbou několika verzí té samé služby.<br />
Interceptory navíc nabízejí skvělé místo pro úpravy jak dotazu tak odpovědi. Narazil jsem na následující problém, SAAJ negeneroval XML deklaraci na začátku XML dokumentu. Takové to <code>&lt;?xml version="1.0"?&gt;</code>. Bohužel jeden klient se toho dožadoval. Po půlhodině strávené výzkumem toho kde je chyba, jsem přišel na to, že z neznámého důvodu SAAJ implicitně XML deklaraci negeneruje. Všechno vyřešil trojřádkový interceptor, který nastavil správnou <a href="http://java.sun.com/j2ee/1.4/docs/api/javax/xml/soap/SOAPMessage.html#WRITE_XML_DECLARATION">property</a> tak, aby ji používal.<br />
	Co mě také potěšilo je generování WSDL. Člověk by si řekl, že je to samozřejmost. Nicméně například <a href="http://xfire.codehaus.org/">XFire</a> měl s generováním WSDL z existujících XSD souborů pěkné problémy. Zamotal se v několikanásobných importech stejného XSD souboru a vracel mi nevalidní WSDL. To byl jeden z důvodů proč jsme přešli na Spring WS. (Druhý důvod byl, že už jeho vývoj skončil, teď se jmenuje <a href="http://cxf.apache.org/">CXF</a> a konfigurace rozhodně není kompatibilní). Spring WS se stejným schématem neměl nejmenší problém, naopak potěšil takovou maličkostí jako je automatická změna URL webové služby ve WSDL podle toho, kde je nasazen.<br />
	Takže abych to shrnul, pokud děláte webové služby stylem contract-first a jste zvyklí na Spring, pak je Spring WS rozhodně dobrá volba. Jeho nevýhodou je, že vám nedá nic zadarmo. Chcete generovat WSDL? Musíte si to <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-automatic-wsdl-exposure">nakonfigurovat</a>. Chcete validovat dotazy pomocí XSD? Musíte nastavit správný interceptor. Trochu nešikovné je, že pro integraci s frameworkem musíte implementovat jeho rozhraní nebo rozšířit jeho třídu. Nicméně pokud nemáte stovky různých webových služeb, tak vás pár obalovacích piditříd nezabije. Pokud je i malá obalovací třída pro vás moc, pak můžete použít <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#d0e2852">anotace</a>. Ty jsem ale nezkoušel, takže nemohu sloužit.<br />
	Mezi nevýhody Spring WS patří, že nepodporuje anotaci <code>@WebMethod</code>. Autoři tvrdí, že je to záměrně, že prý lidi nabádá ke škodlivému pohledu na webové služby jako na vzdálené volání metod. Nevím, jejich anotace <code><a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#d0e2852">@Endpoint</a></code> mi nepřipadá o moc lepší. Ale i přes tyto nevýhody mi Spring WS připadá jako dobrá volba. Dává vám svobodu volby a to je podle mě docela užitečná věc.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2008/11/25/webove-sluzby-a-la-spring/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Specific environment setting with Spring</title>
		<link>http://blog.krecan.net/2008/11/14/specific-environment-setting-with-spring/</link>
		<comments>http://blog.krecan.net/2008/11/14/specific-environment-setting-with-spring/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 19:11:40 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/?p=140</guid>
		<description><![CDATA[There is one issue that people usually have with J2EE deployment. I call it specific environment setting. Imagine that you have several environments that you want to deploy your J2EE application to. For example development, test, stress test, staging or production. For all those environments you need specific settings like JDBC URL, JDBC user name [...]]]></description>
			<content:encoded><![CDATA[<p>There is one issue that people usually have with J2EE deployment. I call it specific environment setting. Imagine that you have several environments that you want to deploy your J2EE application to. For example development, test, stress test, staging or production. For all those environments you need specific settings like JDBC URL, JDBC user name and password, path to a directory for data export etc. The question is where to put such setting. If you store it in the WAR (JAR, EAR, SAR or other AR) you have to create specific archive for every environment.<br />
	It is not a big problem, provided you have an automated build. Nevertheless I do not like this solution. I like to have the same archive for all environments. This way I am sure that the application on production is exactly the same as the one I have tested on the test environment.  Moreover, there is a problem with passwords. You have to make them part of the build process and effectively publish them by doing so.<br />
	One possible solution is to use JNDI. It is probably the best solution if you can use it. But what if you don't use big and heavy J2EE server.  What if you use a servlet container like Tomcat or Jetty instead. In this case I have one of my favorite tricks for you. I use Spring configuration similar to the following one:</p>
<pre name="code" class="xml">
 &lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
	&lt;property name="locations"&gt;
		&lt;list&gt;
			&lt;value&gt;
			  classpath:main-config.properties
			&lt;/value&gt;
			&lt;value&gt;
			  file:///${user.home}/spring-test.properties
			&lt;/value&gt;
		&lt;/list&gt;
	&lt;/property&gt;
	&lt;property name="ignoreResourceNotFound" value="true"/&gt;
	&lt;property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/&gt;
 &lt;/bean&gt;

&lt;bean class="net.krecan.spring.TstBean"&gt;
	&lt;property name="property1" value="${property1}"/&gt;
	&lt;property name="property2" value="${property2}"/&gt;
	&lt;property name="property3" value="${property3}"/&gt;
&lt;/bean&gt;
</pre>
<p>Spring tries to load a configuration file from user home directory. If the file is found, properties from the main-config file are overwritten by those found in the spring-test file. And you can even overwrite those by defining a system property with the same name.<br />
	I like it. This way every developer can have his own configuration. There is no danger of accidentally committing passwords to a source control system. You can use exactly the same WAR on every environment. It is relatively safe, although some system administrators do not like it. This way you can distribute an application over the internet without forcing users to unpack it, edit a config file and pack it again afterwards.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2008/11/14/specific-environment-setting-with-spring/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

