<?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>Xebia Blog &#187; Okke Harsta</title>
	<atom:link href="http://blog.xebia.com/author/oharsta/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xebia.com</link>
	<description>Software development done right!</description>
	<lastBuildDate>Wed, 01 Feb 2012 00:30:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Color up your mind-map</title>
		<link>http://blog.xebia.com/2007/03/31/color-up-your-mind-map/</link>
		<comments>http://blog.xebia.com/2007/03/31/color-up-your-mind-map/#comments</comments>
		<pubDate>Sat, 31 Mar 2007 18:41:51 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[General]]></category>

	<!-- AutoMeta Start -->
	<category>freemind</category>
	<category>nodes</category>
	<category>traverse_element</category>
	<category>color</category>
	<category>color</category>
	<category>ruby</category>
	<category>node</category>
	<category>colors</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2007/03/31/color-up-your-mind-map/</guid>
		<description><![CDATA[And now for something completely different: how to mind-map in color with a little help from ruby? I like to mind-map and the tool I use is FreeMind. You can add icons to your nodes, import pictures etc.etc. You can also add some color to your mind-map; select a node and change the color. For [...]]]></description>
			<content:encoded><![CDATA[<p>And now for something completely different: how to mind-map in color with a little help from ruby?</p>
<p>I like to mind-map and the tool I use is <a href="http://freemind.sourceforge.net/wiki/index.php/Main_Page">FreeMind</a>. You can add icons to your nodes, import pictures etc.etc. You can also add some color to your mind-map; select a node and change the color. For some -strange- reason I wanted to have all my nodes in different colors and after one minute of selecting nodes, changing colors I already abandoned that idea => too tedious. Ruby to the rescue: Freemind stores your mind-maps in XML format and this little ruby script turns your boring mind-map into something colorful:</p>
<pre class="brush: ruby; title: ; notranslate">

require 'rexml/document'
include REXML

def traverse_element(element)
    element.elements.each('node') do |e|
        e.attributes['COLOR']= (&quot;#%06x&quot; % rand(0xffffff))
        traverse_element(e)
    end
end

doc = Document.new(File.new(&quot;original_boring_mindmap.mm&quot;))
traverse_element(doc.root)
out = File.new(&quot;new_colorful_mindmap.mm&quot;,&quot;w&quot;)
out.write(doc)
</pre>
<p>Nerdy? You bet ya&#8230;..</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2007/03/31/color-up-your-mind-map/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2007%2F03%2F31%2Fcolor-up-your-mind-map%2F&amp;title=Color%20up%20your%20mind-map" id="wpa2a_2"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2007/03/31/color-up-your-mind-map/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to implement your own Security provider with the Acegi framework.</title>
		<link>http://blog.xebia.com/2007/03/04/how-to-implement-your-own-security-provider-with-the-acegi-framework/</link>
		<comments>http://blog.xebia.com/2007/03/04/how-to-implement-your-own-security-provider-with-the-acegi-framework/#comments</comments>
		<pubDate>Sun, 04 Mar 2007 07:21:51 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[Security]]></category>

	<!-- AutoMeta Start -->
	<category>usernamepasswordauthenticationtoken</category>
	<category>acegisecurity</category>
	<category>authentication</category>
	<category>dofilter</category>
	<category>filterchainproxy</category>
	<category>customauthenticationmanager</category>
	<category>providers</category>
	<category>acegi</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2007/03/04/how-to-implement-your-own-security-provider-with-the-acegi-framework/</guid>
		<description><![CDATA[In a previous blog I described the minimal basic configuration of the Acegi framework. In this blog I&#8217;ll show you how easy it is to implement your own security provider. There can be many reasons why you would want to implement such a customized security provider. In my case I had to secure an application [...]]]></description>
			<content:encoded><![CDATA[<p>In a previous <a href="http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/">blog</a> I described the minimal basic configuration of the Acegi framework. In this blog I&#8217;ll show you how easy it is to implement your own security provider. There can be many reasons why you would want to implement such a customized security provider. In my case I had to secure an application using user information that was being maintained by an external php-based application. The user information could only be retrieved using a web service. In this blog I will demonstrate several ways to implement your own security provider.</p>
<p><span id="more-177"></span>  </p>
<p>The starting point is -again- the simple web application from the previous <a href="http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/">blog</a>. The part of the acegi-security.xml that is relevant is shown below.</p>
<pre class="brush: xml; title: ; notranslate">

	&lt;!--
		The authenticationManager is the hook for all authenticationProviders we want
		to configure.
	--&gt;
	 &lt;bean id=&quot;authenticationManager&quot;
        class=&quot;org.acegisecurity.providers.ProviderManager&quot;&gt;
        &lt;property name=&quot;providers&quot;&gt;
            &lt;list&gt;
                &lt;ref local=&quot;authenticationProvider&quot; /&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

	&lt;!--
		The Acegi DaoAuthenticationProvider
	--&gt;
    &lt;bean id=&quot;authenticationProvider&quot;
		class=&quot;org.acegisecurity.providers.dao.DaoAuthenticationProvider&quot;&gt;
        &lt;property name=&quot;userDetailsService&quot; ref=&quot;userDetailsServiceImpl&quot;/&gt;
	&lt;/bean&gt;

    &lt;!--
        The Acegi InMemoryDaoImpl
    --&gt;
    &lt;bean id=&quot;userDetailsServiceImpl&quot;
        class=&quot;org.acegisecurity.userdetails.memory.InMemoryDaoImpl&quot;&gt;
        &lt;property name=&quot;userProperties&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;admin&quot;&gt;secret,ROLE_ADMIN&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre>
<p>We will replace this fragment with the following code:</p>
<pre class="brush: xml; title: ; notranslate">

	 &lt;bean id=&quot;authenticationManager&quot;
        class=&quot;com.xebia.acegi.CustomAuthenticationManager&quot;/&gt;
</pre>
<p>What does our CustomAuthenticationManager has to do? Well actually the interface AuthenticationProvider that needs to be implemented is quite straightforward:</p>
<pre class="brush: java; title: ; notranslate">

public Authentication authenticate(Authentication authentication)
        throws AuthenticationException;
</pre>
<p>Lets begin with the most simple implementation possible:</p>
<pre class="brush: java; title: ; notranslate">

	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		authentication.setAuthenticated(true);
		return authentication;
	}
</pre>
<p>When we start jetty (see previous blog) we can tweak Maven to give us a remote debugging hook by setting the MAVEN_OPTS variable:</p>
<pre class="brush: plain; title: ; notranslate">

$ echo $MAVEN_OPTS
-XX:MaxPermSize=512m -Xmx1024m -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n
</pre>
<p>The first two arguments allocate more memory to the Maven process and the last arguments provide us a way to remotely debug the application. Using eclipse we can configure a <a href="http://blog.xebia.com/wp-content/uploads/2007/03/eclipse_remote_debug.GIF">remote debug application</a>:</p>
<p><img id="img_erd" src="http://blog.xebia.com/wp-content/uploads/2007/03/eclipse_remote_debug_sized.GIF" alt="Eclipse Remote Debugging" /></p>
<p>The implementation of the Authentication interface used by Acegi is an instance of UsernamePasswordAuthenticationToken as we can see when <a href="http://blog.xebia.com/wp-content/uploads/2007/03/eclipse_debug_info.GIF">debugging the application</a>. </p>
<p><img id="img_edi" src="http://blog.xebia.com/wp-content/uploads/2007/03/eclipse_debug_info_sized.GIF" alt="Eclipse Debug Info" /></p>
<p>The UsernamePasswordAuthenticationToken is constructed in the AuthenticationProcessingFilter -as configured in acegi-secutiry.xml-, but we could also subclass this filter to use more exotic implementations like the X509AuthenticationToken.</p>
<p>When checking out the result at http://localhost:8080/blog-acegi/site/admin.html it appears the implementation we have provided is to simple:</p>
<pre class="brush: plain; title: ; notranslate">

HTTP ERROR: 500

Cannot set this token to trusted - use constructor containing GrantedAuthority[]s instead

RequestURI=/blog-acegi/j_acegi_security_check
Caused by:

java.lang.IllegalArgumentException: Cannot set this token to trusted - use constructor containing GrantedAuthority[]s instead
	at org.acegisecurity.providers.UsernamePasswordAuthenticationToken.setAuthenticated(UsernamePasswordAuthenticationToken.java:85)
	at com.xebia.acegi.CustomAuthenticationManager.authenticate(CustomAuthenticationManager.java:25)
	at org.acegisecurity.ui.webapp.AuthenticationProcessingFilter.attemptAuthentication(AuthenticationProcessingFilter.java:71)
	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:199)
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
	at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:148)
	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1065)
</pre>
<p>Acegi insists we create our instance of the Authentication interface. So let&#8217;s change our custom authentication manager using the following code:</p>
<pre class="brush: java; title: ; notranslate">

return new UsernamePasswordAuthenticationToken(
				authentication.getPrincipal(),
				authentication.getCredentials(),
				new GrantedAuthority[] { new GrantedAuthorityImpl(&quot;ROLE_ADMIN&quot;) });
</pre>
<p>Of course a more serious implementation would do some lookup of the User and apply business logic to authenticate the user.</p>
<p>Acegi provides also an abstract AbstractUserDetailsAuthenticationProvider class that can be subclassed in able to benefit from the existing functionality from the Acegi framework. We change the relevant xml part in the acegi-security.xml with this fragment: </p>
<pre class="brush: xml; title: ; notranslate">

	&lt;!--
		The authenticationManager is the hook for all authenticationProviders we want
		to configure.
	--&gt;
	 &lt;bean id=&quot;authenticationManager&quot;
        class=&quot;org.acegisecurity.providers.ProviderManager&quot;&gt;
        &lt;property name=&quot;providers&quot;&gt;
            &lt;list&gt;
                &lt;ref local=&quot;authenticationProvider&quot; /&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

	&lt;!--
		Our own custom authenticationProvider.
	--&gt;
    &lt;bean id=&quot;authenticationProvider&quot;
		class=&quot;com.xebia.acegi.CustomUserDetailsAuthenticationProvider&quot;&gt;
	&lt;/bean&gt;
</pre>
<p>The abstract methods that need to be implemented are simple:</p>
<pre class="brush: java; title: ; notranslate">

protected abstract void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException ;

protected UserDetails retrieveUser(String username,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException ;
</pre>
<p>And a -again very simple- implementation could be:</p>
<pre class="brush: java; title: ; notranslate">

protected UserDetails retrieveUser(String username,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		Assert.hasText(username);
		Assert.notNull(authentication.getCredentials());
		if (username.equals(&quot;admin&quot;)
				&amp;&amp; authentication.getCredentials().equals(&quot;secret&quot;)) {
			return new User(&quot;admin&quot;, &quot;secret&quot;, true, true, true, true,
					getAuthorities());
		}
		throw new BadCredentialsException(&quot;invalid username/password&quot;);
	}
	/*
	 * return GrantedAuthorities
	 */
	private GrantedAuthority[] getAuthorities() {
		return new GrantedAuthority[] { new GrantedAuthorityImpl(&quot;ROLE_ADMIN&quot;) };
	}
</pre>
<p>The hook that Acegi offers when subclassing the AbstractUserDetailsAuthenticationProvider allows you to call a web service to get the relevant information, query a legacy database or do whatever it takes to populate the User object. Note that because the authentication providers/managers are normal Spring beans you can inject them with configured data sources or any other -more exotic- beans.</p>
<p>A more complex use case could require the following security constraints to be implemented:</p>
<ul>
<li>An user account will be locked if the number of consecutive faulty login attempts exceeds 3.</li>
<li>The password of an user account must be stored encrypted.</li>
<li>An user account can be disabled/enabled for a certain period.</li>
<li>An user account expiries after a certain period of inactivity.</li>
<li>A password expiries after a certain period.</li>
</ul>
<p>The actual implementation (not provided <img src='http://blog.xebia.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> , but you can use <a href="http://blog.xebia.com/wp-content/uploads/2007/03/blog-acegi-part2.zip">this</a> as a starting point ) of such a security policy is quite simple using the Acegi framework and the many hooks Acegi provides. When you consider implementing your own authentication provider do have a good look at the stuff that Acegi provides. There is good chance you can use/re-use existing functionality. There is a lot more to tell about the Acegi Framework like securing your services, securing specific part of your pages, accessing the user data stored in the session, integration with LDAP and using Acegi for standalone desktop applications but not now&#8230;&#8230;</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2007/03/04/how-to-implement-your-own-security-provider-with-the-acegi-framework/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2007%2F03%2F04%2Fhow-to-implement-your-own-security-provider-with-the-acegi-framework%2F&amp;title=How%20to%20implement%20your%20own%20Security%20provider%20with%20the%20Acegi%20framework." id="wpa2a_4"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2007/03/04/how-to-implement-your-own-security-provider-with-the-acegi-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to get started with the Acegi framework</title>
		<link>http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/</link>
		<comments>http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/#comments</comments>
		<pubDate>Sun, 04 Mar 2007 06:44:15 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[Security]]></category>

	<!-- AutoMeta Start -->
	<category>acegi</category>
	<category>acegisecurity</category>
	<category>filter</category>
	<category>login</category>
	<category>jetty</category>
	<category>admin</category>
	<category>admin</category>
	<category>authenticationmanager</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/</guid>
		<description><![CDATA[How to get started with the Acegi framework and implement your own Security provider? In the old days folks used the J2EE securing capabilities of the app server. This is of course still an option, but there are superior alternatives like the Acegi framework. Acegi is far from new and with the latest releases it [...]]]></description>
			<content:encoded><![CDATA[<p>How to get started with the Acegi framework and implement your own Security provider?</p>
<p>In the old days folks used the J2EE securing capabilities of the app server. This is of course still an option, but there are superior alternatives like the Acegi framework. Acegi is far from new and with the latest releases it has become a very stable and easy-to-use framework, especially when combined with Spring. I had to implement a custom security provider for a customer and was very surprised how easy this was accomplished. This blog describes the steps I took to get started with Acegi.</p>
<p><span id="more-172"></span>  </p>
<p>The starting point is a -very- simple web application using the Spring MVC framework. This is the web.xml:</p>
<pre class="brush: xml; title: ; notranslate">

&lt;web-app version=&quot;2.4&quot; xmlns=&quot;http://java.sun.com/xml/ns/j2ee&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd&quot;&gt;

    &lt;context-param&gt;
        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;/WEB-INF/acegi-security.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;blog-acegi-basic&lt;/servlet-name&gt;
        &lt;servlet-class&gt;
            org.springframework.web.servlet.DispatcherServlet
        &lt;/servlet-class&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;

    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;blog-acegi-basic&lt;/servlet-name&gt;
        &lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre>
<p>And the blog-acegi-basic-servlet.xml configuration. </p>
<pre class="brush: xml; title: ; notranslate">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot; &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;

&lt;beans&gt;

    &lt;bean id=&quot;viewResolver&quot;
        class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
        &lt;property name=&quot;viewClass&quot;&gt;
            &lt;value&gt;org.springframework.web.servlet.view.JstlView&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name=&quot;prefix&quot;&gt;
            &lt;value&gt;/WEB-INF/views/&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name=&quot;suffix&quot;&gt;
            &lt;value&gt;.jsp&lt;/value&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean name=&quot;/site/admin.html&quot;
        class=&quot;com.xebia.mvc.AdminController&quot;&gt;
    &lt;/bean&gt;

    &lt;bean name=&quot;/site/public.html&quot;
        class=&quot;com.xebia.mvc.PublicController&quot;&gt;
    &lt;/bean&gt;

&lt;/beans&gt;
</pre>
<p>The two Controllers are also very simple (for demo purposes):</p>
<pre class="brush: java; title: ; notranslate">

public class AdminController implements Controller {
	/*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		return new ModelAndView(&quot;admin&quot;, &quot;info&quot;, &quot;adminInfo&quot;);
	}
}

public class PublicController implements Controller {
	/*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		return new ModelAndView(&quot;public&quot;, &quot;info&quot;, &quot;publicInfo&quot;);
	}
}
</pre>
<p> As are the views admin.jsp </p>
<pre class="brush: xml; title: ; notranslate">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot; ?&gt;
&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot;
    pageEncoding=&quot;ISO-8859-1&quot;%&gt;
&lt;%@ taglib prefix=&quot;authz&quot; uri=&quot;http://acegisecurity.org/authz&quot; %&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot; /&gt;
		&lt;title&gt;Admin&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		Hello Admin
		&lt;c:out value='${info}' /&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>and public.jsp that are placed in the folder WEB-INF/views:</p>
<pre class="brush: xml; title: ; notranslate">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot; ?&gt;
&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot;
    pageEncoding=&quot;ISO-8859-1&quot;%&gt;
&lt;%@ taglib prefix=&quot;authz&quot; uri=&quot;http://acegisecurity.org/authz&quot; %&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot; /&gt;
		&lt;title&gt;Public&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		Hello Public
		&lt;c:out value='${info}'/&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>For now we&#8217;ll leave the acegi-security.xml empty.</p>
<pre class="brush: xml; title: ; notranslate">

&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot; &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;

&lt;beans&gt;
&lt;/beans&gt;
</pre>
<p>When you use maven2 to build your web-application you can use the jetty plugin to test it. The following pom.xml has all dependencies and the plugin configuration to use jetty with the jdk1.5:</p>
<pre class="brush: xml; title: ; notranslate">

&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;groupId&gt;com.xebia&lt;/groupId&gt;
    &lt;artifactId&gt;acegi-blog&lt;/artifactId&gt;
    &lt;packaging&gt;war&lt;/packaging&gt;
    &lt;version&gt;0-1-SNAPSHOT&lt;/version&gt;
    &lt;name&gt;acegi-blog&lt;/name&gt;
    &lt;url&gt;http://maven.apache.org&lt;/url&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring&lt;/artifactId&gt;
            &lt;version&gt;2.0.2&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;junit&lt;/groupId&gt;
            &lt;artifactId&gt;junit&lt;/artifactId&gt;
            &lt;version&gt;3.8.1&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-mock&lt;/artifactId&gt;
            &lt;version&gt;2.0.2&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.acegisecurity&lt;/groupId&gt;
            &lt;artifactId&gt;acegi-security&lt;/artifactId&gt;
            &lt;version&gt;1.0.3&lt;/version&gt;
            &lt;exclusions&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-jdbc&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-aop&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-dao&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;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-web&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-support&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                    &lt;artifactId&gt;spring-remoting&lt;/artifactId&gt;
                &lt;/exclusion&gt;
            &lt;/exclusions&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
            &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
            &lt;version&gt;2.4&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;log4j&lt;/groupId&gt;
            &lt;artifactId&gt;log4j&lt;/artifactId&gt;
            &lt;version&gt;1.2.14&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
                &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
                &lt;version&gt;6.1.1&lt;/version&gt;
                &lt;configuration&gt;
                    &lt;scanIntervalSeconds&gt;1&lt;/scanIntervalSeconds&gt;
                    &lt;contextPath&gt;/blog-acegi&lt;/contextPath&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;source&gt;1.5&lt;/source&gt;
                    &lt;target&gt;1.5&lt;/target&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;
</pre>
<p>The transitive dependency mechanism of maven2 pulls in a lot of the Spring dependencies because of the Acegi 1.0.3 pom configuration. Because I want to use the latest release of Spring I have excluded them from Acegi. When you fire up jetty:</p>
<pre class="brush: plain; title: ; notranslate">
$ mvn jetty:start
</pre>
<p>You can view the public and admin page with the url&#8217;s http://localhost:8080/blog-acegi/site/public.html and http://localhost:8080/blog-acegi/site/admin.html. Now we will introduce Acegi into the equation. We will secure the admin page with an user/password combination, while the public page may remain unsecured. First we add an Acegi Filter to the web.xml:</p>
<pre class="brush: xml; title: ; notranslate">

	&lt;filter&gt;
		&lt;filter-name&gt;Acegi Filter Chain Proxy&lt;/filter-name&gt;
		&lt;filter-class&gt;
			org.acegisecurity.util.FilterToBeanProxy
		&lt;/filter-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;targetClass&lt;/param-name&gt;
			&lt;param-value&gt;
				org.acegisecurity.util.FilterChainProxy
			&lt;/param-value&gt;
		&lt;/init-param&gt;
	&lt;/filter&gt;

	&lt;filter-mapping&gt;
		&lt;filter-name&gt;Acegi Filter Chain Proxy&lt;/filter-name&gt;
		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;
</pre>
<p>The FilterToBeanProxy is configured with a targetClass. Acegi expects an instance of this target class configured in the Spring bean context. We will code the Acegi beans in the Spring context file acegi-security.xml.</p>
<p>As specified in the Acegi Filter we need at least an instance of the FilterChainProxy in the acegi-secutity.xml. </p>
<pre class="brush: xml; title: ; notranslate">

&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot; &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;

&lt;beans&gt;

	&lt;bean id=&quot;filterChainProxy&quot;
		class=&quot;org.acegisecurity.util.FilterChainProxy&quot;&gt;
		&lt;property name=&quot;filterInvocationDefinitionSource&quot;&gt;
			&lt;value&gt;
				&lt;![CDATA[
                PATTERN_TYPE_APACHE_ANT
                /**=exceptionTranslationFilter,filterInvocationInterceptor,authenticationProcessingFilter
            ]]&gt;
			&lt;/value&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;exceptionTranslationFilter&quot;
		class=&quot;org.acegisecurity.ui.ExceptionTranslationFilter&quot;&gt;
		&lt;property name=&quot;authenticationEntryPoint&quot;&gt;
			&lt;bean
				class=&quot;org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint&quot;&gt;
				&lt;property name=&quot;loginFormUrl&quot; value=&quot;/login.jsp&quot; /&gt;
				&lt;property name=&quot;forceHttps&quot; value=&quot;false&quot; /&gt;
			&lt;/bean&gt;
		&lt;/property&gt;

	&lt;/bean&gt;

	&lt;bean id=&quot;authenticationProcessingFilter&quot;
		class=&quot;org.acegisecurity.ui.webapp.AuthenticationProcessingFilter&quot;&gt;
		&lt;property name=&quot;authenticationManager&quot;
			ref=&quot;authenticationManager&quot; /&gt;
		&lt;property name=&quot;authenticationFailureUrl&quot;
			value=&quot;/login.jsp?login_error=1&quot; /&gt;
		&lt;property name=&quot;defaultTargetUrl&quot; value=&quot;/site/public.html&quot; /&gt;
		&lt;property name=&quot;filterProcessesUrl&quot;
			value=&quot;/j_acegi_security_check&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;filterInvocationInterceptor&quot;
		class=&quot;org.acegisecurity.intercept.web.FilterSecurityInterceptor&quot;&gt;
		&lt;property name=&quot;authenticationManager&quot;
			ref=&quot;authenticationManager&quot; /&gt;
			&lt;property name=&quot;accessDecisionManager&quot;&gt;
			&lt;bean class=&quot;org.acegisecurity.vote.AffirmativeBased&quot;&gt;
				&lt;property name=&quot;allowIfAllAbstainDecisions&quot;
					value=&quot;false&quot; /&gt;
				&lt;property name=&quot;decisionVoters&quot;&gt;
					&lt;list&gt;
						&lt;bean class=&quot;org.acegisecurity.vote.RoleVoter&quot; /&gt;
						&lt;bean
							class=&quot;org.acegisecurity.vote.AuthenticatedVoter&quot; /&gt;
					&lt;/list&gt;
				&lt;/property&gt;
			&lt;/bean&gt;
		&lt;/property&gt;
		&lt;property name=&quot;objectDefinitionSource&quot;&gt;
			&lt;value&gt;
				&lt;![CDATA[
                PATTERN_TYPE_APACHE_ANT
                /site/admin.html=ROLE_ADMIN
            ]]&gt;
			&lt;/value&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

	 &lt;bean id=&quot;authenticationManager&quot;
        class=&quot;org.acegisecurity.providers.ProviderManager&quot;&gt;
        &lt;property name=&quot;providers&quot;&gt;
            &lt;list&gt;
                &lt;ref local=&quot;authenticationProvider&quot; /&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;authenticationProvider&quot;
		class=&quot;org.acegisecurity.providers.dao.DaoAuthenticationProvider&quot;&gt;
        &lt;property name=&quot;userDetailsService&quot; ref=&quot;userDetailsServiceImpl&quot;/&gt;
	&lt;/bean&gt;

    &lt;bean id=&quot;userDetailsServiceImpl&quot;
        class=&quot;org.acegisecurity.userdetails.memory.InMemoryDaoImpl&quot;&gt;
        &lt;property name=&quot;userProperties&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;admin&quot;&gt;secret,ROLE_ADMIN&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

&lt;/beans&gt;
</pre>
<p>This rather large xml document configures Acegi to prevent people to see the admin part of the application. The configured beans with some details:</p>
<ul>
<li>The filterChainProxy defines all filters that will be called when an user requests a url that matches the Acegi Filter Chain Proxy filter mapping in the web.xml. I have configured 3 filters.</li>
<li>The exceptionTranslationFilter is responsible for redirecting to the login.jsp in case of a Security Exception. Without this bean our admin page would stil be secured, but the user would get a error stacktrace when trying to access the page without being logged in. </li>
<li>The authenticationProcessingFilter is responsible for handling the form post in the login.jsp. In case of failure it will redirect to the login page and in case of a successfull login the user will be redirected to the defaultTargetUrl.</li>
<li>The filterInvocationInterceptor contains the actual configuration of the security restrictions. It uses two acegi decisionVoters that will check the username/password and the role of the user. In this case we limit the access to the url /site/admin.html to users with the role ROLE_ADMIN.
</li>
<li>The authenticationManager is the hook for all authenticationProviders we want to configure. In this example we use only one provider, but you could configure as many as you would like. I have not encountered an usecase yet where this was required.</li>
<li>The authenticationProvider we use is the one which is provided by Acegi. The retrieving of the user is being delegated to an implementation of the userDetailsService</li>
<li>The implementation of the userDetailsService we use is the InMemoryDaoImpl which can be configured with a list of users, password and roles. Acegi also provides a JdbcDaoImpl which actually retrieves the users and their roles from the database.</li>
</ul>
<p>Because auto-formatting the acegi-secutiry.xml file can mess up the ANT like configuration I have coded those parts within CDATA sections. The one thing missing is the login.jsp; the login.jsp needs to be placed in the root of war file. When using maven2 for packaging the war the login.jsp must be placed in the webapp directory.</p>
<pre class="brush: xml; title: ; notranslate">

&lt;%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt'%&gt;
&lt;%@ page import=&quot;org.acegisecurity.ui.AbstractProcessingFilter&quot;%&gt;
&lt;%@ page
	import=&quot;org.acegisecurity.ui.webapp.AuthenticationProcessingFilter&quot;%&gt;
&lt;%@ page import=&quot;org.acegisecurity.AuthenticationException&quot;%&gt;

&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;Login&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;
	&lt;c:if test=&quot;${not empty param.login_error}&quot;&gt;
		&lt;font color=&quot;red&quot;&gt; Your login attempt was not successful, try
		again.&lt;BR&gt;
		&lt;BR&gt;
		Reason: &lt;%=((AuthenticationException) session
											.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY))
											.getMessage()%&gt; &lt;/font&gt;
	&lt;/c:if&gt;

	&lt;form action=&quot;&lt;c:url value='j_acegi_security_check'/&gt;&quot; method=&quot;POST&quot;&gt;

	&lt;center&gt;
		&lt;table align=&quot;center&quot; cellpadding=&quot;4&quot; cellspacing=&quot;0&quot; border=&quot;0&quot;
					class=&quot;loginform&quot;&gt;
			&lt;tr&gt;
				&lt;td bgcolor=&quot;f0f0f0&quot; colspan=&quot;2&quot;&gt;Enter your details below to
					login to admin site:&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr /&gt;
			&lt;tr&gt;
				&lt;td nowrap align=&quot;right&quot; valign=&quot;top&quot;&gt;&lt;label class=&quot;label&quot;&gt;&lt;u&gt;U&lt;/u&gt;sername:&lt;/label&gt;&lt;/td&gt;
				&lt;td&gt;&lt;input type='text' name='j_username' accessKey=&quot;U&quot;&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td nowrap align=&quot;right&quot; valign=&quot;top&quot;&gt;&lt;label class=&quot;label&quot;&gt;&lt;u&gt;P&lt;/u&gt;assword:&lt;/label&gt;&lt;/td&gt;
				&lt;td&gt;&lt;input type='password' name='j_password' accessKey=&quot;P&quot;&gt;&lt;/td&gt;
			&lt;/tr&gt;

			&lt;tr&gt;
				&lt;td valign=&quot;middle&quot; align=&quot;center&quot; colspan=&quot;2&quot;&gt;&lt;input
						id=&quot;loginButton&quot; type=&quot;submit&quot; value=&quot;Log In&quot; /&gt;&lt;/td&gt;
			&lt;/tr&gt;

		&lt;/table&gt;
	&lt;/center&gt;
	&lt;/form&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Again using the jetty plugin we can verify the result. When trying to access the admin page we will be prompted for an username and password and when providing the correct combination we will be forwarded to the admin page. The public page is still accessible for everyone. I have attached the <a href="http://blog.xebia.com/wp-content/uploads/2007/03/blog-acegi.zip">source code</a> of this example. The InMemoryDaoImpl is of course not very sophisticated. In a next blog I&#8217;ll show you how to implement your own security provider.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2007%2F03%2F04%2Fhow-to-get-started-with-the-acegi-framework%2F&amp;title=How%20to%20get%20started%20with%20the%20Acegi%20framework" id="wpa2a_6"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2007/03/04/how-to-get-started-with-the-acegi-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AspectJ and Maven2</title>
		<link>http://blog.xebia.com/2006/11/04/aspectj-and-maven2/</link>
		<comments>http://blog.xebia.com/2006/11/04/aspectj-and-maven2/#comments</comments>
		<pubDate>Sat, 04 Nov 2006 13:13:05 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[Java]]></category>

	<!-- AutoMeta Start -->
	<category>aspectj</category>
	<category>adrian</category>
	<category>play</category>
	<category>colyer</category>
	<category>println</category>
	<category>dontwritetotheconsole</category>
	<category>sysoutorerraccess</category>
	<category>console</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2006/11/04/aspectj-and-maven2/</guid>
		<description><![CDATA[How to use AspectJ to check your code in combination with maven2? A couple a weeks ago me and some colleagues took a two day course in AOP. The course was given by the excellent teacher Adrian Colyer. In this short blog I want to show you a very nice (not well known) feature of [...]]]></description>
			<content:encoded><![CDATA[<p>How to use AspectJ to check your code in combination with maven2?</p>
<p>A couple a weeks ago me and some colleagues took a two day course in AOP. The course was given by the excellent teacher Adrian Colyer. In this short blog I want to show you a very nice (not well known) feature of AspectJ and how you can integrate AspectJ in your build using the maven2 plugin.</p>
<p><span id="more-130"></span></p>
<p>When you want to play around with AspectJ the first thing you should do is install the <a href="http://www.eclipse.org/ajdt/">AspectJ eclipse plugin.</a> With this plugin you can enable AspectJ support for your project.</p>
<p>Often the use of aspects, beside the obvious usages like security, transactions, and tracing, is frowned upon: too complex, too difficult and where is the world going to. Conservatists! I was one of those people, but in the course Adrian showed us some good real-world usecases where aspects can improve your code. I&#8217;ll show you one example (and I hope Adrian won&#8217;t mind me using some of his code). </p>
<p>I don&#8217;t like code like this:</p>
<pre class="brush: java; title: ; notranslate">
    //do Something
    System.out.println(&quot;Something happened&quot;);
</pre>
<p>Everyone will agree that it is far better to use a logging framework to inform people that something happened.</p>
<pre class="brush: java; title: ; notranslate">
    //do Something
    if (log.isDebugEnabled()) {
        log.debug(&quot;Something happened&quot;);
    }
</pre>
<p>But when doing audits/working on projects I almost always encounter the &#8216;System.out&#8217; anti-pattern. With AspectJ it is very easy to write an aspect that checks during the build if the code tries to write messages to the console. </p>
<pre class="brush: java; title: ; notranslate">
/**
 * @author Adrian Colyer
 */
public aspect DontWriteToTheConsole {

	pointcut sysOutOrErrAccess() : get(* System.out) || get(* System.err);

	declare error
	  : sysOutOrErrAccess()
	  : &quot;Don't write to the console&quot;;

}
</pre>
<p>The above pointcut expression detects all attempts to access the public property &#8216;out&#8217; of the &#8216;System&#8217; class and generates a compile error (it would probably be better to declare a warning in this specific case, but this is just an example). When you want to check all of your code simply put the aspect in your codebase and add the following dependency to your maven2 pom.xml:</p>
<p>&lt;dependency&gt;<br />
    &lt;groupId&gt;aspectj&lt;/groupId&gt;<br />
    &lt;artifactId&gt;aspectjrt&lt;/artifactId&gt;<br />
    &lt;version&gt;1.5.2a&lt;/version&gt;<br />
&lt;/dependency&gt;</p>
<p>The next thing you want to do is add the aspectj-maven-plugin to the build section of your pom.xml:</p>
<p>&lt;plugins&gt;<br />
  &lt;plugin&gt;<br />
    &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;<br />
    &lt;artifactId&gt;aspectj-maven-plugin&lt;/artifactId&gt;<br />
    &lt;executions&gt;<br />
      &lt;execution&gt;<br />
        &lt;goals&gt;<br />
          &lt;goal&gt;compile&lt;/goal&gt;&lt;!&#8211; use this goal to weave all your main classes &#8211;&gt;<br />
          &lt;goal&gt;test-compile&lt;/goal&gt;&lt;!&#8211; use this goal to weave all your test classes &#8211;&gt;<br />
        &lt;/goals&gt;<br />
      &lt;/execution&gt;<br />
    &lt;/executions&gt;<br />
  &lt;/plugin&gt;<br />
&lt;/plugins&gt;</p>
<p>Now when your build your project</p>
<pre class="brush: plain; title: ; notranslate">$ mvn clean install</pre>
<p>the build breaks when you write &#8220;Hello World&#8221; to the console:</p>
<p>[INFO] &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
[ERROR] BUILD ERROR<br />
[INFO] &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
[INFO] Compiler errors :<br />
error at System.out.println(&#8220;Hello World!&#8221;);<br />
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br />
E:\workspace\play-time\src\main\java\org\harsta\HelloWorld.java:9:0::0 Don&#8217;t write to the console<br />
        see also: E:\workspace\play-time\src\main\java\org\harsta\DontWriteToTheConsole.aj:18::0</p>
<p>The example is simple, but there are a lot more ways to check if your code is &#8216;clean&#8217;. You could even write a maven2 profile that enables the weaving process only under some circumstances (like the presence of an environment variable).</p>
<p>If you want to read more about AspectJ in combination with Spring 2.0 this <a href="http://www.infoq.com/articles/Simplifying-Enterprise-Apps">article</a> is a good starting point.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2006/11/04/aspectj-and-maven2/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2006%2F11%2F04%2Faspectj-and-maven2%2F&amp;title=AspectJ%20and%20Maven2" id="wpa2a_8"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2006/11/04/aspectj-and-maven2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the Maven2 assembly plug-in to package and deliver your applications</title>
		<link>http://blog.xebia.com/2006/07/30/using-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications/</link>
		<comments>http://blog.xebia.com/2006/07/30/using-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications/#comments</comments>
		<pubDate>Sun, 30 Jul 2006 19:33:37 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[Java]]></category>

	<!-- AutoMeta Start -->
	<category>petshop</category>
	<category>module</category>
	<category>modules</category>
	<category>dist</category>
	<category>archive</category>
	<category>dist</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2006/07/30/using-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications/</guid>
		<description><![CDATA[You have finished your first iteration in your project and in order to get feedback from the business you wish to have your application deployed on the test environment. In many projects the test environment is maintained by the developers. That is fine, but the acceptance and production environment are not. Why not start packaging [...]]]></description>
			<content:encoded><![CDATA[<p>You have finished your first iteration in your project and in order to get feedback from the business you wish to have your application deployed on the test environment. In many projects the test environment is maintained by the developers. That is fine, but the acceptance and production environment are not. Why not start packaging and delivering your project artifacts like you would with a production release? This way you have a chance to fine-tune this process. When the time comes that you will have to deliver to an acceptance or production release you will have automated this process, aligned it with the expectations of the department responsible for deployment and, hopefully, made it less fallible. Where to start?</p>
<p><span id="more-78"></span></p>
<p>I&#8217;ll be assuming in this blog that you use <a href="http://maven.apache.org/">Maven2</a> for building the different parts of your Java application. If this is not the case I advise you to have a look at Maven2. With release 2.0.4 Maven2 has come to a maturity level that I feel I can safely recommend it to customers. Maven2 advocates one artifact for each project. A typical Java application has more than one sub-artifact: several jar files, a web archive and finally an ear file to package the lot. This typical setup is supported by Maven through the use of sub-modules. First you begin with a top level <a href="http://maven.apache.org/ref/2.0.4/maven-model/maven.html">pom.xml</a> where you define all the global configurations of your application. These normally would include things like: </p>
<ul>
<li>The groupId.</li>
<li>The version.</li>
<li>An &#8216;issueManagement&#8217; section</li>
<li>A &#8216;ciManagement&#8217; section </li>
<li>Information about the developers</li>
<li>The configuration of the repositories (local and remote)</li>
<li>Source Control Management (scm) information</li>
<li>All the shared dependencies for all modules</li>
<li>&#8216;distributionManagement&#8217; section including site information, your local company repository and snapshotRepository</li>
</ul>
<p>The next thing to configure in your top pom.xml are the sub-modules of your project. The following xml fragment specifies that your application has five sub modules (oh, not the petshop again&#8230;):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;modules&gt;
    &lt;module&gt;xebia-petshop-core-jar&lt;/module&gt;
    &lt;module&gt;xebia-petshop-util-jar&lt;/module&gt;
    &lt;module&gt;xebia-petshop-war&lt;/module&gt;
    &lt;module&gt;xebia-petshop-statistices-war&lt;/module&gt;
    &lt;module&gt;xebia-petshop-ear&lt;/module&gt;
  &lt;/modules&gt;
</pre>
<p>Good descriptive names of your sub-modules, including their artifact type, are always helpful and especially as their number grow. I have found it good practice to have the artifactId of a module equal the name of the module minus the type definition. Following this rule the artifactId name of the <i>xebia-petshop-util-jar</i> module would be <i>xebia-petshop-util</i> resulting in the artifact <i>xebia-petshop-util-0.1-SNAPSHOT.jar</i>. The pom.xml configuration of this sub-module would be something like this:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;parent&gt;
    &lt;groupId&gt;com.xebia.petshop&lt;/groupId&gt;
    &lt;artifactId&gt;xebia-petshop&lt;/artifactId&gt;
    &lt;version&gt;0.1-SNAPSHOT&lt;/version&gt;
  &lt;/parent&gt;
  &lt;artifactId&gt;xebia-petshop-util&lt;/artifactId&gt;
  &lt;packaging&gt;jar&lt;/packaging&gt;
</pre>
<p>Looking at the names of the sub-modules it is not too difficult to guess what the content would be. The <i>xebia-petshop-core</i> module has a dependency on the <i>xebia-petshop-util</i> module. The <i>xebia-petshop-war</i> module is dependent on the <i>xebia-petshop-core</i> module (this way the artifact of <i>xebia-petshop-core</i> will end up in the WEB-INF/lib directory of the xebia-petshop-0.1-SNAPSHOT.war. Finally the <i>xebia-petshop-ear</i> is dependent on the two war modules. The final deployable artifact is the xebia-petshop-0.1-SNAPSHOT.ear. I have found it also good practice to have an <a href="http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/">environment independent deployable artifact</a>. So with this multi-module setup all the tests will be run and the -sub- artifacts will be created and deployed to your local and company repository when issuing the following Maven2 command:</p>
<pre class="brush: plain; title: ; notranslate">$ mvn clean install deploy</pre>
<p>Using the excellent <a href="http://maven.apache.org/plugins/maven-release-plugin/introduction.html"/>Maven2 release plugin</a> you can perform a release saving a lot of repetitive, manual work like updating the version, tagging the source code and deploying the artifacts to your repository. Now basically here should end your tasks as developer or not? The department or person responsible for deploying the<br />
xebia-petshop-0.1-SNAPSHOT.ear probably needs additional information to succesfully deploy the application. For this reason we introduce a new module:</p>
<pre class="brush: xml; title: ; notranslate">&lt;module&gt;xebia-petshop-dist&lt;/module&gt;</pre>
<p>The <i>xebia-petshop-dist</i> module will produce a tar archive including our ear and everything else needed for configuring the target environment. The choice of your application server of course has a significant impact on the required configuration. Let us assume that the IT department has developed a hardened configuration of the open source <a href="www.jboss.org">JBoss server</a>. A hardened configuration of the  JBoss server should at least address the following issues:</p>
<ul>
<li>Securing the management console.</li>
<li>Securing the jmx console and jmx invoker.</li>
<li>Removal of the http invokers.</li>
<li>Removal of the default HsqDB datasource/database.</li>
<li>Configuration of the different security domains.</li>
<li>SSL enabling.</li>
<li>Removal of the download service.</li>
<li>Configuration of Log4J.</li>
<li>Configuration of the clustering capabilities.</li>
</ul>
<p>It is out-of-scope to discuss in detail <a href="http://www.oreilly.com/catalog/jbossadn/">how to configure this</a>. Based on a company specific configuration the developers of the xebia-petshop application must specify to the deployer which additional resources the application depends on. Let us assume that the application uses the following environment specific resources:</p>
<ul>
<li>A DataSource configured in a xebia-petshop-ds.xml file.</li>
<li>Environment specific variables for configuring and injecting a Ldap server instance coded in a jndi.properties file. </li>
<li>SQL create scripts for the database schema and alternatively alter scripts for consecutive releases.</li>
</ul>
<p>It is a matter of taste where to store these additional configuration files. Basically you will have to choose between the <i>xebia-petshop-dist</i> or <i>xebia-petshop-ear</i> module. Lets choose the second option and configure the pom.xml of the <i>xebia-petshop-dist</i> to use the assembly plug-in of Maven2 to build a tar archive including the ear file and the additional configuration files in order for the deployer to do his work:</p>
<pre class="brush: xml; title: ; notranslate">
 &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;goals&gt;
              &lt;goal&gt;attached&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;phase&gt;package&lt;/phase&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;descriptor&gt;src/main/assembly/dep.xml&lt;/descriptor&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
   &lt;/plugins&gt;
 &lt;/build&gt;
 &lt;/build&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.xebia.petshop&lt;/groupId&gt;
      &lt;artifactId&gt;xebia-petshop-ear&lt;/artifactId&gt;
      &lt;type&gt;ear&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
</pre>
<p>The xebia-petshop-ds.xml and the jndi.properties files contains placeholders for the variables that need to be replaced by the deployer. </p>
<pre class="brush: xml; title: ; notranslate">
&lt;datasources&gt;
   &lt;local-tx-datasource&gt;
        &lt;jndi-name&gt;PetshopDS&lt;/jndi-name&gt;
        &lt;connection-url&gt;@petshop.jdbc.url@&lt;/connection-url&gt;
        &lt;driver-class&gt;com.mysql.jdbc.Driver&lt;/driver-class&gt;
        &lt;user-name&gt;@petshop.jdbc.user@&lt;/user-name&gt;
        &lt;password&gt;@petshop.jdbc.password@&lt;/password&gt;
    &lt;/local-tx-datasource&gt;
&lt;/datasources&gt;
</pre>
<p>One additional file is necessary to include in our final archive: a README.html file that sums up the content of the archive and contains a list of all placeholders that need to replaced by the deployment team. The assembly plugin source file &#8216;dep.xml&#8217; sums up all the content to be placed in the final archive.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;assembly&gt;
  &lt;id&gt;bin&lt;/id&gt;
  &lt;formats&gt;
    &lt;format&gt;tar.gz&lt;/format&gt;
  &lt;/formats&gt;
  &lt;fileSets&gt;
    &lt;fileSet&gt;
      &lt;directory&gt;src/main/html/&lt;/directory&gt;
      &lt;outputDirectory&gt;/&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;README.html&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
    &lt;fileSet&gt;
      &lt;directory&gt;../xebia-petshop-ear/src/jboss4x/deploy&lt;/directory&gt;
      &lt;outputDirectory&gt;jboss/deploy&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*.*&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
    &lt;fileSet&gt;
      &lt;directory&gt;../xebia-petshop-ear/src/jboss4x/conf&lt;/directory&gt;
      &lt;outputDirectory&gt;jboss/conf&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*.*&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
    &lt;fileSet&gt;
      &lt;directory&gt;../xebia-petshop-ear/src/main/sql&lt;/directory&gt;
      &lt;outputDirectory&gt;db&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*.*&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
  &lt;/fileSets&gt;
  &lt;dependencySets&gt;
    &lt;dependencySet&gt;
      &lt;outputDirectory&gt;/&lt;/outputDirectory&gt;
      &lt;unpack&gt;false&lt;/unpack&gt;
      &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependencySet&gt;
  &lt;/dependencySets&gt;
&lt;/assembly&gt;
</pre>
<p>When the <i>xebia-petshop-dist</i> module is installed the xebia-petshop-dist-0.1-SNAPSHOT-bin.tar.gz will be uploaded to your local company maven2 repository where the deployer can pick it up and actually start his/their deployment procedure. One could even use the <a href="http://mojo.codehaus.org/docbook-maven-plugin/">docbook plugin</a> of Maven2 to generate the README.html based on a docbook xml source file.</p>
<p>Having an &#8216;dist&#8217; module in your Maven2 project structure that uses the assembly plugin to archive all necessary resources and artifacts is a good step to a more controlled and automated release procedure.  </p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2006/07/30/using-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2006%2F07%2F30%2Fusing-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications%2F&amp;title=Using%20the%20Maven2%20assembly%20plug-in%20to%20package%20and%20deliver%20your%20applications" id="wpa2a_10"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2006/07/30/using-the-maven2-assembly-plug-in-to-pacakge-and-deliver-your-applications/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Configure your external dependencies with Spring &amp; Jndi</title>
		<link>http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/</link>
		<comments>http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/#comments</comments>
		<pubDate>Sun, 16 Jul 2006 09:48:19 +0000</pubDate>
		<dc:creator>Okke Harsta</dc:creator>
				<category><![CDATA[Java]]></category>

	<!-- AutoMeta Start -->
	<category>propertyplaceholderconfigurer</category>
	<category>ldap</category>
	<category>placeholders</category>
	<category>deployable</category>
	<category>environment</category>
	<category>variables</category>
	<category>jndi</category>
	<category>assembly</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/</guid>
		<description><![CDATA[How to deal with platform environment (Test, Acceptance, Production etc.) specific variables in Java applications? Applications often need resources like databases, third-company web services, ldap servers and other external systems. It is common practice to externalize the configuration of such resources. In the case of a database dependency the use of a DataSource (hiding the [...]]]></description>
			<content:encoded><![CDATA[<p>How to deal with platform environment (Test, Acceptance, Production etc.) specific variables in Java applications?</p>
<p>Applications often need resources like databases, third-company web services, ldap servers and other external systems. It is common practice to externalize the configuration of such resources. In the case of a database dependency the use of a DataSource (hiding the complexity of configuring and connecting to the database) is a good example of this. The details of the configuration are in most cases platform environment specific. So how do we properly externalize the details of the configuration?</p>
<p><span id="more-63"></span></p>
<p>Basically the development team has two options:</p>
<ul>
<li>Build an application and specify the target environment</li>
<li>Externalize the variables from the deployable unit</li>
</ul>
<p>I have seen many development teams using the first option. They use ant, maven or maven2 to build their java application and they use a command parameter to specify the target environment of the build. It usually looks something like this:</p>
<pre class="brush: plain; title: ; notranslate">$ ant install -Denv=test</pre>
<p>or in the case of maven2 using profiles: </p>
<pre class="brush: plain; title: ; notranslate">$ mvn -P test clean install</pre>
<p>There are numerous ways to accomplish this using properties files, xml descriptors, filtering etc. The end result is a deployable unit that can only be deployed in the environment it was built for. I don&#8217;t like this approach. It is better to have a deployable unit that can be deployed in any environment. This is mainly because the deployment of an application should not be the responsibility of developers. It is the responsibility of the maintenance department and the environment specific variables should be part of the environment and not of the application. The final argument is that developers often have no knowledge about the acceptance or production environmental resources. For instance, how can they possibly know the username/password of the production database? So how do we make the deployable unit independent of the target environment?</p>
<p>First it requires that we don&#8217;t hardcode any environment specific values in the codebase. This is, apart from the problem we are dealing with, always a good practice. So we use properties files or even better (when using <a href="http://www.springframework.org">Spring</a>, and you should!) we use placeholders in our application context files. An example: we are using an LDAP server to authenticate our users in combination with the excellent <a href="http://www.acegisecurity.org/">Acegi</a> framework. Let us assume we have a test LDAP server and a production LDAP server.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;initialDirContextFactory&quot; class=&quot;org.acegisecurity.ldap.DefaultInitialDirContextFactory&quot;&gt;
   &lt;constructor-arg index=&quot;0&quot; value=&quot;${ldap_address}&quot;/&gt;
&lt;/bean&gt;
</pre>
<p>Spring already has support for resolving placeholders like <em>${ldap_address}</em> during the runtime initialization of the bean factory. Simply define a <em><a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderConfigurer</a></em> in your application context file that uses a properties file for pulling values into bean definitions. However the problem with that approach is that you have to wire the <em>PropertyPlaceholderConfigurer</em> with the location of the properties file. The developer can not make assumptions about the location of the properties file nor is it wise to do so. It would be nice if we had a generic way of wiring a <em>PropertyPlaceholderConfigurer</em> with the correct values. Enter Jndi! If you would have a generic hook to populate the environment of the InitialContext with the values of the placeholders then we could use the Jndi Context to lookup and resolve the specific placeholders. Most application servers have such a hook and I will show how to do this with the excellent <a href="http://labs.jboss.com/portal/">JBoss</a> application server.</p>
<p>Using the <em>jndi.properties</em> file in the <em>conf</em> directory of your server configuration you can easily pass the platform environment specific values to the <em>InitialContext</em>. You don&#8217;t have to hardcode an absolute or relative path into your <em>PropertyPlaceholderConfigurer</em> if you use the <em>jndi.properties</em> file. Continuing our example we would need the following key-value entry for our <em>initialDirContextFactory</em> bean:</p>
<pre class="brush: plain; title: ; notranslate">ldap_address=ldap://organization.intra.local.test</pre>
<p>Add this key-value pair to the <em>jndi.properties</em> file located in the <em>conf</em> directory of your JBoss server configuration and use a customized <em>PropertyPlaceholderConfigurer</em> to resolve your placeholders:</p>
<pre class="brush: java; title: ; notranslate">
public class JndiPlaceholderConfigurer extends PropertyPlaceholderConfigurer  implements InitializingBean {
    private Map environment;
    public void afterPropertiesSet() throws Exception {
        Context context = new InitialContext();
        environment = context.getEnvironment();
    }
    protected String resolvePlaceholder(String placeholder, Properties props) {
        return (String) this.environment.get(placeholder);
    }
}
</pre>
<p>With one line of xml code in one of your spring bean definitions files the post-processing of the <em>BeanFactory</em> initialization will take care of resolving the placeholders:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;propertyConfigurer&quot; class=&quot;xxx.xxx.JndiPlaceholderConfigurer&quot;/&gt;
</pre>
<p>Of course you need a proper procedure set up for communicating the environment specific variables your application depends on to the person/department responsible for deploying the application. Currently I&#8217;m looking at the <a href="http://maven.apache.org/plugins/maven-assembly-plugin/">Assembly</a> plugin for <a href="http://maven.apache.org/">Maven 2</a> to automate the process of delivering more than just the deployable application unit to the people responsible for deploying applications. In my next blog I will elaborate more on the assembly plugin and how to make sure that the application server configuration meets the demands of your application.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2006%2F07%2F16%2Fconfigure-your-external-dependencies-with-spring-jndi%2F&amp;title=Configure%20your%20external%20dependencies%20with%20Spring%20%26%23038%3B%20Jndi" id="wpa2a_12"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2006/07/16/configure-your-external-dependencies-with-spring-jndi/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.xebia.com/author/oharsta/feed/ ) in 0.72067 seconds, on Feb 9th, 2012 at 4:04 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 9th, 2012 at 5:04 pm UTC -->
