<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19517292</id><updated>2012-02-11T12:02:18.339+01:00</updated><category term='sonar'/><category term='TargetAdapter'/><category term='javascript templates'/><category term='acceptance test'/><category term='SpelExpressionParser'/><category term='ServiceLoader'/><category term='jaxb'/><category term='localization'/><category term='maven'/><category term='JavaCSV'/><category term='jawr'/><category term='Glob'/><category term='DecimalFormatSymbols'/><category term='lordofthejars.com'/><category term='java-based spring container configuration'/><category term='caching static resources'/><category term='dzone'/><category term='Google Chrome Developer Tools'/><category term='AOP Advice &quot;Spring'/><category term='git'/><category term='AccessDecisionManager'/><category term='Backbone'/><category term='recaptcha'/><category term='John Ferguson Smart'/><category term='closures'/><category term='standardized working environment'/><category term='parameterized'/><category term='HttpMessageConverter'/><category term='i18n'/><category term='spring internationalization'/><category term='java'/><category term='flyway'/><category term='Criteria API'/><category term='hamcrest'/><category term='best practices'/><category term='jsr 203'/><category term='java 1.7'/><category term='maven aspectj'/><category term='Spring Integration'/><category term='aspectj'/><category term='smack'/><category term='rest'/><category term='spring 3.1'/><category term='maven repository'/><category term='ajdt'/><category term='categories'/><category term='spring security oauth'/><category term='groovy'/><category term='custom fest'/><category term='clean code'/><category term='hamcrest xml'/><category term='JUnit Kung Fu'/><category term='joda time'/><category term='100k visits'/><category term='table selectors'/><category term='openjdk 7'/><category term='performance web'/><category term='dsl'/><category term='unit testing'/><category term='itd'/><category term='maven-datanucleus-plugin'/><category term='ubuntu'/><category term='SourceAdapter'/><category term='hamcrest develop'/><category term='ServiceListFactoryBean'/><category term='json'/><category term='MIME type'/><category term='AOP'/><category term='spEL'/><category term='java.util.Objects'/><category term='voter'/><category term='oauth 2'/><category term='java security'/><category term='maven gae'/><category term='nullable hash'/><category term='spring mvc'/><category term='github'/><category term='tomcat'/><category term='OSGI'/><category term='database migration'/><category term='spring profile'/><category term='spring-oxm'/><category term='ServiceLoaderFactoryBean'/><category term='gmaven'/><category term='internationalization'/><category term='barrier'/><category term='jetty'/><category term='ApplicationEvent'/><category term='hibernate second level cache'/><category term='ApplicationListener'/><category term='open authentication'/><category term='aggregate pom'/><category term='Distributed Version Control System'/><category term='protecting forms'/><category term='html5 template engine'/><category term='wakaleo'/><category term='claim check pattern'/><category term='springframework'/><category term='embedded'/><category term='java persistence'/><category term='custom hamcrest'/><category term='spring framework'/><category term='minification javascript'/><category term='spring-aspects'/><category term='scm'/><category term='html5boilerplate'/><category term='ssh'/><category term='jdk 7'/><category term='active record pattern'/><category term='StaticApplicationContext'/><category term='Selenium 2'/><category term='spring events'/><category term='jquery'/><category term='etag'/><category term='comma-separated values'/><category term='nullable equals'/><category term='sql'/><category term='class responsibilities'/><category term='domain specific language'/><category term='hibernate metamodel java persistence'/><category term='twitter'/><category term='enterprise integration patterns'/><category term='EJP'/><category term='Authentication'/><category term='hibernate query cache'/><category term='Maven Verifier Plugin'/><category term='asynchronous UI'/><category term='named pointcuts'/><category term='yui compression'/><category term='hibernate metamodel'/><category term='jsr166y'/><category term='theories'/><category term='central repository'/><category term='dao pattern'/><category term='spring MVC res'/><category term='nexus'/><category term='continuous integration'/><category term='archetype from existing project'/><category term='aspectj-maven-plugin'/><category term='html5'/><category term='web'/><category term='awaitility'/><category term='java util date'/><category term='oauth service provider'/><category term='junit'/><category term='files operations'/><category term='observer observable pattern'/><category term='annotations'/><category term='recaptcha4j'/><category term='l10n'/><category term='jpa 2'/><category term='Spring-Data'/><category term='restful web services'/><category term='WebDriver'/><category term='test'/><category term='groovy java'/><category term='spring roo'/><category term='restclient'/><category term='css'/><category term='easymock'/><category term='spring roo addon java'/><category term='jsr 310'/><category term='jsmin'/><category term='FileWatcher'/><category term='spring MVC rest'/><category term='css minification'/><category term='fest'/><category term='hibernate cache'/><category term='jdbc extension'/><category term='xml'/><category term='asynchronous test'/><category term='maven-gae-plugin'/><category term='java Datecalc'/><category term='polyglot programming'/><category term='spring EL'/><category term='css3'/><category term='spring security'/><category term='groovy regular expressions'/><category term='theserverside'/><category term='pom'/><category term='script engine'/><category term='oauth consumer'/><category term='JdbcTemplate'/><category term='ThreadPoolExecutor'/><category term='thymeleaf'/><category term='web security'/><category term='test automation'/><category term='inter-type declarations'/><category term='yaml'/><category term='nullable toString'/><category term='Smack Jabber'/><category term='junit testing java'/><category term='Scripting API'/><category term='verifier'/><category term='regular expressions'/><category term='javacodegeeks'/><category term='maven archetype'/><category term='version control'/><category term='testing'/><category term='eclispe'/><category term='maven deploy'/><category term='message storage'/><category term='visits'/><category term='servlet 3.0'/><category term='DVCS'/><category term='rules'/><category term='flyway-maven-plugin'/><category term='springsource'/><category term='javascript'/><category term='groovy xml'/><category term='custom SimpleApplicationEventMulticaster'/><category term='QueryDSL'/><category term='java concurrency'/><category term='jenkins'/><category term='maven release plugin'/><category term='hibernate performance'/><category term='mock'/><category term='META-INF/services'/><category term='Authorization'/><category term='gzip'/><category term='configuration files'/><category term='css shadows'/><category term='SimpleApplicationEventMulticaster'/><category term='test mock stubbing'/><category term='parent pom'/><category term='JBehave'/><category term='STS'/><category term='neal ford'/><category term='maven metrics'/><category term='jsr 223'/><category term='devoxx'/><category term='script'/><category term='debian'/><category term='liquibase'/><category term='google fonts'/><category term='Spring'/><category term='jackson'/><category term='csv'/><category term='Compilable script'/><category term='mockito'/><category term='testing private methods'/><category term='database'/><category term='deploy'/><category term='hibernate'/><category term='minification'/><category term='Spring http message converter'/><category term='jsr303'/><category term='GAE'/><category term='assertions'/><category term='XMPP'/><category term='eis'/><category term='type-safe queries'/><category term='phaser'/><category term='jdk services'/><category term='mongodb'/><category term='spring liquibase'/><category term='Google App Engine'/><category term='injecting mocks'/><category term='time'/><category term='junit testing private methods neal ford'/><category term='tests'/><category term='captcha'/><category term='JPF'/><category term='ehcache'/><category term='NIO 2'/><category term='integration tests'/><category term='Spring Template Project'/><category term='spring framework 3.1'/><category term='XML parsing'/><category term='fishing'/><category term='japan'/><category term='ServiceFactoryBean'/><category term='aggregation'/><category term='groovy sql'/><category term='YamlHttpMessageConverter'/><category term='fork-join'/><category term='snakeyaml'/><title type='text'>One Jar To Rule Them All</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>68</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19517292.post-3714661550480385448</id><published>2012-01-31T08:26:00.000+01:00</published><updated>2012-01-31T08:26:30.896+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate performance'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate cache'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate second level cache'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate query cache'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><title type='text'>Giuro per sempre a te, Di viver, morire per te, Se tu sarai con me lo so, Dea Roma, vincerò!</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://static.ddmcdn.com/gif/hibernation-dormouse.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://static.ddmcdn.com/gif/hibernation-dormouse.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;One of the common problems of people that start using &lt;b&gt;Hibernate&lt;/b&gt; is performance, if you don't have much experience in &lt;b&gt;Hibernate&lt;/b&gt; you will find how quickly your application becomes slow. If you enable &lt;i&gt;sql&lt;/i&gt; traces, you would see how many queries are sent to database that can be avoided with little&amp;nbsp;&lt;b&gt;Hibernate&lt;/b&gt; knowledge. In current post I am going to explain how to use &lt;b&gt;Hibernate Query Cache&lt;/b&gt; to avoid amount of traffic between your application and database.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Hibernate&lt;/b&gt; offers two caching levels:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The first level cache is the &lt;i&gt;session cache&lt;/i&gt;. Objects are cached within the current session and they are only alive until the session is closed.&lt;/li&gt;&lt;li&gt;The second level cache exists as long as the &lt;i&gt;session factory&lt;/i&gt; is alive. Keep in mind that in case of &lt;b&gt;Hibernate&lt;/b&gt;, second level cache is not a tree of objects; object instances are not cached, instead it stores attribute values.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;After this brief introduction (so brief I know) about &lt;b&gt;Hibernate&lt;/b&gt; cache, let's see what is&lt;b&gt; Query Cache&lt;/b&gt; and how is interrelated with second level cache.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Query Cache&lt;/b&gt; is responsible for caching the combination of query and values provided as parameters as key, and list of identifiers of objects returned by query execution as values. Note that using &lt;b&gt;Query Cache&lt;/b&gt; requires a second level cache too because when query result is get from cache (that is a list of identifiers), &lt;b&gt;Hibernate&lt;/b&gt; will load objects using cached identifiers from second level.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;To sum up, and as a conceptual schema, given next query: "&lt;i&gt;from Country where population &amp;gt; :number&lt;/i&gt;", after first execution,&amp;nbsp;&lt;b&gt;Hibernate&lt;/b&gt; caches would contain next fictional values (note that &lt;i&gt;number&lt;/i&gt; parameter is set to 1000):&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;L2 Cache&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;[&lt;br /&gt;id:1, {name='Spain', population=1000, ....}&lt;br /&gt;id:2, {name='Germany', population=2000,...}&lt;br /&gt;....&lt;br /&gt;]&lt;br /&gt;&lt;b&gt;&lt;u&gt;QueryCache&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;[{from Country where population &amp;gt; :number, 1000}, {id:2}]&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So before start using&lt;b&gt; Query Cache&lt;/b&gt;, we need to configure cache of second level.&lt;br /&gt;First of all you must decide what cache provider you are going to use. For this example &lt;b&gt;Ehcache&lt;/b&gt; is chosen, but refer to &lt;b&gt;Hibernate&lt;/b&gt; documentation for complete list of all supported providers.&lt;br /&gt;&lt;br /&gt;To configure second level cache, set next &lt;b&gt;Hibernate&lt;/b&gt; properties:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider&lt;/i&gt;&lt;br /&gt;&lt;i&gt;hibernate.cache.use_structured_entries = true&lt;/i&gt;&lt;br /&gt;&lt;i&gt;hibernate.cache.use_second_level_cache = true&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And if you are using &lt;i&gt;annotation&lt;/i&gt; approach, annotate cachable entities with:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;@Cacheable&lt;/i&gt;&lt;br /&gt;&lt;i&gt;@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;See that in this case cache concurrency strategy is &lt;i&gt;NONSTRICT_READ_WRITE&lt;/i&gt;, but depending on cache provider, other strategies can be followed like &lt;i&gt;TRANSACTIONAL&lt;/i&gt;, &lt;i&gt;READ_ONLY&lt;/i&gt;, ... take a look at cache section of &lt;b&gt;Hibernate&lt;/b&gt; documentation to chose the one that fits better with your requirements.&lt;br /&gt;&lt;br /&gt;And finally add &lt;b&gt;Ehcache&lt;/b&gt; dependencies:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;dependency&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;groupId&amp;gt;net.sf.ehcache&amp;lt;/groupId&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;artifactId&amp;gt;ehcache-core&amp;lt;/artifactId&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;version&amp;gt;2.5.0&amp;lt;/version&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;/dependency&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;dependency&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;artifactId&amp;gt;hibernate-ehcache&amp;lt;/artifactId&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&amp;lt;version&amp;gt;3.6.0.Final&amp;lt;/version&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;/dependency&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now second level cache is configured, but not &lt;b&gt;query cache&lt;/b&gt;; anyway we are not far from our goal.&lt;br /&gt;&lt;br /&gt;Set&lt;i&gt; hibernate.cache.use_query_cache&lt;/i&gt; property to &lt;i&gt;true&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;And for each cachable query, we must call &lt;i&gt;setCachable&lt;/i&gt; method during query creation:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;List&amp;lt;Country&amp;gt; list = session.createQuery("from Country where population &amp;gt; 1000").setCacheable(true).list();&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To make example more practical I have uploaded a full &lt;b&gt;query cache&lt;/b&gt; example with &lt;i&gt;Spring Framework&lt;/i&gt;. To see clearly that &lt;b&gt;query cache&lt;/b&gt; works I have used one public database hosted in &lt;a href="http://ensembl.org/"&gt;ensembl.org&lt;/a&gt;. The &lt;i&gt;Ensembl&lt;/i&gt; project produces genome databases for vertebrates and other eukaryotic species, and makes this information freely available online. In this example query to &lt;i&gt;dna&lt;/i&gt; table is cached.&lt;br /&gt;&lt;br /&gt;First of all &lt;b&gt;Hibernate&lt;/b&gt; configuration:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1697445.js?file=HibernateConfiguration.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;It is a simple &lt;b&gt;Hibernate&lt;/b&gt; configuration, using properties previously explained to configure second level cache.&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;i&gt;Entity&lt;/i&gt; class is an entity that represents a sequence of &lt;i&gt;DNA&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1697448.js?file=Dna.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To try &lt;b&gt;query cache&lt;/b&gt;, we are going to implement one test where same query is executed multiple times.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1697451.js?file=gistfile1.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;We can see that we are returning first fifty &lt;i&gt;dna&lt;/i&gt; sequences, and if you execute it, you will see that elapsed time between creation of query and commiting transaction is printed. As you can suppose only first iteration takes about 5 seconds to get all data, but the other ones only milliseconds.&lt;br /&gt;&lt;br /&gt;The foreach line just before query iteration will print object identifier through console. If you look carefully none of these identifiers will be repeated during all execution. This fact just goes to show you that &lt;b&gt;Hibernate&lt;/b&gt; cache does not save objects but properties values, and the object itself is created each time.&lt;br /&gt;&lt;br /&gt;Last note, remember that &lt;b&gt;Hibernate &lt;/b&gt;does not cache associations by default.&lt;br /&gt;&lt;br /&gt;Now after writing a query, think if it will contain static data and if it will be executed often. If it is the case, &lt;b&gt;query cache&lt;/b&gt; is your friend to make &lt;b&gt;Hibernate&lt;/b&gt; applications run faster.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/hibernate-query-cache.zip"&gt;Download Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=fw1VJSU92mw"&gt;http://www.youtube.com/watch?v=fw1VJSU92mw&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3714661550480385448?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3714661550480385448/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3714661550480385448' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3714661550480385448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3714661550480385448'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2012/01/giuro-per-sempre-te-di-viver-morire-per.html' title='Giuro per sempre a te, Di viver, morire per te, Se tu sarai con me lo so, Dea Roma, vincerò!'/><author><name>Alex Soto</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-K5culsfcV6U/AAAAAAAAAAI/AAAAAAAAAEU/FoAl9MfEF-w/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-6557617900700903405</id><published>2012-01-27T11:54:00.001+01:00</published><updated>2012-01-27T11:54:43.839+01:00</updated><title type='text'>Once upon a time and long ago, I heard someone singing, Soft and low (Distant Melody - Peter Pan)</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.thymeleaf.org/artwork/thymeleaflogonameverysmall.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="58" src="http://www.thymeleaf.org/artwork/thymeleaflogonameverysmall.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Thymeleaf Spring-MVC Maven Archetype&lt;/b&gt; aims to create a web application that uses &lt;i&gt;Thymeleaf &lt;/i&gt;template engine&amp;nbsp;and &lt;i&gt;Spring Framework&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The main goal of &lt;i&gt;Thymeleaf &lt;/i&gt;is to provide an elegant and well-formed way of creating &lt;i&gt;HTML 5&lt;/i&gt; templates. Its&amp;nbsp;&lt;i&gt;Standard &lt;/i&gt;and &lt;i&gt;SpringStandard &lt;/i&gt;dialects allow you to create powerful natural templates, that can be correctly&amp;nbsp;displayed by browsers and therefore work also as static prototypes.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You can read more about &lt;i&gt;Thymeleaf &lt;/i&gt;at:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Thymeleaf: &lt;a href="http://www.thymeleaf.org/"&gt;http://www.thymeleaf.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HTML5 + CSS 3 Form Using Thymeleaf + Spring MVC tutorial:&amp;nbsp;&lt;a href="http://www.lordofthejars.com/2011/11/your-big-daddys-got-no-place-to-stay.html"&gt;http://www.lordofthejars.com/2011/11/your-big-daddys-got-no-place-to-stay.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;When you create an application using this &lt;i&gt;archetype&lt;/i&gt;, generated web application will be composed by &lt;u&gt;two html&amp;nbsp;templates&lt;/u&gt;&amp;nbsp;in &lt;i&gt;WEB-INF/views,&lt;/i&gt; one for showing a form using &lt;i&gt;HTML5 &lt;/i&gt;and &lt;i&gt;CSS3 &lt;/i&gt;and another one for listing inserted&amp;nbsp;data.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;Spring&lt;/u&gt; controllers are located in &lt;i&gt;controller &lt;/i&gt;package.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Application is &lt;u&gt;internationalized &lt;/u&gt;too using &lt;i&gt;LocaleChangeInterceptor &lt;/i&gt;with &lt;i&gt;en_US&lt;/i&gt; as default locale. Properties&amp;nbsp;are in &lt;i&gt;src/main/resources/locale&lt;/i&gt; folder.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally &lt;u&gt;server-side validation&lt;/u&gt; is provided by using &lt;i&gt;JSR-303 provider&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Versions of used jars are:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spring Framework: 3.0.5&lt;/li&gt;&lt;li&gt;Thymeleaf: 1.1.2&lt;/li&gt;&lt;li&gt;Hibernate-Validator: 4.1.0&lt;/li&gt;&lt;li&gt;Slf4j: 1.5.10&lt;/li&gt;&lt;li&gt;Servlet-api: 2.5&lt;/li&gt;&lt;li&gt;JUnit: 4.9&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You can install this archetype from source or from jar file:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;From source:&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;mvn clean install&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;mvn archetype:generate -DarchetypeCatalog=local&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;From jar:&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Download &lt;i&gt;archetype &lt;/i&gt;from&amp;nbsp;&lt;a href="https://oss.sonatype.org/content/repositories/releases/com/lordofthejars/thymeleafarchetype/thymeleaf-spring-maven-archetype/1.0.0/thymeleaf-spring-maven-archetype-1.0.0.jar"&gt;https://oss.sonatype.org/content/repositories/releases/com/lordofthejars/thymeleafarchetype/thymeleaf-spring-maven-archetype/1.0.0/thymeleaf-spring-maven-archetype-1.0.0.jar&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;and execute:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;mvn install:install-file \ -DgroupId=com.lordofthejars \ -DartifactId=thymeleaf-spring-maven-archetype \&amp;nbsp;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;-Dversion=DOWNLOADED_VERSION \ -Dpackaging=jar&amp;nbsp;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;-Dfile=PATH_TO_JAR_YOU_DOWNLOADED/thymeleaf-spring-maven-archetype-VERSION.jar&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Maven &lt;/i&gt;repository is located at&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="https://oss.sonatype.org/content/repositories/releases/com/lordofthejars/thymeleafarchetype/thymeleaf-spring-maven-archetype"&gt;https://oss.sonatype.org/content/repositories/releases/com/lordofthejars/thymeleafarchetype/thymeleaf-spring-maven-archetype&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;and source code is stored at &amp;nbsp;&lt;a href="https://github.com/maggandalf/thymeleaf-spring-maven-archetype"&gt;https://github.com/maggandalf/thymeleaf-spring-maven-archetype&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For any question regarding of how to use this &lt;i&gt;archetype &lt;/i&gt;or any &lt;i&gt;issue/improvement&lt;/i&gt;, do not hesitate to contact me or open a new issue on github.&lt;br /&gt;&lt;br /&gt;I wish this &lt;i&gt;archetype &lt;/i&gt;can help you to start a new project using &lt;i&gt;Thymeleaf &lt;/i&gt;template engine.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=7EaGSocm5dc"&gt;http://www.youtube.com/watch?v=7EaGSocm5dc&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-6557617900700903405?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/6557617900700903405/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=6557617900700903405' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6557617900700903405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6557617900700903405'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2012/01/once-upon-time-and-long-ago-i-heard.html' title='Once upon a time and long ago, I heard someone singing, Soft and low (Distant Melody - Peter Pan)'/><author><name>Alex Soto</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-K5culsfcV6U/AAAAAAAAAAI/AAAAAAAAAEU/FoAl9MfEF-w/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-1033610272329234015</id><published>2012-01-23T19:03:00.002+01:00</published><updated>2012-01-23T19:03:35.170+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dzone'/><category scheme='http://www.blogger.com/atom/ns#' term='100k visits'/><category scheme='http://www.blogger.com/atom/ns#' term='lordofthejars.com'/><category scheme='http://www.blogger.com/atom/ns#' term='theserverside'/><category scheme='http://www.blogger.com/atom/ns#' term='javacodegeeks'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='springsource'/><title type='text'>Nevermind, I'll find someone like you, I wish nothing but the best, for you too, Don't forget me, I beg, I remember you said:-, Sometimes it lasts in love but sometimes it hurts instead (Someone Like You - Adele))</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Jok6n-Y0GMI/Tx1rUyPQhKI/AAAAAAAAAFY/u-dCmlY9yDs/s1600/100K.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-Jok6n-Y0GMI/Tx1rUyPQhKI/AAAAAAAAAFY/u-dCmlY9yDs/s200/100K.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="text-align: justify;"&gt;This week I have reached &lt;/span&gt;&lt;b style="text-align: justify;"&gt;100K&lt;/b&gt;&lt;span style="text-align: justify;"&gt; visits on blog. Simply I would like to say thank you very much to all people that have come and found useful information, my intention is writing posts to make developers life easier.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Especially I would like to thank all &lt;i&gt;dzone&lt;/i&gt; folks, &lt;i&gt;theserverside&lt;/i&gt; people, &lt;i&gt;springsource&lt;/i&gt; bloggers, &lt;i&gt;JavaCodeGeeks&lt;/i&gt;, and of course my &lt;i&gt;Twitter&lt;/i&gt; followers all of them have helped to reach this number of visits.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To celebrate this event, now &lt;i&gt;alexsotob&lt;/i&gt; blog is converted to &lt;b&gt;lordofthejars&lt;/b&gt;, so now you can access this blog through &lt;a href="http://alexsotob.blogspot.com/"&gt;alexsotob.blogspot.com&lt;/a&gt; or by &lt;a href="http://www.lordofthejars.com/"&gt;www.lordofthejars.com&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Thank you very much again to read my blog; my next challenge is to reach 250k visits.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See you next time, keep reading,&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Alex.&lt;/div&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=hLQl3WQQoQ0&amp;amp;ob=av3e"&gt;http://www.youtube.com/watch?v=hLQl3WQQoQ0&amp;amp;ob=av3e&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-1033610272329234015?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/1033610272329234015/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=1033610272329234015' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1033610272329234015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1033610272329234015'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2012/01/nevermind-ill-find-someone-like-you-i.html' title='Nevermind, I&apos;ll find someone like you, I wish nothing but the best, for you too, Don&apos;t forget me, I beg, I remember you said:-, Sometimes it lasts in love but sometimes it hurts instead (Someone Like You - Adele))'/><author><name>Alex Soto</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-K5culsfcV6U/AAAAAAAAAAI/AAAAAAAAAEU/FoAl9MfEF-w/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Jok6n-Y0GMI/Tx1rUyPQhKI/AAAAAAAAAFY/u-dCmlY9yDs/s72-c/100K.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-3892067911528313547</id><published>2012-01-02T20:44:00.000+01:00</published><updated>2012-01-17T08:09:17.602+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='restclient'/><category scheme='http://www.blogger.com/atom/ns#' term='spring MVC res'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='Backbone'/><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='restful web services'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript templates'/><title type='text'>Sábado na balada, A galera começou a dançar, E passou a menina mais linda, Tomei coragem e comecei a falar (Ai se eu te pego - Michel Teló)</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.annatomczak.com/images/figurestudies-img/DevilsBackboneII.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://www.annatomczak.com/images/figurestudies-img/DevilsBackboneII.jpg" width="156" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Backbone&lt;/b&gt; is a &lt;i&gt;Javascript&lt;/i&gt; library that provides a clean way to:&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;define models in &lt;i&gt;Javascript&lt;/i&gt;.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;deal with &lt;i&gt;Collections&lt;/i&gt; using a rich &lt;i&gt;API&lt;/i&gt;.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;define &lt;i&gt;Views&lt;/i&gt; with declarative event handling and template support.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;interface to&amp;nbsp;&lt;i&gt;Rest&lt;/i&gt; architectures.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In current post I am going to use the &lt;i&gt;Rest WebApp&lt;/i&gt; of my old &lt;a href="http://alexsotob.blogspot.com/2011/10/cant-you-see-it-all-makes-perfect-sense.html"&gt;post&lt;/a&gt;, where I only explained the &lt;i&gt;server side&amp;nbsp;&lt;/i&gt;to show you how to implement client side using&amp;nbsp;&lt;b&gt;Backbone.&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;So the first thing to do is create a web structure into &lt;i&gt;IDE&lt;/i&gt;, for this example I will reuse same project of &lt;i&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/restserver.zip"&gt;RestServer&lt;/a&gt; &lt;/i&gt;post.&lt;br /&gt;&lt;br /&gt;Then download&lt;b&gt; backbone.js&lt;/b&gt; and its dependencies and copy to&lt;i&gt;&amp;nbsp;webapp/resources/js&lt;/i&gt; directory:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.json.org/json2.js"&gt;json2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.jquery.com/jquery-1.5.js"&gt;jquery 1.5&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/documentcloud/underscore/blob/1.2.3/underscore.js"&gt;underscore 1.2.3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentcloud.github.com/backbone/backbone.js"&gt;backbone 0.5.3&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="text-align: justify;"&gt;Open &lt;/span&gt;&lt;i style="text-align: justify;"&gt;servlet-context.xml&lt;/i&gt;&lt;span style="text-align: justify;"&gt; and add &lt;/span&gt;&lt;i style="text-align: justify;"&gt;root&lt;/i&gt;&lt;span style="text-align: justify;"&gt; and&amp;nbsp;&lt;/span&gt;&lt;i style="text-align: justify;"&gt; js&lt;/i&gt;&lt;span style="text-align: justify;"&gt; folder as static resource.&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1579174.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Then go to &lt;i&gt;webapp/resources&lt;/i&gt; and create &lt;i&gt;index.html&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1579216.js?file=index.html"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Add all &lt;i&gt;Javascript&lt;/i&gt; libraries into page, but most important, add them in the same order as appears here, if not, some &lt;i&gt;Javascript&lt;/i&gt; failures would appear in your browser and the application will not work.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note that some content is created directly using &lt;i&gt;HTML&lt;/i&gt; tags rather than using &lt;b&gt;Backbone&lt;/b&gt; views. Normally page layout, headers, footers ... are treated as static content and they are directly written into page.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's start modeling our data, in this case a &lt;i&gt;character&lt;/i&gt; with its attributes (id, name, url, isHuman...).&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1579231.js?file=model.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;i&gt;Models&lt;/i&gt; in &lt;b&gt;Backbone&lt;/b&gt; has a particularity that make them useful, they are an implementation of &lt;i&gt;Active Record&lt;/i&gt; pattern, so when you are creating a model you will have &lt;i&gt;CRUD&lt;/i&gt; operations against a &lt;i&gt;Rest-WebService&lt;/i&gt;. So for example when you call &lt;i&gt;save &lt;/i&gt;method of your model, &lt;b&gt;Backbone&lt;/b&gt; converts that model to &lt;i&gt;JSON&lt;/i&gt; and sends the result to server as &lt;i&gt;HTTP POST&lt;/i&gt; (if model has no id), or &lt;i&gt;HTTP PUT &lt;/i&gt;(update). Other available operations are fetch (load) and destroy (delete).&lt;br /&gt;&lt;br /&gt;See how in this case we have created a &lt;i&gt;Character&lt;/i&gt; model setting &lt;i&gt;urlRoot&lt;/i&gt; property. This property is used to build endpoint to &lt;i&gt;ResetServer.&amp;nbsp;&amp;nbsp;&lt;/i&gt;As long as the endpoint returns &lt;i&gt;JSON &lt;/i&gt;for a single character, properties will be merged into model.&lt;br /&gt;&lt;br /&gt;And the same applies to &lt;i&gt;Collections&lt;/i&gt;. When you call&amp;nbsp;&lt;i&gt;fetch&lt;/i&gt; method of &lt;i&gt;characters &lt;/i&gt;var, all characters returned by calling &lt;i&gt;GET .../characters&lt;/i&gt; will be stored into.&lt;br /&gt;&lt;br /&gt;See how easy is implementing a &lt;i&gt;Rest Client&lt;/i&gt; using &lt;b&gt;Backbone&lt;/b&gt;. And I suppose you are wondering where are attributes' definition? Don't worry, with &lt;b&gt;Backbone&lt;/b&gt; is not necessary to explicitly define at definition time.&lt;br /&gt;&lt;br /&gt;Now it is time for &lt;i&gt;Views&lt;/i&gt;. As I cited at the begin of post, &lt;b&gt;Backbone&lt;/b&gt; has template support. For this example two templates are going to be used, one for filling a new &lt;i&gt;character &lt;/i&gt;and another for showing&amp;nbsp;&lt;i&gt;character&lt;/i&gt; information.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1579384.js?file=template.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;To define a template you must use &amp;lt;script&amp;gt; tag with&amp;nbsp;&lt;i&gt;text/template&lt;/i&gt;&amp;nbsp;type instead of &lt;i&gt;text/javascript &lt;/i&gt;and an &lt;i&gt;id&lt;/i&gt;. The structure is similar to &lt;i&gt;JSP (&lt;/i&gt;embedded&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;i&gt;HTML&lt;/i&gt; code,&amp;nbsp;&lt;i&gt;&amp;lt;%= %&amp;gt; &lt;/i&gt;for printing variables and &lt;i&gt;&amp;lt;% %&amp;gt;&lt;/i&gt; for logical structures&lt;i&gt;).&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;Next step is creating &lt;i&gt;Views&lt;/i&gt;.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;For this example we are going to create three views, one for each template, and one that will be a composition of both.&lt;br /&gt;&lt;br /&gt;Let's start with &lt;i&gt;View&lt;/i&gt; responsible of showing information of one &lt;i&gt;character&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1601866.js?file=character-view.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;At line 3 we are loading template content defined previously with &lt;i&gt;id&lt;/i&gt; &lt;i&gt;show-characters&lt;/i&gt;, into &lt;i&gt;showCharactersTemplate&lt;/i&gt; object.&lt;br /&gt;&lt;br /&gt;Next important line is number 6. There we are defining a function that will be invoked each time we want to render a view (one time per character). See how we are passing a &lt;i&gt;model&lt;/i&gt; object (trust me it is not defined yet, but will be there), to template. To fill template variables, template engine requires data in &lt;i&gt;JSON&lt;/i&gt; format, and &lt;b&gt;Backbone&lt;/b&gt; model has a &lt;i&gt;toJSON &lt;/i&gt;method. &amp;nbsp;And finally generated &lt;i&gt;html&lt;/i&gt; code is saved into &lt;i&gt;el&lt;/i&gt; attribute.&lt;br /&gt;&lt;br /&gt;Next &lt;i&gt;View&lt;/i&gt; is responsible of showing &lt;i&gt;character&lt;/i&gt;&amp;nbsp;form, and deal with submit action.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1602080.js?file=new-character.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This &lt;i&gt;View&lt;/i&gt;&amp;nbsp;shows events handling in&amp;nbsp;&lt;b&gt;Backbone&lt;/b&gt;. See line 9. We are defining that when user clicks on tag element "&lt;i&gt;a"&lt;/i&gt; with class &lt;i&gt;submit, &lt;/i&gt;element defined in&lt;i&gt; new-character template&lt;/i&gt;, &lt;i&gt;createOnEnter&lt;/i&gt; function is executed.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;createOnEnter&lt;/i&gt; method does three things:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;gets values from template form.&lt;/li&gt;&lt;li&gt;instantiates&amp;nbsp;&lt;i&gt;CharacterModel&lt;/i&gt; class. See that this is the place where model attributes are defined.&lt;/li&gt;&lt;li&gt;calls &lt;i&gt;save&lt;/i&gt; method. This method sends object data to defined&amp;nbsp;endpoint at server side. Because this operation is asynchronous, a callback is registered, so when&amp;nbsp;a success is received, &lt;i&gt;character&lt;/i&gt; is added into &lt;i&gt;characters&lt;/i&gt; list.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;And last &lt;i&gt;View&lt;/i&gt; is a composite view of two previous views, acts as a controller between adding a new &lt;i&gt;character&lt;/i&gt; and showing all inserted &lt;i&gt;characters&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1615392.js?file=appView.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Initialize function does all required&amp;nbsp;initializations&amp;nbsp;so &lt;i&gt;UI&lt;/i&gt; could be refreshed&amp;nbsp;asynchronously. In first two lines we are binding &lt;i&gt;add&lt;/i&gt; and &lt;i&gt;reset&lt;/i&gt; functions of &lt;i&gt;characters&lt;/i&gt; collection to a method. For example each time &lt;i&gt;add&lt;/i&gt; function is called, &lt;i&gt;addCharacter&lt;/i&gt;&amp;nbsp;is invoked.&lt;br /&gt;&lt;br /&gt;Next line is used to populate data to &lt;i&gt;Collection&lt;/i&gt;. When &lt;i&gt;fetch&lt;/i&gt; is called an &lt;i&gt;HTTP GET&lt;/i&gt; to defined endpoint is sent, data is retrieved and &lt;i&gt;Collection's&lt;/i&gt; &lt;i&gt;add&lt;/i&gt; method is called for each result.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;addCharacter&lt;/i&gt; function is responsible of creating one &lt;i&gt;View&lt;/i&gt; for each character. There is not much secret, we are creating a &lt;i&gt;CharacterView&lt;/i&gt;, and appending the result of calling its render method to &lt;i&gt;html&lt;/i&gt; element with&lt;i&gt; character-list&lt;/i&gt; id.&lt;br /&gt;&lt;br /&gt;And finally &lt;i&gt;render&lt;/i&gt; function that is responsible of rendering &lt;i&gt;CharacterFormView&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;See that page is only loaded first time we access it, subsequent updates are done by &lt;i&gt;DOM&lt;/i&gt; manipulations.&lt;br /&gt;&lt;br /&gt;To finish I&amp;nbsp;embedded all &lt;i&gt;html&lt;/i&gt; file explained here so you can see a global overview of all pieces used. Also feel free to download all &lt;i&gt;Eclipse&lt;/i&gt; project.&amp;nbsp;I wish you find this post useful.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1615507.js?file=index.html"&gt;&lt;/script&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/backbone.zip"&gt;Download Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=q1Ebi9cSn48"&gt;http://www.youtube.com/watch?v=q1Ebi9cSn48&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3892067911528313547?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3892067911528313547/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3892067911528313547' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3892067911528313547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3892067911528313547'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2012/01/sabado-na-balada-galera-comecou-dancar.html' title='Sábado na balada, A galera começou a dançar, E passou a menina mais linda, Tomei coragem e comecei a falar (Ai se eu te pego - Michel Teló)'/><author><name>Alex Soto</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-K5culsfcV6U/AAAAAAAAAAI/AAAAAAAAAEU/FoAl9MfEF-w/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-8985282763871812298</id><published>2011-12-14T21:07:00.002+01:00</published><updated>2011-12-14T21:29:42.350+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='minification javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='devoxx'/><category scheme='http://www.blogger.com/atom/ns#' term='minification'/><category scheme='http://www.blogger.com/atom/ns#' term='jawr'/><category scheme='http://www.blogger.com/atom/ns#' term='aggregation'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='css minification'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Elle ne me quitte pas d'un pas, fidèle comme une ombre. Elle m'a suivi ça et là, aux quatres coins du monde.  Non, je ne suis jamais seul avec ma solitude (Ma Solitude - Georges Moustaki)</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.devoxx.com/download/attachments/5013581/LogoDevoxx150dpi.jpg?version=1&amp;amp;modificationDate=1305564520000" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="118" src="http://www.devoxx.com/download/attachments/5013581/LogoDevoxx150dpi.jpg?version=1&amp;amp;modificationDate=1305564520000" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In current post I have uploaded my &lt;b&gt;Devoxx&lt;/b&gt; presentation. This year I was at &lt;a href="http://www.devoxx.com/"&gt;Devoxx&lt;/a&gt;&amp;nbsp;as speaker. My presentation was about how to speed up &lt;b&gt;HTML 5&lt;/b&gt; applications, and &lt;b&gt;Javascript&lt;/b&gt; and &lt;b&gt;CSS&lt;/b&gt; in general, using &lt;b&gt;Aggregation&lt;/b&gt; and &lt;b&gt;Minification&lt;/b&gt;.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div id="__ss_10594353" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/asotobu/speeding-up-js-and-css-download-times-with-aggregation-and-minification-10594353" title="Speeding Up JS and CSS Download Times with Aggregation and Minification"&gt;Speeding Up JS and CSS Download Times with Aggregation and Minification&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse10594353" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dv11q17041-111214141519-phpapp01&amp;stripped_title=speeding-up-js-and-css-download-times-with-aggregation-and-minification-10594353&amp;userName=asotobu" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="wmode" value="transparent"/&gt;&lt;embed name="__sse10594353" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dv11q17041-111214141519-phpapp01&amp;stripped_title=speeding-up-js-and-css-download-times-with-aggregation-and-minification-10594353&amp;userName=asotobu" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/asotobu"&gt;Alex Soto&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Also you can visit two entries of my blog where I talk about same theme.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://alexsotob.blogspot.com/2011/06/y-hay-un-decano-tambien-y-un-abogado.html"&gt;YUI compressor Maven plugin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://alexsotob.blogspot.com/2011/06/i-hitched-ride-with-chris-mccandless-i.html"&gt;Jawr&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;u&gt;Links of technologies I talked about:&lt;/u&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Jawr:&amp;nbsp;&lt;a href="http://jawr.java.net/"&gt;http://jawr.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Wro4j:&amp;nbsp;&lt;a href="http://code.google.com/p/wro4j/"&gt;http://code.google.com/p/wro4j/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Finally I want to say thank you to all people who came to watch me, and of course &lt;b&gt;Devoxx&lt;/b&gt; folks, for&amp;nbsp;organising&amp;nbsp;such amazing event.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I wish you have discovered a great way to speed up your web applications.&lt;/div&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=qSZKO5K2eTE"&gt;http://www.youtube.com/watch?v=qSZKO5K2eTE&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-8985282763871812298?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/8985282763871812298/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=8985282763871812298' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8985282763871812298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8985282763871812298'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/12/elle-ne-me-quitte-pas-dun-pas-fidele.html' title='Elle ne me quitte pas d&apos;un pas, fidèle comme une ombre. Elle m&apos;a suivi ça et là, aux quatres coins du monde.  Non, je ne suis jamais seul avec ma solitude (Ma Solitude - Georges Moustaki)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5129077486981261569</id><published>2011-12-09T20:47:00.001+01:00</published><updated>2012-01-02T20:13:26.109+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database migration'/><category scheme='http://www.blogger.com/atom/ns#' term='flyway-maven-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='continuous integration'/><category scheme='http://www.blogger.com/atom/ns#' term='flyway'/><title type='text'>Far away, long ago, glowing dim as an Ember, Things my heart use to know, things it yearns to remember (Once upon a December - Anastasia)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://wiki.flyway.googlecode.com/hg/img/flyway-logo-small.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://wiki.flyway.googlecode.com/hg/img/flyway-logo-small.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;You never develop code without version control, why do you develop your database without it? &lt;b&gt;Flyway&lt;/b&gt; &amp;nbsp;is database-independent library for tracking, managing and applying database changes.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Personally I find that using a database migration tool like &lt;a href="http://code.google.com/p/flyway/"&gt;Flyway&lt;/a&gt; is "a must", because covers two scenarios of our software&amp;nbsp;life-cycle:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;Multiple developers developing an application with continuous integration.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Multiple clients each one with different versions of production code.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;Let's start with &lt;u&gt;first point&lt;/u&gt;. If your project is big enough there will be more than one developer working on it, each one developing a new feature. Each feature may require a database update (adding a new table, a new constraint, ...), so developer creates a&lt;i&gt; .sql&lt;/i&gt; file with all required changes.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;After each developer finishes its work, these changes are merged into main branch and &lt;i&gt;integration/acceptance&lt;/i&gt; tests are executed on test machine. And the problem is obvious which process updates testing database? And how?&amp;nbsp;&lt;i&gt;QA&lt;/i&gt; department executes &lt;i&gt;sql&lt;/i&gt; files manually? Or we develop a program that executes these updates automatically? And in what order must be executed? Also same problem arises in production environment.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;Second point&lt;/u&gt; is only applicable if your application is distributed across multiple clients. And at this point the problem is further accentuated because each client may have different software versions. Hence when an update is required by our client (for example because a bug), you should know which database version was installed and what changes must be applied to get expected database.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Don't worry &lt;b&gt;Flyway&lt;/b&gt; comes to rescue you, and will help to fix all previous questions. Let me start explaining some features of &lt;b&gt;Flyway&lt;/b&gt; that in my opinion make it a good tool.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Automatic migration: &lt;b&gt;Flyway&lt;/b&gt; will update from any version to the latest version of schema. &lt;b&gt;Flyway&lt;/b&gt; can be executed as&lt;i&gt; Command-line &lt;/i&gt;(can be used with non &lt;i&gt;JVM&lt;/i&gt; environments), &lt;i&gt;Ant&lt;/i&gt; script, &lt;i&gt;Maven&lt;/i&gt; script (to update integration/acceptance test environments) or within application (when application is starting up).&lt;/li&gt;&lt;li&gt;Convention over configuration: &lt;b&gt;Flyway&lt;/b&gt; comes with default configuration so no configuration is required to start using.&lt;/li&gt;&lt;li&gt;Plain &lt;i&gt;SQL&lt;/i&gt; scripts or &lt;i&gt;Java&lt;/i&gt; classes: To execute updates, you can use plain &lt;i&gt;SQL&lt;/i&gt; files or &lt;i&gt;Java&lt;/i&gt; classes for advanced migrations.&lt;/li&gt;&lt;li&gt;Highly reliable: safe for cluster environments.&lt;/li&gt;&lt;li&gt;Schema clean: &lt;b&gt;Flyway&lt;/b&gt; can clean existing schema, so empty installation is produced.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Conventions to be followed if they are not explicitly modified are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Plain &lt;i&gt;SQL&lt;/i&gt; files go to &lt;i&gt;db/migration&lt;/i&gt; directory inside&lt;i&gt; src/main/resources &lt;/i&gt;structure.&lt;/li&gt;&lt;li&gt;Java classes go to &lt;i&gt;db.migration&lt;/i&gt; package.&lt;/li&gt;&lt;li&gt;Files (&lt;i&gt;SQL&lt;/i&gt; and &lt;i&gt;Java&lt;/i&gt;) must follow next name convention: &lt;i&gt;V&amp;lt;version&amp;gt;[__description]. &lt;/i&gt;Where each&amp;nbsp;&lt;i&gt;version&lt;/i&gt;&amp;nbsp;number is separated by dots (.) or underscore (_) and if &lt;i&gt;description &lt;/i&gt;is provided, two underscores must proceed. A valid example is &lt;i&gt;V_1_1_0__Update.sql&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So let's see &lt;b&gt;Flyway&lt;/b&gt; in action. In this application I am going to focus only on how to use &lt;b&gt;Flyway&lt;/b&gt;, I am not going to create any &lt;i&gt;DAO&lt;/i&gt;, &lt;i&gt;DTO&lt;/i&gt; or &lt;i&gt;Controller&lt;/i&gt; class, only database migration part.&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Imagine we are going to develop a small application using &lt;i&gt;Spring Framework&lt;/i&gt; that will allow us registering authors and which books they have written.&lt;br /&gt;&lt;br /&gt;First version will contain two tables, &lt;i&gt;Author&lt;/i&gt; and &lt;i&gt;Book&lt;/i&gt;&amp;nbsp;related with one to many relationship.&lt;br /&gt;&lt;br /&gt;First step is registering &lt;b&gt;Flyway&lt;/b&gt; into &lt;i&gt;Spring Application Context&lt;/i&gt;. &lt;b&gt;Flyway&lt;/b&gt; class is the main class and requires a &lt;i&gt;javax.sql.DataSource &lt;/i&gt;instance. &lt;i&gt;migrate&lt;/i&gt; method is responsible to start migration&amp;nbsp;process.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1516961.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;See that there is no secret. Only be careful because if your project uses &lt;i&gt;JPA&lt;/i&gt;&amp;nbsp;or&amp;nbsp;&lt;i&gt;ORM&lt;/i&gt;&amp;nbsp;frameworks for persistence, you should configure them to avoid auto creation of tables, because now &lt;b&gt;Flyway&lt;/b&gt; is responsible of managing database structure. And because of that, creation of &lt;i&gt;SessionFactory&lt;/i&gt; (in case of &lt;i&gt;Hibernate&lt;/i&gt;) or &lt;i&gt;EntityManagerFactoryBean&lt;/i&gt;( in case of &lt;i&gt;JPA&lt;/i&gt;), &amp;nbsp;should depends on &lt;b&gt;Flyway&lt;/b&gt; bean.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1516968.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Flyway&lt;/b&gt; is configured. Each time you start application, it&lt;b&gt;&amp;nbsp;&lt;/b&gt;will review if configured &lt;i&gt;datasource&lt;/i&gt; requires an update or not.&lt;br /&gt;&lt;br /&gt;And now let's write first version of&amp;nbsp;&lt;i&gt;SQL&lt;/i&gt;&amp;nbsp;migration. Create &lt;i&gt;db/migration&lt;/i&gt; directory into &lt;i&gt;src/main/resources&lt;/i&gt; and create a file called &lt;i&gt;V1__Initial_version.sql &lt;/i&gt;with next content:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1516990.js?file=V1__Initial_version.sql"&gt;&lt;/script&gt;&lt;br /&gt;This script creates &lt;i&gt;Author&lt;/i&gt; and &lt;i&gt;Book&lt;/i&gt; tables with their&amp;nbsp;respective&amp;nbsp;attributes.&lt;br /&gt;&lt;br /&gt;And if you run next &lt;i&gt;JUnit&lt;/i&gt;&amp;nbsp;both tables are created into database.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1516991.js?file=WhenFirstVersionSystemIsBootstraped.java"&gt;&lt;/script&gt;&lt;br /&gt;Take a look at your console and next log message has appeared:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;10:33:49,512 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 119 - Current schema version: null&lt;/i&gt;&lt;br /&gt;&lt;i&gt;10:33:49,516 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 206 - Migrating to version 1&lt;/i&gt;&lt;br /&gt;&lt;i&gt;10:33:49,577 INFO glecode.flyway.core.migration.DbMigrator: 188 - Successfully applied 1 migration (execution time 00:00.085s).&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;And if you open your database:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1516999.js?file=testdb.sql"&gt;&lt;/script&gt;&lt;br /&gt;Note that &lt;b&gt;Flyway&lt;/b&gt; has created a table to annotate all updates that have been executed (&lt;i&gt;SCHEMA_VERSION&lt;/i&gt;) and last insert is a "&lt;b&gt;Flyway&lt;/b&gt; insert" marking which is the current version.&lt;br /&gt;&lt;br /&gt;Then your first version of application is distributed&amp;nbsp;across&amp;nbsp;the world.&lt;br /&gt;&lt;br /&gt;And you can start to develop version 1.1.0 of application. For next release,&amp;nbsp;&lt;i&gt;Address&lt;/i&gt; table must be added with a relationship to &lt;i&gt;Author.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;As done before, create a new &lt;i&gt;SQL &lt;/i&gt;file &lt;i&gt;V1_1_0__AddressTable.sql&lt;/i&gt; into &lt;i&gt;db/migration&lt;/i&gt; folder.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1517072.js?file=V1_1_0__AddressTable.sql"&gt;&lt;/script&gt;&lt;br /&gt;And run next unit test:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1517075.js?file=WhenFirstUpgradeIsBootstraped.java"&gt;&lt;/script&gt;&lt;br /&gt;your database will be upgraded to version 1.1.0. Also take a look at log messages and database:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;11:27:30,149 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 119 - Current schema version: 1&lt;/i&gt;&lt;br /&gt;&lt;i&gt;11:27:30,152 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 206 - Migrating to version 1.1.0&lt;/i&gt;&lt;br /&gt;&lt;i&gt;11:27:30,191 INFO glecode.flyway.core.migration.DbMigrator: 188 - Successfully applied 1 migration (execution time 00:00.053s).&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1517082.js?file=testdb.sql"&gt;&lt;/script&gt;&lt;br /&gt;New table is created, and a new entry into &lt;i&gt;SCHEMA_VERSION&lt;/i&gt; table is inserted marking that current database version is 1.1.0.&lt;br /&gt;&lt;br /&gt;When your 1.1.0 application is&amp;nbsp;distributed to your clients, &lt;b&gt;Flyway&lt;/b&gt; will be the responsible of updating their databases without&amp;nbsp;losing&amp;nbsp;data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Previously I have mentioned that &lt;b&gt;Flyway&lt;/b&gt; also supports &lt;i&gt;Java&lt;/i&gt; classes for advanced migrations. Let's see how.&lt;br /&gt;&lt;br /&gt;Imagine that in your next release, authors can upload their personal photo, and you decide to store as &amp;nbsp;blob attribute into &lt;i&gt;Author&lt;/i&gt; table. The problem resides on already created authors because you should set some data into this attribute. Your marketing department decides that authors inserted prior to this version will contain a photo of &lt;i&gt;Spock&lt;/i&gt;,&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lIuhcqwOaGk/TvWuC3sdZGI/AAAAAAAAAFE/GdCYZuQcFWY/s1600/Spock.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-lIuhcqwOaGk/TvWuC3sdZGI/AAAAAAAAAFE/GdCYZuQcFWY/s200/Spock.jpg" width="163" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;So now you must alter&amp;nbsp;&lt;i&gt;Author&lt;/i&gt; table and moreover update a field with a photo. You can see clearly that for this update you will need something more than a simple &lt;i&gt;SQL&lt;/i&gt; file, because you will need to add a new property and updating &lt;i&gt;them&amp;nbsp;&lt;/i&gt;with chunk of bytes. This problem could be accomplished using only one &lt;i&gt;Java&lt;/i&gt; class but for showing a particularity of &lt;b&gt;Flyway&lt;/b&gt;, problem will be treated with one &lt;i&gt;SQL&lt;/i&gt; and one &lt;i&gt;Java &lt;/i&gt;object.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;First of all new &lt;i&gt;SQL&lt;/i&gt; script adding a new binary field is created. This new feature will be implemented on &lt;i&gt;version 2.0.0&lt;/i&gt;, so script file is named &lt;i&gt;V2_0_0__AddAvatar.sql&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1519598.js?file=V2__AddAvatar.sql"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Next step is developing a &lt;i&gt;Java Migration&lt;/i&gt; class. Create a new package &lt;i&gt;db.migration&lt;/i&gt; on &lt;i&gt;src/main/java. &lt;/i&gt;Notice that this class cannot be named &lt;i&gt;V2_0_0_AddAvatar.java&lt;/i&gt; because &lt;b&gt;Flyway&lt;/b&gt; will try to execute two different migrations with same version, and obviously &lt;b&gt;Flyway&lt;/b&gt;&amp;nbsp;will detect a conflict.&lt;br /&gt;&lt;br /&gt;To avoid this conflict you can follow many different strategies, but in this case we are going to add a letter as version suffix, so class will be named &lt;i&gt;V2_0_0_A__AddAvatar.java&lt;/i&gt; instead of &lt;i&gt;V2_0_0__AddAvatar.java&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1535357.js?file=V2_0_0_A__AddDefaultAvatar.java"&gt;&lt;/script&gt;&lt;br /&gt;Before run previous unit test, open &lt;i&gt;testdb.script&lt;/i&gt; file and add next line just under&amp;nbsp;&lt;i&gt;SET SCHEMA PUBLIC&lt;/i&gt; command.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;INSERT INTO AUTHOR(ID, FIRSTNAME, LASTNAME, BIRTHDATE) VALUES(1, 'Alex', 'Soto', null);&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And running unit test, next lines are logged:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1534955.js?file=WhenAvatarFielsIsAdded.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;i&gt;20:21&lt;/i&gt;&lt;i&gt;:18,032 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 119 - Current schema version: 1.1.0&lt;/i&gt;&lt;br /&gt;&lt;i&gt;20:21:18,035 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 206 - Migrating to version 2.0.0&lt;/i&gt;&lt;br /&gt;&lt;i&gt;20:21:18,088 &amp;nbsp;INFO glecode.flyway.core.migration.DbMigrator: 206 - Migrating to version 2.0.0.A&lt;/i&gt;&lt;br /&gt;&lt;i&gt;20:21:18,114 INFO glecode.flyway.core.migration.DbMigrator: 190 - Successfully applied 2 migrations (execution time 00:00.094s).&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And if you open updated database, next lines are added:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1534300.js?file=testdb.sql"&gt;&lt;/script&gt;&lt;br /&gt;See how all previous authors have &lt;i&gt;avatar &lt;/i&gt;column with data.&lt;br /&gt;&lt;br /&gt;Note that now you have not to worry about database migrations, your application is packaged and delivered to all your clients regardless of the version they had installed;&amp;nbsp;&lt;b&gt;Flyway&lt;/b&gt; will execute only required migration files depending on installed version.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you are not using &lt;i&gt;Spring,&amp;nbsp;&lt;/i&gt;you can update your database using &lt;b&gt;Flyway-Maven-Plugin. &lt;/b&gt;Next piece of &lt;i&gt;pom&lt;/i&gt;&amp;nbsp;shows you how to execute migration&amp;nbsp;during &lt;i&gt;test-compile&lt;/i&gt; phase. By default plugin is executed during &lt;i&gt;pre-integration-test &lt;/i&gt;phase.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1535386.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Thanks of &lt;i&gt;Maven &lt;/i&gt;plugin, we can configure our continuous integration system so all environments (test, production,...) would be updated during deployment of application.&lt;br /&gt;&lt;br /&gt;I wish &lt;b&gt;Flyway&lt;/b&gt; will help you make better life as developer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/flyway.zip"&gt;Download Code&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=oyUBdLm3s9U"&gt;http://www.youtube.com/watch?v=oyUBdLm3s9U&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5129077486981261569?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5129077486981261569/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5129077486981261569' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5129077486981261569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5129077486981261569'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/12/far-away-long-ago-glowing-dim-as-ember.html' title='Far away, long ago, glowing dim as an Ember, Things my heart use to know, things it yearns to remember (Once upon a December - Anastasia)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-lIuhcqwOaGk/TvWuC3sdZGI/AAAAAAAAAFE/GdCYZuQcFWY/s72-c/Spock.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5568831298346831681</id><published>2011-12-01T19:55:00.001+01:00</published><updated>2011-12-07T11:05:01.870+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='maven archetype'/><category scheme='http://www.blogger.com/atom/ns#' term='archetype from existing project'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='standardized working environment'/><title type='text'>All my scientists are working on a deadline, So my psychologist is working day and nighttime, They say they know what's best for me, But they don't know what they're doing (Atomic Garden - Bad Religion)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.unlimitedgamer.net/coverage/loz/images/Legend_tent_scnreenshots_013.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://www.unlimitedgamer.net/coverage/loz/images/Legend_tent_scnreenshots_013.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Maven&lt;/b&gt; &lt;i&gt;archetypes&lt;/i&gt; are project templates that allow users create project structure with a simple &lt;b&gt;Maven&lt;/b&gt; command. In my company we are using &lt;i&gt;archetypes&lt;/i&gt; because provide a way to standardize projects structure. All our projects are built using the same directory structure, all of us use the same version of common libraries like &lt;i&gt;JUnit&lt;/i&gt;, &lt;i&gt;Hamcrest&lt;/i&gt;,&lt;i&gt; Spring Framework&lt;/i&gt;, &lt;i&gt;Mockito&lt;/i&gt;, or in case of web applications bundling them with company's approved &lt;i&gt;CSS&lt;/i&gt; and &lt;i&gt;Javascript&lt;/i&gt; libraries. Also &lt;i&gt;PMD&lt;/i&gt;, &lt;i&gt;checkstyle&lt;/i&gt; or &lt;i&gt;findbugs&lt;/i&gt; coding rules can be stored in distributed &lt;i&gt;archetype&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If each time you start a new project you are of those who copy files from existing projects to the new one, apply &lt;i&gt;DRY&lt;/i&gt; principle and create a &lt;b&gt;Maven&lt;/b&gt; &lt;i&gt;archetype&lt;/i&gt; from existing project.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First thing to do is create your template project with all files to be bundled into &lt;i&gt;archetype&lt;/i&gt;. In this example, simple&lt;i&gt; Spring MVC&lt;/i&gt; project will be transformed &amp;nbsp;to be a &lt;b&gt;Maven&lt;/b&gt; &lt;i&gt;archetype.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;After template project is created and all desired files are added, you should have a directory layout like:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1427808.js?file=directorystructure"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;My personal advice is that if you are thinking about distributing this &lt;i&gt;archetype&lt;/i&gt; with community (not only for your company), remove all &lt;i&gt;IDE&lt;/i&gt; specific files.&lt;br /&gt;&lt;br /&gt;Now you have your project created and ready to be packaged as &lt;i&gt;archetype&lt;/i&gt;. Execute next command on root of your project.&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;mvn archetype:create-from-project&lt;/i&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;And &lt;b&gt;Maven&lt;/b&gt;&amp;nbsp;console output should be:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1430927.js?file=archetype:create-from-project"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now your &lt;i&gt;archetype&lt;/i&gt; is created in&lt;i&gt; target/generated-sources/archetype&lt;/i&gt; directory with next&amp;nbsp;hierarchy:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1430945.js?file=archetype-layout"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Now project is inside &lt;i&gt;archetype-resources&lt;/i&gt; directory. This directory contains all files that will be added in generated project.&lt;br /&gt;&lt;br /&gt;At first sight, not much differences between original project and "template" project, it seems that only three files has been added&lt;i&gt; archetype-metadata.xml&lt;/i&gt;, &lt;i&gt;archetype.properties&lt;/i&gt; and &lt;i&gt;goal.txt, &lt;/i&gt;but shortly you will see that original project content has been modified too.&lt;br /&gt;&lt;br /&gt;Before continuing see that in project exists two &lt;i&gt;poms&lt;/i&gt;, one &lt;i&gt;pom&lt;/i&gt; that is in root directory, that will be called &lt;i&gt;archetype pom&lt;/i&gt;, because it contains all &lt;i&gt;archetype &lt;/i&gt;configuration, and another one into &lt;i&gt;archetype-resources,&lt;/i&gt;&amp;nbsp;called &lt;i&gt;template&lt;/i&gt; &lt;i&gt;pom&lt;/i&gt;, because it will be the &lt;i&gt;pom&lt;/i&gt; used in generated project.&lt;br /&gt;&lt;br /&gt;Next step is isolate &lt;i&gt;archetype&lt;/i&gt; project into separate folder, so can be dealt as alone project.&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;mv target/generated-sources/archetype ../spring-mvc-archetype&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;Following step is adding a name to generated &lt;i&gt;archetype&lt;/i&gt;, so open &lt;i&gt;archetype&lt;/i&gt; &lt;i&gt;pom &lt;/i&gt;and change &amp;nbsp;&lt;i&gt;&amp;lt;name&amp;gt;&lt;/i&gt; tag value to your &lt;i&gt;archetype&lt;/i&gt; name, for example &lt;i&gt;spring-mvc-archetype, &lt;/i&gt;and if you want &amp;nbsp;&lt;i&gt;artifactId&lt;/i&gt; and &lt;i&gt;groupId&lt;/i&gt; too.&lt;br /&gt;&lt;br /&gt;After this modification, open archetype-resources' &lt;i&gt;pom, &lt;/i&gt;and see&amp;nbsp;how &lt;i&gt;&amp;lt;artifactId&amp;gt;&lt;/i&gt; or &lt;i&gt;&amp;lt;groupId&amp;gt; &lt;/i&gt;values are&amp;nbsp;surrounded with &lt;i&gt;${artifactId}&lt;/i&gt; or &lt;i&gt;${groupId}&lt;/i&gt;. When you are creating a new &lt;i&gt;archetype&lt;/i&gt;, by default&amp;nbsp;&lt;b&gt;Maven&lt;/b&gt; will ask you to enter four parameters, &lt;i&gt;groupId&lt;/i&gt;, &lt;i&gt;artifactId&lt;/i&gt;, &lt;i&gt;version&lt;/i&gt; and &lt;i&gt;package&lt;/i&gt;. Entered values will be used to fill placeholders.&lt;br /&gt;&lt;br /&gt;With default four parameters should be enough, but imagine you want that user provides more information, for example,&amp;nbsp;&lt;i&gt;war&lt;/i&gt; name. To get this, open &lt;i&gt;archetype-metadata.xml&lt;/i&gt; file (&lt;i&gt;src/main/resources/META-INF/maven&lt;/i&gt;) and&amp;nbsp;add one required property, using &lt;i&gt;&amp;lt;requiredProperties&amp;gt; &lt;/i&gt;tag.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1434898.js?file=archetype-metadata.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In previous file we are adding a new required property named &lt;i&gt;warName&lt;/i&gt;. And last thing to do is update&lt;br /&gt;&lt;i&gt;archetype.properties&lt;/i&gt; located on &lt;i&gt;test/resources/projects/basic &lt;/i&gt;with default value of new property.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1437490.js?file=archetype.properties"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And that's all, if you open any &lt;i&gt;Java&lt;/i&gt; class or any &lt;i&gt;Xml&lt;/i&gt; file, you will see that has been modified with &lt;i&gt;${package}&lt;/i&gt; variable. This information is filled when you generate the project&lt;i&gt;.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now you can install &lt;i&gt;archetype&lt;/i&gt; into your local catalog and start generating&amp;nbsp;standardized&amp;nbsp;&amp;nbsp;projects.&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;mvn clean install&lt;/i&gt;&lt;/blockquote&gt;And your artifact is ready to be used. Try next &lt;i&gt;command&lt;/i&gt; or if you have installed &lt;i&gt;m2Eclipse&lt;/i&gt; plugin open &lt;i&gt;Eclipse&lt;/i&gt; and try your new &lt;i&gt;archetype&lt;/i&gt;:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;mvn archetype:generate -DarchetypeCatalog=local&lt;/i&gt;&lt;/blockquote&gt;A list of all installed &lt;i&gt;archetypes&lt;/i&gt; is shown. Choose previously created and fill up all required properties, and your new project is built and configured. You can start coding with same libraries that your workmates use and same style rules.&lt;br /&gt;&lt;br /&gt;In this post a simple example has been provided, but think about all kind of elements that you copy and paste from one project to another like &lt;i&gt;SCM&lt;/i&gt; connection, &lt;i&gt;surefire&lt;/i&gt; plugin configuration, &lt;i&gt;release&lt;/i&gt; plugin tag name, to cite a few, and how you can integrate them into your &lt;i&gt;archetype&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;I wish you have found this post interesting.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=AhzhiQA6-Aw&amp;amp;ob=av3e"&gt;http://www.youtube.com/watch?v=AhzhiQA6-Aw&amp;amp;ob=av3e&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5568831298346831681?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5568831298346831681/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5568831298346831681' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5568831298346831681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5568831298346831681'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/12/all-my-scientists-are-working-on.html' title='All my scientists are working on a deadline, So my psychologist is working day and nighttime, They say they know what&apos;s best for me, But they don&apos;t know what they&apos;re doing (Atomic Garden - Bad Religion)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5406185781917856833</id><published>2011-11-25T18:40:00.001+01:00</published><updated>2011-11-30T08:22:51.102+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css3'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='html5 template engine'/><category scheme='http://www.blogger.com/atom/ns#' term='thymeleaf'/><category scheme='http://www.blogger.com/atom/ns#' term='html5boilerplate'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr303'/><category scheme='http://www.blogger.com/atom/ns#' term='css shadows'/><category scheme='http://www.blogger.com/atom/ns#' term='google fonts'/><category scheme='http://www.blogger.com/atom/ns#' term='spring internationalization'/><category scheme='http://www.blogger.com/atom/ns#' term='table selectors'/><title type='text'>Your big daddy's got no place to stay, Bad communication, I feel like the president of the USA (Mr. Bad Guy - Freddie Mercury)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.thymeleaf.org/artwork/thymeleaflogonameverysmall.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="58" src="http://www.thymeleaf.org/artwork/thymeleaflogonameverysmall.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In current post I am going to explain how to implement nice&amp;nbsp;&lt;i style="text-align: justify;"&gt;web form&lt;/i&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; using &lt;/span&gt;&lt;b style="text-align: justify;"&gt;HTML 5 &lt;/b&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt;and &lt;/span&gt;&lt;b style="text-align: justify;"&gt;CSS 3&lt;/b&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; effects, and how can be integrated into&lt;/span&gt;&lt;b style="text-align: justify;"&gt; Spring MVC&lt;/b&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; web application.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First thing to do is create a &lt;b&gt;Spring MVC&lt;/b&gt;&amp;nbsp;skeleton project using &lt;i&gt;STS Spring Templates. &lt;/i&gt;In fact you can use any other method but I prefer to use a standard template.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next step is create an &lt;b&gt;HTML 5&lt;/b&gt; web structure, but exists some online applications that can do this for you, hence I am going to&lt;b&gt; HTML 5&lt;/b&gt; &lt;a href="http://www.html5boilerplate.com/"&gt;Boilerplate&lt;/a&gt; site, and create a custom &lt;b&gt;HTML 5&lt;/b&gt; template.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-dgBSyFcXKEM/Ts_WXT4wgpI/AAAAAAAAGBM/FAl7FHqYuA8/s1600/html5.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="257" src="http://2.bp.blogspot.com/-dgBSyFcXKEM/Ts_WXT4wgpI/AAAAAAAAGBM/FAl7FHqYuA8/s400/html5.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Then open downloaded &lt;i&gt;zip&lt;/i&gt; and copy required structure into previous generated project. &lt;i style="text-align: justify;"&gt;Css&lt;/i&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; and &lt;/span&gt;&lt;i style="text-align: justify;"&gt;Js&lt;/i&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; folders into resources directory, and rename &lt;/span&gt;&lt;i style="text-align: justify;"&gt;index.html&lt;/i&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; to &lt;/span&gt;&lt;i style="text-align: justify;"&gt;index.jsp&lt;/i&gt;&lt;span class="Apple-style-span" style="text-align: justify;"&gt; and copy it to &lt;i&gt;views&lt;/i&gt; directory.&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now open &lt;i&gt;servlet-context&lt;/i&gt; and add&lt;i&gt; mvc:resources&lt;/i&gt; tag for serving static resources.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1394079.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;If you deploy application a white screen should be showed but without any client/server error.&lt;br /&gt;&lt;br /&gt;Let's start creating next html form.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-2_lQoyz6kvE/TtPXvmTxnaI/AAAAAAAAGBs/4y9IfkatWXU/s1600/Screenshot-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="207" src="http://1.bp.blogspot.com/-2_lQoyz6kvE/TtPXvmTxnaI/AAAAAAAAGBs/4y9IfkatWXU/s400/Screenshot-1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now open &lt;i&gt;index.jsp &lt;/i&gt;and remove &lt;i&gt;div&lt;/i&gt; with id &lt;i&gt;main&lt;/i&gt; and create next form:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1394273.js?file=index.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now if you run again, you should see something like:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Zaf96nFUcww/Ts_ti8NV_4I/AAAAAAAAGBU/2XqHefl2MK8/s1600/form1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="95" src="http://4.bp.blogspot.com/-Zaf96nFUcww/Ts_ti8NV_4I/AAAAAAAAGBU/2XqHefl2MK8/s400/form1.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Add &lt;i&gt;@import url(http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);&lt;/i&gt; on top of &lt;b&gt;CSS&lt;/b&gt; file&lt;i&gt;.&lt;/i&gt;This will make a nice font available from&amp;nbsp;&lt;a href="http://code.google.com/webfonts"&gt;Google Fonts&lt;/a&gt; directory.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now it is time to start applying &lt;b&gt;CSS&lt;/b&gt; for creating a better layout. Open &lt;i&gt;style.css&lt;/i&gt; and modify/create next elements:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1394284.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now your form should look with next layout:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ECgU86zierg/Ts_viB13ReI/AAAAAAAAGBk/MwlXIOnqx74/s1600/form2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="205" src="http://3.bp.blogspot.com/-ECgU86zierg/Ts_viB13ReI/AAAAAAAAGBk/MwlXIOnqx74/s400/form2.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that new font is not used, simply find&lt;i&gt;&amp;nbsp;body,button,input,select,textarea &lt;/i&gt;entry&lt;i&gt;&amp;nbsp;&lt;/i&gt;and remove &lt;i&gt;font-family&lt;/i&gt; property.&lt;br /&gt;&lt;br /&gt;Better than before, see how only modifying &lt;b&gt;CSS,&lt;/b&gt;&amp;nbsp;form layout is modified.&lt;br /&gt;&lt;br /&gt;And now let's start with &lt;b&gt;CSS3&lt;/b&gt; magic.&lt;br /&gt;&lt;br /&gt;First trick is adding shadows and gradients to &lt;i&gt;form&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1394292.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And next lines into &lt;i&gt;input&lt;/i&gt;, &lt;i&gt;textarea &lt;/i&gt;style:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1394302.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;where&lt;i&gt; -moz&lt;/i&gt; prefix is used for &lt;i&gt;Gecko&lt;/i&gt; based browsers, and &lt;i&gt;-webkit&lt;/i&gt; is used for &lt;i&gt;Webkit&lt;/i&gt; browsers.&lt;br /&gt;&lt;br /&gt;Next lines add some mouse over effects into form elements.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1394309.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;And to finish applying styles, we are going to modify &lt;i&gt;submit &lt;/i&gt;button.&lt;br /&gt;&lt;br /&gt;Remove &lt;i&gt;input[type="submit"]&lt;/i&gt; from &lt;i&gt;button&lt;/i&gt; and &lt;i&gt;input&lt;/i&gt; style.&lt;br /&gt;&lt;br /&gt;And add next lines into &lt;i&gt;&lt;b&gt;CSS&amp;nbsp;&lt;/b&gt;&lt;/i&gt;file:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1394312.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;b&gt;CSS&lt;/b&gt; magic is over, now it is time to start with server side.&lt;br /&gt;&lt;br /&gt;If you look careful &lt;b&gt;Spring &lt;/b&gt;&lt;i&gt;taglibs&lt;/i&gt;, you will see that you cannot create for example &lt;i&gt;email&lt;/i&gt; input types directly or URL &lt;i&gt;types &lt;/i&gt;to cite a few. So I decided to use a new template engine called &lt;b&gt;Thymeleaf&lt;/b&gt;, that offers a really nice approach for integrating&amp;nbsp;&lt;b&gt;HTML 5&lt;/b&gt;&amp;nbsp;with&lt;b&gt;&amp;nbsp;Spring MVC&lt;/b&gt; applications.&lt;br /&gt;&lt;br /&gt;The main goal of &lt;b&gt;Thymeleaf&lt;/b&gt; is to provide an elegant and well-formed way of creating &lt;b&gt;HTML 5&lt;/b&gt; templates. Its &lt;i&gt;Standard&lt;/i&gt; and &lt;i&gt;SpringStandard&lt;/i&gt; dialects allow you to create powerful natural templates, that can be correctly displayed by browsers and therefore work also as &lt;i&gt;static prototypes&lt;/i&gt;. This is possible due the absence of &lt;i&gt;taglibs&amp;nbsp;&lt;/i&gt;like &amp;nbsp;&lt;i&gt;&amp;lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %&amp;gt;&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;First thing to do is change &lt;i&gt;index.jsp&lt;/i&gt; to &lt;i&gt;index.html&lt;/i&gt;, and change &lt;i&gt;ViewResolver&lt;/i&gt; to &lt;b&gt;Thymeleaf&lt;/b&gt; &lt;i&gt;ViewResolver&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;First add &lt;b&gt;Thymeleaf&lt;/b&gt; dependencies into &lt;i&gt;pom&lt;/i&gt; and then modify &lt;i&gt;servlet-context.xml&lt;/i&gt; to register &lt;i&gt;TempateResolver&lt;/i&gt;, &lt;i&gt;TemplateEngine&lt;/i&gt; and &lt;i&gt;ThymeleafViewResolver&lt;/i&gt; and remove the deault view resolver.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1395431.js?file=pom.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1395432.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Next step is modeling our form to a model class, and modify &lt;i&gt;Spring Controller&lt;/i&gt; to manage form submition.&lt;br /&gt;&lt;br /&gt;Model class is not shown because is a simple &lt;i&gt;POJO&lt;/i&gt; with form fields. Let's see how controller is modified.&lt;br /&gt;&lt;br /&gt;Open &lt;i&gt;HomeController&lt;/i&gt; class and create two methods (&lt;i&gt;GET&lt;/i&gt;, &lt;i&gt;POST&lt;/i&gt;) to deal with&lt;b&gt; HTML5&lt;/b&gt; form. Note that it is a typical &lt;i&gt;Spring Form Controller;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1395435.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally we are going to templarize &lt;i&gt;index.html&lt;/i&gt; content, using &lt;b&gt;Thymeleaf&lt;/b&gt; engine.&lt;br /&gt;&lt;br /&gt;Open &lt;i&gt;index.html &lt;/i&gt;and make next changes:&lt;br /&gt;&lt;br /&gt;Add &lt;b&gt;Thymeleaf&lt;/b&gt; namespace on &lt;i&gt;html&lt;/i&gt; tag.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;html xmlns:th="http://www.thymeleaf.org"&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Then change form tag with two new attributes, one with object's model name (form backing object) and other one with submition &lt;i&gt;URL&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;form action="#" th:object="${messageInfo}" th:action="@{/}" method="post"&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Next thing to do is change each form element with &lt;i&gt;th:value&lt;/i&gt; attribute containing backing object property name.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;input type="text" name="name" value="" id="name" placeholder="Your Name" required="required"&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;autofocus="autofocus" th:value="*{name}"/&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And more few changes should be performed:&lt;br /&gt;&lt;br /&gt;Use&lt;i&gt; DOCTYPE&lt;/i&gt; instead of &lt;i&gt;doctype&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;At time of writing this post, &lt;i&gt;html5boilporate&lt;/i&gt;&amp;nbsp;introduces &lt;i&gt;link&lt;/i&gt; tag without closing, so &lt;b&gt;Thymeleaf &lt;/b&gt;parser will throw an exception if is executed as is, so let's terminate &lt;i&gt;link&lt;/i&gt; tag and &lt;i&gt;meta&lt;/i&gt; tags.&lt;br /&gt;&lt;br /&gt;And finally last change is required because of &lt;i&gt;xhtml&lt;/i&gt; correctness:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1395569.js?file=index.html"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;script&amp;gt;&lt;/i&gt; tag is&amp;nbsp;surrounded&amp;nbsp;with &lt;b&gt;CDATA&lt;/b&gt; tags. See explanation here: &amp;nbsp;&lt;a href="http://javascript.about.com/library/blxhtml.htm"&gt;http://javascript.about.com/library/blxhtml.htm&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now you can deploy application and your &lt;b&gt;HTML5+CSS3&lt;/b&gt; form is displayed and data submitted is displayed through server console and form page is reloaded with introduced data. And now I am going to explain what are those strange expressions in form and then we will add a new page.&lt;br /&gt;&lt;br /&gt;Inside each &lt;b&gt;Thymelef&lt;/b&gt; attribute four kind of expressions can be used:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;${...} are &lt;i&gt;Spring EL&lt;/i&gt; expressions and are executed on model attributes.&lt;/li&gt;&lt;li&gt;*{...} are expressions executed on the &lt;i&gt;form backing bean&lt;/i&gt;, it is like a pointer to form object (root).&lt;/li&gt;&lt;li&gt;&amp;nbsp;#{...} are for &lt;i&gt;internationalization.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;@{...} are link expressions to rewrite &lt;i&gt;URLs&lt;/i&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And before jumping to next section try this, instead of opening &lt;i&gt;index.html&lt;/i&gt; from &lt;i&gt;http://localhost:.....&lt;/i&gt; try to open from your drive &lt;i&gt;file://....&lt;/i&gt; and I suppose you see that that's not a nice prototype because no styling is&amp;nbsp;applied. This happens because we are using &lt;b&gt;CSS&lt;/b&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;location as:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;link rel="stylesheet" href="css/style.css"/&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;HTML&lt;/b&gt;&amp;nbsp;file is at &lt;i&gt;/src/main/webapp/WEB-INF/views/&lt;/i&gt;&amp;nbsp;and this directory does not contain &lt;i&gt;css&lt;/i&gt; folder. And now you can think that I have not told you the true about prototyping with &lt;b&gt;Thymeleaf&lt;/b&gt;, but wait trust me and change that line to:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;link rel="stylesheet" href="../../css/style.css" th:href="@{/css/style.css}"/&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And open again, and wow now you can see it, a real page as one generated by the server. What we have changed is that when a browser opens &lt;b&gt;HTML&lt;/b&gt; file without using template engine (&lt;i&gt;offline&lt;/i&gt;), &lt;i&gt;href&lt;/i&gt; attribute is used, but when page is &lt;i&gt;online &lt;/i&gt;(and requested file acts as a template), &lt;i&gt;th:href&lt;/i&gt; attribute is used.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Listing Messages:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let's start creating a new &lt;b&gt;HTML&lt;/b&gt; file to display all inserted messages and apply some styling with &lt;b&gt;CSS&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-37qB_RXS8CA/TtPgNNL_fVI/AAAAAAAAGB0/H40LZhQnoAQ/s1600/Screenshot-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="81" src="http://3.bp.blogspot.com/-37qB_RXS8CA/TtPgNNL_fVI/AAAAAAAAGB0/H40LZhQnoAQ/s400/Screenshot-2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;First add a new &lt;b&gt;CSS &lt;/b&gt;property to apply same design in table.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1395657.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;New &lt;b&gt;CSS 3&lt;/b&gt; property (&lt;i&gt;nth-child&lt;/i&gt;) is used so &lt;i&gt;even tr tags&lt;/i&gt; of a table will contain different style than &lt;i&gt;odd tr tags&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Then create a file called &lt;i&gt;list.html&lt;/i&gt; in same level of &lt;i&gt;index.html&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397787.js?file=list.html"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This is a copy paste of &lt;i&gt;index.html&lt;/i&gt; but changing &lt;i&gt;div &lt;/i&gt;with id&lt;i&gt;&amp;nbsp;content&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;In this case we are using another nice feature of &lt;b&gt;Thymeleaf&lt;/b&gt;, collection iteration. With &lt;i&gt;th:each&lt;/i&gt; you are iterating over a collection of elements. See that&amp;nbsp;&lt;i&gt;rowStat&amp;nbsp;&lt;/i&gt;variable&amp;nbsp;can be used for retrieving column information like &lt;i&gt;number of column&lt;/i&gt;. And also see how we are defining default values between &lt;i&gt;td&lt;/i&gt; tags, so this file is a&amp;nbsp;prototype&amp;nbsp;too.&lt;br /&gt;&lt;br /&gt;Next step is changing our controller, so &lt;i&gt;homeForm&lt;/i&gt; (renamed to &lt;i&gt;showResults&lt;/i&gt;) method returns a list of messages:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397790.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Using a simple list as repository is not a good design, but for teaching purpose is enough. See that view name is set to &lt;i&gt;list&lt;/i&gt;, and list of&lt;i&gt; messageForm&lt;/i&gt; are sent back with model name used in &lt;i&gt;th:each&lt;/i&gt; attribute.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Internationalization:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next step is internationalizing the application. For this reason we create a message properties file (&lt;i&gt;messages_en_US.properties&lt;/i&gt;) into &lt;i&gt;src/main/resources/locale&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397794.js?file=messages_en_US.properties"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Then you must configure &lt;i&gt;Locale&lt;/i&gt; beans in &lt;b&gt;Spring&lt;/b&gt; context file.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397802.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally change &lt;i&gt;index.html&lt;/i&gt; and &lt;i&gt;list.html&lt;/i&gt; static values to internationalized keys using &lt;i&gt;#{}&lt;/i&gt; expression:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;th th:text="#{theader.count}"&amp;gt;&amp;lt;/th&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;lt;label for="name" th:text="#{theader.name}"&amp;gt;Name: &amp;lt;/label&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And although internationalization is used, web page is still a prototype.&lt;br /&gt;&lt;br /&gt;It seems like application is working well, but it has one problem. Try next sequence of events:&lt;br /&gt;&lt;br /&gt;1. Add a new message.&lt;br /&gt;2. When list of all messages are shown, refresh the page (F5).&lt;br /&gt;&lt;br /&gt;And surprise the same message is added too, so now we have two repeated messages, but you have only inserted one.&lt;br /&gt;&lt;br /&gt;To fix this problem we must change our controller and use &lt;i&gt;redirect&lt;/i&gt; keyword on &lt;i&gt;create&lt;/i&gt; method to&amp;nbsp;&lt;i&gt;redirect&lt;/i&gt; to a method of controller that finds all inserted messages.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397812.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;When a new message is created (&lt;i&gt;create&lt;/i&gt; method), a redirect to &lt;i&gt;/list&lt;/i&gt; is returned, then &lt;i&gt;showResults&lt;/i&gt; method is called, and returns a list with all inserted messages. Remember to change &lt;i&gt;th:action&lt;/i&gt; from form tag to &lt;i&gt;/insert&lt;/i&gt; too.&lt;br /&gt;&lt;br /&gt;And now if you execute the same process as before, no multiple insertions occur.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Validation:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;And as final step let's see how to implement validation with &lt;b&gt;Thymeleaf&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;First thing is adding&lt;i&gt; Jsr-303&lt;/i&gt; provider into our &lt;i&gt;pom&lt;/i&gt;. In this case&lt;i&gt; Hibernate-Validator&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397821.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Next step is changing our model by for example creating a length constraint in &lt;i&gt;phone&lt;/i&gt; field:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;@Length(min=9)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;private String phone;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To trigger validation of a &lt;i&gt;@Controller&lt;/i&gt; input, you must annotate input arguments with &lt;i&gt;@Valid&lt;/i&gt;. So our controller is modified to:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397829.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally modify form page so when an error occurs, a message is shown.&lt;br /&gt;&lt;br /&gt;First a new &lt;b&gt;CSS&lt;/b&gt; style is created for showing error message:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397834.js?file=style.css"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that in previous style we are defining an &lt;i&gt;img&lt;/i&gt; folder so new static resource resolution in &lt;i&gt;servlet-context.xml &lt;/i&gt;as done with &lt;i&gt;css&amp;nbsp;&lt;/i&gt;and &lt;i&gt;js&lt;/i&gt;&amp;nbsp;folders must be registered.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397983.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;And finally in &lt;i&gt;index.html &lt;/i&gt;a new &lt;i&gt;div&lt;/i&gt; is created for showing errors:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1397959.js?file=index.html"&gt;&lt;/script&gt;&lt;br /&gt;For showing errors, &lt;i&gt;#fields&lt;/i&gt; variable is used. This variable is provided by &lt;b&gt;Thymeleaf&lt;/b&gt; and contains all errors bound by &lt;i&gt;Validation Framework&lt;/i&gt;. Note that star '*' is used as&amp;nbsp;&lt;i&gt;errors&lt;/i&gt; function parameters for returning all errors produced by all form fields, but &lt;b&gt;Thymeleaf&lt;/b&gt; allows you to specify only one particular field.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;b&gt;Conclusions:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;From this post I have learned some&amp;nbsp;interesting&amp;nbsp;points:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;With new &lt;b&gt;HTML5&lt;/b&gt; tags, some &lt;i&gt;Javascript&lt;/i&gt; validation (like entering well-formatted email) is not required anymore.&lt;/li&gt;&lt;li&gt;&lt;b&gt;CSS 3&lt;/b&gt; shadows and gradients properties allow us to create amazing forms without using complicated structures of images.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Thymeleaf&lt;/b&gt; is an amazing template engine, in fact for me a real way for creating prototypes and final code at once.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Thymeleaf&lt;/b&gt; is a young project, and for example does not support &lt;i&gt;jQuery&lt;/i&gt; by default, but exists &amp;nbsp; a&amp;nbsp;&lt;b&gt;Thymeleaf&lt;/b&gt; dialect that integrate it. I think that in nearest future it will be a template engine to be consider.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;Hope you find &lt;b&gt;Thymeleaf&lt;/b&gt; useful too.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/html5form.zip"&gt;Download Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=MMr1zH8NoEY"&gt;http://www.youtube.com/watch?v=MMr1zH8NoEY&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5406185781917856833?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5406185781917856833/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5406185781917856833' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5406185781917856833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5406185781917856833'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/11/your-big-daddys-got-no-place-to-stay.html' title='Your big daddy&apos;s got no place to stay, Bad communication, I feel like the president of the USA (Mr. Bad Guy - Freddie Mercury)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-dgBSyFcXKEM/Ts_WXT4wgpI/AAAAAAAAGBM/FAl7FHqYuA8/s72-c/html5.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-3982756357448814124</id><published>2011-11-18T16:17:00.001+01:00</published><updated>2011-11-22T08:15:01.027+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring EL'/><category scheme='http://www.blogger.com/atom/ns#' term='spEL'/><category scheme='http://www.blogger.com/atom/ns#' term='script engine'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='SpelExpressionParser'/><category scheme='http://www.blogger.com/atom/ns#' term='Scripting API'/><category scheme='http://www.blogger.com/atom/ns#' term='Compilable script'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr 223'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk services'/><title type='text'>What a wicked game you play,  To make me feel this way,  What a wicked thing to do,  To let me dream of you ( Wicked Game - Chris Isaak)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.familycar.com/Classroom/Images/Engine.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="193" src="http://www.familycar.com/Classroom/Images/Engine.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;In my previous &lt;a href="http://alexsotob.blogspot.com/2011/11/en-ti-puedo-ver-la-libertad-tu-me-haces.html"&gt;post&lt;/a&gt; I was talking about how to create a service using &lt;i&gt;Jdk service provider&lt;/i&gt;. In current post I am going to talk about how to implement your own &lt;b&gt;Jsr223 Script Engine&lt;/b&gt;. And as you will see, &lt;b&gt;script engines&lt;/b&gt; are a kind of&lt;i&gt; Jdk service providers&lt;/i&gt;, so instead of creating your own set of interfaces, we are going to see how to implement a service provider of an already defined service.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Moreover we are going to see how we can convert a scripting language expression evaluator (in this case &lt;b&gt;Spring EL&lt;/b&gt;) to be &lt;b&gt;Jsr-223&lt;/b&gt; compliant.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First of all for those who do not know what is &lt;b&gt;Jsr-223 &lt;/b&gt;specification (or &lt;b&gt;Java Scripting API&lt;/b&gt;), &lt;b&gt;Jsr-223&lt;/b&gt; is a scripting language&amp;nbsp;independent&amp;nbsp;framework for using script engines from &lt;i&gt;Java&lt;/i&gt; code. Thanks of &lt;b&gt;Jsr-223&lt;/b&gt;, we only use&lt;i&gt; javax.script&lt;/i&gt; package instead of importing language specific classes.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For example using&lt;b&gt; Spring EL&lt;/b&gt; scripting language, requires you import in your business class at least two &lt;i&gt;Spring&lt;/i&gt; classes &lt;i&gt;ExpressionParser&lt;/i&gt; and &lt;i&gt;SpelExpressionParser&lt;/i&gt;, and if you want to use another scripting language, more specific vendor classes should be added, so your code is tied to script parser used.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If you use &lt;b&gt;Java Scripting API&lt;/b&gt;, two classes are required, &lt;i&gt;ScriptEngineFactory&lt;/i&gt; and &lt;i&gt;ScriptEngine&lt;/i&gt;, regardless of the language used. And this occurs because &lt;i&gt;ScriptEngine&lt;/i&gt; is an interface returned by &lt;i&gt;ScriptEngineFactory service&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Let's start coding:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First class to implement is&amp;nbsp;&lt;i&gt;ScriptEngineFactory &lt;/i&gt;and&amp;nbsp;is responsible of creating a new &lt;i&gt;ScriptEngine&lt;/i&gt;. It must implement&amp;nbsp;&lt;i&gt;ScriptEngineFactory &lt;/i&gt;interface&lt;i&gt;&amp;nbsp;&lt;/i&gt;and its implementation will be the&lt;i&gt; service provider &lt;/i&gt;of&lt;i&gt;&amp;nbsp;Scripting API&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1378833.js?file=SpelScriptEngineFactory.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;First part of class is where we are defining what is the name of script language&amp;nbsp;used to get the engine, the version of language (I have chosen &lt;i&gt;Spring&lt;/i&gt; version), and version of engine.&lt;br /&gt;&lt;br /&gt;Then three special methods:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;getMethodCallSyntax&lt;/i&gt;: returns a &lt;i&gt;String&lt;/i&gt; which can be used to invoke a method of a &lt;i&gt;Java&lt;/i&gt; object using the syntax of the supported scripting language. In case &lt;b&gt;spEL&lt;/b&gt;, the equivalent of calling a Java method from script, is using &lt;i&gt;Types &lt;/i&gt;with special &lt;i&gt;T&lt;/i&gt; operator.&lt;/li&gt;&lt;li&gt;&lt;i&gt;getOutputStream&lt;/i&gt;: returns a &lt;i&gt;String&lt;/i&gt; that can be used as a statement to display the specified &lt;i&gt;String&lt;/i&gt; using the syntax of the supported scripting language. In case of &lt;b&gt;spEL&lt;/b&gt;, there is no output stream so an unsupported exception is thrown.&lt;/li&gt;&lt;li&gt;&lt;i&gt;getProgram&lt;/i&gt;: returns a valid scripting language executable progam with given statements. As previous method, an unsupported exception is thrown.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and finally the most important method &lt;i&gt;getScriptEngine&lt;/i&gt;, which must return an implementation of &lt;i&gt;ScriptEngine&lt;/i&gt;&amp;nbsp;interface. In this case the &lt;b&gt;Spring EL&lt;/b&gt; script engine. Let's see how &lt;b&gt;spEL &lt;/b&gt;&lt;i&gt;ScriptEngine&amp;nbsp;&lt;/i&gt;is implemented.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1380124.js?file=SpelScriptEngineImpl.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;First of all class extends from &lt;i&gt;AbstractScriptEngine&lt;/i&gt;, which provides implementation for several of the variants of the &lt;i&gt;eval &lt;/i&gt;method. &lt;i&gt;Compilable&lt;/i&gt; interface is implemented too. &lt;i&gt;ScriptEngines &lt;/i&gt;that implements this interface can compile scripts so any further execution of expression does not require any recompilation.&lt;br /&gt;&lt;br /&gt;Most important method is&amp;nbsp;&lt;i&gt;eval &lt;/i&gt;which&lt;i&gt;&amp;nbsp;&lt;/i&gt;should cause immediate script execution using vendor library.&lt;br /&gt;&lt;br /&gt;Main purpose of this class is adapt &lt;b&gt;Jsr-223&lt;/b&gt; classes to &lt;b&gt;Spring&amp;nbsp;EL &lt;/b&gt;classes. If you look carefully this class, it contains a private inner class that extends &lt;i&gt;CompiledScript&lt;/i&gt;. This class is responsible of storing compiled expression, so subsequent calls of &lt;i&gt;eval&lt;/i&gt; method requires no reparsing. This class is returned when &lt;i&gt;compile&lt;/i&gt; method is called.&lt;br /&gt;&lt;br /&gt;As final note &lt;b&gt;spEL &lt;/b&gt;language contains some features that go beyond a standard script like registering &lt;i&gt;Java &lt;/i&gt;functions into script, referencing &lt;i&gt;Spring Beans&lt;/i&gt;, expression templating or navigation through properties of &lt;a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/expressions.html#d0e11747"&gt;root objects&lt;/a&gt;. Of all of these features I think it would be useful having root objects support in &lt;b&gt;Jsr-223&lt;/b&gt; implementation, so I have coded a special attribute named "&lt;i&gt;root&lt;/i&gt;". So if you set an attribute to script context with name "&lt;i&gt;root&lt;/i&gt;", &amp;nbsp;attribute's content will be treated as root object.&lt;br /&gt;&lt;br /&gt;Before implementing this solution I wondered another possibilities like not implementing root objects, or using &lt;i&gt;Adapter &lt;/i&gt;pattern implementing two interfaces &lt;i&gt;ScriptContext &lt;/i&gt;and &lt;i&gt;EvaluationContext, &lt;/i&gt;but I&amp;nbsp;dismissed because there were duplicated methods (different signature, same behaviour), and from developer's point of view &amp;nbsp;could be a bit confusing. Moreover this approach implies that caller should know that are running &lt;b&gt;spEL &lt;/b&gt;script. Also I planned of using &lt;i&gt;MethodResolver &lt;/i&gt;or &lt;i&gt;PropertyResolver &lt;/i&gt;but was rejected because &lt;b&gt;spEL &lt;/b&gt;would have been extended.&lt;br /&gt;&lt;br /&gt;With attribute approach, if you are not using root objects, there are no differences between using &lt;b&gt;Scripting API&lt;/b&gt; with &lt;i&gt;Javascript&lt;/i&gt;, &lt;i&gt;Groovy &lt;/i&gt;or &lt;b&gt;spEL&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;And finally service configuration. Create &lt;i&gt;META-INF/services&lt;/i&gt; directory into resources folder, and create&amp;nbsp;&lt;i&gt;javax.script.ScriptEngineFactory &lt;/i&gt;file&lt;i&gt;;&lt;/i&gt;&amp;nbsp;this is the&lt;i&gt;&amp;nbsp;&lt;/i&gt;full qualified name of service interface with next content:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1380355.js?file=javax.script.ScriptEngineFactory"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And that's all about implementation, with next unit tests you will see clearly how is used:&lt;br /&gt;&lt;br /&gt;First one is testing that &lt;i&gt;SpelScriptEngine&lt;/i&gt; is returned by &lt;i&gt;ScriptEngineManager&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1383515.js?file=ScriptEngineManagerBehaviour.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Not complicated, it is used as you would use for retrieving &lt;i&gt;Javascript&lt;/i&gt; engine.&lt;i&gt; Short name&lt;/i&gt; is used as engine identifier.&lt;br /&gt;&lt;br /&gt;And next unit test contains some assertions about how some &lt;b&gt;Spring EL&lt;/b&gt; features are used with&amp;nbsp;&lt;i&gt;ScriptEngine&lt;/i&gt; rather than &lt;i&gt;SpelExpressionParser&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1383588.js?file=SpelScriptEngineBehaviour.java"&gt;&lt;/script&gt;&lt;/div&gt;Notice how in first test,&amp;nbsp;&lt;i&gt;SpelScriptEngineImpl.ROOT_OBJECT&lt;/i&gt; constant is used, so &lt;i&gt;Inventor&lt;/i&gt; instance is specified as root object.&lt;br /&gt;&lt;br /&gt;Hope you found this post useful.&lt;br /&gt;&lt;br /&gt;Feel free to use this code, I have created a &lt;i&gt;git &lt;/i&gt;repository so you can download, branch, ...&amp;nbsp;&lt;a href="https://github.com/maggandalf/spEL223"&gt;https://github.com/maggandalf/spEL223&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also I have uploaded project as zip file.&amp;nbsp;Download &lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/spel223.zip"&gt;Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=UAOxCqSxRD0"&gt;http://www.youtube.com/watch?v=UAOxCqSxRD0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3982756357448814124?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3982756357448814124/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3982756357448814124' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3982756357448814124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3982756357448814124'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/11/what-wicked-game-you-play-to-make-me.html' title='What a wicked game you play,  To make me feel this way,  What a wicked thing to do,  To let me dream of you ( Wicked Game - Chris Isaak)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-3696293192916425743</id><published>2011-11-10T20:26:00.000+01:00</published><updated>2011-11-15T19:30:23.095+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven-gae-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='maven-datanucleus-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Google App Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='maven gae'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='spring MVC rest'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Fear of the dark, fear of the dark I have a phobia that someone's always there (Fear of the Dark - Iron Maiden)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://code.google.com/appengine/images/appengine_lowres.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://code.google.com/appengine/images/appengine_lowres.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Some time ago I wrote about how to implement your &lt;i&gt;Restful Web API&lt;/i&gt; using&lt;b&gt; Spring MVC&lt;/b&gt;. Read my previous &amp;nbsp;&lt;a href="http://alexsotob.blogspot.com/2011/10/cant-you-see-it-all-makes-perfect-sense.html"&gt;post &lt;/a&gt;to know about it.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In that post it was developed a simple &lt;i&gt;Rest &lt;/i&gt;example. For testing the application, &amp;nbsp;file was copied into a web server &amp;nbsp;(&lt;i&gt;Tomcat &lt;/i&gt;for example), and then accessing to &lt;i&gt;http://localhost:8080/RestServer/characters/1&lt;/i&gt;&amp;nbsp;information of character 1 was returned.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In current post I am going to explain how to transform that application to a &lt;b&gt;Google App Engine&lt;/b&gt; and be deployed into Google's infrastructure using &lt;b&gt;Maven&lt;/b&gt;. Of course in this case we are going to deploy a &lt;b&gt;Rest&lt;/b&gt; &lt;b&gt;Spring MVC&lt;/b&gt; application, but same approach can be used for migrating a &lt;b&gt;Spring MVC&lt;/b&gt; web application (or any other application developed with other web framework) to &lt;b&gt;GAE&lt;/b&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;First of all, obviously you should create a &lt;i&gt;&lt;a href="http://code.google.com/appengine/"&gt;Google Account&lt;/a&gt;&lt;/i&gt; and register a new &lt;i&gt;application (&lt;/i&gt;remember the name because will be used in next step&lt;i&gt;)&lt;/i&gt;. After that you can start the migration.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Three changes are required, create&lt;i&gt; appengine-web.xml &lt;/i&gt;defining application name;&amp;nbsp;add &lt;i&gt;server&lt;/i&gt; tag to&lt;i&gt; settings.xml &lt;/i&gt;with Google account information&lt;i&gt;, &lt;/i&gt;and modify&lt;i&gt;&amp;nbsp;pom.xml &lt;/i&gt;for adding&amp;nbsp;&lt;b&gt;GAE&lt;/b&gt; plugin and its dependencies.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Let's start with &lt;i&gt;appengine-web.xml&lt;/i&gt;. This file is used by &lt;b&gt;GAE&lt;/b&gt; to configure application and is created into &lt;i&gt;WEB-INF&lt;/i&gt; directory (at same level of &lt;i&gt;web.xml&lt;/i&gt;).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1355807.js?file=appengine-web.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;The most important field is &lt;i&gt;application&lt;/i&gt; tag. This tag contains the name of our application (defined when you register a new Google Application).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Other tags are version, system properties and environment variables, and misc configuration like if you want a precompilation to enhance performance or if your application requires sessions.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And your project should not be modified anymore, now only &lt;b&gt;Maven&lt;/b&gt; files will be touched.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In&lt;i&gt; settings.xml,&lt;/i&gt; account information should be added:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1355844.js?file=settings.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;See that it is as easy as registering any other server in &lt;b&gt;Maven&lt;/b&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And finally the most tedious part, modifying &lt;i&gt;pom.xml.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;First thing is adding new properties:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1355869.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;At first line we are defining &lt;i&gt;Appengine Java SDK&lt;/i&gt; location. If you have already installed then insert location in this tag, if not, copy same location of this &lt;i&gt;pom&lt;/i&gt; and simply change m&lt;i&gt;aven repository &lt;/i&gt;directory, in my case &lt;i&gt;/media/share/maven_repo,&lt;/i&gt; to yours. Typically your &lt;b&gt;Maven&lt;/b&gt; repository location will be &amp;nbsp;&lt;i&gt;/home/user/.m2/repositories.&amp;nbsp;&lt;/i&gt;&lt;b&gt;Maven&lt;/b&gt; will download &lt;i&gt;SDK&lt;/i&gt; for you at deploy time.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next step is adding &lt;b&gt;Maven GAE&lt;/b&gt; repository.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362069.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Because our project is dummy project, &lt;i&gt;Datanucleus&lt;/i&gt; are not used. In case of more complex projects, that database access is required using, for example JDO, next dependencies should be added:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362164.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And in case you are using &lt;i&gt;Datanucleus&lt;/i&gt;,&amp;nbsp;&lt;i&gt;maven-datanucleus-plugin&lt;/i&gt; should be registered&lt;i&gt;. &lt;/i&gt;Take care to configure it properly depending on your project.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362169.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Now&lt;b&gt; Google App Engine&lt;/b&gt; dependencies are added.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362179.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Then if you want to test &lt;b&gt;GAE&lt;/b&gt;&amp;nbsp;&lt;a href="http://code.google.com/appengine/docs/java/howto/unittesting.html"&gt;functionalities&lt;/a&gt;&amp;nbsp;(not used in our dummy project), next&amp;nbsp;&lt;b&gt;GAE&lt;/b&gt; libraries are added:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362076.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next change is a modification on &lt;i&gt;maven-war-plugin&lt;/i&gt; including&lt;i&gt; appengine-web.xml &lt;/i&gt;into generated package:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362184.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And finally adding &lt;i&gt;maven-gae-plugin&lt;/i&gt; and configuring it to upload application to &lt;i&gt;appspot&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362190.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;See that &amp;lt;serviceId&amp;gt; tag contains the server name defined previously in &lt;i&gt;settings.xml&lt;/i&gt; file.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Also if you are using &lt;i&gt;maven-release-plugin&lt;/i&gt; you can upload application to the &lt;i&gt;appspot&lt;/i&gt; automatically, during &lt;i&gt;release:perform&lt;/i&gt; goal:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1362215.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Now run &lt;i&gt;gae:deploy&lt;/i&gt; goal. If you have already installed&amp;nbsp;&lt;i&gt;Appengine Java SDK, &lt;/i&gt;then your application will be uploaded to your &lt;b&gt;GAE &lt;/b&gt;site. But if it is the first time you run the plugin, you will receive an error. Do not panic, this error occurs because &lt;b&gt;Maven &lt;/b&gt;plugin does not find &lt;i&gt;Appengine SDK&lt;/i&gt; into directory you specified in &amp;lt;gae.home&amp;gt; tag. But if you have configured &lt;i&gt;gae.home&lt;/i&gt; location into your local &lt;b&gt;Maven &lt;/b&gt;repository, simply run &lt;i&gt;gae:unpack&lt;/i&gt; goal, and &lt;i&gt;SDK &lt;/i&gt;will be installed correctly so when you rerun &lt;i&gt;gae:deploy &lt;/i&gt;your application will be uploaded into Google infrastructure.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In post example you can go to&amp;nbsp;&lt;a href="http://alexsotoblog.appspot.com/characters/1" style="text-align: -webkit-auto;"&gt;http://alexsotoblog.appspot.com/characters/1&lt;/a&gt;&amp;nbsp;and character information in &lt;i&gt;JSON &lt;/i&gt;format is displayed into your browser.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;As I have noted at the beginning of the post, the same process can be used for any web application, not only for &lt;i&gt;Spring Rest&lt;/i&gt; &lt;i&gt;MVC&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Because of teaching purpose all modifications have been made into application &lt;i&gt;pom&lt;/i&gt;. My advice is that you create a parent &lt;i&gt;pom &lt;/i&gt;with &lt;b&gt;GAE &lt;/b&gt;related tags, so each project that must be uploaded into &lt;b&gt;Google App Engine &lt;/b&gt;extends from same &lt;i&gt;pom &lt;/i&gt;file.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;I wish you have found this post useful.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;This week I am at &lt;a href="http://www.devoxx.com/display/DV11/Home"&gt;devoxx&lt;/a&gt;, meet me there ;) I will be speaking on Thursday 17 at 13:00 about &lt;a href="http://www.devoxx.com/display/DV11/Quickie+Day+4"&gt;Speeding Up Javascript &amp;amp; CSS Download Times With Aggregation and Minification&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Full &lt;i&gt;pom &lt;/i&gt;file:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1367845.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/restServerGAE.zip"&gt;Download&lt;/a&gt; Code.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=Nba3Tr_GLZU" style="text-align: -webkit-auto;"&gt;http://www.youtube.com/watch?v=Nba3Tr_GLZU&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3696293192916425743?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3696293192916425743/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3696293192916425743' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3696293192916425743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3696293192916425743'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/11/fear-of-dark-fear-of-dark-i-have-phobia.html' title='Fear of the dark, fear of the dark I have a phobia that someone&apos;s always there (Fear of the Dark - Iron Maiden)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2590960457860604589</id><published>2011-11-07T09:27:00.000+01:00</published><updated>2011-11-07T09:27:11.477+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaCSV'/><category scheme='http://www.blogger.com/atom/ns#' term='internationalization'/><category scheme='http://www.blogger.com/atom/ns#' term='localization'/><category scheme='http://www.blogger.com/atom/ns#' term='i18n'/><category scheme='http://www.blogger.com/atom/ns#' term='l10n'/><category scheme='http://www.blogger.com/atom/ns#' term='DecimalFormatSymbols'/><category scheme='http://www.blogger.com/atom/ns#' term='comma-separated values'/><title type='text'>I en una paret al fons imprès en blanc i negre hi havia un pòster d'en Godard. Potser ell em podria dir-me perquè em ballava el cap.  (Jean Luc - Els Amics de les Arts)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/3/38/CsvDelimited001.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/3/38/CsvDelimited001.svg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Although you can think that &lt;b&gt;Comma-Separated Values&lt;/b&gt; (&lt;i&gt;CSV&lt;/i&gt;) files are simple files where each value is separated by commas, it is far from reality. The most important part of &lt;i&gt;CSV&lt;/i&gt; files are delimiters, and one can think that the delimiter, as type name suggests, is &lt;i&gt;comma&lt;/i&gt;. But this assumption is not always true and &lt;i&gt;CSV&lt;/i&gt; is often applied to files using other delimiters. Typical example is found in countries where &lt;i&gt;comma&lt;/i&gt; (&lt;i&gt;,&lt;/i&gt;) is used as decimal separator, because you would have no way to discern between decimal number or separator, &lt;i&gt;semicolon&lt;/i&gt; (&lt;i&gt;;&lt;/i&gt;) is used.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If your application is distributed across different countries and your application should support &amp;nbsp;&lt;b&gt;Comma-Separated Values&lt;/b&gt; files, then you should take care about this important fact.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's see how can we resolve this problem so we can read &lt;i&gt;CSV&lt;/i&gt; files depending on country.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For reading &lt;i&gt;CSV&lt;/i&gt; files we are going to use &lt;a href="http://opencsv.sourceforge.net/"&gt;open&lt;i&gt;CSV&lt;/i&gt;&lt;/a&gt;&amp;nbsp;library. This &lt;i&gt;API&lt;/i&gt; contains one class for reading &lt;i&gt;CSV&lt;/i&gt; files (&lt;i&gt;CsvReader&lt;/i&gt;) and another for writing (&lt;i&gt;CsvWriter&lt;/i&gt;). By default it uses &lt;i&gt;comma&lt;/i&gt; as column delimiter, but you can also inform which delimiter character must be used.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So the problem is how to know which delimiter we should use. And for resolving this problem we can use &lt;i&gt;DecimalFormatSymbols&lt;/i&gt; class. This class represents the set of symbols needed to format numbers.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;DecimalFormatSymbols&lt;/i&gt; has a method called&lt;i&gt; getDecimalSeparator()&lt;/i&gt; that as his name suggests returns a decimal symbol, &lt;i&gt;comma&lt;/i&gt; (&lt;i&gt;,&lt;/i&gt;) in case of countries like&amp;nbsp;&lt;i&gt;Germany&lt;/i&gt;, and &lt;i&gt;dot&lt;/i&gt; (&lt;i&gt;.&lt;/i&gt;) in case &lt;i&gt;US &lt;/i&gt;for example. So with a simple ternary you could know which delimiter is used in &lt;i&gt;CSV&lt;/i&gt; files depending on &lt;i&gt;locale&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1337436.js?file=Csv.java"&gt;&lt;/script&gt;&lt;br /&gt;So final class will look like:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1341282.js?file=CsvParserFactory.java"&gt;&lt;/script&gt;&lt;br /&gt;And previous factory can be instantiated with &lt;i&gt;Spring&lt;/i&gt; and injecting delimiter, using &lt;i&gt;Spring Expression&lt;/i&gt; module.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1341286.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;See that thanks of&amp;nbsp;&lt;i&gt;Spring Expression&lt;/i&gt; delimiter is injected directly into class.&lt;br /&gt;&lt;br /&gt;I think it is not difficult to implement an application that can read&amp;nbsp;&lt;b&gt;Localized Comma-Separated Values &lt;/b&gt;files, and can avoid having problems when application is distributed around the world.&lt;br /&gt;&lt;br /&gt;Full Code:&amp;nbsp;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/csv.zip"&gt;https://github.com/downloads/maggandalf/Blog-Examples/csv.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=A3Yl3Fsj7tw&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=A3Yl3Fsj7tw&amp;amp;feature=related&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2590960457860604589?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2590960457860604589/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2590960457860604589' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2590960457860604589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2590960457860604589'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/11/i-en-una-paret-al-fons-impres-en-blanc.html' title='I en una paret al fons imprès en blanc i negre hi havia un pòster d&apos;en Godard. Potser ell em podria dir-me perquè em ballava el cap.  (Jean Luc - Els Amics de les Arts)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-4847776575515915258</id><published>2011-11-02T08:43:00.006+01:00</published><updated>2011-11-02T08:43:59.443+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ServiceLoaderFactoryBean'/><category scheme='http://www.blogger.com/atom/ns#' term='META-INF/services'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGI'/><category scheme='http://www.blogger.com/atom/ns#' term='JPF'/><category scheme='http://www.blogger.com/atom/ns#' term='comma-separated values'/><category scheme='http://www.blogger.com/atom/ns#' term='ServiceListFactoryBean'/><category scheme='http://www.blogger.com/atom/ns#' term='ServiceFactoryBean'/><category scheme='http://www.blogger.com/atom/ns#' term='ServiceLoader'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk services'/><title type='text'>En ti puedo ver la libertad, Tu me haces sentir que puedo volar, Y se que aquí es mi lugar, Y se que a ti yo quiero amar (Cuando Me Miras Asi - Cristian Castro)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm1.static.flickr.com/50/109221859_36b57aaa3d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://farm1.static.flickr.com/50/109221859_36b57aaa3d.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;From &lt;i&gt;ServiceLoader javadoc&lt;/i&gt;: A service is a well-known set of interfaces and classes. A &lt;b&gt;service provider&lt;/b&gt; is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself.&lt;/blockquote&gt;&lt;br /&gt;Since &lt;i&gt;JDK 6&lt;/i&gt;, a simple &lt;b&gt;service-provider&lt;/b&gt; loading facility is implemented. As is suggested it is simple, you cannot understand that implementation as a complex system for implementing plugins for your application, but can help you in many situations where you want &amp;nbsp;implementations of a service could be discovered by other module automatically.&lt;br /&gt;&lt;br /&gt;What I really like about using &lt;b&gt;JDK Services&lt;/b&gt; is that your services do not have any dependency to any class.&amp;nbsp;Moreover for registering a new implementation of a service, you just have to put &lt;i&gt;jar&lt;/i&gt; file into &lt;i&gt;classpath&lt;/i&gt; and nothing more.&lt;br /&gt;&lt;br /&gt;Now I will explain the service we are going to implement, and then I will show you how to code it.&lt;br /&gt;&lt;br /&gt;We want to implement a system that depending on kind of structured input (comma-separated value, tab-separated value, ...) returns a &lt;i&gt;String[]&lt;/i&gt; of each value; so for example you can receive input &lt;i&gt;a,b,c,d&lt;/i&gt; or &lt;i&gt;1&amp;lt;tab&amp;gt;2&amp;lt;tab&amp;gt;3&amp;lt;tab&amp;gt;4&lt;/i&gt; and the system should return an array with &amp;nbsp;&lt;i&gt;[a, b, c, d]&lt;/i&gt; or &lt;i&gt;[1, 2, 3, 4]&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;So our system will have three &lt;i&gt;Java &lt;/i&gt;projects.&lt;br /&gt;&lt;br /&gt;One defining service contract (an &lt;i&gt;interface&lt;/i&gt;) and, because of teaching purpose, a main class where internet media type, for example &lt;i&gt;text/csv,&lt;/i&gt;&amp;nbsp;is received with input data. Then using a factory class that I have created, it will ask which registered service can transform &lt;i&gt;input &lt;/i&gt;to&lt;i&gt; String[]&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;And two projects each one implementing a service following defined contract, one for &lt;i&gt;comma-separated values&lt;/i&gt; and another one for &lt;i&gt;tab-separated values&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Let's see the code:&lt;br /&gt;&lt;br /&gt;Main project (&lt;i&gt;reader&lt;/i&gt;) is composed by an &lt;i&gt;interface&lt;/i&gt;, a &lt;i&gt;main&lt;/i&gt; class and a &lt;i&gt;factory &lt;/i&gt;class.&lt;br /&gt;&lt;br /&gt;The most important part is &lt;i&gt;Decode &lt;/i&gt;interface which defines service contract.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1330491.js?file=Decode.java"&gt;&lt;/script&gt;&lt;br /&gt;Two operations are defined, one that returns if service supports given input, and another that transforms data to &lt;i&gt;String[]&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;DecodeFactory&lt;/i&gt; class is responsible for finding an implementation service that supports required encoding. In fact, this class encapsulates &lt;i&gt;java.util.ServiceLoader&lt;/i&gt; calls. &lt;i&gt;ServiceLoader &lt;/i&gt;class is in charge of load registered services.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1330496.js?file=DecodeFactory.java"&gt;&lt;/script&gt;&lt;br /&gt;At line 3 we are loading all services that are registered in classpath. At line 7 we only iterate through all services asking if given encoding name is supported.&lt;br /&gt;&lt;br /&gt;And finally main class.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1330497.js?file=App.java"&gt;&lt;/script&gt;&lt;br /&gt;And now if you run this class with &lt;i&gt;java -jar reader.jar "text/cvs" "a, b, c, d"&lt;/i&gt;, an &lt;i&gt;UnsupportedEncodingException &lt;/i&gt;will be thrown. Now we are going to implement our first service. Note that reader project will not be modified nor recompiled.&lt;br /&gt;&lt;br /&gt;First service we are going to implement is one that can support &lt;i&gt;comma-separated values&lt;/i&gt; encoding. Only one class and one file are important.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;CSV &lt;/i&gt;class is an implementation of &lt;i&gt;Decode &lt;/i&gt;interface and transforms comma-separated values.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1330499.js?file=CSVDecoder"&gt;&lt;/script&gt;&lt;br /&gt;As you can see a simple &lt;i&gt;StringTokenizer &lt;/i&gt;class. Only take care that this class is &lt;i&gt;Locale &lt;/i&gt;sensitive, countries where comma (,) is used as decimal delimiter, separation character is semicolon (;).&lt;br /&gt;&lt;br /&gt;And next important file is a file that is placed into &lt;i&gt;META-INF.&amp;nbsp;&lt;/i&gt;This file contains a pointer to service implementation class.&lt;br /&gt;&lt;br /&gt;This file should be in &lt;i&gt;META-INF/services&lt;/i&gt; and should be called as interface full qualified name. In this case &lt;i&gt;org.alexsotob.reader.Decode&lt;/i&gt;. And its content should be service implementation full qualified name.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1330501.js?file=org.alexsotob.reader.Decode"&gt;&lt;/script&gt;&lt;br /&gt;And now you can package this project, and you can reexecute &lt;i&gt;reader &lt;/i&gt;project but with generated &lt;i&gt;jar&lt;/i&gt; (&lt;i&gt;csv.jar&lt;/i&gt;) into &lt;i&gt;classpath&lt;/i&gt;. And now output will be an array with &lt;i&gt;a, b, c and d&lt;/i&gt; characters instead of unsupported exception.&lt;br /&gt;&lt;br /&gt;See that reader project has not been modified and its behaviour has been changed. Now you can develop new implementations for decoding new inputs, and you should only take care of copying them into classpath.&lt;br /&gt;&lt;br /&gt;Only take care that all services should have a default constructor with no arguments.&lt;br /&gt;&lt;br /&gt;And for those who use &lt;i&gt;Spring Framework&lt;/i&gt;, &lt;b&gt;Services &lt;/b&gt;are also supported through three different &lt;i&gt;FactoryBeans&lt;/i&gt;, &lt;i&gt;ServiceFactoryBean&lt;/i&gt;, &lt;i&gt;ServiceListFactoryBean&lt;/i&gt;, &lt;i&gt;ServiceLoaderFactoryBean&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As I have noted at start of this post, &lt;b&gt;JDK services&lt;/b&gt; is a simple (yet powerful) solution if you need to create a simple plugins system. In my case it has been enough with &lt;b&gt;JDK services,&lt;/b&gt;&amp;nbsp;and I have never required more complex structure; but in case you are thinking about a complete plugin solution you can use &lt;i&gt;JPF &lt;/i&gt;that offers a solution like &lt;i&gt;Eclipse plugins&lt;/i&gt;, or even &lt;i&gt;OSGI&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I wish you have found this post useful and now you know (if you didn't know yet), an easy solution to develop modules that are plugged and play.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Download Main Project:&amp;nbsp;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/reader.zip"&gt;https://github.com/downloads/maggandalf/Blog-Examples/reader.zip&lt;/a&gt;&lt;br /&gt;Download Comma-Separated Values Service Project:&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/csvDec.zip"&gt;&amp;nbsp;https://github.com/downloads/maggandalf/Blog-Examples/csvDec.zip&lt;/a&gt;&lt;br /&gt;Download Tab-Separated Values Service Project:&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/tsvDec.zip"&gt;&amp;nbsp;https://github.com/downloads/maggandalf/Blog-Examples/tsvDec.zip&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=5cV_sIdpXeA&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=5cV_sIdpXeA&amp;amp;feature=related&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-4847776575515915258?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/4847776575515915258/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=4847776575515915258' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4847776575515915258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4847776575515915258'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/11/en-ti-puedo-ver-la-libertad-tu-me-haces.html' title='En ti puedo ver la libertad, Tu me haces sentir que puedo volar, Y se que aquí es mi lugar, Y se que a ti yo quiero amar (Cuando Me Miras Asi - Cristian Castro)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/50/109221859_36b57aaa3d_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-8549214229180570074</id><published>2011-10-25T08:11:00.001+02:00</published><updated>2011-10-25T08:11:37.307+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration tests'/><category scheme='http://www.blogger.com/atom/ns#' term='mock'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='injecting mocks'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='mockito'/><category scheme='http://www.blogger.com/atom/ns#' term='StaticApplicationContext'/><title type='text'>Soy el rey de la mar tiburón Que te come a besos Pero yo soy el rey del mar tiburón  El que te come mi amor (El Rey Tiburón - Maná))</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://errtheblog.com/static/images/inject.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="http://errtheblog.com/static/images/inject.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Today I was googling about &lt;b&gt;mocking &lt;/b&gt;when I have found next &lt;a href="http://stackoverflow.com/questions/4278788/injecting-mock-beans-into-spring-context-for-testing"&gt;question&lt;/a&gt;:&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;"Injecting mock beans into spring context for testing. What I want to be able to do is via the HotswappableTargetSource override the bean definitions of select beans in my application context with my test versions and then run the test.&lt;br /&gt;Then for each test case I'd like to specify which beans I want to be hot swappable and then each test must be able to create its own mock versions and swap those in, and be able to swap back again."&lt;/blockquote&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And there you can find a solution using &lt;i&gt;ProxyFactoryBean &lt;/i&gt;and &lt;i&gt;HotSwappableTargetSource&lt;/i&gt;. Well it is a solution for me a bit complicated, if I should do the same I would do using &lt;b&gt;StaticApplicationContext &lt;/b&gt;class, because from my point of view, environment is more controlled and easy to understand. Of course the easiest solution is using &lt;i&gt;Spring 3.1 Profile feature&lt;/i&gt;, but meanwhile it is a &lt;i&gt;milestone/RC&amp;nbsp;&lt;/i&gt;or simply because you will not be able to change &lt;i&gt;Spring &lt;/i&gt;version, I will show you how to use &lt;b&gt;StaticApplicationContext &lt;/b&gt;and how to inject &lt;b&gt;mocked beans&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;StaticApplicationContext &lt;/b&gt;is an implementation of &lt;i&gt;ApplicationContext &lt;/i&gt;interface which supports programmatic registration of beans and messages, rather than reading bean definitions from external configuration sources.&amp;nbsp;&lt;b&gt;StaticApplicationContext &lt;/b&gt;has been created mainly for testing purpose. To solve the problem &amp;nbsp;we focus, some of registered beans will be the "&lt;i&gt;real&lt;/i&gt;" beans, but others will be &lt;b&gt;mocked beans&lt;/b&gt; with all their interactions.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For this example &lt;b&gt;Mockito &lt;/b&gt;has been &lt;a href="http://alexsotob.blogspot.com/2010/03/she-spends-her-last-dollar-for-bottle.html"&gt;used&lt;/a&gt;. Let's see some code.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Imagine you have an application that should create users into a database. I suppose we would have a &lt;i&gt;UserDao &lt;/i&gt;class for communicating with database and a &lt;i&gt;UserService &lt;/i&gt;class to aggregate user operations. Moreover &lt;i&gt;UserService &lt;/i&gt;class would not be alone, would be used in several modules; in fact all modules that requires user information.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now it is time for testing. &lt;i&gt;Unit &lt;/i&gt;test is simple, when you want to test &lt;i&gt;UserService &lt;/i&gt;you set a mock of &lt;i&gt;UserDao&lt;/i&gt;. Here no problem with &lt;i&gt;Spring &lt;/i&gt;because it has not started to play yet.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But when you want to test whole system, may be you want that low-level classes like &lt;i&gt;UserDao &lt;/i&gt;be mocked and also you want to run tests with&amp;nbsp;&lt;b&gt;Spring &lt;/b&gt;capabilities (for example developed &lt;i&gt;BeanPostProcessors&lt;/i&gt;, &lt;i&gt;Messaging&lt;/i&gt;, &lt;i&gt;Spring AOP&lt;/i&gt;, ...). For solving this case you can create a test &lt;b&gt;Spring &lt;/b&gt;context file, then you can create required mocks and set them manually. But as you can suppose another approach is using &lt;b&gt;StaticApplicationContext&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1308879.js?file=UserServiceBehaviour.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;The most important line is number 12 where we are injecting &lt;i&gt;UserDao &lt;/i&gt;mock into &lt;b&gt;Spring &lt;/b&gt;context. See that at line 11 we are also registering autowired annotation post processor. If &amp;nbsp;it was not registered, classes annotated with &lt;i&gt;@Autowired&lt;/i&gt; would not work.&lt;br /&gt;&lt;br /&gt;In current post I have explained how to inject mock beans into &lt;i&gt;Spring Context &lt;/i&gt;for testing. Personally I don't like mixing mock beans with real beans in integration tests, I prefer only real beans in this kind of tests; but I can understand that in big modules where a system has multiple subsystems can be useful to isolate some modules from test.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For example in my department we are developing clinical instruments which as you can imagine contains complex modules all related between them. When we are running some integration test, we are not available to connect to device, so communication module could be mocked. But in our case we are running integration tests with an emulator, but mocking some parts of our system could be another solution.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The example in this case is so simple I know, but in more complex scenarios you can create an application context referencing to real beans and passing it to &lt;b&gt;StaticApplicationContext &lt;/b&gt;constructor so in static application context you only register mock beans.&lt;br /&gt;&lt;br /&gt;This this would look:&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1311501.js?file=UserServiceBehaviour.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Well now I have showed you how to register mock beans into a &lt;b&gt;Spring &lt;/b&gt;Application Context using &lt;b&gt;StaticApplicationContext &lt;/b&gt;instead of using &lt;i&gt;HotSwappableTargetSource&lt;/i&gt;.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;Thank you very much for reading my blog.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/sac.zip"&gt;Download &lt;/a&gt;Code.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=Njbm_MABQJE&amp;amp;ob=av2n"&gt;http://www.youtube.com/watch?v=Njbm_MABQJE&amp;amp;ob=av2n&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-8549214229180570074?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/8549214229180570074/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=8549214229180570074' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8549214229180570074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8549214229180570074'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/10/soy-el-rey-de-la-mar-tiburon-que-te.html' title='Soy el rey de la mar tiburón Que te come a besos Pero yo soy el rey del mar tiburón  El que te come mi amor (El Rey Tiburón - Maná))'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2768597505637736505</id><published>2011-10-17T14:22:00.000+02:00</published><updated>2011-10-17T14:22:44.982+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring events'/><category scheme='http://www.blogger.com/atom/ns#' term='custom SimpleApplicationEventMulticaster'/><category scheme='http://www.blogger.com/atom/ns#' term='SimpleApplicationEventMulticaster'/><category scheme='http://www.blogger.com/atom/ns#' term='ApplicationListener'/><category scheme='http://www.blogger.com/atom/ns#' term='ThreadPoolExecutor'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='observer observable pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='ApplicationEvent'/><title type='text'>Una terra promessa Un mondo diverso Dove crescere i nostri pensieri Noi non ci fermeremo Non ci stancheremo di cercare Il nostro camino (Terra Promessa - Eros Ramazzotti)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.gdargaud.net/Photo/BaseJump/BaseVerdon03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://www.gdargaud.net/Photo/BaseJump/BaseVerdon03.jpg" width="209" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;INTRODUCTION&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style="text-align: justify;"&gt;The essence of the &lt;b&gt;Observer Pattern&lt;/b&gt; is to "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically." &lt;i&gt;GoF&lt;/i&gt;. &lt;b&gt;Observer pattern &lt;/b&gt;is a subset of &lt;i&gt;publish/subscribe&lt;/i&gt; pattern which allows a number of observer objects to see an event.&amp;nbsp;&lt;/blockquote&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;This pattern can be used in different situations, but in summary we can say that &lt;b&gt;Observer &lt;/b&gt;pattern can be applied when an object should be able to notify messages to other objects, and you don't want these objects &amp;nbsp;being tightly coupled. In my case I have used this pattern when an asynchronous event should be notified to one or more graphical component.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;This pattern can be implemented using an adhoc solution or using &lt;i&gt;java.util.Observer/Observable &lt;/i&gt;classes. But my projects are always developed with &lt;b&gt;Spring &lt;/b&gt;whether they are &lt;i&gt;web &lt;/i&gt;or &lt;i&gt;desktop applications&lt;/i&gt;. So in current post I will explain how I implement &lt;b&gt;Observer &lt;/b&gt;pattern with &lt;b&gt;Spring&lt;/b&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;HANDS ON&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Event handling in &lt;i&gt;Spring&amp;nbsp;ApplicationContext &lt;/i&gt;is provided through &lt;i&gt;ApplicationEvent &lt;/i&gt;class and &lt;i&gt;ApplicationListener &lt;/i&gt;interface. If a bean that implements &lt;i&gt;ApplicationListener &lt;/i&gt;interface is deployed into the context, every time an &lt;i&gt;ApplicationEvent &lt;/i&gt;is published to container, &lt;i&gt;ApplicationListener &lt;/i&gt;receives it.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Spring &lt;/b&gt;comes with built-in events, like &lt;i&gt;ContextStartedEvent&lt;/i&gt;, &lt;i&gt;ContextStoppedEvent&lt;/i&gt;, but you can also create your own custom events.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;For developing your own events, three classes are required, &lt;i&gt;observer &lt;/i&gt;role, &lt;i&gt;observable &lt;/i&gt;role&amp;nbsp;and the &lt;i&gt;event&lt;/i&gt;. &lt;i&gt;Observers &lt;/i&gt;are those who receive events and must implement &lt;i&gt;ApplicationListener &lt;/i&gt;class. &lt;i&gt;Observable &lt;/i&gt;classes are responsible of publishing events and must implement &lt;i&gt;ApplicationEventPublisherAware&lt;/i&gt;. Finally &lt;i&gt;event &lt;/i&gt;class has to extend &lt;i&gt;ApplicationEvent&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;CODING&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;What I am going to implement is wikipedia example of &lt;i&gt;Observer &lt;/i&gt;pattern (&lt;a href="http://en.wikipedia.org/wiki/Observer_pattern#Example"&gt;http://en.wikipedia.org/wiki/Observer_pattern#Example&lt;/a&gt;) but using &lt;b&gt;Spring Events&lt;/b&gt; instead of &lt;i&gt;Observer/Observable&lt;/i&gt;&amp;nbsp;&lt;i&gt;Java &lt;/i&gt;classes. The example is a basic &lt;i&gt;publish/subscribe&lt;/i&gt; example where one String message is sent from one module to another one.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Let's create &lt;i&gt;MessageEvent&lt;/i&gt;. This event contains a String that represents the message we want to send. It is a simple class that extends from &lt;i&gt;ApplicationEvent&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;script src="https://gist.github.com/1287189.js?file=MessageEvent.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next class is the &lt;i&gt;Observable &lt;/i&gt;class. This class must implements&amp;nbsp;&lt;i&gt;ApplicationEventPublisherAware&lt;/i&gt;. This interface defines a setter method with &lt;i&gt;ApplicationEventPublisher &lt;/i&gt;as parameter. This parameter is used for publishing events.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In current implementation see that also implements &lt;i&gt;Runnable &lt;/i&gt;interface so user can create from console input, asynchronous messages. Most important line is 26 where an event is created and published.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;script src="https://gist.github.com/1287192.js?file=EventSource.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;The &lt;i&gt;Observer &lt;/i&gt;class is even simpler. Implements &lt;i&gt;ApplicationListener &lt;/i&gt;interface. Method &lt;i&gt;onApplicationEvent &lt;/i&gt;is called when an event is published. See that it is a generic interface, so no cast is required. This differs from&lt;i&gt; java.util.Observer&lt;/i&gt; class.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;script src="https://gist.github.com/1287195.js?file=ResponseHandler.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In application context file, you register both &lt;i&gt;ApplicationListener &lt;/i&gt;and &lt;i&gt;ApplicationEventPublisherAware &lt;/i&gt;beans.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And finally a main class to test the system. A thread is created to execute multiple&amp;nbsp;asynchronous&amp;nbsp;events.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1287227.js?file=MyApp.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;So start the program and write something to console. You will see something like:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;hello&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;Thread-0&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;Thread-0&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;MessageEvent [message=hello]&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;I have entered "&lt;i&gt;hello&lt;/i&gt;" message and &lt;u&gt;thread name of event publisher&lt;/u&gt; is printed. Then event is sent and &lt;u&gt;handler thread name&lt;/u&gt; is printed too. Finally the received event is shown. There is one thing that should call your attention. Both sender (&lt;i&gt;Observable&lt;/i&gt;) and receiver (&lt;i&gt;Observer&lt;/i&gt;) are executed in same thread; by default event listeners receive events synchronously. This means that &lt;i&gt;publishEvent()&lt;/i&gt; method, blocks until all listeners have finished processing the event. This approach has many advantages (for example reusing transaction contexts, ...), but in some cases you will prefer that each event is executed in new thread, &lt;b&gt;Spring &lt;/b&gt;also supports this strategy.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In &lt;b&gt;Spring&lt;/b&gt;, class responsible of managing events is &lt;i&gt;SimpleApplicationEventMulticaster&lt;/i&gt;. This class multicasts all events to all registered listeners, leaving it up to the listeners to ignore events that they are not interested in. Default behaviour is that all listeners are invoked in calling thread.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Now I am going to explain how &lt;b&gt;Spring Event Architecture&lt;/b&gt; is initialized and how you can modify. By default when &lt;i&gt;ApplicationContext &lt;/i&gt;is&lt;i&gt;&amp;nbsp;&lt;/i&gt;started up, it calls &lt;i&gt;initApplicationEventMulticaster &lt;/i&gt;method. This method verify if exists a bean with id &lt;i&gt;applicationEventMulticaster &lt;/i&gt;of type &lt;i&gt;ApplicationEventMulticaster&lt;/i&gt;. If it is the case defined &lt;i&gt;ApplicationEventMulticaster &lt;/i&gt;is used, if not a new &lt;i&gt;SimpleApplicationEventMulticaster &lt;/i&gt;with default configuration is created.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;SimpleApplicationEventMulticaster &lt;/i&gt;has a &lt;i&gt;setTaskExecutor &lt;/i&gt;which can be used for specifying which &lt;i&gt;java.util.concurrent.Executor&lt;/i&gt; will execute events. So if you want that each event is executed in a different thread, a good approach would be using a &lt;i&gt;ThreadPoolExecutor&lt;/i&gt;. As explained in last paragraph, now we must explicitly define &lt;i&gt;SimpleApplicationEventMulticaster &lt;/i&gt;instead of&lt;i&gt;&amp;nbsp;&lt;/i&gt;using default ones.&amp;nbsp;Let's implement:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;script src="https://gist.github.com/1287229.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;First of all &lt;i&gt;SimpleApplicationEventMulticaster &lt;/i&gt;must be defined as a bean with id &lt;i&gt;applicationEventMulticaster&lt;/i&gt;. Then task pool is set, and we rerun our main class. And output will be:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;hello&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;Thread-1&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;pool-1&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;MessageEvent [message=hello]&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Note that now sender and receiver thread is different.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;And of course you can create your own &lt;i&gt;ApplicationEventMulticaster &lt;/i&gt;for more complex operations. You just have to implement &lt;i&gt;ApplicationEventMulticaster &lt;/i&gt;and defining it with&amp;nbsp;&lt;i&gt;applicationEventMulticaster&amp;nbsp;&lt;/i&gt;bean name, and events will be executed depending on your own strategy.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Hope that now your &lt;b&gt;Spring &lt;/b&gt;desktop applications can take full advantage of &lt;b&gt;Spring &lt;/b&gt;events for separating modules.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/springobserverpattern.zip"&gt;Download Code.&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=GfnkcKiocRw"&gt;http://www.youtube.com/watch?v=GfnkcKiocRw&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2768597505637736505?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2768597505637736505/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2768597505637736505' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2768597505637736505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2768597505637736505'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/10/una-terra-promessa-un-mondo-diverso.html' title='Una terra promessa Un mondo diverso Dove crescere i nostri pensieri Noi non ci fermeremo Non ci stancheremo di cercare Il nostro camino (Terra Promessa - Eros Ramazzotti)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5652710511820879793</id><published>2011-10-11T08:24:00.001+02:00</published><updated>2011-10-11T08:52:50.534+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restclient'/><category scheme='http://www.blogger.com/atom/ns#' term='YamlHttpMessageConverter'/><category scheme='http://www.blogger.com/atom/ns#' term='jackson'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='snakeyaml'/><category scheme='http://www.blogger.com/atom/ns#' term='yaml'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring http message converter'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='jaxb'/><category scheme='http://www.blogger.com/atom/ns#' term='spring MVC rest'/><category scheme='http://www.blogger.com/atom/ns#' term='HttpMessageConverter'/><title type='text'>You're so sexy sex sex sexy. Feel me now and stop the conversation. No, no, no don't stop the desire no, No, no, no, no! (Sexy - French Affair)</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.importcatalytic.com/images/catalytic_coverter_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="http://www.importcatalytic.com/images/catalytic_coverter_2.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;INTRODUCTION&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In current post I am going to explain how to implement and register a custom &lt;b&gt;Spring MVC&lt;/b&gt; &lt;b&gt;HttpMessageConverter &lt;/b&gt;object. Specifically a converter that binds objects to &lt;b&gt;Yaml &lt;/b&gt;protocol. As starting point I am going to use the &lt;b&gt;Rest &lt;/b&gt;application I implemented in previous &lt;a href="http://alexsotob.blogspot.com/2011/10/cant-you-see-it-all-makes-perfect-sense.html"&gt;post&lt;/a&gt;. That application is a simple &lt;b&gt;Restful &lt;/b&gt;application where &lt;i&gt;XML &lt;/i&gt;and &lt;i&gt;JSON&lt;/i&gt; (&lt;b&gt;Spring MVC&lt;/b&gt; already support them) are used. Because &lt;b&gt;Spring MVC&lt;/b&gt; does not implement &lt;b&gt;YamlMessageConverter&lt;/b&gt;, I am going to explain how to transform previous application from supporting &lt;i&gt;XML &lt;/i&gt;and &lt;i&gt;JSON &lt;/i&gt;to support &lt;b&gt;Yaml&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Yaml&amp;nbsp;&lt;/b&gt;is a human-readable data serialization format that takes concepts from programming languages such as &lt;i&gt;C&lt;/i&gt;, &lt;i&gt;Perl&lt;/i&gt;, and &lt;i&gt;Python&lt;/i&gt;, and ideas from &lt;i&gt;XML &lt;/i&gt;and the data format of electronic mail (&lt;i&gt;RFC 2822&lt;/i&gt;).&lt;/div&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/snakeyaml/"&gt;&lt;b&gt;SnakeYAML&lt;/b&gt;&amp;nbsp; &lt;/a&gt;is a &lt;b&gt;YAML &lt;/b&gt;parser and emitter for the &lt;i&gt;Java &lt;/i&gt;programming language, and will be used to implement our message converter.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;DESIGN&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Let's start with a &lt;i&gt;UML &lt;/i&gt;class diagram of &lt;b&gt;HttpMessageConverter &lt;/b&gt;that are going to be implemented.&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-hKRMxzZrfQI/TosQyYk9F6I/AAAAAAAAGAY/SY7cEwsT3dM/s1600/yamluml.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-hKRMxzZrfQI/TosQyYk9F6I/AAAAAAAAGAY/SY7cEwsT3dM/s320/yamluml.JPG" width="310" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;HttpMessageConverter &lt;/b&gt;is a base interface that must be implemented. It is a strategy interface that specifies methods to convert objects from and to &lt;i&gt;HTTP &lt;/i&gt;requests and responses. &lt;b&gt;AbstractHttpMessageConverter &lt;/b&gt;is the abstract base class for most &lt;b&gt;HttpMessageConverter &lt;/b&gt;implementation (both provided by &lt;i&gt;springframework&lt;/i&gt;), and is our base class.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First developed class is an abstract class called &lt;b&gt;AbstractYamlHttpMessageConverter&lt;/b&gt;. This class is responsible of generic operations that "&lt;i&gt;should&lt;/i&gt;" be required by all &lt;b&gt;Yaml &lt;/b&gt;parsers/emitters. In my case it deals with &lt;i&gt;charset &lt;/i&gt;options, and transforms &lt;i&gt;HttpInputMessage &lt;/i&gt;and &lt;i&gt;HttpOutputMessage &lt;/i&gt;to &lt;i&gt;java.io.InputStreamWriter&lt;/i&gt; and &lt;i&gt;java.io.OutputStreamWriter&lt;/i&gt;. In fact it acts as a &lt;a href="http://en.wikipedia.org/wiki/Template_method_pattern"&gt;Template Pattern&lt;/a&gt; to read and write operations (&lt;i&gt;readInternal &lt;/i&gt;and &lt;i&gt;writeInternal &lt;/i&gt;methods).&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Next abstract class is &lt;b&gt;AbstractSnakeYamlHttpMessageConverter&lt;/b&gt;. This class is a base class for &lt;b&gt;HttpMessageConverters &lt;/b&gt;that use &lt;b&gt;SnakeYaml &lt;/b&gt;as &lt;b&gt;Yaml&amp;nbsp;&lt;/b&gt;binder. This class gets an instance of &lt;i&gt;Yaml &lt;/i&gt;class (central class of &lt;b&gt;SnakeYaml&lt;/b&gt; project).&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And finally &lt;b&gt;JavaBeanSnakeYamlHttpMessageConverter&lt;/b&gt;. This class uses &lt;b&gt;SnakeYaml &lt;/b&gt;&lt;i&gt;JavaBeans &lt;/i&gt;features for converting from object to &lt;b&gt;Yaml &lt;/b&gt;and viceversa. &lt;b&gt;SnakeYaml&lt;/b&gt; does not support annotations like &lt;i&gt;Jackson &lt;/i&gt;(JSON) or &lt;i&gt;Jaxb &lt;/i&gt;(XML), but if some day this feature is implemented, we should create a new class extending from &lt;b&gt;AbstractSnakeYamlHttpMessageConverter &lt;/b&gt;with required change.&lt;/div&gt;&lt;br /&gt;&lt;b&gt;CODE&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;First of all is adding a new dependency to &lt;i&gt;pom&lt;/i&gt;. In this case &lt;b&gt;SnakeYaml&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275298.js?file=pom.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Then three classes previously exposed should be developed.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;First class is a generic &lt;b&gt;Yaml &lt;/b&gt;converter where we are setting accepted media type, in this case &lt;i&gt;application/yaml&lt;/i&gt;, and creating a &lt;i&gt;Reader &lt;/i&gt;and &lt;i&gt;Writer &lt;/i&gt;with required &lt;i&gt;Charset&lt;/i&gt;. We are leaving to children classes the&amp;nbsp;responsibility&amp;nbsp;of implementing read and write code.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275306.js?file=AbstractYamlHttpMessageConverter.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Next class is specific of &lt;b&gt;API &lt;/b&gt;that will be used to bind classes to messages, in this case &lt;b&gt;SnakeYaml&lt;/b&gt;. This class will be responsible of creating an instance of &lt;b&gt;Yaml &lt;/b&gt;class&amp;nbsp;(from&amp;nbsp;&lt;b&gt;SnakeYaml&lt;/b&gt;). As is warned in &lt;a href="http://snakeyamlrepo.appspot.com/releases/1.9/site/apidocs/index.html"&gt;http://snakeyamlrepo.appspot.com/releases/1.9/site/apidocs/index.html&lt;/a&gt; each thread must have its own instance; for this reason a &lt;i&gt;ThreadLocal &lt;/i&gt;is used to carry out this restriction.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275313.js?file=AbstractSnakeYamlHttpMessageConverter.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Final class is an implementation of read/write methods using &lt;b&gt;SnakeYaml&lt;/b&gt;. As I have explained previously this class has a meaning because allows us changing &lt;b&gt;SnakeYaml &lt;/b&gt;binding strategy (for example to annotation approach) and only worries to rewrite read/write operations.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275319.js?file=JavaBeanSnakeYamlHttpMessageConverter.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now it is time to register created message converter to &lt;b&gt;AnnotationMethodHandlerAdapter&lt;/b&gt;. First thing you should do is not to use &amp;lt;mvc:annotation-driven&amp;gt;. This annotation registers default message converters and you are not able to modify them. So first step is comment or remove &lt;i&gt;annotation-driven&lt;/i&gt;. Next step is declare &lt;i&gt;DefaultAnnotationHandlerMapping &lt;/i&gt;bean and &lt;i&gt;AnnotationMethodHandlerAdapter &lt;/i&gt;which registers http message converters. In our case only &lt;b&gt;Yaml &lt;/b&gt;http message converter is added.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275329.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;RUNNING&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And now you can try application. Deploy it on a server, and using for example &lt;i&gt;Rest Client&lt;/i&gt;, try http://localhost:8080/RestServer/characters/1 and you will receive a response like:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_hI_BvvL-Es/TosQbdhrnzI/AAAAAAAAGAU/R9RqGgNJXuw/s1600/yamlResp.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://2.bp.blogspot.com/-_hI_BvvL-Es/TosQbdhrnzI/AAAAAAAAGAU/R9RqGgNJXuw/s320/yamlResp.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you want you can use &lt;i&gt;POST &lt;/i&gt;instead of &lt;i&gt;GET &lt;/i&gt;to insert a new &lt;i&gt;Character &lt;/i&gt;to our &lt;i&gt;Map&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1275342.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As you can see developing a &lt;b&gt;Spring MVC HTTP Message Converter&lt;/b&gt; is so easy, in fact you must implement two basic operations, when a resource can be read or written and resource conversion.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Hope you found this post useful.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/restserveryaml.zip"&gt;Download code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=J8cr_CpuFO0"&gt;http://www.youtube.com/watch?v=J8cr_CpuFO0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5652710511820879793?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5652710511820879793/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5652710511820879793' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5652710511820879793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5652710511820879793'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/10/youre-so-sexy-sex-sex-sexy-feel-me-now.html' title='You&apos;re so sexy sex sex sexy. Feel me now and stop the conversation. No, no, no don&apos;t stop the desire no, No, no, no, no! (Sexy - French Affair)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-hKRMxzZrfQI/TosQyYk9F6I/AAAAAAAAGAY/SY7cEwsT3dM/s72-c/yamluml.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-1520077866626903656</id><published>2011-10-04T09:09:00.000+02:00</published><updated>2011-10-04T09:09:51.829+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restclient'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='jackson'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='yaml'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='jaxb'/><category scheme='http://www.blogger.com/atom/ns#' term='spring MVC rest'/><category scheme='http://www.blogger.com/atom/ns#' term='restful web services'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Can't you see, It all makes perfect sense, Express in dollars and cents, Pounds shillings and pents, Can't you see, It all makes perfect sense (Perfect Sense Part II - Roger Waters)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Mr_y1USLz8k/ToMtm-hfrZI/AAAAAAAAGAI/TOcUHEYXW8g/s1600/sabbath_rest.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="233" src="http://4.bp.blogspot.com/-Mr_y1USLz8k/ToMtm-hfrZI/AAAAAAAAGAI/TOcUHEYXW8g/s320/sabbath_rest.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;b&gt;REST INTRODUCTION&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;From Wikipedia:&lt;b&gt; REST-style&lt;/b&gt; architectures consist of clients and servers. Clients initiate requests to servers; servers process requests and return appropriate responses. Requests and responses are built around the transfer of representations of resources. A resource can be essentially any coherent and meaningful concept that may be addressed.&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you have read the most important thing in &lt;b&gt;Rest &lt;/b&gt;architecture is the existance of a resource. This resource &amp;nbsp;can be anything (typically required information requested by client) that can be identified with a global identifier (&lt;i&gt;URI&lt;/i&gt; in case of &lt;i&gt;HTTP&lt;/i&gt;). In order to manipulate these resources, client communicates using standard interfaces (like &lt;i&gt;HTTP&lt;/i&gt;) and exchange representations of these resources (using&amp;nbsp;&lt;i&gt;HTML&lt;/i&gt;, &lt;i&gt;XML&lt;/i&gt;, ...).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Note that &lt;b&gt;Rest&lt;/b&gt; does not force you to use any specific network protocol nor how resources are identified.&lt;br /&gt;&lt;br /&gt;For those who have never read about &lt;b&gt;Rest&lt;/b&gt; this description of &lt;b&gt;Rest&lt;/b&gt; architecture could seem something strange and bit complicated.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;A &lt;b&gt;RESTful&lt;/b&gt; web service is a simple web service implemented using &lt;i&gt;HTTP&lt;/i&gt; and the principles of &lt;b&gt;REST&lt;/b&gt;. &lt;i&gt;URI&lt;/i&gt; is defined as global identified, communication interface is HTTP and resource representation can be any valid Internet media type like &lt;i&gt;JSON&lt;/i&gt;, &lt;i&gt;XML&lt;/i&gt; or &lt;i&gt;YAML&lt;/i&gt;. The set of operations that can be executed to resources depend on &lt;i&gt;HTTP&lt;/i&gt; Methods and are (&lt;i&gt;GET&lt;/i&gt; - retrieving/listing, &lt;i&gt;PUT&lt;/i&gt; - replacing/updating, &lt;i&gt;POST&lt;/i&gt; - creating and &lt;i&gt;DELETE&lt;/i&gt; - deleting).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;HANDS ON WORK&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;Let's create our first &lt;b&gt;Rest&lt;/b&gt; application with help of &lt;b&gt;Spring MVC&lt;/b&gt;. Imagine an application that has a database of manga characters, and you want to provide a &lt;b&gt;Rest &lt;/b&gt;interface so clients can retrieve characters following a &lt;b&gt;RESTful &lt;/b&gt;strategy.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;First thing to do is identify the resource. In this case it is easy, "&lt;i&gt;a character&lt;/i&gt;". Next step is finding a &lt;i&gt;URI&lt;/i&gt; that determines unequivocally a character. Easy too &lt;i&gt;de facto&lt;/i&gt; rule can be applied here. This rule suggests that a unique &lt;i&gt;URI&lt;/i&gt; can be &amp;lt;host&amp;gt;/&amp;lt;applicationname&amp;gt;/&amp;lt;resourceName&amp;gt;s/&amp;lt;id&amp;gt; in our case to return (&lt;i&gt;GET&lt;/i&gt;) character with id 1 the URI would be "&lt;i&gt;http://localhost:8080/RestServer/characters/1&lt;/i&gt;". If no identifier is present all characters should be retrieved. If instead of &lt;i&gt;GET&lt;/i&gt;, &lt;i&gt;POST&lt;/i&gt; is used, a character with id "1" would be inserted. And finally decide which&lt;i&gt; Internet media type&lt;/i&gt; is required, in this case doesn't matter because we are implementing both client and server so initially &lt;i&gt;XML&lt;/i&gt; will be used.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;CODING&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's start with a simple&amp;nbsp;&lt;b&gt;Spring MVC&lt;/b&gt; application created with &lt;b&gt;Spring MVC&lt;/b&gt; template. Not much secret here, you will have a &lt;i&gt;servlet-context.xml&lt;/i&gt; where &lt;i&gt;component-scan&lt;/i&gt;, &lt;i&gt;annotation-driven&lt;/i&gt; and &lt;i&gt;InternalResourceViewResolver&lt;/i&gt; are registered.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1258604.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next step is defining &lt;i&gt;Character&lt;/i&gt; class. A simple &lt;i&gt;POJO&lt;/i&gt; with four attributes. Class is converted to its &lt;i&gt;XML&lt;/i&gt; representation using &lt;i&gt;Jaxb&lt;/i&gt; annotation. &amp;nbsp;&lt;i&gt;Jaxb&lt;/i&gt; allows developers to map &lt;i&gt;Java&lt;/i&gt; classes to &lt;i&gt;XML&lt;/i&gt; representations and viceversa.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1258608.js?file=Character.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally the most important class in &lt;b&gt;Spring MVC&lt;/b&gt;, "&lt;i&gt;The Controller&lt;/i&gt;". Controller will be the responsible of implementing required operations of &lt;i&gt;Character&lt;/i&gt; resource. In current case only &lt;i&gt;GET&lt;/i&gt; is implemented, the other operations would be similar. Let's see the code:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1258691.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First part is a map where all characters are stored. I have used this approach to not focus in data access. Then &lt;i&gt;findCharacter &lt;/i&gt;method that is called when &lt;i&gt;URI &lt;/i&gt;is &lt;i&gt;/characters/{characterId}&lt;/i&gt;. This is a &lt;i&gt;URI &lt;/i&gt;template and is a &lt;i&gt;URI&lt;/i&gt;-like string, containing one or more variable names, which can be accessed using &lt;i&gt;@PathVariable&lt;/i&gt; annotation. So when you are accessing to &lt;i&gt;/characters/1&lt;/i&gt; parameter &lt;i&gt;characterId&lt;/i&gt; is bound to &lt;i&gt;1&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Last important part is &lt;i&gt;@ResponseBody&lt;/i&gt; annotation. This annotation can be put on a method and indicates that the return type should be written straight to the &lt;i&gt;HTTP &lt;/i&gt;response body, and not placed in a &lt;i&gt;Model&lt;/i&gt;, or interpreted as a view name as standard behaviour of &lt;b&gt;Spring MVC&lt;/b&gt;. So&amp;nbsp;&lt;i&gt;findCharacter &lt;/i&gt;method returns a &lt;i&gt;Character &lt;/i&gt;object.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And that's all if you execute this code, and for example you enter &lt;i&gt;URI http://localhost:8080/RestServer/characters/1&lt;/i&gt; the output (using&lt;a href="http://code.google.com/p/rest-client/"&gt; RestClient UI&lt;/a&gt;) will be:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-DoKM4KSBsmg/ToSkzHzekAI/AAAAAAAAGAM/HOThgEYoUuc/s1600/restXML.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="323" src="http://4.bp.blogspot.com/-DoKM4KSBsmg/ToSkzHzekAI/AAAAAAAAGAM/HOThgEYoUuc/s640/restXML.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now is when you are wondering, ¿If I am returning a &lt;i&gt;Character &lt;/i&gt;object and output is a &lt;i&gt;XML&lt;/i&gt;, where is conversion between object and &lt;i&gt;XML&lt;/i&gt;? So easy, let me introduce a new concept: &lt;b&gt;HttpMessageConverters&lt;/b&gt;. &lt;b&gt;HttpMessageConverter &lt;/b&gt;is responsible for converting from &lt;i&gt;HTTP&lt;/i&gt; request message to an object and converting from an object to &lt;i&gt;HTTP &lt;/i&gt;response body. Next &lt;b&gt;HttpMessageConverters &lt;/b&gt;are registered by default:&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- ByteArrayHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- StringHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- ResourceHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- SourceHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- XmlAwareHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- Jaxb2RootElementHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;- MappingJacksonHttpMessageConverter&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;So now you understand why works perfectly. When you are returning &lt;i&gt;Character &lt;/i&gt;instance, &lt;b&gt;Jaxb2RootElementHttpMessageConverter &lt;/b&gt;using &lt;i&gt;canWrite &lt;/i&gt;method checks if class contains &lt;i&gt;XmlRootElement &lt;/i&gt;annotation. If class is annotated, write method is called. In this case &lt;i&gt;Jaxb &lt;/i&gt;marshaller is called, and &lt;i&gt;XML &lt;/i&gt;is returned. Same from &lt;i&gt;XML &lt;/i&gt;to object but using &lt;i&gt;Jaxb &lt;/i&gt;unmarshaller class.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So easy, no complicated configurations, no complicated mappings, no unclear code, and you only need to worry about your model objects, not in conversion. But let me introduce one change. Now instead of returning &lt;i&gt;XML &lt;/i&gt;we want to return &lt;i&gt;JSON&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Change could not be easier, add &lt;i&gt;Jackson&lt;/i&gt; library to &lt;i&gt;pom.xml&lt;/i&gt; and change &lt;i&gt;@XmlRootElement&lt;/i&gt; to &lt;i&gt;@JsonAutoDetect&lt;/i&gt;. And now &lt;b&gt;MappingJacksonHttpMessageConverter &lt;/b&gt;will handle this object and will transform &lt;i&gt;Character &lt;/i&gt;instance to &lt;i&gt;JSON &lt;/i&gt;protocol using &lt;i&gt;Jackson&lt;/i&gt; library. Only changing one line of code!!!&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now output will be:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/--9RWRSNSVzI/ToSk-WnAQuI/AAAAAAAAGAQ/Ho7R-GCDrfw/s1600/restJSON.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="398" src="http://2.bp.blogspot.com/--9RWRSNSVzI/ToSk-WnAQuI/AAAAAAAAGAQ/Ho7R-GCDrfw/s640/restJSON.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;b&gt;CONCLUSIONS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Of course this is a very simple application with only one operation, but it gives you an idea of how to develop &lt;b&gt;Restful &lt;/b&gt;web services using &lt;b&gt;Spring MVC.&lt;/b&gt;&amp;nbsp;It is a matter of time of writing all your required operations using same approach that I have used with &lt;b&gt;GET&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Arriving at this point I think that all of us have arrived to same conclusion. Annotations are really really powerful, and &lt;b&gt;Spring MVC&lt;/b&gt; fits perfectly for developing &lt;b&gt;RESTful &lt;/b&gt;web services.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See you next time.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=RiFC8nLfiUw"&gt;http://www.youtube.com/watch?v=RiFC8nLfiUw&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/restserver.zip"&gt;Download Code.&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-1520077866626903656?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/1520077866626903656/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=1520077866626903656' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1520077866626903656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1520077866626903656'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/10/cant-you-see-it-all-makes-perfect-sense.html' title='Can&apos;t you see, It all makes perfect sense, Express in dollars and cents, Pounds shillings and pents, Can&apos;t you see, It all makes perfect sense (Perfect Sense Part II - Roger Waters)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Mr_y1USLz8k/ToMtm-hfrZI/AAAAAAAAGAI/TOcUHEYXW8g/s72-c/sabbath_rest.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-4543987713840361451</id><published>2011-09-28T08:32:00.002+02:00</published><updated>2011-09-28T08:40:45.691+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='eis'/><category scheme='http://www.blogger.com/atom/ns#' term='message storage'/><category scheme='http://www.blogger.com/atom/ns#' term='claim check pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='mongodb'/><category scheme='http://www.blogger.com/atom/ns#' term='enterprise integration patterns'/><title type='text'>Ratti Ratti Sachi Maine Jaan Gavayi Hai, Nach Nach Koylo Pe Raat Bitayi Hai, Akhiyon Ki Neend Maine Phoonko Se Uda Di (Jai Ho - A.R. Rahman)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-kqTTnLl8o1k/TnbhX1584BI/AAAAAAAAF_8/YBwT0QV5YeI/s1600/claim.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="147" src="http://4.bp.blogspot.com/-kqTTnLl8o1k/TnbhX1584BI/AAAAAAAAF_8/YBwT0QV5YeI/s200/claim.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Last week &lt;b&gt;Spring Integration 2.1 M1&lt;/b&gt; was released. One of new features is an implementation of &lt;b&gt;MessageStorage&lt;/b&gt; interface that relies upon &lt;b&gt;MongoDB&lt;/b&gt; for persistence. &amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In current post I will show you an example of &lt;b&gt;Spring Integration&lt;/b&gt; using &lt;b&gt;Claim Check&lt;/b&gt; pattern and &lt;b&gt;MongoDB&lt;/b&gt; as storage system.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First of all a small introduction of each component we will use.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Spring Integration&lt;/b&gt; provides an extension of the &lt;i&gt;Spring&lt;/i&gt; programming model to support the well-known &lt;i&gt;Enterprise Integration Patterns&lt;/i&gt;. It enables lightweight messaging within &lt;i&gt;Spring&lt;/i&gt;-based applications and supports integration with external systems via declarative adapters.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;MongoDB&lt;/b&gt; is a high-performance, schema-free, document-oriented database, which stores &lt;i&gt;JSON&lt;/i&gt;-like documents.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Claim Check&lt;/b&gt; pattern is an&amp;nbsp;&lt;i&gt;EIP&lt;/i&gt; pattern which allows you to replace message content with a claim check (a unique key), which can be used to retrieve the message content at later time. This pattern can be used when message content is very large and should be sent by request or when you cannot trust the information with an outside party and you use a claim check to talk with it.&lt;/div&gt;&lt;br /&gt;As an example I have used a simplified version of &lt;i&gt;Cafe Sample Application&lt;/i&gt; that are shipped with &lt;b&gt;Spring Integration&lt;/b&gt; bundle, but adding&amp;nbsp;&lt;b&gt;MongoDB MessageStore&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-LAaM0uVWC8I/TntU1GO0YcI/AAAAAAAAGAE/2OfNW4Aylh4/s1600/pipe.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="377" src="http://3.bp.blogspot.com/-LAaM0uVWC8I/TntU1GO0YcI/AAAAAAAAGAE/2OfNW4Aylh4/s640/pipe.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In this diagram you can see a schema of sample application. First of all &lt;i&gt;cafe&lt;/i&gt; component is the &lt;i&gt;gateway&lt;/i&gt;, the point of entree to the system, and is connected to &lt;i&gt;orders&lt;/i&gt; &lt;i&gt;channel&lt;/i&gt;. Orders are sent to &lt;i&gt;splitter&lt;/i&gt;, and each order is sent through &lt;i&gt;pack channel&lt;/i&gt;. Last step is &lt;i&gt;check-in&lt;/i&gt; component. This component is responsible to store order into &lt;b&gt;MongoDB&lt;/b&gt; and generate an&amp;nbsp;&lt;i&gt;UUID.&lt;/i&gt;&amp;nbsp;Finally &lt;i&gt;UUID&lt;/i&gt; is sent to &lt;i&gt;output&lt;/i&gt;&amp;nbsp;(in this case console output).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now I will show you the code of first part of application. I have assumed that you have already installed &lt;b&gt;MongoDB&lt;/b&gt; on your system and is running.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1235237.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Application context&lt;/i&gt; file contains &lt;b&gt;Spring Integration&lt;/b&gt; beans that define structure defined above. See that the most important part is the definition of &lt;i&gt;MongoDbFactory&lt;/i&gt; at line 18, and line 22 where we are defining database name (&lt;i&gt;test&lt;/i&gt; database is created by &lt;b&gt;MongoDB&lt;/b&gt; by default). The other part of file is self-explained. See that in line 37, &lt;b&gt;claim check&lt;/b&gt; is defined and &lt;b&gt;MongoDB&lt;/b&gt;&amp;nbsp;&lt;i&gt;message storage&lt;/i&gt; is referenced.&lt;br /&gt;&lt;br /&gt;Next important piece of code is &lt;i&gt;Cafe&lt;/i&gt; interface. This class acts as a facade for placing orders and not explained yet, for retrieving orders. Let's see this class:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1235286.js?file=Cafe.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Typical &lt;b&gt;Spring Integration&lt;/b&gt; &lt;i&gt;gateway&lt;/i&gt; class, where entering points are defined. For now line 7 is the most important because this method will be called for placing orders into &lt;i&gt;orders&lt;/i&gt; channel.&lt;br /&gt;And now you are ready to send orders using &lt;i&gt;Cafe&lt;/i&gt; interface and receiving at console output not the order but an&amp;nbsp;&lt;i&gt;UUID&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1236829.js?file=PlaceOrderBehaviour.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This is a simple snippet that can be executed as unit test (in fact this is not a unit test I know, but for teaching purpose is enough). And if you execute it you will see two long numbers in console, something like:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1242588.js?file=output.sh"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Remember that number because is required in next step. Meanwhile orders are stored into database. If &lt;b&gt;mongo &lt;/b&gt;console is opened, we can query test database and all orders stored will be returned.&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1242591.js?file=mongo.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now that &lt;i&gt;check-in &lt;/i&gt;has been implemented and tested, it is time to implement&lt;i&gt; check-out&lt;/i&gt; method. In this example user (&lt;i&gt;you&lt;/i&gt;) will enter &lt;i&gt;UUID &lt;/i&gt;using console. Entered reference will be sent to &lt;i&gt;input&lt;/i&gt; channel, &lt;i&gt;order&lt;/i&gt; object with entered code will be retrieved from database, and sent it to &lt;i&gt;stdout &lt;/i&gt;channel. Let's see the code:&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1242608.js?file=app-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Not much difference but instead of using &lt;i&gt;claim-check-in&lt;/i&gt; we are using &lt;i&gt;claim-check-out&lt;/i&gt;. In line 37 we are defining a &lt;i&gt;gateway&lt;/i&gt; to enter &lt;i&gt;UUID&lt;/i&gt;&amp;nbsp;(&lt;i&gt;recoverOrderAndSent&lt;/i&gt;&amp;nbsp;method of &lt;i&gt;Cafe&lt;/i&gt; interface). Introduced identification is sent to &lt;i&gt;input&lt;/i&gt; channel and &lt;i&gt;check-out&lt;/i&gt; is executed, consequently order with that identifier is sent to &lt;i&gt;output&lt;/i&gt; channel (console output).&lt;/div&gt;&lt;br /&gt;And our "&lt;i&gt;test&lt;/i&gt;" now looks like:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1242636.js?file=PlaceOrderBehaviour.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Take a look, first of all two orders are sent to&lt;i&gt; check-in&lt;/i&gt; component. Orders are saved to &lt;b&gt;MongoDB&lt;/b&gt; and returned &lt;i&gt;UUID&lt;/i&gt; are printed to console. Next step in that method is asking user to introduce one of previous &lt;i&gt;UUID &lt;/i&gt;and order is &lt;i&gt;checked-out.&lt;/i&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And the output:&lt;/div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1242651.js?file=output.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note how simply is to configure your application to use &lt;b&gt;claim-check&lt;/b&gt; pattern with &lt;b&gt;Spring Integration&lt;/b&gt;, only configuring &lt;i&gt;XML&lt;/i&gt;s, without writing one line of code.. This is a simple example, of course you can use all the power of&lt;b&gt; Spring Integration&lt;/b&gt;&amp;nbsp;(&lt;i&gt;aggregators&lt;/i&gt;, &lt;i&gt;splitters&lt;/i&gt;, &lt;i&gt;adapters&lt;/i&gt;, ...) with &lt;b&gt;claim-check&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I wish you have found that post useful.&lt;/div&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/ccm.zip"&gt;Download&lt;/a&gt; code.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=NtDzUwVWQL0"&gt;http://www.youtube.com/watch?v=NtDzUwVWQL0&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-4543987713840361451?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/4543987713840361451/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=4543987713840361451' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4543987713840361451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4543987713840361451'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/09/ratti-ratti-sachi-maine-jaan-gavayi-hai.html' title='Ratti Ratti Sachi Maine Jaan Gavayi Hai, Nach Nach Koylo Pe Raat Bitayi Hai, Akhiyon Ki Neend Maine Phoonko Se Uda Di (Jai Ho - A.R. Rahman)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-kqTTnLl8o1k/TnbhX1584BI/AAAAAAAAF_8/YBwT0QV5YeI/s72-c/claim.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-4435198392416080481</id><published>2011-09-22T08:52:00.000+02:00</published><updated>2011-09-22T14:15:46.766+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven aspectj'/><category scheme='http://www.blogger.com/atom/ns#' term='pom'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-aspects'/><category scheme='http://www.blogger.com/atom/ns#' term='aspectj-maven-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='ajdt'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='eclispe'/><category scheme='http://www.blogger.com/atom/ns#' term='aspectj'/><title type='text'>Luna quieres ser madre Y no encuentras querer Que te haga mujer Dime luna de plata (Hijo de la Luna - Mecano)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-dnEdDdiCOJs/TnnhEFBHDII/AAAAAAAAGAA/2-VMZULLz54/s1600/we-love-to-build01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://1.bp.blogspot.com/-dnEdDdiCOJs/TnnhEFBHDII/AAAAAAAAGAA/2-VMZULLz54/s320/we-love-to-build01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In previous post &lt;a href="http://alexsotob.blogspot.com/2011/09/bell-that-rings-inside-your-mind-is.html"&gt;link&lt;/a&gt; I talked about &lt;b&gt;aspects&lt;/b&gt;, concretely &lt;i&gt;ITD&lt;/i&gt;, and how can be used to design your classes with its own responsibilities while maintaining source code clear and concise. In that post I used &lt;b&gt;aspectj&lt;/b&gt; and &lt;b&gt;spring-aspects&lt;/b&gt; as aspect-oriented implementations. An important concept of &lt;i&gt;aspect programming&lt;/i&gt; is the process of &lt;i&gt;weaven&lt;/i&gt;. An&lt;i&gt; aspect weaver&lt;/i&gt; takes information from raw classes and aspects and creates new classes with the aspect code appropriately weaved into the classes.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If you are using &lt;i&gt;Eclipse&lt;/i&gt; with &lt;i&gt;AJDT&lt;/i&gt; plugin, weaver is executed automatically, but if you are using any build tool like &lt;b&gt;Maven&lt;/b&gt;, you should take care of configuring correctly so generated classes contains aspect code too.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In this post I will explain how I have modified a &lt;b&gt;pom&lt;/b&gt; file so compilation process also weaves aspect code into classes.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First thing I always do when I generate a &lt;b&gt;pom&lt;/b&gt; file is adding component version in &lt;i&gt;properties&lt;/i&gt; section. In this case &lt;i&gt;spring&lt;/i&gt; and &lt;i&gt;aspectj&lt;/i&gt;:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;script src="https://gist.github.com/1232586.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;div style="text-align: justify;"&gt;Next step is adding &lt;i&gt;dependencies&lt;/i&gt;. To work with &lt;i&gt;aspectj&lt;/i&gt; and &lt;i&gt;spring-aspects&lt;/i&gt; four dependencies must be added.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1232597.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But one more important dependency is required, and let me surprise you:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1232604.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;You can think I am joking, but not, &lt;i&gt;JPA API&lt;/i&gt; is required. Here you can read why: &lt;a href="https://jira.springsource.org/browse/SPR-6819"&gt;https://jira.springsource.org/browse/SPR-6819&lt;/a&gt;. &lt;i&gt;AnnotationDrivenStaticEntityMockingControl&lt;/i&gt; class requires &lt;i&gt;javax.persistence.Entity&lt;/i&gt; to be in classpath. Hopefully nowadays most projects use &lt;i&gt;JPA&lt;/i&gt;, so this dependency may already be required by your code, if not, then you should append it as &lt;i&gt;dependency&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;And finally &lt;b&gt;aspectj-maven-plugin&lt;/b&gt; is registered:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1232611.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;This plugin requires that you define which dependencies will be used using &amp;lt;&lt;i&gt;dependencies&lt;/i&gt;&amp;gt; tag. In order to apply already compiled aspects to your own sources you need to setup all &lt;i&gt;JAR&lt;/i&gt; files you would like to weave in the plugin configuration using &amp;lt;&lt;i&gt;aspectLibraries&lt;/i&gt;&amp;gt; section; in this case &lt;b&gt;spring-aspects&lt;/b&gt; artifact is required so application can use capabilities that offer &lt;i&gt;@Configurable &lt;/i&gt;annotation. Finally execution section should contain &lt;i&gt;compile&lt;/i&gt; and &lt;i&gt;test-compile goals&lt;/i&gt; so main and test classes can be woven.&lt;br /&gt;&lt;br /&gt;Hope you find this post useful.&lt;br /&gt;&lt;br /&gt;Alex.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=HzeMbN90Pz8"&gt;http://www.youtube.com/watch?v=HzeMbN90Pz8&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-4435198392416080481?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/4435198392416080481/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=4435198392416080481' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4435198392416080481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4435198392416080481'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/09/luna-quieres-ser-madre-y-no-encuentras.html' title='Luna quieres ser madre Y no encuentras querer Que te haga mujer Dime luna de plata (Hijo de la Luna - Mecano)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-dnEdDdiCOJs/TnnhEFBHDII/AAAAAAAAGAA/2-VMZULLz54/s72-c/we-love-to-build01.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-1090940953944071621</id><published>2011-09-19T07:40:00.002+02:00</published><updated>2011-12-20T19:01:54.147+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ajdt'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-aspects'/><category scheme='http://www.blogger.com/atom/ns#' term='dao pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-oxm'/><category scheme='http://www.blogger.com/atom/ns#' term='itd'/><category scheme='http://www.blogger.com/atom/ns#' term='active record pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='hamcrest xml'/><category scheme='http://www.blogger.com/atom/ns#' term='class responsibilities'/><category scheme='http://www.blogger.com/atom/ns#' term='inter-type declarations'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='jaxb'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><category scheme='http://www.blogger.com/atom/ns#' term='aspectj'/><title type='text'>The Bell That Rings Inside Your Mind, Is Challenging The Doors Of Time, It’s A Kind Of Magic (A Kind Of Magic - Queen)</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-e_Wnnfq_v14/Tmzuo6hDbMI/AAAAAAAAF_4/_TRUYtwaN3s/s1600/pez002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://3.bp.blogspot.com/-e_Wnnfq_v14/Tmzuo6hDbMI/AAAAAAAAF_4/_TRUYtwaN3s/s200/pez002.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;During class design we should take decisions about the assignment of&amp;nbsp;responsibilities&amp;nbsp;that will have every class. If we have chosen well, systems tend to be easier to understand, maintain and extend.&lt;br /&gt;&lt;br /&gt;Almost all of our projects have a persistence layer, either relational database, document stores, or simply &lt;i&gt;XML&lt;/i&gt; files. And typically you will use &lt;i&gt;DAO&lt;/i&gt; pattern to implement abstract interface between your business objects and your data store.&lt;br /&gt;&lt;br /&gt;In this post but I am going to explain another pattern that can be used instead of &lt;i&gt;DAO&lt;/i&gt; pattern. &lt;b&gt;Active record pattern&lt;/b&gt; is an architectural pattern that force you to implement &lt;i&gt;CRUD&lt;/i&gt; operations on your model &amp;nbsp;class, hence model class itself is responsible for saving, deleting, loading from database.&lt;br /&gt;&lt;br /&gt;There are many strategies to follow to implement this pattern, but for me, the best one is using &lt;b&gt;Aspect Oriented Programming, &lt;/b&gt;because we are still maintaining separation of concerns favoring isolated unit testing, and not breaking encapsulation.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Aspect-oriented&lt;/b&gt; programming entails breaking down program logic into distinct parts. These parts are known as &lt;i&gt;crosscutting concerns&lt;/i&gt; because they "&lt;i&gt;cut across&lt;/i&gt;" multiple abstractions in a program. Example of crosscutting concerns can be &lt;i&gt;logging&lt;/i&gt;, &lt;i&gt;transaction manager&lt;/i&gt;, &lt;i&gt;error manager&lt;/i&gt; or &lt;i&gt;splitting large datasets&lt;/i&gt;. For people that have worked with &lt;i&gt;aspects&lt;/i&gt; not much secret here, to use them you simply create an &lt;i&gt;aspect&lt;/i&gt; defining the &lt;i&gt;advice&lt;/i&gt; and the &lt;i&gt;pointcut&lt;/i&gt;, and your aspect is ready to be executed.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I guess most of us use &lt;b&gt;aspects-oriented&lt;/b&gt; programming as I have described in previous paragraph, but will be fewer that uses &lt;b&gt;ITD&lt;/b&gt; (&lt;b&gt;Inter-type Declarations&lt;/b&gt;) feature.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Inter-type Declarations&lt;/b&gt; provide a way to express &lt;i&gt;crosscutting concerns&lt;/i&gt; affecting the structure of modules enabling programmers to declare members of another class.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As we say in my country "&lt;i&gt;bad said but well understood&lt;/i&gt;", &lt;b&gt;ITD&lt;/b&gt; is a way to declare new components (&lt;i&gt;attributes, methods, annotations&lt;/i&gt;) of a &lt;i&gt;class&lt;/i&gt; from an &lt;i&gt;aspect&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;AspectJ&lt;/b&gt; is an&lt;b&gt; aspect-oriented&lt;/b&gt; extension for &lt;i&gt;Java&lt;/i&gt;. &lt;b&gt;AspectJ&lt;/b&gt; supports &lt;b&gt;ITD&lt;/b&gt;, and for this reason will be used in this post. Moreover I recommend you install &lt;i&gt;AJDT&lt;/i&gt; plugin because it will help you develop aspects and having a quick overview of which &lt;i&gt;Java&lt;/i&gt; classes are aspecterized.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.eclipse.org/ajdt/logo.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.eclipse.org/ajdt/logo.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;If you have not understood what &lt;b&gt;ITD&lt;/b&gt; is, don't worry, it is a typical example of concept that is best understood with an example.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Let's start with simple example:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Imagine having to model a car. You would have a car class, with some attributes, for this example three attributes (&lt;i&gt;vin&lt;/i&gt; number, &lt;i&gt;miles&lt;/i&gt; drived and &lt;i&gt;model&lt;/i&gt;) is enough.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;script src="https://gist.github.com/1211646.js?file=Car.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;It is a &lt;i&gt;POJO&lt;/i&gt; with three attributes and their &lt;i&gt;getters&lt;/i&gt; and &lt;i&gt;setters&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Now we want to add persistence layer, but in this case we are going to persist our &lt;i&gt;POJOs&lt;/i&gt; in a &lt;i&gt;XML&lt;/i&gt; file instead of a database. So&amp;nbsp;&lt;i&gt;Car&lt;/i&gt;&amp;nbsp;objects should be transformed to &lt;i&gt;XML&lt;/i&gt; stream. For this&amp;nbsp;purpose&amp;nbsp;&lt;i&gt;JAXB&lt;/i&gt; annotations will be used. For those who don’t know, &lt;i&gt;JAXB&lt;/i&gt; allows developers to map &lt;i&gt;Java&lt;/i&gt; classes to &lt;i&gt;XML&lt;/i&gt;&amp;nbsp;representations and viceversa.&lt;/div&gt;&lt;br /&gt;I am sure that first idea that comes to your brain is annotating &lt;i&gt;Car&lt;/i&gt; class with &lt;i&gt;@XmlRootElement&lt;/i&gt; (annotation to map root element in &lt;i&gt;JAXB&lt;/i&gt;). Don’t do that, use &lt;b&gt;aspects&lt;/b&gt;. Your first mission is trying to maintain &lt;i&gt;Car&lt;/i&gt; file as simple as possible. To add an annotation using &lt;b&gt;ITD&lt;/b&gt;, is as simple as:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1216961.js?file=Car_Jaxb.aj"&gt;&lt;/script&gt;&lt;br /&gt;With &lt;i&gt;@type&lt;/i&gt; you are exposing which member is annotated. In this case only &lt;i&gt;class&lt;/i&gt;. Other possibilities are &lt;i&gt;@method&lt;/i&gt;, &lt;i&gt;@constructor&lt;/i&gt; and &lt;i&gt;@field&lt;/i&gt;. Then elements pattern that should be annotated, in this case &lt;i&gt;Car&lt;/i&gt; class, but you could use any regular expressions like&lt;i&gt; org.alexsotob..*&lt;/i&gt;. Finally the &lt;i&gt;annotation&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Next step is using &lt;i&gt;JAXB&lt;/i&gt; classes to marshalling/unmarshalling objects. In this example I am using &lt;i&gt;spring-oxm&lt;/i&gt; package and briefly you will understand why. &lt;i&gt;Spring-oxm&lt;/i&gt; is a part of &lt;i&gt;spring-core&lt;/i&gt; that contains classes for dealing with &lt;i&gt;O/X Mapping&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;This &lt;i&gt;spring&lt;/i&gt; module contains one class for each &lt;i&gt;Xml&lt;/i&gt; binding supported. In our case &lt;i&gt;Jaxb2Marshaller&lt;/i&gt; is used as marshaller and unmarshaller.&lt;br /&gt;&lt;br /&gt;It is possible that you are thinking of creating a service class where you inject &lt;i&gt;Jaxb2Marshaller&lt;/i&gt; instance. This service would include two methods (&lt;i&gt;save&lt;/i&gt; and &lt;i&gt;load&lt;/i&gt;) with &lt;i&gt;Car&lt;/i&gt; class as argument or return value. Sorry but, doing this, you are implementing &lt;i&gt;DAO&lt;/i&gt; pattern. Let's implement &lt;b&gt;Active Record pattern&lt;/b&gt;&amp;nbsp;approach.&amp;nbsp;And as you may suppose, &lt;b&gt;aspectj&lt;/b&gt; comes to rescue you to avoid mixing concepts in same source file.&lt;br /&gt;&lt;br /&gt;Let's update previous &lt;b&gt;aspect&lt;/b&gt; file so all required logic by &lt;i&gt;JAXB&lt;/i&gt; will be in same file.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1212280.js?file=Car_Jaxb.aj"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;See that apart from annotating &lt;i&gt;Car&lt;/i&gt; class we are creating two methods, and an annotated attribute.&amp;nbsp;&amp;nbsp;Attributes must follow same rule as methods, &amp;nbsp;&amp;lt;&lt;i&gt;class name&lt;/i&gt;&amp;gt; dot (&lt;b&gt;.&lt;/b&gt;) and &amp;lt;&lt;i&gt;attribute name&lt;/i&gt;&amp;gt;. Note that in this case attribute is &lt;i&gt;transient&lt;/i&gt; because should not be bound in &lt;i&gt;XML&lt;/i&gt; file.&lt;br /&gt;&lt;br /&gt;Last step is configuring&amp;nbsp;&lt;i&gt;marshaller&lt;/i&gt; in &lt;i&gt;spring&lt;/i&gt; context file.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1219944.js?file=context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Not much secret. Now let's code a unit test.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1219961.js?file=CarOxmBehaviour.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Run &lt;i&gt;junit&lt;/i&gt; class and &lt;b&gt;BOOM&lt;/b&gt; all red, with an amazing &lt;i&gt;NullPointerException&lt;/i&gt;. &lt;i&gt;Marshaller&lt;/i&gt; is created in S&lt;i&gt;pring context&lt;/i&gt;, but not injected into &lt;i&gt;Car&lt;/i&gt; class (&lt;i&gt;Car&lt;/i&gt; is not managed by &lt;i&gt;spring container&lt;/i&gt;, so is impossible to be injected). And now I suppose you are telling yourself: "&lt;i&gt;I told you a service layer would be better, because it would be managed by Spring and autowired would work perfect.&lt;/i&gt;". But wait and see. How about using &lt;b&gt;spring-aspects&lt;/b&gt; module? &lt;i&gt;Spring Aspects&lt;/i&gt;&amp;nbsp;contains an annotation-driven aspect (&lt;i&gt;@Configurable&lt;/i&gt;) allowing dependency injection of any object, whatever is or not controlled by container. So let's apply last two changes and the application will run.&lt;br /&gt;&lt;br /&gt;First of all is creating a new &lt;b&gt;aspectj&lt;/b&gt; file to annotate &lt;i&gt;Car&lt;/i&gt; class as &lt;i&gt;Configurable&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1212272.js?file=Car_Configurable.aj"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And finally modify &lt;i&gt;spring&lt;/i&gt; context file to allow &lt;i&gt;@Configurable&lt;/i&gt; annotation.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1212289.js?file=context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Adding&amp;nbsp;&lt;i&gt;&amp;lt;context:spring-configured&amp;gt;&amp;lt;/context:spring-configured&amp;gt; &lt;/i&gt;namespace is enough.&amp;nbsp;As a result, any time you instantiate an object (via the "&lt;i&gt;new&lt;/i&gt;" keyword), &lt;i&gt;Spring &lt;/i&gt;will attempt to perform dependency injection on that object.&lt;br /&gt;&lt;br /&gt;Now run unit test again and green will&amp;nbsp;invade&amp;nbsp;your computer :D.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ITD &lt;/b&gt;is a really nice solution to design classes with its own&amp;nbsp;responsibilities. It gives you the oportunity of writing maintainable and understandable code, without loosing encapsulation. Of course you should take care of not to have high coupling in aspected classes, and convert them in "God Classes".&lt;br /&gt;&lt;br /&gt;Note that implementing same approach but using relational database, it is as simple as changing &lt;i&gt;Jaxb2Marshaller&lt;/i&gt; to &lt;i&gt;EntityManager.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I wish you have found this post useful.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/itd.zip"&gt;Download Full code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Music: &amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=KLFZzInXAWI"&gt;http://www.youtube.com/watch?v=KLFZzInXAWI&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-1090940953944071621?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/1090940953944071621/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=1090940953944071621' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1090940953944071621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1090940953944071621'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/09/bell-that-rings-inside-your-mind-is.html' title='The Bell That Rings Inside Your Mind, Is Challenging The Doors Of Time, It’s A Kind Of Magic (A Kind Of Magic - Queen)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-e_Wnnfq_v14/Tmzuo6hDbMI/AAAAAAAAF_4/_TRUYtwaN3s/s72-c/pez002.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-6756141414410819176</id><published>2011-09-12T08:23:00.000+02:00</published><updated>2011-09-12T08:23:19.870+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='maven deploy'/><category scheme='http://www.blogger.com/atom/ns#' term='maven repository'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Questa di Marinella è la storia vera Che scivolò nel fiume a Primavera Ma il vento che la vide così bella Dal fiume la portò sopra una stella (Canzone Di Marinella - Mina)</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Rp4YBKfp8vg/TmebhirtcFI/AAAAAAAAF_o/T7wVXsza_Yo/s1600/github-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-Rp4YBKfp8vg/TmebhirtcFI/AAAAAAAAF_o/T7wVXsza_Yo/s200/github-logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Most of us use &lt;b&gt;Maven&lt;/b&gt; as a build automation tool. One of most important section are those related to dependencies. Typically projects have dependencies to external libraries like &lt;i&gt;Spring&lt;/i&gt;, &lt;i&gt;Hibernate&lt;/i&gt;, S&lt;i&gt;lf4j&lt;/i&gt;, ... which are downloaded from &lt;i&gt;External Maven Repository Servers&lt;/i&gt; like &lt;i&gt;&lt;a href="http://mvnrepository.com/"&gt;mvnrepository&lt;/a&gt;&lt;/i&gt;, &lt;a href="http://mirrors.ibiblio.org/pub/mirrors/maven2/"&gt;ibiblio&lt;/a&gt; or from own&amp;nbsp;&lt;i&gt;Internal Maven Repository Server&lt;/i&gt;&amp;nbsp;using &lt;i&gt;JFrog&lt;/i&gt; or &lt;i&gt;Nexus&lt;/i&gt;. This scenario but does not cover all possible cases.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It is uncommon that your project requires an external library that is not present in any repository, but can occurs, and in these cases are where you use company &lt;i&gt;Internal Maven Repository&lt;/i&gt; to upload these artifacts. But this is not always possible, and typical example is when you are writing in a blog about a &lt;i&gt;beta&lt;/i&gt; library and it is not present in any repository, and you want to add this library to &lt;i&gt;pom&lt;/i&gt; file. Would be perfect if &lt;b&gt;Maven&lt;/b&gt; could resolve these dependencies too without packaging them into project. So what can we do?&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;There are some alternatives:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;- packaging &lt;i&gt;.class&lt;/i&gt; files of external library into your project, so they are packaged as project files.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;- asking library creators to upload &lt;i&gt;Milestones&lt;/i&gt; to public repositories.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;- create your own public&lt;b&gt; Maven&lt;/b&gt; &lt;i&gt;Repository&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;- using &lt;b&gt;GitHub&lt;/b&gt;?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Using &lt;b&gt;GitHub&lt;/b&gt;, YES!!. You can configure your &lt;b&gt;GitHub&lt;/b&gt; account as &lt;b&gt;Maven&lt;/b&gt; &lt;i&gt;Repository&lt;/i&gt;. In my case I always upload sample code to &lt;b&gt;GitHub&lt;/b&gt;. Why not creating a &lt;b&gt;GitHub&lt;/b&gt; project that acts as a &lt;b&gt;Maven&lt;/b&gt;&amp;nbsp;&lt;i&gt;Repository&lt;/i&gt; and &lt;i&gt;poms&lt;/i&gt;&amp;nbsp;referencing to this repository?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now I will summarize steps that shall be followed: (assuming that you have already created a project).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Create a&amp;nbsp;&lt;b&gt;GitHub&lt;/b&gt;&amp;nbsp;repository.&lt;/li&gt;&lt;li&gt;Initialize local directory as &lt;b&gt;Git&lt;/b&gt; repo.&lt;/li&gt;&lt;li&gt;Modify project &lt;i&gt;pom&lt;/i&gt; so &lt;i&gt;distribution management&lt;/i&gt; tag points to local repository.&lt;/li&gt;&lt;li&gt;Perform &lt;i&gt;deploy&lt;/i&gt; goal so artifact is deployed to local repository.&lt;/li&gt;&lt;li&gt;Push changes to &lt;b&gt;GitHub&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Nothing more. Now other project &lt;i&gt;poms&lt;/i&gt; can use your repository.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Let's get down to work:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The first thing you should know is that the project I want to upload to &lt;b&gt;Maven&lt;/b&gt; &lt;i&gt;Repository &lt;/i&gt;is located at&amp;nbsp;&lt;i&gt;/media/share/workspace/github-test &lt;/i&gt;and project that will have a dependency will be located at&lt;i&gt;&amp;nbsp;/media/share/workspace/bar.&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;&lt;b&gt;First step&lt;/b&gt;&lt;/u&gt; is creating a new &lt;b&gt;GitHub&lt;/b&gt; repository. So login to your &lt;b&gt;GitHub&lt;/b&gt; account and create a new repository. In my case I have named &lt;i&gt;maven-repository&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-p-go753W3KQ/TmektATr13I/AAAAAAAAF_w/kg0VDSa2B8g/s1600/Screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="257" src="http://1.bp.blogspot.com/-p-go753W3KQ/TmektATr13I/AAAAAAAAF_w/kg0VDSa2B8g/s640/Screenshot.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Second step&lt;/u&gt;&lt;/b&gt; is initialize local directory as &lt;b&gt;Git&lt;/b&gt; repository.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1201145.js?file=mavenrepo.sh"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Third step&lt;/u&gt;&lt;/b&gt; is adding &lt;i&gt;distributionManagement&lt;/i&gt; &lt;i&gt;tag&lt;/i&gt; pointing to repository so when project is deployed, artifact is created to &lt;b&gt;Git&lt;/b&gt; directory.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1201191.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that &lt;i&gt;url&lt;/i&gt; tag is pointing to previously created &lt;b&gt;Git&lt;/b&gt; directory (local disk).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Fourth Step&lt;/u&gt;&lt;/b&gt; is running&amp;nbsp;&lt;i&gt;mvn -DperformRelease=true clean deploy.&amp;nbsp;&lt;/i&gt;Project is &lt;i&gt;compiled&lt;/i&gt;, &lt;i&gt;tested&lt;/i&gt;, and&amp;nbsp;&lt;i&gt;packaged.&lt;/i&gt;&amp;nbsp;Now go to local repository and see what has appeared.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1201201.js?file=repository.sh"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Fifth Step&lt;/u&gt;&lt;/b&gt; implies two operations, &lt;i&gt;committing&lt;/i&gt; changes and &lt;i&gt;pushing&lt;/i&gt; them to &lt;b&gt;GitHub&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1201323.js?file=checkin.sh"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that first command is adding root directory. Then all files are committed to local repository and pushed to &lt;b&gt;GitHub&lt;/b&gt; repository.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-KsjYGIN_42o/Tme4_UH337I/AAAAAAAAF_0/PgsfLXUsoNQ/s1600/Screenshot-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="288" src="http://2.bp.blogspot.com/-KsjYGIN_42o/Tme4_UH337I/AAAAAAAAF_0/PgsfLXUsoNQ/s640/Screenshot-1.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;&lt;b&gt;Sixth Step&lt;/b&gt;&lt;/u&gt; if you want to call it step, is adding&amp;nbsp;&lt;i&gt;repository&lt;/i&gt; tag to project that requires published component. In our case &lt;i&gt;bar&lt;/i&gt; project requires it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1204045.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This &lt;i&gt;pom&lt;/i&gt; represents a project that wants to use &lt;i&gt;github-test&lt;/i&gt; module. It is important to note that repository &lt;i&gt;url&lt;/i&gt; is special (not showed when you explore &lt;b&gt;GitHub&lt;/b&gt; projects with navigator), and is&lt;i&gt;&amp;nbsp;https://github.com/maggandalf/maven-repository/raw/master.&lt;/i&gt;&amp;nbsp;After repository name (in this case &lt;i&gt;maven-repository&lt;/i&gt;) you should concatenate &lt;i&gt;/raw/master&lt;/i&gt;. &lt;i&gt;raw&lt;/i&gt; because you want to access to files without any decoration (no &lt;i&gt;HTML&lt;/i&gt;), and &lt;i&gt;master&lt;/i&gt; because it is the branch name.&lt;br /&gt;&lt;br /&gt;When &lt;i&gt;bar&lt;/i&gt; project is being compiled,&lt;i&gt; github-test&lt;/i&gt; artifact is downloaded.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1204076.js?file=output.sh"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;I think it is a good approach when you need to upload a &lt;b&gt;Maven&lt;/b&gt; artifact&amp;nbsp;temporally, or simply because your project requires a &lt;i&gt;milestone&lt;/i&gt; version of artifact that is not uploaded into any repository.&lt;br /&gt;&lt;br /&gt;I hope you like this post, and ... MOVE TO GIT.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=TL69oTe6HHY"&gt;http://www.youtube.com/watch?v=TL69oTe6HHY&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-6756141414410819176?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/6756141414410819176/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=6756141414410819176' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6756141414410819176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6756141414410819176'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/09/questa-di-marinella-e-la-storia-vera.html' title='Questa di Marinella è la storia vera Che scivolò nel fiume a Primavera Ma il vento che la vide così bella Dal fiume la portò sopra una stella (Canzone Di Marinella - Mina)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Rp4YBKfp8vg/TmebhirtcFI/AAAAAAAAF_o/T7wVXsza_Yo/s72-c/github-logo.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-8216131608636255950</id><published>2011-09-06T21:33:00.000+02:00</published><updated>2011-09-06T21:33:33.788+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='polyglot programming'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy sql'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><category scheme='http://www.blogger.com/atom/ns#' term='gmaven'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><category scheme='http://www.blogger.com/atom/ns#' term='integration tests'/><category scheme='http://www.blogger.com/atom/ns#' term='XML parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy java'/><category scheme='http://www.blogger.com/atom/ns#' term='regular expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy regular expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy xml'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><title type='text'>Soy El Capitán De La Nave Tengo El Control, Llamando A La Tierra Esperando Contestación, Soy Un Cowboy Del Espacio Azul Eléctrico (Llamando A La Tierra - M.Clan)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Groovy-logo.svg/614px-Groovy-logo.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="98" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Groovy-logo.svg/614px-Groovy-logo.svg.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Groovy&lt;/b&gt; is an object-oriented programming language for the &lt;i&gt;Java&lt;/i&gt; platform and can be used as a scripting language. Most of us but instead of using &lt;b&gt;Groovy&lt;/b&gt; alone, we use &lt;i&gt;Grails&lt;/i&gt; (web framework based on &lt;b&gt;Groovy&lt;/b&gt;) for developing web applications.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But &lt;b&gt;Groovy&lt;/b&gt; can be used standalone for developing your internal tools. Let me explain why &lt;b&gt;Groovy&lt;/b&gt; scripts have simplified our development of tools for generating data for integration tests.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In my company we create clinical instruments. These instruments are so expensive, and big enough to say that they are not portable. For these reasons each instrument has an &lt;i&gt;emulator&lt;/i&gt;, so integration tests are run without having physically any instrument.&lt;br /&gt;&lt;br /&gt;Our e&lt;i&gt;mulator&lt;/i&gt; has an &lt;i&gt;XML&lt;/i&gt; file where all required resources for running tests are configured. In summary each file contains a list of blood barcodes, and reagent barcodes. In our case barcodes have a meaning (kind of resource,&amp;nbsp;expiry&amp;nbsp;date, checksum, ...).&lt;br /&gt;&lt;br /&gt;So one can think about creating a standard configuration file that is used in integration tests. It is a good idea if you don't know that expiry date is expressed in months. So one day without knowing exactly why your tests begin to fail. The answer is obvious, resources have become expired. We need a (&lt;i&gt;script&lt;/i&gt; ?) that updates this &lt;i&gt;XML&lt;/i&gt; file so when a resource is becoming expired, its month field is changed.&lt;br /&gt;&lt;br /&gt;Moreover not all resources should be updated. Some tests imply working with expired resources. For this reason some barcodes have special format that suggests that update should not be applied.&lt;br /&gt;&lt;br /&gt;Because project is developed in &lt;i&gt;Java&lt;/i&gt;, one can think about creating a small &lt;i&gt;Java&lt;/i&gt; class that do all these work. But wait and think if this class would be small or not, we need a parser (&lt;i&gt;DocumentBuilder&lt;/i&gt;), a method that walks all nodes and see if resource is expired or not (&lt;i&gt;NodeList, Element.getAttribute()&lt;/i&gt;, ...), and finally writing modifications to file. Furthermore, some barcodes contains special charachtrs that should be detected using a regular expression (&lt;i&gt;Pattern&lt;/i&gt;, &lt;i&gt;Matcher&lt;/i&gt;) for avoiding its update. Although this class is not difficult, it is far away from a small class with few lines.&lt;br /&gt;&lt;br /&gt;But how about polyglot programming? &lt;b&gt;Groovy&lt;/b&gt; can be a choice. Let's see how &lt;b&gt;Groovy&lt;/b&gt; deals with &lt;i&gt;XML&lt;/i&gt; and &lt;i&gt;Regular Expressions&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Imagine next &lt;i&gt;XML&lt;/i&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1186916.js?file=contents.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Groovy and XML&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Meanwhile in &lt;i&gt;Java&lt;/i&gt; you create a &lt;i&gt;DocumentBuilderFactory&lt;/i&gt; that returns a &lt;i&gt;DocumentBuilder&lt;/i&gt;, and then call &lt;i&gt;parse&lt;/i&gt; method, in &lt;b&gt;Groovy&lt;/b&gt; is as simple as:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1186987.js?file=root.groovy"&gt;&lt;/script&gt;and &lt;i&gt;root&lt;/i&gt; variable points to root element of &lt;i&gt;XML&lt;/i&gt; file.&lt;br /&gt;&lt;br /&gt;And now imagine that you want to update all blood barcodes of given holder. With &lt;i&gt;Java&lt;/i&gt; you will use an iterator over &lt;i&gt;NodeList&lt;/i&gt; or using an &lt;i&gt;XPath&lt;/i&gt; expression. See the simplicity with &lt;b&gt;Groovy&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1186968.js?file=samples.groovy"&gt;&lt;/script&gt;&lt;br /&gt;See that with &lt;b&gt;Groovy,&lt;/b&gt; nodes are explored as object attributes, and finally we call &lt;i&gt;findAll()&lt;/i&gt; method that returns a list of &lt;i&gt;sample&lt;/i&gt; nodes belonging to &lt;i&gt;SampleHolder11&lt;/i&gt; tag. For returning an attribute value is as easy as adding &lt;b&gt;@&lt;/b&gt; character before attribute name, in our case &lt;i&gt;barcode&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;And for writing an &lt;i&gt;XML&lt;/i&gt; is as easy as:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1190926.js?file=writeXml.groovy"&gt;&lt;/script&gt;&lt;br /&gt;In previous example, output is written to console.&lt;br /&gt;&lt;div style="font-weight: bold; text-decoration: underline;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;u&gt;&lt;b&gt;Groovy and Regular Expressions&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Remember that some barcodes have special format. In our case if any barcode starts with &lt;u&gt;A&lt;/u&gt;, &lt;u&gt;B&lt;/u&gt;, &lt;u&gt;C&lt;/u&gt; or &lt;u&gt;D&lt;/u&gt;, should not be modified. A clean, reusable and maintainable solution is using &lt;i&gt;regular expressions&lt;/i&gt; to check if one barcode matches or not special format. In &lt;i&gt;Java&lt;/i&gt; the process is not banal, you have to create a &lt;i&gt;Pattern&lt;/i&gt; object with a regular expression, a &lt;i&gt;Matcher&lt;/i&gt; and use &lt;i&gt;find()&lt;/i&gt; method to see if pattern is found on entry or not.&lt;br /&gt;&lt;br /&gt;But how we can determine if one string matches a regular expression&amp;nbsp;in &lt;b&gt;Groovy&amp;nbsp;&lt;/b&gt;?&lt;b&gt;&lt;i&gt; ==~&lt;/i&gt;&lt;/b&gt; operator does the work for us. Tell me what you think about this expression:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1190936.js?file=RegExp.groovy"&gt;&lt;/script&gt;&lt;br /&gt;Elementary.&amp;nbsp;You will agree with me that &lt;b&gt;Groovy&lt;/b&gt; approach is simpler than &lt;i&gt;Java&lt;/i&gt; one. &amp;nbsp;For specifying a pattern you only have to use &lt;b&gt;~&lt;/b&gt;&amp;nbsp;character plus a slash&lt;b&gt;&amp;nbsp;&lt;/b&gt;(&lt;b&gt;/&lt;/b&gt;) then a regular expression and finally a slash to delimit. But &lt;b&gt;Groovy&lt;/b&gt; also supports &lt;b&gt;=~&lt;/b&gt;&amp;nbsp;(create a &lt;i&gt;Matcher&lt;/i&gt;) and &lt;b&gt;==~&lt;/b&gt;&amp;nbsp;(return boolean, whether &lt;i&gt;String&lt;/i&gt; matches the pattern).&lt;br /&gt;&lt;br /&gt;I think that creating a script that&lt;u&gt; reads/parses/writes&lt;/u&gt; &lt;b&gt;XML&lt;/b&gt; file is so fast and easy, not much classes are involved compared to &lt;i&gt;Java&lt;/i&gt;. And not worth making the comparison with &lt;u&gt;regular expression&lt;/u&gt; approach, in &lt;b&gt;Groovy&lt;/b&gt; is the simplest way one may think.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After the success of previous &lt;b&gt;Groovy&lt;/b&gt; script, we decided to create another tool (&lt;b&gt;Groovy&lt;/b&gt; script) for manipulating database.&lt;br /&gt;&lt;br /&gt;System registers into database every incidence that has occurred&amp;nbsp;to an execution. Some incidences are easy to reproduce with emulator, but others not. In integration tests there is no problem, because a defined-filled database is used, but acceptance tests contains no data and is generated with the execution of tests. But because there are some incidences that are hard to reproduce in emulator, a &lt;b&gt;Groovy&lt;/b&gt; script to insert incidences are created.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Groovy and SQL&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;As &lt;i&gt;Java&lt;/i&gt;, &lt;b&gt;Groovy&lt;/b&gt; can also access to databases and as you can suppose in a simple way. No &lt;i&gt;Connection &lt;/i&gt;object, no &lt;i&gt;PreparedStatement&lt;/i&gt;, no &lt;i&gt;ResultSet&lt;/i&gt;, ....&lt;br /&gt;&lt;br /&gt;Let's see an example of searching data and using them for creating a new registry. Imagine that we have a table called &lt;i&gt;Execution&lt;/i&gt; and another one called &lt;i&gt;Incidence&lt;/i&gt;, and &lt;i&gt;one-to-many &lt;/i&gt;relationship.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1191018.js?file=sql.groovy"&gt;&lt;/script&gt;&lt;br /&gt;Simple, yes? With one line a connection to database is established.&lt;br /&gt;&lt;br /&gt;Executing &lt;i&gt;SELECT&lt;/i&gt; query and iterate over results are also easy. Using &lt;i&gt;eachRow&lt;/i&gt; method, all results are iterated. No &lt;i&gt;ResultSet&lt;/i&gt; object is required anymore. Parameters values are passed between brackets ([]), and as &lt;i&gt;XML&lt;/i&gt; each row is accessed using &lt;i&gt;Closure&lt;/i&gt;. In previous example each row is mapped to execution variable. Moreover see how easy is read a value of each tuple. As in &lt;i&gt;XML&lt;/i&gt; you access the value as a class attribute, no more &lt;i&gt;getters &lt;/i&gt;of&amp;nbsp;&lt;i&gt;ResultSet&lt;/i&gt; methods, in example &lt;i&gt;execution.dboid&lt;/i&gt; is used to refer to &lt;i&gt;dboid&lt;/i&gt; field.&lt;br /&gt;&lt;br /&gt;Finally &lt;i&gt;execute&lt;/i&gt; method is used to update database.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that I have shown you some of nice features that &lt;b&gt;Groovy&lt;/b&gt; offers us, I will explain you how we execute these tools.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;GMaven&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We use &lt;i&gt;Jenkins&lt;/i&gt; with &lt;i&gt;Maven&lt;/i&gt; as &lt;i&gt;Continuos Integration System&lt;/i&gt;. Before &lt;i&gt;Jenkins&lt;/i&gt; starts to execute &lt;i&gt;Integration Tests&lt;/i&gt;, &lt;b&gt;Groovy&lt;/b&gt; scripts are executed so e&lt;i&gt;mulator&lt;/i&gt; is configured propertly. The iteresting part of this step is how &lt;i&gt;pom&lt;/i&gt; is configured for executing &lt;b&gt;Groovy&lt;/b&gt;&amp;nbsp;scripts.&lt;br /&gt;&lt;br /&gt;Exists a plugin called &lt;i&gt;gmaven-plugin&lt;/i&gt;. This plugin runs&amp;nbsp;&lt;b&gt;Groovy&lt;/b&gt; scripts depending on phase and goal.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1198022.js?file=pom.xml"&gt;&lt;/script&gt;&lt;br /&gt;No problem configuring &lt;i&gt;gmaven&lt;/i&gt; plugin, the most important part is where you specify which script should be executed.&lt;br /&gt;&lt;br /&gt;As final notes I want to say that I am a huge fan of &lt;i&gt;Java&lt;/i&gt; and my intention is not criticize it, but I think that there are some problems that are best suited using other languages rather than &lt;i&gt;Java&lt;/i&gt;. My advice is &amp;nbsp;learning as many kind of languages as you can (&lt;i&gt;Scala&lt;/i&gt;, &lt;i&gt;Groovy&lt;/i&gt;, ...) so as programmer you can choose the best solution to a given problem.&lt;br /&gt;&lt;br /&gt;I wish you find this post useful.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=9u54Xs22_SI"&gt;http://www.youtube.com/watch?v=9u54Xs22_SI&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-8216131608636255950?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/8216131608636255950/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=8216131608636255950' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8216131608636255950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8216131608636255950'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/09/soy-el-capitan-de-la-nave-tengo-el.html' title='Soy El Capitán De La Nave Tengo El Control, Llamando A La Tierra Esperando Contestación, Soy Un Cowboy Del Espacio Azul Eléctrico (Llamando A La Tierra - M.Clan)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-8823595498015740679</id><published>2011-07-22T09:20:00.001+02:00</published><updated>2011-07-25T08:09:45.900+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='custom fest'/><category scheme='http://www.blogger.com/atom/ns#' term='hamcrest'/><category scheme='http://www.blogger.com/atom/ns#' term='assertions'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='custom hamcrest'/><category scheme='http://www.blogger.com/atom/ns#' term='fest'/><title type='text'>Tu I Jo Asseguts A La Barra D’un Bar, Sona Bona Música I Som Davant Del Mar (Al Mar - Manel)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/en/3/39/Studioghibli.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="90" src="http://upload.wikimedia.org/wikipedia/en/3/39/Studioghibli.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In current post I am going to talk about differences between &lt;b&gt;Hamcrest &lt;/b&gt;and &lt;b&gt;Fest Fluent Assertions&lt;/b&gt;. The reason of this post is not to tell you if you should use one or the other. I only want to show you how both implementations resolve the problem of writing readable assertions.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;To compare both &lt;i&gt;APIs &lt;/i&gt;I have created two &lt;i&gt;JUnits&lt;/i&gt;, one using &lt;b&gt;Hamcrest &lt;/b&gt;assertions&amp;nbsp;and one where &lt;b&gt;Fest &lt;/b&gt;assertions are used.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The comparision is done using only common operations (&lt;i&gt;Logical&lt;/i&gt;, &lt;i&gt;Object&lt;/i&gt;, &lt;i&gt;Collections&lt;/i&gt;, &lt;i&gt;Number&lt;/i&gt;, &lt;i&gt;Text&lt;/i&gt;) and creation of new matchers. I am not going to compare which ones have implemented more matchers or kinds of matchers, because I think this is not a parameter to use for choosing what library fits better to your project. Moreover in both &lt;i&gt;APIs &lt;/i&gt;you can extend them for creating your own matchers.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's start showing model representing a simple modelling of &lt;i&gt;Studio Ghibli &lt;/i&gt;&lt;a href="http://en.wikipedia.org/wiki/Studio_Ghibli"&gt;http://en.wikipedia.org/wiki/Studio_Ghibli&lt;/a&gt; movies information.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080964.js?file=StudioGhibli.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Imports:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Hamcrest &lt;/b&gt;requires 11 imports:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080979.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;while &lt;b&gt;Fest &lt;/b&gt;requires 2 imports:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080984.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;in fact this is not a good or bad thing how many imports are required, but it is always a headache remember where a required assertion is packaged. Because &lt;b&gt;Fest &lt;/b&gt;uses &lt;i&gt;Fluent Interfaces&lt;/i&gt; approach with two imports all operations are available with &lt;i&gt;IDE's &lt;/i&gt;"auto-completation" feature.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Simple asserts:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Not much difference between &lt;b&gt;Hamcrest &lt;/b&gt;and &lt;b&gt;Fest&lt;/b&gt;, in case of &lt;b&gt;Fest&lt;/b&gt; verb is also added in method name creating a much readable assert.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080990.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080994.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Logical asserts:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In this case we find a big difference. &lt;b&gt;Hamcrest &lt;/b&gt;supports logical operations and can be used independently, meanwhile logical operations in &lt;b&gt;Fest &lt;/b&gt;are a part of the method:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1080999.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1081005.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;u&gt;Object asserts:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Same object operations are provided in both &lt;i&gt;APIs&lt;/i&gt;. There is only one difference, in &lt;b&gt;Fest &lt;/b&gt;you can chain callings of methods, so number of asserts compared to &lt;b&gt;Hamcrest &lt;/b&gt;are fewer.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1081019.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1081025.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Collection asserts:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;In case of &lt;i&gt;Collections&lt;/i&gt; is where they differ more from each other. &lt;b&gt;Hamcrest&lt;/b&gt; deals with &lt;i&gt;Collections&lt;/i&gt; and &lt;i&gt;Maps&lt;/i&gt; with methods like &lt;i&gt;hasKey&lt;/i&gt;, &lt;i&gt;hasValue&lt;/i&gt;, &lt;i&gt;hasItem&lt;/i&gt;. &lt;b&gt;Fest&lt;/b&gt; uses a more generic calling like &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;entry&lt;/i&gt;; I have not found any way for asserting key instead of key-value in &lt;b&gt;Fest&lt;/b&gt;.&lt;br /&gt;Moreover in this example I also compare how to access a &lt;i&gt;bean property&lt;/i&gt;&amp;nbsp;in each elements of collection. From my point of view I think that &lt;b&gt;Fest&lt;/b&gt; has a better approach resolving this case.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1083008.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1083011.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;&lt;b&gt;Number asserts:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;As in simple asserts, there is no much difference between them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1083036.js?file=HamcrestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1088697.js?file=FestAssertion.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;&lt;b&gt;String asserts:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;b&gt;Hamcrest&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1088701.js?file=FestAssertion.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Fest&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1083041.js?file=FestAssertions.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you have noted &lt;b&gt;Hamcrest &lt;/b&gt;and &lt;b&gt;Fest &lt;/b&gt;are very similar, but I think that &lt;b&gt;Fest &lt;/b&gt;solves the same problem but in much cleaner way.&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Although both solutions offer very similar matchers, each implementation is so different, so creation of a custom matcher is different too. In &lt;b&gt;Hamcrest &lt;/b&gt;you should create a class that extends from &lt;i&gt;TypeSafeMatcher&lt;/i&gt;. In &lt;b&gt;Fest &lt;/b&gt;there are two possibilities, first one is extending &lt;b&gt;Fest&lt;/b&gt;-assertions with custom condition (using already &lt;b&gt;Fest &lt;/b&gt;structure and &lt;u&gt;defined types&lt;/u&gt;), and the second one is extending with custom assertion (creating a new &lt;i&gt;assertThat &lt;/i&gt;implementation for required type).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Hamcrest &lt;/b&gt;extension for asserting that a character is a human:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1088732.js?file=IsCharacterHuman.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In case of &lt;b&gt;Fest&lt;/b&gt; there are two approaches, the first one, that requires that our class extends from &lt;i&gt;Condition&lt;/i&gt;. As I told previously, extending &lt;i&gt;Condition&lt;/i&gt; implies using the same kind of types supported by &lt;i&gt;org.fest.assertions.Assertions.assertThat&lt;/i&gt; method (object, int, short, list, array, ...). In previous case our type is &lt;i&gt;Character&lt;/i&gt;, and of course does not exist an overload of &lt;i&gt;Assertions.assertThat&lt;/i&gt; method with &lt;i&gt;Character&lt;/i&gt;, but &lt;i&gt;java.lang.Object&lt;/i&gt;. So our class should be:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1088749.js?file=CharacterHumanCondition.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As you probably noted, you need to cast &lt;i&gt;character&lt;/i&gt; variable to &lt;i&gt;Character&lt;/i&gt;, neither a clean solution nor optimal. But of course you can use second method, extending from&lt;i&gt; GenericAssert&lt;/i&gt;. This class (a &lt;i&gt;Fluent&lt;/i&gt; class) will be the responsible of implementing an &lt;i&gt;assertThat&lt;/i&gt; that accepts &lt;i&gt;Character&lt;/i&gt; objects, and moreover will implement matcher methods. And I say methods because unlike &lt;b&gt;Hamcrest&lt;/b&gt;, &lt;b&gt;Fest&lt;/b&gt; can contain more than one matcher in each class. For example if there are some tests that we are asserting if character is human, and in another ones asserting if is human and if has a name, in &lt;b&gt;Hamcrest&lt;/b&gt; we should create two classes. In &lt;b&gt;Fest&lt;/b&gt; you don't have this restriction.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1088751.js?file=CharacterAssert.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As it is told in &lt;b&gt;Fest&lt;/b&gt; site &lt;quote&gt;"Which one to use? Hamcrest or FEST-Assert? It is up to you...it depends on the needs of your project and your coding style!"&lt;/quote&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/HVF.zip"&gt;Download&lt;/a&gt; code.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=GjWLXZ4WdQU"&gt;http://www.youtube.com/watch?v=GjWLXZ4WdQU&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-8823595498015740679?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/8823595498015740679/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=8823595498015740679' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8823595498015740679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8823595498015740679'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/07/tu-i-jo-asseguts-la-barra-dun-bar-sona.html' title='Tu I Jo Asseguts A La Barra D’un Bar, Sona Bona Música I Som Davant Del Mar (Al Mar - Manel)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2530551166760559475</id><published>2011-07-04T08:44:00.000+02:00</published><updated>2011-07-04T08:44:53.107+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJP'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring-Data'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc extension'/><category scheme='http://www.blogger.com/atom/ns#' term='java persistence'/><title type='text'>Umetxoak Ikusirik Lorea Ezin Bizirik Arantzak Kendu Nahi Dizkio Bizi Berri Bat Eman (Loretxoa - Benito Lertxundi)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.easierjava.com/images/easierjava.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="30" src="http://www.easierjava.com/images/easierjava.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;EJP&lt;/b&gt; (or &lt;a href="http://www.easierjava.com/"&gt;Easy Java Persistence&lt;/a&gt;) is a powerful and easy to use relational database persistence API for &lt;i&gt;Java&lt;/i&gt;.&amp;nbsp;It has no need for mapping &lt;i&gt;Annotations&lt;/i&gt; or &lt;i&gt;XML&lt;/i&gt; configuration, and there is no need to extend any classes or implement any interfaces. In it is site we can find the following statement: "&lt;i&gt;EJP is, by far, the easiest persistence API available for Java.&lt;/i&gt;"&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;From my point of view &lt;b&gt;EJP&lt;/b&gt; is a mixture of some features between &lt;i&gt;myBatis&lt;/i&gt; and&lt;i&gt; Spring Jdbc Template Row Mapper&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;An example of &lt;b&gt;EJP&lt;/b&gt; from its website:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1056757.js?file=EJP.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;and Customer and Support classes are simple &lt;i&gt;POJOs&lt;/i&gt; without annotations or any special tag, and no configuration file.&lt;br /&gt;&lt;br /&gt;What I am going to explain in this post is how integrate &lt;b&gt;EJP&lt;/b&gt; with &lt;i&gt;Spring&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;First of all, we are going to create an interface which defines all permitted operations:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1056760.js?file=EjpJdbcOperations.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This is an example of common operations provided by &lt;b&gt;EJP&lt;/b&gt;. Methods that should be clarified are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;newDatabase&lt;/i&gt; method is used for returning a &lt;i&gt;Database&lt;/i&gt; object. This object is a facade that implements all operations supported by &lt;b&gt;EJP&lt;/b&gt;. It is the main class of &lt;b&gt;EJP&lt;/b&gt; project with permission of &lt;i&gt;DatabaseManager&lt;/i&gt; class.&lt;/li&gt;&lt;li&gt;&lt;i&gt;loadAssociations&lt;/i&gt; are responsible (as its name suggests) to load an object associations.&lt;/li&gt;&lt;li&gt;&lt;i&gt;queryForObject&lt;/i&gt; methods execute a "query by example" queries.&lt;/li&gt;&lt;li&gt;&lt;i&gt;queryForInt&lt;/i&gt; is a method used for queries that return numerical results like &lt;i&gt;count&lt;/i&gt;(*), &lt;i&gt;avg&lt;/i&gt;(...), ...&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div&gt;&lt;i&gt;EjpJdbcTemplate&lt;/i&gt; is the implementation of previous interface, and makes use of &lt;i&gt;JdbcTemplate&lt;/i&gt; class as core.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Getting a new Database:&lt;/u&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1059921.js?file=EjpJdbcTemplate.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Remember that &lt;i&gt;Database&lt;/i&gt; object is the core of &lt;b&gt;EJP&lt;/b&gt;, and is required to execute all &lt;b&gt;EJP&lt;/b&gt; operations. This method creates one &lt;i&gt;Database&lt;/i&gt; with given &lt;i&gt;Connection&lt;/i&gt;. &lt;i&gt;databaseName&lt;/i&gt; is not mandatory, but for no reason is a constructor attribute. A null can be passed without any problem. In this implementation database name is a class attribute.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Deleting:&lt;/u&gt;&lt;br /&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1059922.js?file=EjpJdbcTemplate.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No secret in deleting an object. Using &lt;i&gt;ConnectionCallback&lt;/i&gt;, connection is provided, and &lt;i&gt;Database&lt;/i&gt; object is created.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Loading Associations:&lt;/u&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1059924.js?file=EjpJdbcTemplate.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you want to load explicitly all associations of an object, load associations method must be called. The only integration difficult is that &lt;i&gt;database.loadAssociations&lt;/i&gt;&amp;nbsp;returns &lt;i&gt;void&lt;/i&gt;, and &lt;i&gt;ConnectionCallback&lt;/i&gt; should always return a result. In this case &lt;i&gt;void.TYPE&lt;/i&gt; is used.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Executing Queries:&lt;/u&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1059926.js?file=EjpJdbcTemplate.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In this case most important line is where &lt;i&gt;Database&lt;/i&gt; &lt;i&gt;executeQuery&lt;/i&gt; method is called. This method returns a class of type &lt;i&gt;Result&lt;/i&gt;. This class is a wrapper of &lt;i&gt;ResultSet&lt;/i&gt; class but also can deal directly with beans (implicit wrapping), instead of getting one-by-one each parameter. But for following &lt;i&gt;JdbcTemplate&lt;/i&gt; strategy and use a row mapper, &lt;i&gt;ResultSet&lt;/i&gt; is used for mapping results.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Querying&amp;nbsp;for Int:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1059928.js?file=EjpJdbcTemplate.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;See that follows the same schema as &lt;i&gt;executeQuery&lt;/i&gt;, but instead of using &lt;i&gt;RowMapperResultSetExtractor&lt;/i&gt;, a &lt;i&gt;SingleColumnRowMapper&lt;/i&gt; is used. This mapper is used when the query result returns a single result.&lt;br /&gt;&lt;br /&gt;Now I am going to show how to use this template into a &lt;i&gt;DAO&lt;/i&gt; implementation.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1059929.js?file=EjpCustomerDao"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Not much secret in this &lt;i&gt;DAO&lt;/i&gt;. Only two methods requires special review &lt;i&gt;findAllCustomersOrderedByName&lt;/i&gt;() and &lt;i&gt;findCustomerByExample&lt;/i&gt;()&lt;br /&gt;&lt;br /&gt;The first one:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;this.template.queryForObject(Customer.class, "ORDER BY first_name",BeanPropertyRowMapper.newInstance(Customer.class))&amp;nbsp;&lt;/blockquote&gt;&lt;br /&gt;&amp;nbsp;is converted by &lt;b&gt;EJP&lt;/b&gt; to &lt;i&gt;SELECT * FROM Customer ORDER BY first_name&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;The second one:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;this.template.queryForObject(customer, BeanPropertyRowMapper.newInstance(Customer.class))&amp;nbsp;&lt;/blockquote&gt;&lt;br /&gt;instead of receiving a &lt;i&gt;Class&lt;/i&gt;&amp;nbsp;it receives an instance itself to execute the query. In case that &lt;i&gt;first name&lt;/i&gt; field was set to &lt;i&gt;alex&lt;/i&gt;, the equivalent &lt;i&gt;SQL&lt;/i&gt; query would be &lt;i&gt;SELECT * FROM Customer WHERE first_name='alex'&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now I have explained a strategy to integrate &lt;b&gt;EJP&lt;/b&gt; with &lt;i&gt;Spring&lt;/i&gt;. Because I have followed same structure as &lt;b&gt;Spring-Data Jdbc-Extension&lt;/b&gt; project, rather than create a &lt;i&gt;"HelloWorld"&lt;/i&gt; project, I decided to fork &lt;b&gt;Spring-Data&lt;/b&gt; project into my &lt;i&gt;Github&lt;/i&gt; account, and uploaded the code as a new extension for the project. Moreover a &lt;i&gt;Jira&lt;/i&gt; issued has been created with id &lt;b&gt;DATAJDBC-11&lt;/b&gt;. If you want to watch full code and unit tests go to &lt;i&gt;git@github.com:maggandalf/spring-data-jdbc-ext.git &lt;/i&gt;and review&amp;nbsp;&lt;i&gt;spring-data-jdbc-ext/spring-data-jdbc-core/src/main/java/org/springframework/data/jdbc/ejp&lt;/i&gt; directory.&lt;/div&gt;&lt;br /&gt;I wish you have found this post useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=PlEknDUSRc0&amp;amp;feature=fvwrel"&gt;http://www.youtube.com/watch?v=PlEknDUSRc0&amp;amp;feature=fvwrel&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2530551166760559475?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2530551166760559475/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2530551166760559475' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2530551166760559475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2530551166760559475'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/07/umetxoak-ikusirik-lorea-ezin-bizirik.html' title='Umetxoak Ikusirik Lorea Ezin Bizirik Arantzak Kendu Nahi Dizkio Bizi Berri Bat Eman (Loretxoa - Benito Lertxundi)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5024971817096249918</id><published>2011-06-20T08:50:00.005+02:00</published><updated>2011-06-20T11:47:43.333+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring framework 3.1'/><category scheme='http://www.blogger.com/atom/ns#' term='STS'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='spring 3.1'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Template Project'/><title type='text'>Tonari No To To Ro   Totoro   To To Ro   Totoro,   Kodomo No Toki Ni Dake   Anata Ni Otozureru,   Fushigina Deai (Tonari No Totoro - Ghibli Songs)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;Spring Framework 3.1 M2&lt;/b&gt;&amp;nbsp;has been released past week. This new release is the last milestone, and next versions will be tagged as&amp;nbsp;&lt;i&gt;RC&lt;/i&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;This new version completes the work started in &lt;i&gt;M1&lt;/i&gt;, and adds some new&amp;nbsp;functionalities.&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;To summarize them we can name:&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Configuring&amp;nbsp;&lt;i&gt;Spring Web MVC&lt;/i&gt;&amp;nbsp;application without&amp;nbsp;&lt;i&gt;web.xml (&lt;a href="http://alexsotob.blogspot.com/2011/06/its-strange-but-its-true-i-cant-get.html"&gt;post&lt;/a&gt;)&lt;/i&gt;.&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Cache abstraction&lt;/i&gt;&amp;nbsp;has been revised.&lt;/li&gt;&lt;li&gt;A new "&lt;i&gt;packagesToScan&lt;/i&gt;" feature for&amp;nbsp;&lt;i&gt;JPA&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;&lt;i&gt;REST&lt;/i&gt;&amp;nbsp;support refinements with respect to&amp;nbsp;&lt;i&gt;URI templates&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;And many more refinements.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In current post I will talk about &lt;b&gt;Java-based&amp;nbsp;container configuration&lt;/b&gt;&amp;nbsp;approach to setting up a&amp;nbsp;&lt;i&gt;Spring Web MVC&lt;/i&gt; application.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;As a reference application we are going to migrate &lt;i&gt;Spring MVC Template Project&lt;/i&gt; to &lt;b&gt;100% Java-based container configuration&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If you are using &lt;i&gt;STS&lt;/i&gt;, you can create a new &lt;i&gt;Spring&lt;/i&gt; project from&lt;i&gt; Spring Template Project&lt;/i&gt; wizard:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_yoYEGyLWQKc/TLWj6CVmlpI/AAAAAAAAABw/VxuRkYS24Ak/s1600/templateWizard.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/_yoYEGyLWQKc/TLWj6CVmlpI/AAAAAAAAABw/VxuRkYS24Ak/s400/templateWizard.PNG" width="367" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;One of these templates is for creating a &lt;i&gt;Spring Web MVC&lt;/i&gt; application. In my &lt;i&gt;STS&lt;/i&gt; version, this template creates a &lt;i&gt;XML-based container configuration&lt;/i&gt; project.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Dd3Qkh0qvJ8/TfyAVRJtDfI/AAAAAAAAF_c/QfntRqlh3EE/s1600/oldSpringmvc.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/-Dd3Qkh0qvJ8/TfyAVRJtDfI/AAAAAAAAF_c/QfntRqlh3EE/s400/oldSpringmvc.JPG" width="226" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you have already noted, important elements of this project are:&amp;nbsp;&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;HomeController&lt;/i&gt; that redirects to &lt;i&gt;home.jsp&lt;/i&gt; page.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;web.xml&lt;/i&gt; file where&lt;i&gt; Spring DispatcherServlet&lt;/i&gt;&amp;nbsp;(loading &lt;i&gt;servlet-context.xml&lt;/i&gt;) and &lt;i&gt;ContextLoaderListener&lt;/i&gt; (loading&lt;i&gt; root-context.xml&lt;/i&gt;) are specified.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;root-context.xml&lt;/i&gt; defining shared resources visible to all other web components.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;servlet-context.xml&lt;/i&gt; defining servlet's request-processing infrastructure, and importing &lt;i&gt;controllers.xml&lt;/i&gt; configuration file.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;controllers.xml&lt;/i&gt; as its name suggests configures controllers.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;What we are going to create is a revision of&amp;nbsp;&lt;i&gt;Spring MVC Template Project&lt;/i&gt;&amp;nbsp;that instead of setting up project using &lt;i&gt;XMLs&lt;/i&gt;, is configured using &lt;i&gt;Java classes&lt;/i&gt;. The new directory structure is:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-vFVFXPE95v4/Tf8LcEfx8hI/AAAAAAAAF_k/8rRU59wcOpU/s1600/newSpringMVC.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/-vFVFXPE95v4/Tf8LcEfx8hI/AAAAAAAAF_k/8rRU59wcOpU/s400/newSpringMVC.JPG" width="222" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="text-align: justify;"&gt;If you look carefully, under &lt;i&gt;src/main/webapp&lt;/i&gt; directory, there are no &lt;i&gt;XML&lt;/i&gt; &lt;i&gt;Spring&lt;/i&gt; configuration files. And no &lt;i&gt;web.xml&lt;/i&gt;, but I will talk about that later. For now imagine that under &lt;i&gt;WEB&lt;/i&gt;-INF there is a &lt;i&gt;web.xml &lt;/i&gt;file.&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that structure is very similar to previous one, but &lt;i&gt;spring&lt;/i&gt; directory is removed and &lt;i&gt;config&lt;/i&gt; package is created. Moreover &lt;i&gt;XML&lt;/i&gt; files have been converted to &amp;nbsp;standard classes.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Again ignore&amp;nbsp;strange &lt;i&gt;WebAppInitializer&lt;/i&gt;&amp;nbsp;class that has&amp;nbsp;appeared. Let's see applied changes:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;root-context.xml&lt;/i&gt; has its&amp;nbsp;equivalent&amp;nbsp;with &lt;i&gt;mytld.mycompany.myapp.config.RootContextConfig&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1035342.js?file=RootContext.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Most important thing in previous class is &lt;i&gt;@Configuration&lt;/i&gt; annotation. This annotation indicates that the class can be used by the &lt;i&gt;Spring IoC&lt;/i&gt; container as a source of bean definitions.&lt;br /&gt;&lt;br /&gt;Class that replaces &lt;i&gt;servlet-context.xml&lt;/i&gt; file is:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1035336.js?file=ServletContext.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I am going to show you &lt;i&gt;servlet-context.xml &lt;/i&gt;content so you can ensure that &lt;i&gt;XML&lt;/i&gt; and &lt;i&gt;Class&lt;/i&gt; contain &amp;nbsp;the same parameters.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1033060.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Apart from &lt;i&gt;@Configuration&lt;/i&gt; annotation, this class is annotated with &lt;i&gt;@EnableWebMvc&lt;/i&gt;, which enables &lt;i&gt;@Controller&lt;/i&gt;&amp;nbsp;programming model, and &lt;i&gt;@Import &lt;/i&gt;for importing other bean definitions, like&lt;i&gt; servlet-context.xml&lt;/i&gt; imports &lt;i&gt;controllers.xml&lt;/i&gt;. This class extends from &lt;i&gt;WebMvcConfigurerAdapter &lt;/i&gt;because some extra configuration is required.&amp;nbsp;&lt;i&gt;WebMvcConfigurerAdapter&lt;/i&gt;&amp;nbsp;defines options for&amp;nbsp;customizing&amp;nbsp;or adding to the default &lt;i&gt;Spring MVC configuration&lt;/i&gt;. In summary it provides customizing parameters as &lt;i&gt;mvc namespace&lt;/i&gt; does.&amp;nbsp;In our case, as &lt;i&gt;servlet-context&lt;/i&gt; does, we define static resources path to &lt;i&gt;/resources/&lt;/i&gt;, so we only override &lt;i&gt;configureResourceHandling&lt;/i&gt; method. If for example we would like to register interceptors, &lt;i&gt;configureInteceptors&lt;/i&gt; method should be&amp;nbsp;overridden. And finally&lt;i&gt; @Bean&lt;/i&gt; is used for creating the view resolver bean. &lt;i&gt;@Bean&lt;/i&gt; methods define instantiation, configuration, and initialization logic for objects to be managed by the &lt;i&gt;Spring IoC container&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next class is called &lt;i&gt;ControllerConfig&amp;nbsp;&lt;/i&gt;and is the responsible of registering controllers. In this case &lt;i&gt;@Bean&lt;/i&gt; approach is used because&lt;i&gt; component-scan&lt;/i&gt; is not supported directly. Anyway you can use &lt;i&gt;scan&lt;/i&gt; method of &lt;i&gt;AnnotationConfigApplicationContext &lt;/i&gt;for same purpose but in&amp;nbsp;this case first choice has been chosen.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1035337.js?file=Controller.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And finally &lt;i&gt;web.xml&lt;/i&gt; must be changed for loading &lt;i&gt;Java-based configuration&lt;/i&gt; instead of &lt;i&gt;XML-based&lt;/i&gt; ones. In this case &lt;i&gt;contextClass&lt;/i&gt;&amp;nbsp;parameter of &lt;i&gt;DispatcherServlet&lt;/i&gt; and &lt;i&gt;ContextLoader&lt;/i&gt; listener must be changed to &lt;i&gt;AnnotationConfigWebApplicationContext&lt;/i&gt; so &lt;i&gt;Spring IoC Container&lt;/i&gt; can load beans from configuration classes, and &lt;i&gt;contextConfigLocation&lt;/i&gt; must be pointing to configuration classes, and not &lt;i&gt;XML&lt;/i&gt; files.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1035338.js?file=web.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And I suppose you are wondering why in previous directory structure cannot be seen &lt;i&gt;web.xml&lt;/i&gt; but &lt;i&gt;WebAppInitializer&lt;/i&gt; class. This is explained in my &lt;a href="http://alexsotob.blogspot.com/2011/06/its-strange-but-its-true-i-cant-get.html"&gt;post&lt;/a&gt;, and is another new feature of&lt;i&gt; Spring 3.1 M2, &lt;/i&gt;that you can configure a&amp;nbsp;&lt;i&gt;Spring Web MVC&lt;/i&gt; application with no &lt;i&gt;web.xml&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;So if you want a &lt;b&gt;100% Java-based configuration&lt;/b&gt;, simply removes &lt;i&gt;web.xml&lt;/i&gt; file and creates the &lt;i&gt;WebAppInitializer&lt;/i&gt; class, which looks like:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1035340.js?file=WebAppInitializer.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you can see, same elements of &lt;i&gt;web.xml&lt;/i&gt; are present but they are configured in a programmatic way.&lt;br /&gt;&lt;br /&gt;Hope you find the post useful, of course you can create hybrid applications, mixing elements configured in &lt;i&gt;XML&lt;/i&gt; way and other ones configured in &lt;i&gt;Java&lt;/i&gt; classes.&lt;br /&gt;&lt;br /&gt;Two &lt;b&gt;Spring Template Projects&lt;/b&gt; are provided, one configuring &lt;i&gt;Spring MVC&lt;/i&gt; application in a Java-based fashion and &lt;i&gt;web.xml&lt;/i&gt;, and another one &lt;i&gt;100% Java-based&lt;/i&gt; configured.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/spring-mvc3.1M2-template.zip"&gt;Spring Template Project with web.xml&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/spring-mvc3.1M2-template-nowebxml.zip"&gt;Spring Template Project no web.xml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=KzLDdof7U8M&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=KzLDdof7U8M&amp;amp;feature=related&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5024971817096249918?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5024971817096249918/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5024971817096249918' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5024971817096249918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5024971817096249918'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/06/tonari-no-to-to-ro-totoro-to-to-ro.html' title='Tonari No To To Ro   Totoro   To To Ro   Totoro,   Kodomo No Toki Ni Dake   Anata Ni Otozureru,   Fushigina Deai (Tonari No Totoro - Ghibli Songs)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_yoYEGyLWQKc/TLWj6CVmlpI/AAAAAAAAABw/VxuRkYS24Ak/s72-c/templateWizard.PNG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2178790676482262390</id><published>2011-06-15T08:34:00.000+02:00</published><updated>2011-06-15T08:34:09.878+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring framework 3.1'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='servlet 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='java-based spring container configuration'/><title type='text'>It's Strange But It's True,  I Can't Get Over The Way You Love Me Like You Do,  But I Have To Be Sure,  When I Walk Out That Door  (I Want To Break Free - Queen)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.zenzi.org/blog-imagen/Diciembre-2010/record-guiness-acrobacia-avion.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="218px" src="http://www.zenzi.org/blog-imagen/Diciembre-2010/record-guiness-acrobacia-avion.jpg" t8="true" width="320px" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Spring Framework 3.1 M2&lt;/b&gt; has been released past week. This new release is the last milestone, and next versions will be tagged as &lt;i&gt;RC&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This new version completes the work started in M1, and adds&amp;nbsp;new&amp;nbsp;functionalities.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To summarize them we can name:&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Java-based&lt;/i&gt; &lt;i&gt;application configuration&lt;/i&gt; approach has changed from the&lt;i&gt; @Feature&lt;/i&gt; approach in &lt;i&gt;M1&lt;/i&gt; to &lt;i&gt;@Enable*&lt;/i&gt; annotations (I will talk about this in next post).&lt;/li&gt;&lt;li&gt;&lt;i&gt;Cache abstraction&lt;/i&gt; has been revised.&lt;/li&gt;&lt;li&gt;A new "&lt;i&gt;packagesToScan&lt;/i&gt;" feature for &lt;i&gt;JPA&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;&lt;i&gt;REST&lt;/i&gt; support refinements with respect to &lt;i&gt;URI templates&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Many more refinements.&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;In current post I will talk about one new feature that will allow us to configure &lt;i&gt;Spring Web MVC&lt;/i&gt; application without &lt;i&gt;web.xml&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With &lt;b&gt;Servlet 3.0&lt;/b&gt; specification,&lt;i&gt; web.xml&lt;/i&gt; is not required anymore, you can configure your servlets using &lt;i&gt;@WebServlet&lt;/i&gt; annotation. Prior to &lt;i&gt;Spring 3.1&lt;/i&gt;, &lt;i&gt;DispatcherServlet&lt;/i&gt; should be declared and configured in &lt;i&gt;web.xml, &lt;/i&gt;so although our application was deployed using&lt;b&gt; Servlet 3.0 specification&lt;/b&gt;, &lt;i&gt;web.xml&lt;/i&gt; was "&lt;u&gt;a must&lt;/u&gt;". With &lt;b&gt;Spring 3.1&lt;/b&gt;, things are different. You can use &lt;b&gt;WebApplicationInitializer&lt;/b&gt; approach for bootstrapping a &lt;em&gt;Spring&lt;/em&gt; web application without &lt;i&gt;web.xml&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;First of all let’s take a look at traditional way (using &lt;i&gt;web.xml&lt;/i&gt;).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1026559.js?file=web.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;No problem here, if you have developed applications using &lt;i&gt;Spring MVC&lt;/i&gt; this file will sound you familiar.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But now let’s use &lt;b&gt;WebApplicationInitializer&lt;/b&gt; approach.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Spring 3.1&lt;/b&gt; comes with &lt;b&gt;WebApplicationInitializer&lt;/b&gt;&amp;nbsp;interface, that must be implemented in &lt;b&gt;Servlet 3.0&lt;/b&gt; environments in order to configure the &lt;i&gt;ServletContext&lt;/i&gt;&amp;nbsp;programmatically&amp;nbsp;- as opposed to (or in conjunction with) the traditional &lt;i&gt;web.xml&lt;/i&gt;-based approach.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What we need is a class (can be created in &lt;u&gt;any&lt;/u&gt; &lt;i&gt;package, &lt;/i&gt;next I will explain why!!!) that will implement &lt;b&gt;WebApplicationInitializer&lt;/b&gt;. Our equivalent class to previous &lt;i&gt;web.xml&lt;/i&gt; is:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1026562.js?file=MyWebAppInitializer.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that same information is required, but is provided programmatically instead of using &lt;i&gt;web.xml&lt;/i&gt;. &lt;i&gt;Spring&lt;/i&gt; application context must be created by you setting config file/s location, &lt;i&gt;DispatcherServlet&lt;/i&gt; is still valid and must be registered too using &lt;i&gt;addServlet&lt;/i&gt; method, and of course &lt;i&gt;context-param&lt;/i&gt; can be added using &lt;em&gt;setInitParameter&lt;/em&gt; method. And only creating this class that&amp;nbsp;implements &lt;strong&gt;WebApplicationInitializer&lt;/strong&gt;, you can remove your &lt;em&gt;web.xml&lt;/em&gt; from your application&lt;em&gt;.&lt;/em&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Look ma' no &lt;i&gt;web.xml&lt;/i&gt; and &lt;i&gt;Spring Web&lt;/i&gt; application is still working. And now let me explain why if our class is not configured anywhere and moreover is created in any place (inside classpath), is&amp;nbsp;instantiated and its &lt;i&gt;onStartup&lt;/i&gt; method called?&amp;nbsp;&lt;b&gt;Servlet 3.0&lt;/b&gt; &lt;i&gt;ServletContainerInitializer&lt;/i&gt;&amp;nbsp;is designed to support code-based configuration of the servlet container at startup phase. &lt;em&gt;Spring&lt;/em&gt; people have created&amp;nbsp;&lt;i&gt;SpringServletContainerInitializer &lt;/i&gt;class that implements&amp;nbsp;&lt;i&gt;ServletContainerInitializer, &lt;/i&gt;and&amp;nbsp;this class will be loaded and instantiated and&amp;nbsp;&lt;i&gt;onStartup&lt;/i&gt; method invoked by any &lt;b&gt;Servlet 3.0&lt;/b&gt;-compliant container during container startup.&amp;nbsp;This occurs through the &lt;i&gt;JAR Services API&lt;/i&gt; &lt;i&gt;ServiceLoader.load(Class)&lt;/i&gt; method detecting the &lt;b&gt;spring-web&lt;/b&gt; module's &lt;b&gt;META-INF/services/javax.servlet.ServletContainerInitializer&lt;/b&gt; service provider configuration file.&lt;/div&gt;&lt;br /&gt;Hope you like this new feature.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Note: Servlet 3.0 container is required (for example Tomcat 7), and versions of Tomcat &amp;lt;=7.0.14, root mapping ("/") cannot be used.&lt;/blockquote&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/spring-mvc3.1-nowebxml.zip"&gt;Download &lt;/a&gt;Code.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=Odk3W3qLByI"&gt;http://www.youtube.com/watch?v=Odk3W3qLByI&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2178790676482262390?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2178790676482262390/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2178790676482262390' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2178790676482262390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2178790676482262390'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/06/its-strange-but-its-true-i-cant-get.html' title='It&apos;s Strange But It&apos;s True,  I Can&apos;t Get Over The Way You Love Me Like You Do,  But I Have To Be Sure,  When I Walk Out That Door  (I Want To Break Free - Queen)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-4656735761742010907</id><published>2011-06-14T07:49:00.000+02:00</published><updated>2011-06-14T07:49:47.568+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='minification javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='yui compression'/><category scheme='http://www.blogger.com/atom/ns#' term='jsmin'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='jawr'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='css minification'/><title type='text'>Y Hay Un Decano También, Y Un Abogado También,  Y Un Policía Rodeado De Ladrones (La Taberna del Buda - Café Quijano)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://l.yimg.com/a/i/brand/purplelogo/uh/us/ydn.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://l.yimg.com/a/i/brand/purplelogo/uh/us/ydn.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Due to the advent of mobile internet, a variety of devices have connection to the world (mobiles, pads, GPS, netbooks, ...), and these devices could not be as powerful as desktops/notebooks. For this reason, keeping web pages as lightweight as possible is a must. Improving the engineering design of a page or a web application usually is the biggest savings and that should always be a primary strategy. With the right design, some other strategies can be followed. One of these is code minification.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now-days, &lt;i&gt;jQuery&lt;/i&gt; are becoming so popular in client-side of web development. &lt;i&gt;jQuery&lt;/i&gt; is a cross-browser &lt;i&gt;Javascript&lt;/i&gt; library designed to simplify the client-side scripting of &lt;i&gt;HTML&lt;/i&gt;. &lt;i&gt;jQuery&lt;/i&gt; itself is composed by "one" file. Thanks of that boom, &lt;i&gt;Javascript&lt;/i&gt; is becoming more important when a web interface is developed.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Have you ever opened &lt;i&gt;jQuery Javascript&lt;/i&gt; file? Let me tell you what you will see. Nothing human readable, all code occupied only one long line, and variables and methods name are as short as possible:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See this example:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1020471.js?file=jQuery.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Of course, there is no developer in the world (or at least I wish), that could write this code. So where this code comes from? It is so easy, it comes from a &lt;i&gt;Javascript&lt;/i&gt; minifier tool.&lt;br /&gt;&lt;br /&gt;The goal of &lt;i&gt;Javascript&lt;/i&gt; and &lt;i&gt;CSS&lt;/i&gt; minification is always to preserve the operational qualities of the code while reducing its overall byte footprint&lt;br /&gt;&lt;br /&gt;There are a lot of tools designed for minifying &lt;i&gt;Javascript&lt;/i&gt; files. One of these are &lt;b&gt;YUI Compressor&lt;/b&gt;&amp;nbsp;from &lt;i&gt;Yahoo&lt;/i&gt;. From its site:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;“The &lt;b&gt;YUI Compressor&lt;/b&gt; is &lt;i&gt;Javascript/CSS&lt;/i&gt; minifier designed to be 100% safe and yield a higher compression ratio than most other tools. Tests on the &lt;i&gt;YUI Library&lt;/i&gt; have shown savings of over 20% compared to &lt;i&gt;JSMin&lt;/i&gt; (becoming 10% after HTTP compression).”&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Because the growth of popularity of &lt;i&gt;jQuery&lt;/i&gt;, and &lt;i&gt;HTML 5/CSS3&lt;/i&gt;, client-side coding is playing an increasingly important role in web development, and one of these consequences is that in client-side you could need to develop some custom &lt;i&gt;Javascript&lt;/i&gt; files, apart from using already developed &lt;i&gt;Javascript&lt;/i&gt; libraries like &lt;i&gt;jQuery&lt;/i&gt;. And then the question is, if &lt;i&gt;jQuery&lt;/i&gt; minify their files, why I cannot do the same with my &lt;i&gt;Javascript/CSS&lt;/i&gt; files? And the answer is: “Yes you are right”, and also I say: “We will automatize this process into &lt;i&gt;Maven&lt;/i&gt;, so your web project will be packaged with minified scripts”.&lt;br /&gt;&lt;br /&gt;Let’s start with a very simple “Hello World” script file:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1020476.js?file=myscript.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If you execute manually &lt;b&gt;YUI Compressor&lt;/b&gt; as standalone application (&lt;i&gt;java -jar yuicompressor-x.y.z.jar&lt;/i&gt;), script is minified to:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1020487.js?file=myscript.js"&gt;&lt;/script&gt;&lt;/div&gt;output: &lt;i&gt;myscript.js (115b) -&amp;gt; myscript.js (54b)[46%]&lt;/i&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Now our script is 46% smaller than the first one, of course the price we are paying is that we are loosing readability, but in production environment makes no sense.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Next step is configuring your &lt;i&gt;pom.xml&lt;/i&gt; (&lt;i&gt;Maven&lt;/i&gt;) so when application is packaged, all packaged &lt;i&gt;Javascript&lt;/i&gt; files are minified. For this porpoise &lt;b&gt;yuicompressor-maven-plugin&lt;/b&gt; (&lt;a href="http://alchim.sourceforge.net/yuicompressor-maven-plugin/"&gt;http://alchim.sourceforge.net/yuicompressor-maven-plugin/&lt;/a&gt;) plugin comes to rescue you.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1020490.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;No secret here, plugin is executed in &lt;i&gt;generate-sources&lt;/i&gt; phase, and is configured with no suffix option because I want that “&lt;i&gt;compressed&lt;/i&gt;” file has the same name as original one, and also I don’t want any line break in minified file.&lt;br /&gt;&lt;br /&gt;And finally the last trick, &lt;i&gt;maven-war-plugin&lt;/i&gt; configuration should be changed for avoiding it replaces minified files for original ones.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/1022496.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In this case scripts are in &lt;i&gt;src/main/webapp/script&lt;/i&gt; so excluded sources are &lt;i&gt;script/*.js&lt;/i&gt;. &lt;b&gt;yuicompression&lt;/b&gt; plugin will copy minified files into target directory that will be used by &lt;i&gt;war&lt;/i&gt; plugin for building &lt;i&gt;war&lt;/i&gt; file. For this reason we should avoid that war plugin also copies the original file to target directory, replacing the good ones (&lt;i&gt;compressed&lt;/i&gt;) for the bad ones (&lt;i&gt;uncompressed&lt;/i&gt;).&lt;/div&gt;&lt;br /&gt;If you read my previous &lt;a href="http://alexsotob.blogspot.com/2011/06/i-hitched-ride-with-chris-mccandless-i.html"&gt;post&lt;/a&gt;, where I talked about decreasing download time of &lt;i&gt;Javascript/CSS&lt;/i&gt; files(using aggregation) and also I explained why not to use an automatic approach in development time but in running time, I suppose you are wondering why I am explaining in this post minification using &lt;i&gt;Maven&lt;/i&gt;? Well let me explain, &lt;b&gt;YUI Compression&lt;/b&gt; should be used in conjunction &amp;nbsp;with aggregation files. &lt;b&gt;YUICompressionplugin&lt;/b&gt; supports aggregation too, so if you are developing a public API it is a good approach using &lt;b&gt;YUICompression&lt;/b&gt; (using Minifing and aggregation) with &lt;i&gt;Maven&lt;/i&gt;. But if you are developing a website, the best approach is applying optimizations at runtime using &lt;i&gt;Jawr API&lt;/i&gt; as I explained in my previous &lt;a href="http://alexsotob.blogspot.com/2011/06/i-hitched-ride-with-chris-mccandless-i.html"&gt;post&lt;/a&gt;. But next question &amp;nbsp;is how to use &lt;i&gt;Jawr&lt;/i&gt; (by default it uses &lt;i&gt;JSMin&lt;/i&gt;) with &lt;b&gt;YUIcompression?&lt;/b&gt;&amp;nbsp;The response is easiest one anyone could think, &lt;i&gt;Jawr&lt;/i&gt; also supports &lt;b&gt;YUI&lt;/b&gt;. Only one line should be added, open &lt;i&gt;jawr.properties&lt;/i&gt; and copy next line:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;jawr.js.bundle.factory.bundlepostprocessors=YUI&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now &lt;i&gt;Jawr&lt;/i&gt; will minify aggregated file using &lt;b&gt;YUI Compression&lt;/b&gt; instead of &lt;i&gt;JSMin&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Hope you find post useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=K_mJ1NgqiSk"&gt;http://www.youtube.com/watch?v=K_mJ1NgqiSk&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-4656735761742010907?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/4656735761742010907/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=4656735761742010907' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4656735761742010907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/4656735761742010907'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/06/y-hay-un-decano-tambien-y-un-abogado.html' title='Y Hay Un Decano También, Y Un Abogado También,  Y Un Policía Rodeado De Ladrones (La Taberna del Buda - Café Quijano)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-543899586490715874</id><published>2011-06-06T08:01:00.001+02:00</published><updated>2011-06-20T08:20:20.757+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='jawr'/><category scheme='http://www.blogger.com/atom/ns#' term='performance web'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>I Hitched A Ride With Chris McCandless,  I Stepped In The Wild With Chris McCandless,  And I Felt Alive With Chris McCandless.  I Was Wide Awake In The Dream. (The Ballad of Chris McCandless - Ellis Paul)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://jawr.java.net/images/index/logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="56" src="http://jawr.java.net/images/index/logo.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Now-days, &lt;i&gt;jQuery&lt;/i&gt; are becoming so popular in client-side of web development. &lt;i&gt;jQuery&lt;/i&gt; is a cross-browser &lt;i&gt;JavaScript&lt;/i&gt; library designed to simplify the client-side scripting of &lt;i&gt;HTML&lt;/i&gt;. &lt;i&gt;jQuery&lt;/i&gt; itself is composed by "one" file called &lt;i&gt;jquery-x.x.x.min.js&lt;/i&gt;. With only one &lt;i&gt;Javascript&lt;/i&gt; there is no performance problem. But with &lt;i&gt;jQuery&lt;/i&gt; has been appeared some "addons/plugins" that uses this library. An example could be &lt;i&gt;jQueryUI&lt;/i&gt; &lt;a href="http://jqueryui.com/"&gt;http://jqueryui.com/&lt;/a&gt;&amp;nbsp;but more can be found at &lt;a href="http://plugins.jquery.com/"&gt;http://plugins.jquery.com/&lt;/a&gt;. Each of these addons contain their own &lt;i&gt;Javascript&lt;/i&gt; file. For example &lt;i&gt;jQueryUI&lt;/i&gt; contains apart from &lt;i&gt;jQuery&lt;/i&gt; file, &lt;i&gt;jquery-ui-x.x.x.custom.min.js&lt;/i&gt; and one &lt;i&gt;CSS&lt;/i&gt; file, so in this case in a web page two &lt;i&gt;Javascript&lt;/i&gt; and a &lt;i&gt;CSS&lt;/i&gt; elements are defined. As more and more extensions are used, more &lt;i&gt;Javascript&lt;/i&gt; files are required. And more scripts imply more connections to server, so for example if three &lt;i&gt;Scripts&lt;/i&gt; and one &lt;i&gt;CSS&lt;/i&gt; are defined, four connections from browser to server are required.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Because of these amounts of connections, downloading time is increased; content negotiation and the fact that normally there will be only two concurrent connections to the same host, produces an overhead that results in a long page loading time. For example, it is faster to serve a 8KB script file than &amp;nbsp;eight of 1KB.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-VRqZmKtMjrQ/TexsinU7lcI/AAAAAAAAF_Y/8k6bwuvBCbw/s1600/multiplejs.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="364" src="http://4.bp.blogspot.com/-VRqZmKtMjrQ/TexsinU7lcI/AAAAAAAAF_Y/8k6bwuvBCbw/s640/multiplejs.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;For speeding up your application, would be desirable that only one &lt;i&gt;Javascript&lt;/i&gt; and one &lt;i&gt;CSS&lt;/i&gt; were downloaded. Arrived at this point, one can think next approach; using a &lt;i&gt;Maven&lt;/i&gt; plugin or any other automatic system, that opens all &lt;i&gt;js&lt;/i&gt; files and concatenate all of them in a single file. This approach is valid, but has a major problem, any small change forces developer to re-run build script before changes can be tested. Also you are duplicating same information in two or more files, so you must take care assuring&amp;nbsp;consistency between them.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;The goal for &lt;b&gt;Jawr&lt;/b&gt; is to provide a system to easily map resources to bundles using a simple descriptor, and a tag library to import these bundles to &lt;i&gt;JSP&lt;/i&gt; pages.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://jawr.java.net/images/index/jawr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" src="http://jawr.java.net/images/index/jawr.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In summary, using &lt;b&gt;Jawr&lt;/b&gt; taglib you define a fictional &lt;i&gt;Javascript&lt;/i&gt; file (for example &lt;i&gt;widgets.js&lt;/i&gt;) in &lt;i&gt;JSP&lt;/i&gt;; this file does not exist physically anywhere. Then in &lt;b&gt;Jawr&lt;/b&gt; configuration file (&lt;i&gt;jawr.properties&lt;/i&gt;), you map which &lt;i&gt;Javascript&lt;/i&gt; files should be appended when client browser requests "unreal" &lt;i&gt;Javascript&lt;/i&gt; file (&lt;i&gt;widgets.js&lt;/i&gt;). So from developers' point of view you could have a hierarchy of several &lt;i&gt;js&lt;/i&gt; files, while from client-side (browser), only one file is sent.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Using &lt;b&gt;Jawr&lt;/b&gt; in only &lt;i&gt;Servlet&lt;/i&gt; based web applications are easy. &lt;b&gt;Jawr&lt;/b&gt; comes with a &lt;i&gt;Servlet&lt;/i&gt; &lt;i&gt;net.jawr.web.servlet.JawrServlet,&lt;/i&gt;&amp;nbsp;where you define&amp;nbsp;&lt;b&gt;Jawr&lt;/b&gt; configuration file, and a workable mapping for &lt;i&gt;js&lt;/i&gt; extensions. (&lt;a href="http://jawr.java.net/docs/servlet.html"&gt;http://jawr.java.net/docs/servlet.html&lt;/a&gt;).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;But in case of &lt;i&gt;Spring MVC&lt;/i&gt; web applications, things are bit complicated. &lt;b&gt;Jawr&lt;/b&gt; provides a &lt;i&gt;Spring&lt;/i&gt; controller, that acts the same manner as previous &lt;i&gt;Servlet&lt;/i&gt;, but instead of using &lt;i&gt;servlet-mapping&lt;/i&gt; tag you must create a &lt;i&gt;SimpleUrlHandlerMapping&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In this post I will explain you how to create a&lt;i&gt; Spring MVC&lt;/i&gt; &lt;i&gt;jQuery&lt;/i&gt; web application integrated with &lt;b&gt;Jawr&lt;/b&gt;. Let's start with a &lt;i&gt;Spring MVC&lt;/i&gt; application that does not contain any references to &lt;b&gt;Jawr&lt;/b&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;JSP&lt;/i&gt; page contains definitions for all elements required by &lt;i&gt;jQuery&lt;/i&gt; plus one custom script file (defining &lt;i&gt;a()&lt;/i&gt; function).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1006835.js?file=home.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;and in &lt;i&gt;servlet-context.xml&lt;/i&gt; static resources (&lt;i&gt;Scripts&lt;/i&gt; and &lt;i&gt;CSS&lt;/i&gt;) mapped correctly.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1006864.js?file=servlet-context.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;This web application contains four references to static resources, so load diagram looks like:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-VRqZmKtMjrQ/TexsinU7lcI/AAAAAAAAF_Y/8k6bwuvBCbw/s1600/multiplejs.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="364" src="http://4.bp.blogspot.com/-VRqZmKtMjrQ/TexsinU7lcI/AAAAAAAAF_Y/8k6bwuvBCbw/s640/multiplejs.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;As you can see there is no file aggregation. With &lt;b&gt;Jawr&lt;/b&gt; these four connections can be reduced to two, one for all &lt;i&gt;Javascript&lt;/i&gt; files and another one for &lt;i&gt;CSS&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Let's start mapping resources. This is specified in &lt;i&gt;jawr.properties&lt;/i&gt; file that should be present in root classpath:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1007751.js?file=jawr.properties"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;First line enables the ability to serve &lt;i&gt;gzipped&lt;/i&gt; resources to browsers that support it. Next two lines are required for mapping script files. &lt;i&gt;jawr.js.bundle.[bundleName].id&lt;/i&gt; is the property where you specify the name of fictional &lt;i&gt;Javascript&lt;/i&gt; file. This name will be the one used in &lt;i&gt;JSP&lt;/i&gt;. The other line&lt;i&gt; jawr.js.bundle.[bundleName].mappings&lt;/i&gt; is where you indicate all &lt;i&gt;Javascript&lt;/i&gt; files that should be appended when &lt;i&gt;jawr.js.bundle.[bundleName].id&lt;/i&gt; file is requested by browser. In previous example when your &lt;i&gt;JSP&lt;/i&gt; page is requesting &lt;i&gt;/script/all.js&lt;/i&gt; resource, &lt;b&gt;Jawr&lt;/b&gt; will join &lt;i&gt;a.js&lt;/i&gt;, &lt;i&gt;jquery-1.5.1.min.js&lt;/i&gt; and &lt;i&gt;jquery-ui-1.8.13.custom.min.js&lt;/i&gt; and sent back the result to &lt;i&gt;client-browser&lt;/i&gt;. Last lines are the same but for &lt;i&gt;CSS&lt;/i&gt; files.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next step is changing &lt;i&gt;JSP&lt;/i&gt;, so instead of having one reference for each file, only contains one reference to &lt;i&gt;jawr.js.bundle.all.id &lt;/i&gt;value.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1007755.js?file=home.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Jawr&lt;/b&gt; provides a tag library used to generate tags that import bundles to clients and these tags are &lt;i&gt;&amp;lt;jawr:script/&amp;gt; and &amp;lt;jawr:style/&amp;gt;&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Unlike &lt;i&gt;Servlet&lt;/i&gt; approach, web.xml don't have to be modified, &lt;b&gt;Jawr&lt;/b&gt; provides a &lt;i&gt;Spring&lt;/i&gt; controller that must be configured as you would do in &lt;i&gt;Servlet&lt;/i&gt; approach.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next step is configuring &lt;i&gt;Spring Controller&lt;/i&gt;. &lt;b&gt;Jawr&lt;/b&gt; site provides documentation about how to configure a&lt;i&gt; Spring MVC&lt;/i&gt; with &lt;b&gt;Jawr&lt;/b&gt;. The example provided uses old-school fashion configuration controllers using &lt;i&gt;SimpleUrlHandlerMapping&lt;/i&gt;. But because I always use annotated controllers and I don't want to have some controllers defined with annotations and other ones in &lt;i&gt;UrlMapping&lt;/i&gt;, in this post &lt;b&gt;Jawr Spring Controller&lt;/b&gt; has been extended for being used with annotations.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;For implementing &lt;b&gt;Jawr Spring Controller&lt;/b&gt; with annotations I have only created an aggregation between annotated controller and &lt;b&gt;Jawr&lt;/b&gt; controller. So class looks:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1007781.js?file=JavascriptJawrController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;and the same approach for &lt;i&gt;CSS&lt;/i&gt; is used but changing &lt;i&gt;RequestMapping&lt;/i&gt; to &lt;i&gt;/**/*.css&lt;/i&gt; and &lt;i&gt;Qualifier&lt;/i&gt; to &lt;i&gt;jawrCSSController&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;As you probably noticed, two &lt;b&gt;Jawr&lt;/b&gt; controllers are used, one for &lt;i&gt;Javascript&lt;/i&gt; and another for &lt;i&gt;CSS&lt;/i&gt;. This is because &lt;b&gt;Jawr&lt;/b&gt; requires that you specify if code to optimize is &lt;i&gt;Script&lt;/i&gt; or &lt;i&gt;StyleSheet&lt;/i&gt;. &lt;i&gt;Spring&lt;/i&gt; configuration looks:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;script src="https://gist.github.com/1007790.js?file=controllers.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Finally &lt;i&gt;&amp;lt;resources&amp;gt;&lt;/i&gt; tag from &lt;i&gt;servlet-context.xml&lt;/i&gt; should be changed to:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;&amp;lt;resources mapping="/css/images/**" location="/css/images/" /&amp;gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;because now only images are required to be served as static resources.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;With previous changes applied, load diagram looks like:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-1ZxWjXkg6vg/TexsW-1Q78I/AAAAAAAAF_U/I6xNHzd9B5o/s1600/singlejs.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="306" src="http://4.bp.blogspot.com/-1ZxWjXkg6vg/TexsW-1Q78I/AAAAAAAAF_U/I6xNHzd9B5o/s640/singlejs.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;See that only one connection for all &lt;i&gt;Javascript&lt;/i&gt; files are performed. And also see how downloaded time has been improved from first version. Times showed here are not calculated in a scientific way, they are calculated from &lt;i&gt;localhost&lt;/i&gt;, but if you compare previous diagram with this diagram, you can see an improvement.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;You can also speed up even more your response time using a &lt;i&gt;cache&lt;/i&gt; strategy, but this topic is out of scope of this document.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;I wish you have found this post useful, and now before using &lt;i&gt;jQuery&lt;/i&gt; scripts, prepare your environment with &lt;b&gt;Jawr&lt;/b&gt; so your application can be loaded even faster.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;I hope you find this post useful.&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Download &lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/jawr-EP.zip"&gt;Code&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=3tdQx4Y3I2c"&gt;http://www.youtube.com/watch?v=3tdQx4Y3I2c&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-543899586490715874?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/543899586490715874/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=543899586490715874' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/543899586490715874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/543899586490715874'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/06/i-hitched-ride-with-chris-mccandless-i.html' title='I Hitched A Ride With Chris McCandless,  I Stepped In The Wild With Chris McCandless,  And I Felt Alive With Chris McCandless.  I Was Wide Awake In The Dream. (The Ballad of Chris McCandless - Ellis Paul)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-VRqZmKtMjrQ/TexsinU7lcI/AAAAAAAAF_Y/8k6bwuvBCbw/s72-c/multiplejs.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2077118062317733353</id><published>2011-05-28T11:14:00.002+02:00</published><updated>2011-05-28T11:17:07.351+02:00</updated><title type='text'>If There's A God In The Sky Looking Down What Can He Think Of What We've Done To The World That He Created (Is This The World We Created - Queen)</title><content type='html'>&lt;div style="text-align: justify;"&gt;Hello, this week I have reached&lt;u&gt; 25K&lt;/u&gt; visits. Not long ago, I wrote that I have reached &lt;u&gt;10K&lt;/u&gt; visits during Japan earthquake. Now thankful &amp;nbsp;Japan nuclear crisis seems that has passed.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I would like to say thank you to all people that have read my blog, specially people from &lt;i&gt;theserverside.com&lt;/i&gt;&amp;nbsp;and&amp;nbsp;&lt;i&gt;springsource&lt;/i&gt;&amp;nbsp;for publishing my posts on their site, and also people that have become followers of my blog.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For now that all, I wish I reach 100K as soon as possible, thank you very much all of you for your support.&lt;/div&gt;&lt;br /&gt;Alex.&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=pUOrAengPH8"&gt;http://www.youtube.com/watch?v=pUOrAengPH8&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2077118062317733353?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2077118062317733353/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2077118062317733353' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2077118062317733353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2077118062317733353'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/05/if-theres-god-in-sky-looking-down-what.html' title='If There&apos;s A God In The Sky Looking Down What Can He Think Of What We&apos;ve Done To The World That He Created (Is This The World We Created - Queen)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-6680525939822375171</id><published>2011-05-27T18:57:00.000+02:00</published><updated>2011-05-27T18:57:08.014+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='captcha'/><category scheme='http://www.blogger.com/atom/ns#' term='spring mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='recaptcha4j'/><category scheme='http://www.blogger.com/atom/ns#' term='protecting forms'/><category scheme='http://www.blogger.com/atom/ns#' term='recaptcha'/><title type='text'>Mornië Utúlië, Believe And You Will Find Your Way (May It Be - Enya)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.google.com/recaptcha/static/images/logo2-new.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.google.com/recaptcha/static/images/logo2-new.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;A &lt;b&gt;CAPTCHA&lt;/b&gt; is a program that can generate and grade tests that humans can pass but computer programs "&lt;i&gt;cannot&lt;/i&gt;". One of strategies followed are showing an image to user with distorted text, and user should write text in input area. If showed text is the same as input by user, then we can "&lt;i&gt;assure&lt;/i&gt;" that a human is on computer. A &lt;b&gt;captcha&lt;/b&gt; example:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.google.com/recaptcha/static/images/recaptcha-example.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.google.com/recaptcha/static/images/recaptcha-example.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Captchas&lt;/i&gt; have several applications for practical security, for example:&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;Preventing &lt;u&gt;Spam&lt;/u&gt; in comment fields.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Protecting from &lt;u&gt;Massive User Registration&lt;/u&gt;.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Preventing &lt;u&gt;Dictionary Attacks&lt;/u&gt;.&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;These distorted texts are acquired as follows:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;ol&gt;&lt;li&gt;Digitizing physical books/newspaper.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Pages are photographically scanned, and then transformed into text using "&lt;i&gt;Optical Character Recognition&lt;/i&gt;" (OCR).&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;i&gt;OCR&lt;/i&gt; is not perfect, each word that cannot be read correctly by &lt;i&gt;OCR&lt;/i&gt; is placed on an image and used as a &lt;b&gt;CAPTCHA&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Word that cannot be read correctly by &lt;i&gt;OCR&lt;/i&gt; is given to a user with another word for which the answer is already known. Then is asked to read both words, if user solves the one for which the answer is known, the system assumes their answer is correct for the new one.&amp;nbsp;The system then gives the new image to a number of other people to determine, with higher confidence, whether the original answer was correct.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Now you know how &lt;b&gt;captcha&lt;/b&gt; works, the problem is that if you want to use &lt;i&gt;captchas&lt;/i&gt; in your website, you should implement yourself process described above, and of course this is not easy&amp;nbsp;and tedious work is required digitalizing works. For this reason there are some "&lt;i&gt;captcha providers&lt;/i&gt;" that have done this work for us. One of these providers is &lt;b&gt;reCaptcha&lt;/b&gt; &lt;a href="http://www.google.com/recaptcha"&gt;http://www.google.com/recaptcha&lt;/a&gt;. &lt;b&gt;reCaptcha&lt;/b&gt; is a free &lt;b&gt;captcha&lt;/b&gt; service that provides us these&amp;nbsp;&lt;i&gt;captchas &lt;/i&gt;ready to be used in our site. As developers we only have to embedded a piece of code in client side for showing &lt;b&gt;captcha&lt;/b&gt; image and text area, and in server side, calling a function for resolving input data. &lt;b&gt;reCaptcha&lt;/b&gt; provides plugins for dealing with lot of programming languages like &lt;i&gt;Java&lt;/i&gt;, &lt;i&gt;PHP&lt;/i&gt;, &lt;i&gt;Perl&lt;/i&gt;, ...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This post will guide you on how to use &lt;b&gt;reCaptcha&lt;/b&gt; in&amp;nbsp;&lt;i&gt;Spring MVC&lt;/i&gt; web application. The application consists in a form to register a new user. This form contains a &lt;b&gt;captcha&lt;/b&gt; for avoiding a bot starts a massive registration attack.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;u&gt;First step&lt;/u&gt;&lt;/i&gt; is open an account to &lt;b&gt;reCaptcha&lt;/b&gt;&amp;nbsp;site (you can use your &lt;i&gt;google&lt;/i&gt; account or create a new one).&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Once you have entered go to &lt;i&gt;My Account&lt;/i&gt; - &lt;i&gt;Add New Site&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Then at domain box you should write the domain which will contain &lt;b&gt;captcha&lt;/b&gt; validation. For this example I have entered &lt;i&gt;localhost&lt;/i&gt; and I have checked &lt;i&gt;Enable this key on all domains (global key)&lt;/i&gt;. Of course information provided here is for testing&amp;nbsp;porpoise&amp;nbsp;and in production environment should be different. After you have registered your site, two keys are provided, &lt;i&gt;private key&lt;/i&gt; (XXXX) and a &lt;i&gt;public key&lt;/i&gt; (YYYY).&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-tf5egRJC98s/Td00DE2wjdI/AAAAAAAAF_Q/t9O4pLns3DA/s1600/recaptcha.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="374" src="http://1.bp.blogspot.com/-tf5egRJC98s/Td00DE2wjdI/AAAAAAAAF_Q/t9O4pLns3DA/s640/recaptcha.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Before coding, let me show basic&amp;nbsp;life-cycle&amp;nbsp;of a &lt;b&gt;reCAPTCHA&lt;/b&gt; challenge. Diagram is from &lt;b&gt;reCaptcha&lt;/b&gt; web:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://code.google.com/apis/recaptcha/images/recaptcha-api-diagram.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="185" src="http://code.google.com/apis/recaptcha/images/recaptcha-api-diagram.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;u&gt;Second step&lt;/u&gt;&lt;/i&gt; is create a&amp;nbsp;&lt;i&gt;Spring MVC&lt;/i&gt; application, no secret here, I am going to explain only parts that are implied in &lt;b&gt;reCaptcha&lt;/b&gt; integration. Apart from&lt;i&gt; SpringMVC&lt;/i&gt; dependencies, &lt;i&gt;recaptcha4j API&lt;/i&gt; should be added:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/991378.js?file=pom.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;recaptcha4j.jar&lt;/i&gt; is an &lt;i&gt;API&lt;/i&gt; that provides a simple way to place a &lt;b&gt;captcha&lt;/b&gt; on your Java-based website. The library wraps the &lt;b&gt;reCAPTCHA&lt;/b&gt; &lt;i&gt;API&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Integrating &lt;b&gt;reCaptcha&lt;/b&gt; into a form, requires two modifications:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;One in client side, for connecting to &lt;b&gt;reCaptcha&lt;/b&gt; server and get the &lt;i&gt;challenge&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Second one in server-side for connecting to &lt;b&gt;reCaptcha&lt;/b&gt; server to send the user's answer, and give back a response.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;u&gt;Client side:&lt;/u&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;For client side a &lt;i&gt;tagfile&lt;/i&gt; has been created to encapsulate all logic of &lt;b&gt;reCaptcha&lt;/b&gt; &lt;i&gt;API&lt;/i&gt; in a single point, so can be reused in all &lt;i&gt;JSP&lt;/i&gt; forms.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/991394.js?file=captcha.tag"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;reCaptcha&lt;/b&gt; class requires the &lt;i&gt;private key&lt;/i&gt; (XXXX) and the&lt;i&gt; public key&lt;/i&gt; (YYYY) provided by &lt;b&gt;reCaptcha&lt;/b&gt; in step one. The method &lt;i&gt;createRecaptchaHtml&lt;/i&gt;(...) creates a piece of &lt;i&gt;html&lt;/i&gt; code to show the&amp;nbsp;challenge. In fact it generates something like:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.google.com/recaptcha/static/images/recaptcha-example.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.google.com/recaptcha/static/images/recaptcha-example.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And finally a &lt;i&gt;JSP&lt;/i&gt; page with a form and &lt;b&gt;captcha&lt;/b&gt; information:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/991413.js?file=register.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;See that form is generated as usual using &lt;i&gt;Spring MVC&lt;/i&gt; &lt;i&gt;taglib&lt;/i&gt;, but also we are using created &lt;i&gt;tagfile&lt;/i&gt; (&lt;i&gt;&amp;lt;tags:captcha&amp;gt;&lt;/i&gt;) for embedding &lt;b&gt;captcha&lt;/b&gt; into form.&lt;/div&gt;&lt;br /&gt;&lt;u&gt;&lt;i&gt;Server Side:&lt;/i&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Server side is even simpler than client side. When a &lt;b&gt;captcha&lt;/b&gt; is created using &lt;i&gt;createRecaptchaHtml&lt;/i&gt;, two form element fields are created, &lt;i&gt;recaptcha_challenge_field&lt;/i&gt; that contains information about the&amp;nbsp;challenge&amp;nbsp;presented to user, and &amp;nbsp;&lt;i&gt;recaptcha_response_field&lt;/i&gt; that contains the user answer to the&amp;nbsp;challenge.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Apart from these two parameters,&amp;nbsp;&lt;i&gt;recaptcha4j&lt;/i&gt; requires remote address too. &lt;i&gt;ServletRequest&lt;/i&gt; interface has a method (&lt;i&gt;getRemoteAddr()&lt;/i&gt;) for this&amp;nbsp;porpoise.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/991436.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;reCaptcha&lt;/b&gt; object is injected using &lt;i&gt;Spring&lt;/i&gt;. It is important to note that &lt;i&gt;UserInfo&lt;/i&gt; (data entered by user in form) does not contain any information about &lt;b&gt;captcha&lt;/b&gt;, it only contains "business" data. Using &lt;i&gt;@RequestParam&lt;/i&gt; &lt;b&gt;reCaptcha&lt;/b&gt; information is retrieved by &lt;i&gt;Spring&lt;/i&gt; and can be used directly into &lt;b&gt;reCaptcha&lt;/b&gt; object.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The other important part is &lt;i&gt;isValid()&lt;/i&gt; method. This method simply checks if response of &lt;b&gt;reCaptcha&lt;/b&gt; site is that user has been passed the challenge or not. Depending on result you should act consequently, if challenge is not passed returning to previous page is a good practice.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/993538.js?file=controller.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This bean definition is simply for instantiating &lt;b&gt;reCaptcha&lt;/b&gt; class with your private key. Using &lt;i&gt;@Autowire&lt;/i&gt;&amp;nbsp;bean is injected into &lt;i&gt;controller&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;u&gt;Step Three:&lt;/u&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Last step is watch that created form shows the &lt;b&gt;captcha&lt;/b&gt; image and controller redirects you to page depending on what you have entered into &lt;b&gt;captcha&lt;/b&gt; text area.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;&lt;i&gt;Extra Step:&lt;/i&gt;&lt;/u&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now you have a basic notion of how to work with &lt;b&gt;reCaptcha&lt;/b&gt;, next step (out of scope of this post) is instead of showing again form without any error message, you could use &lt;i&gt;BindingResult&lt;/i&gt; in &lt;i&gt;Controller &lt;/i&gt;for notifying to user an error message:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/993615.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;result&lt;/i&gt; variable is an attribute passed to &lt;i&gt;submitForm&lt;/i&gt; of type &lt;i&gt;BindingResult&lt;/i&gt;. Of course &lt;i&gt;JSP&lt;/i&gt; should be changed with &lt;i&gt;&amp;lt;form:errors path="captcha"/&amp;gt; &lt;/i&gt;for showing the error message&lt;i&gt;.&lt;/i&gt;&lt;/div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Another&amp;nbsp;improvement is creating&amp;nbsp; a &lt;i&gt;HandlerInterceptor&lt;/i&gt; for validating forms with &lt;i&gt;captchas&lt;/i&gt;. For example &amp;nbsp;&lt;i&gt;ReCaptchaHandlerInterceptorAdapter&lt;/i&gt; would contain &lt;b&gt;reCaptcha&lt;/b&gt; management. &lt;i&gt;preHandle&lt;/i&gt; method would return &lt;i&gt;true&lt;/i&gt; if &lt;b&gt;captcha&lt;/b&gt;&amp;nbsp;challenge&amp;nbsp;is resolved correctly by user (allowing defined controller do its work), or &lt;i&gt;false&lt;/i&gt; and redirecting to an error page.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/993629.js?file=controller.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;With previous handler configuration all forms would have &lt;b&gt;captcha&lt;/b&gt; validation.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Hope you find useful this post, and now you can start protecting your web forms from spam or bots.&lt;/div&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/recaptcha-EP.zip"&gt;Download Eclipse Project&lt;/a&gt;.&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=XOykCYDMKBs"&gt;http://www.youtube.com/watch?v=XOykCYDMKBs&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-6680525939822375171?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/6680525939822375171/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=6680525939822375171' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6680525939822375171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/6680525939822375171'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/05/mornie-utulie-believe-and-you-will-find.html' title='Mornië Utúlië, Believe And You Will Find Your Way (May It Be - Enya)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-tf5egRJC98s/Td00DE2wjdI/AAAAAAAAF_Q/t9O4pLns3DA/s72-c/recaptcha.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-3362102099355875751</id><published>2011-05-22T12:30:00.000+02:00</published><updated>2011-05-22T12:30:22.789+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scm'/><category scheme='http://www.blogger.com/atom/ns#' term='DVCS'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='Distributed Version Control System'/><category scheme='http://www.blogger.com/atom/ns#' term='central repository'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>This Is a Flash Of Pure Inspiration, Més I Més I Messi, Però Més Però Molt Més (The Feet Continue To Dance - The Wizard Of Ox)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://git-scm.com/images/header.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="52" src="http://git-scm.com/images/header.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Git&lt;/b&gt; is a distributed revision control system, where every working directory is a full-fledged repository with complete history and full revision tracking capabilities.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Git&lt;/b&gt; is categorized as &lt;i&gt;DVCS&lt;/i&gt; (Distributed Version Control System), because is not dependant on a central server. So the academic way for working with &lt;b&gt;Git&lt;/b&gt; is pushing/pulling data from/to each developer repository. This works in small teams or in a highly distributed development (open source projects that people are working around the world), but in mid-size teams or business companies, that require a central repository because of infrastructure/workflow process like &lt;i&gt;Continuous Integration System&lt;/i&gt;, &lt;i&gt;QA Checks&lt;/i&gt; before delivering, &lt;i&gt;Environment Backups&lt;/i&gt;, &lt;i&gt;External Manual Audits&lt;/i&gt;... seem that a traditional &lt;i&gt;SCM&lt;/i&gt; should be desired. But this claim is far from reality, &lt;b&gt;Git&lt;/b&gt; is still your &lt;i&gt;VCS&lt;/i&gt;; how about creating a theoretical central repository? I say theoretical because in &lt;b&gt;Git&lt;/b&gt; there is no central repository at a technical level. This repository will act as central because of convention. I call, and in many other posts also call this repository &lt;i&gt;origin&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;A &lt;b&gt;Git&lt;/b&gt; remote repository is a repository without working directory. Only composed by &amp;nbsp;&lt;i&gt;.git&lt;/i&gt; project directory and nothing else.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Nvie&lt;/i&gt; has created a nice schema of this topology:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://nvie.com/img/2010/01/centr-decentr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="297" src="http://nvie.com/img/2010/01/centr-decentr.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;See that each developer pulls and pushes to &lt;i&gt;origin&lt;/i&gt;, but also may exchange data with other peers. For example, if two or more developers are working on a new feature, they can push changes between them before pushing stable version to &lt;i&gt;origin &lt;/i&gt;repository.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Git&lt;/b&gt; is not tied to any particular transmission protocol, it supports transmitting changes via &lt;i&gt;USB&lt;/i&gt; stick, &lt;i&gt;email&lt;/i&gt;, ..., or traditional way like &lt;i&gt;HTTP&lt;/i&gt;, &lt;i&gt;FTP&lt;/i&gt;, &lt;i&gt;SSH&lt;/i&gt;, ...&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;So although &lt;b&gt;Git&lt;/b&gt; has broken the typical &lt;i&gt;SCM&lt;/i&gt; hub architecture to peer-to-peer structure, we can still create (by convention) a central repository for uploading stable code. And let me write again, "This central repo is just another node in the peer not THE REPOSITORY".&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;What I am going to explain is how to install and configure this "central repo" in an &lt;u&gt;Ubuntu Server&lt;/u&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;We can say that &lt;b&gt;Git&lt;/b&gt; only takes care of repository management and leaves transport operations to lower layers. A typical transport configuration for these central repos is using &lt;i&gt;SSH&lt;/i&gt; protocol. So let's install and configure a &lt;i&gt;SSH&lt;/i&gt; server. (if you have already installed skip to next step).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Install SSH Server:&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;$ sudo apt-get install openssh-server&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;after installed try:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div justify;"="" text-align:=""&gt;$ ssh &amp;lt;username&amp;gt;@&amp;lt;servername&amp;gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Configure SSH Server:&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;In &lt;i&gt;/etc/ssh/sshd_config&lt;/i&gt;&amp;nbsp;configure to only use &lt;i&gt;SSH &lt;/i&gt;Protocol 2:&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;Protocol 2&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next step is to install &lt;b&gt;Git&lt;/b&gt;: (You can skip this step if you have already installed).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Install Git (not git-core package):&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;$ sudo apt-get install git&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Then execute &lt;b&gt;Git&lt;/b&gt; command to check that has been installed correctly.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Next step is creating a bare repository for the project. By convention, bare repository directories end with &lt;i&gt;.git&lt;/i&gt;. So first thing to do is create a &lt;i&gt;.git&lt;/i&gt; directory of project.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;b&gt;Creating a bare repository from existing repository:&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;i&gt;$ git clone --bare my_project my_project.git&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;This command transforms the &lt;i&gt;/my_project/.git&lt;/i&gt; to &lt;i&gt;my_project.git&lt;/i&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;Creating a new bare repository:&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;If you are starting a new project you can initialize it directly as bare repository using:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;$ mkdir my_project.git&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;$ cd my_project.git&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;$ git --bare init&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now all structure is created and ready to be transferred. Case that initial project was started on developer computer you should copy this directory (using &lt;i&gt;scp&lt;/i&gt; for example) to &lt;i&gt;origin&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Then execute next command:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;$ git init --bare --shared&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This command will add propertly group read/write permissions.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And now it is time to clone created repository to developer computer, I assume that developer has already an account in server (for connecting using &lt;i&gt;ssh&lt;/i&gt;). So go to developer computer (or open another terminal) and type next command:&lt;/div&gt;&lt;br /&gt;&lt;i&gt;$ git clone &amp;lt;username&amp;gt;@&amp;lt;servername&amp;gt;:/&amp;lt;directories&amp;gt;/my_project.git&lt;/i&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;If user has read permissions to &lt;i&gt;my_project.git&lt;/i&gt; directory, repository will be downloaded to local computer. Write permissions are required for checking in changes.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And now I suppose you are thinking that it was so easy creating a remote repository, but now another problem arises. If your company is small you can manually create a new user into your server for each developer, it should be easy to manage, but if your company is  bigger, then management of all users is hard. You must create an account for each one, and more important, they will have access to server shell using &lt;i&gt;ssh &lt;/i&gt;(not only for uploading code) or &lt;i&gt;ftp&lt;/i&gt;, ..., and this fact implies a problem with security, you should take care of what a user can do and what cannot do in his shell.&lt;br /&gt;&lt;br /&gt;So arrived at this point, one can setup accounts for everyone, which is straightforward but can be cumbersome. Another way is using an &lt;i&gt;LDAP &lt;/i&gt;or any other centralized system, but this is alien topic for this post.&lt;br /&gt;&lt;br /&gt;A second method is to create an account&amp;nbsp;called "&lt;i&gt;git&lt;/i&gt;" on the server, and ask every user who will have &amp;nbsp;access, to send its &lt;i&gt;SSH &lt;/i&gt;public key, and add that key to the&lt;i&gt; .ssh/authorized_keys&lt;/i&gt; file of "&lt;i&gt;git&lt;/i&gt;" user. I am sure that this approach sounds you familiar (github way?). So let's explain this way:&lt;br /&gt;&lt;br /&gt;First of all each user should send you its public key, (they can find in .ssh directory *.pub file), or simply create new, using &lt;i&gt;ssh-keygen&lt;/i&gt; command. See this tutorial for learning how to generate both keys &lt;a href="http://github.com/guides/providing-your-ssh-key"&gt;http://github.com/guides/providing-your-ssh-key&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Setting up Git server with user public keys:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First step is create&amp;nbsp;a &lt;i&gt;git&lt;/i&gt; user with &lt;i&gt;.ssh&lt;/i&gt; directory.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;#from server&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ sudo adduser git&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ su git&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ cd&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ mkdir .ssh&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Next step is create&amp;nbsp;&lt;i&gt;authorized_keys &lt;/i&gt;file where all public keys will be stored:&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;#from server&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ cat id_dsa.user1.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ cat id_dsa.user2.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And now each developer, with public key published in &lt;i&gt;authorized_keys&lt;/i&gt; and private key in his own &lt;i&gt;.ssh&lt;/i&gt; directory, has access to repository. Let's try, open another terminal (would be developer machine in real scenario) and try to clone existing repo from server:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;#from developer computer&lt;/i&gt;&lt;br /&gt;&lt;i&gt;$ git clone git@&amp;lt;servername&amp;gt;:&amp;lt;directories&amp;gt;/my_project.git&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;After repository is cloned to developer computer, modifications can be made and pushed them.&lt;br /&gt;&lt;br /&gt;And now you can say, "&lt;i&gt;Ok, I don't have to create one account for each developer but I am still having a problem with security&lt;/i&gt;", each developer still has access to shell. Yes it is true, but you can easily restrict the "&lt;i&gt;git&lt;/i&gt;" user to only doing &lt;b&gt;Git &lt;/b&gt;activities with a limited shell called &lt;i&gt;git-shell&lt;/i&gt;. Next step is specifying &lt;i&gt;git-shell&lt;/i&gt; instead of bash for &lt;b&gt;Git&lt;/b&gt; user, in &lt;i&gt;/etc/passw&lt;/i&gt;d.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;$ sudo vim /etc/passwd&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;and change&lt;br /&gt;&lt;br /&gt;&lt;i&gt;git:x:1000:1000::/home/git:/bin/sh&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;i&gt;git:x:1000:1000::/home/git:/usr/bin/git-shell&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now your server is secured, only &lt;b&gt;Git &lt;/b&gt;operations are allowed using "&lt;i&gt;git&lt;/i&gt;" account with users that have sent their &lt;i&gt;SSH &lt;/i&gt;public key.&lt;br /&gt;&lt;br /&gt;You have your central remote repository configured and ready to be used; at this point you may consider install &lt;b&gt;Git &lt;/b&gt;tools like &lt;i&gt;gitweb&lt;/i&gt;, &lt;i&gt;gitosis &lt;/i&gt;or &lt;i&gt;gitolite&lt;/i&gt;, but in this post are off topic.&lt;br /&gt;&lt;br /&gt;I hope you have found this post useful.&lt;br /&gt;&lt;br /&gt;Music:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=q2AemC0cwy0"&gt;http://www.youtube.com/watch?v=q2AemC0cwy0&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3362102099355875751?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3362102099355875751/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3362102099355875751' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3362102099355875751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3362102099355875751'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/05/this-is-flash-of-pure-inspiration-mes-i.html' title='This Is a Flash Of Pure Inspiration, Més I Més I Messi, Però Més Però Molt Més (The Feet Continue To Dance - The Wizard Of Ox)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2683579477578094710</id><published>2011-05-10T20:17:00.000+02:00</published><updated>2011-05-10T20:17:35.779+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='oauth 2'/><category scheme='http://www.blogger.com/atom/ns#' term='oauth service provider'/><category scheme='http://www.blogger.com/atom/ns#' term='oauth consumer'/><category scheme='http://www.blogger.com/atom/ns#' term='spring security oauth'/><category scheme='http://www.blogger.com/atom/ns#' term='open authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='java security'/><category scheme='http://www.blogger.com/atom/ns#' term='spring security'/><category scheme='http://www.blogger.com/atom/ns#' term='web security'/><title type='text'>To Seek Out New Life And New Civilizations, To Boldly Go Where No Man Has Gone Before (TNG Soundtrack - Star Trek)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/d/d2/Oauth_logo.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/d/d2/Oauth_logo.svg" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;blockquote style="text-align: justify;"&gt;From Wikipedia: &lt;b&gt;OAuth &lt;/b&gt;(&lt;i&gt;Open Authentication&lt;/i&gt;) is an open standard for authentication. It allows users to share their private resources (e.g. photos, videos, contact lists) stored on one site with another site without having to hand out their credentials, typically username and password.&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;There are a lot of posts talking about &lt;b&gt;OAuth&lt;/b&gt; from &lt;i&gt;Client Side&lt;/i&gt;, for example how to connect to service providers like &lt;i&gt;Twitter&lt;/i&gt; or &lt;i&gt;Facebook&lt;/i&gt;, but there are less posts about &lt;b&gt;OAuth&lt;/b&gt; but from &lt;i&gt;Server Side&lt;/i&gt;, more specificaly how to implement an authentication mechanism using &lt;b&gt;OAuth&lt;/b&gt; for protecting resources, and not for accessing them (&lt;i&gt;Client Side Part&lt;/i&gt;).&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In this post I will talk about how to protect your resources, using &lt;b&gt;Spring Security&lt;/b&gt; (&lt;b&gt;Spring Security OAuth&lt;/b&gt;). The example will be simple enough to understand the basics for implementing an &lt;b&gt;OAuth&lt;/b&gt; service provider.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I have found this post that explains with a simple example, what &lt;b&gt;OAuth&lt;/b&gt; is and how it works. I think it is a good starting point with &lt;b&gt;OAuth&lt;/b&gt; &lt;a href="http://hueniverse.com/2007/10/beginners-guide-to-oauth-part-ii-protocol-workflow/"&gt;http://hueniverse.com/2007/10/beginners-guide-to-oauth-part-ii-protocol-workflow/&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now it is time to start writing our service provider. First of all I will explain what our &lt;i&gt;Service Provider&lt;/i&gt; will offer.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Imagine you are developing a website (called &lt;i&gt;CV&lt;/i&gt;) where users will register and after that they will be able to upload their &lt;i&gt;Curriculum Vitae&lt;/i&gt;. Now we are going to transform this website to a &lt;i&gt;Service Provider&lt;/i&gt; where &lt;b&gt;OAuth&lt;/b&gt; will be used for protecting resources (&lt;i&gt;Curriculm Vitae&lt;/i&gt;&amp;nbsp;of registered users). Imagine again that some companies have agreed with &lt;i&gt;CV&lt;/i&gt; people that when they publish job vacances, users will have the possibility of uploading their curriculum directly from &lt;i&gt;CV&lt;/i&gt; site to &lt;i&gt;HR&lt;/i&gt; department instead of sending by email or copy &amp;amp; paste from document. As you can see here is where &lt;b&gt;OAuth&lt;/b&gt; starts managing security between &lt;i&gt;CV&lt;/i&gt; website and Company &lt;i&gt;RH&lt;/i&gt; site.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In summary we have a &lt;i&gt;Curriculum Vitae Service Provider (CV)&lt;/i&gt; with protected resource (document itself). Companies that offer users the possibility of acquiring directly their &lt;i&gt;Curriculum Vitae&lt;/i&gt; from &lt;i&gt;CV&lt;/i&gt; are the &lt;i&gt;Consumers&lt;/i&gt;. So when a user visits company job vacancies (in our example called &lt;i&gt;fooCompany&lt;/i&gt;) and wants to apply for a job, he only has to authorize &lt;i&gt;FooCompany&lt;/i&gt; "Job Vacancies" website with permissions to download its &lt;i&gt;Curriculum Vitae&lt;/i&gt; from &lt;i&gt;CV&lt;/i&gt; site.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Because we will use &lt;b&gt;Spring Security&lt;/b&gt; for &lt;b&gt;OAuth&lt;/b&gt; authentication, first of all we are going to configure &lt;b&gt;Spring Security&lt;/b&gt; into &lt;i&gt;SpringMVC CV&lt;/i&gt; application. Nothing special here:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In &lt;i&gt;web.xml&lt;/i&gt; file we define &lt;i&gt;Security Filter&lt;/i&gt;:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964772.js?file=web.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And in&amp;nbsp;&lt;i&gt;root-context.xml&lt;/i&gt; we define protected resources and authentication manager. In this case &lt;i&gt;In memory&lt;/i&gt; apporoach is used:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964778.js?file=root-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next step, create an &lt;i&gt;Spring Controller&lt;/i&gt; that returns the &lt;i&gt;Curriculum Vitae&lt;/i&gt; of logged user:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964783.js?file=CVController.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This controller returns directly a &lt;i&gt;String&lt;/i&gt;, instead a &lt;i&gt;ModelView&lt;/i&gt; object. This String is sent directly as &lt;i&gt;HttpServletResponse&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now we have got a simple website that returns the &lt;i&gt;Curriculum Vitae&lt;/i&gt; of logged user. If you try to access to &lt;i&gt;/cvs &lt;/i&gt;resource, if you are not authenticated, &lt;b&gt;Spring Security&lt;/b&gt; will show you a login page, and if you are already logged, your job experience will be returned. Works as any other website that are using &lt;b&gt;Spring Security&lt;/b&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next step is modifing this project for allowing external sites can access to protected resources using &lt;b&gt;OAuth 2&lt;/b&gt; authentication protocol.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In &lt;i&gt;root-context.xm&lt;/i&gt;l:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964788.js?file=root-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First bean, is an &lt;i&gt;OAuth2ProviderTokenServices&lt;/i&gt; interface implementation with id &lt;i&gt;tokenServices&lt;/i&gt;. The &lt;i&gt;OAuth2ProviderTokenServices&lt;/i&gt; interface defines operations that are necessary to manage &lt;b&gt;OAuth 2.0&lt;/b&gt; tokens. These tokens should be stored for subsequent access token can reference it. For this example &lt;i&gt;InMemory&lt;/i&gt; store is enough.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next bean is &amp;lt;oauth:provider&amp;gt;. This tag is used to configure the &lt;b&gt;OAuth 2.0&lt;/b&gt; provider mechanism. And in this case three parameters are configured; the first one is a reference to a bean that defines the client details service, explained in next paragraph. The second one is token service for providing tokens, explained in previous paragraph, and the last one is the URL at which a request for authorization token will be serviced. This is the typically &lt;i&gt;Authorize/Denny&lt;/i&gt; page where service provider asks to user if it permits the &lt;i&gt;Consumer&lt;/i&gt; (in our case &lt;i&gt;fooCompany&lt;/i&gt;) accessing to protected resources (its &lt;i&gt;Curriculum Vitae&lt;/i&gt;).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Last bean is &amp;lt;oauth:client-details-service&amp;gt;. In this tag you define which clients you authorize to access to protected resources with previous authentication. In this case because &lt;i&gt;CV&lt;/i&gt; company has agreed with &lt;i&gt;foo company&lt;/i&gt; that they can connect to its &lt;i&gt;Curriculum Vitae Service&lt;/i&gt;, a client is defined with id &lt;i&gt;foo&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now we have our application configured with &lt;b&gt;OAuth&lt;/b&gt;. Last step is creating a controller for taking requests from &lt;i&gt;/oauth/confirm_access&lt;/i&gt; URL.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964800.js?file=CVController.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This controller returns a &lt;i&gt;ModelAndView&lt;/i&gt; object with client information and which page should be shown for granting permission to protected resources. This &lt;i&gt;JSP&lt;/i&gt; page is called &lt;i&gt;access_confirmation.jsp&lt;/i&gt; and the most important part is:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964804.js?file=access_confirmation.jsp"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you can see &lt;b&gt;Spring Security OAuth&lt;/b&gt; provides helper classes for creating confirmation form and deny form. When the result is submitted, URL &lt;i&gt;/cv/oauth/user/authorize&lt;/i&gt; (internally managed) is called, there &lt;b&gt;OAuth&lt;/b&gt; decides if returns protected resource (String returned by &lt;i&gt;loadCV()&lt;/i&gt; method) to caller or not depending on what option user has chosen.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And that's all about creating an &lt;b&gt;OAuth 2&lt;/b&gt; system using &lt;b&gt;Spring Security OAuth&lt;/b&gt;. But I suppose you are wondering how to test it, so for the same price I will explain how to write the client part (C&lt;i&gt;onsumer&lt;/i&gt;) using &lt;b&gt;Spring Security OAuth&lt;/b&gt; too.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Client application (called &lt;i&gt;fooCompany&lt;/i&gt;) is also a &lt;i&gt;SpringMVC&lt;/i&gt; web application with &lt;b&gt;Spring Security&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;b&gt;Spring Security&lt;/b&gt; part will be ignored here.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;The client application contains a home page (&lt;i&gt;home.jsp&lt;/i&gt;) that has a link to &lt;i&gt;Spring Controller&lt;/i&gt; that will be responsible to download &lt;i&gt;Curriculum Vitae&lt;/i&gt; from &lt;i&gt;CV&lt;/i&gt; site, and redirecting content to a view (&lt;i&gt;show.jsp&lt;/i&gt;).&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964811.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you can see is a simple &lt;i&gt;Controller&lt;/i&gt; that calls a &lt;i&gt;Curriculum Vitae&lt;/i&gt; service. This service will be responsible to connect to &lt;i&gt;CV&lt;/i&gt; website, and download required &lt;i&gt;Curriculum Vitae&lt;/i&gt;. Of course it deals with &lt;b&gt;OAuth&lt;/b&gt; communication protocol too.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Service looks:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964827.js?file=CVServiceImpl.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The suggested method for accessing those resources is by using &lt;i&gt;Rest&lt;/i&gt;. For this porpose &lt;b&gt;Spring Security OAuth&lt;/b&gt; provides an extension of &lt;i&gt;RestTemplate&lt;/i&gt; for dealing with &lt;b&gt;OAuth&lt;/b&gt; protocol. This class (&lt;i&gt;OAuth2RestTemplate&lt;/i&gt;) manages connection to required resources and also manages tokens, &lt;b&gt;OAuth&lt;/b&gt; authorization protocol, ...&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;OAuth2RestTemplate&lt;/i&gt; is injected into &lt;i&gt;CVService&lt;/i&gt;, and it is configured into &lt;i&gt;root-context.xml&lt;/i&gt;:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/964828.js?file=root-context.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that &lt;i&gt;OAuth2RestTemplate&lt;/i&gt; is created using an &lt;b&gt;OAuth&lt;/b&gt; resource that contains all information about where to connect for authorizing access to protected resource,&amp;nbsp;and in this case is &lt;i&gt;CV&lt;/i&gt; website, see that we are referencing an external website, although in this example we are using &lt;i&gt;localhost&lt;/i&gt;. Also service provider URL (http://localhost:8080/cvs/cv) is set, so &lt;i&gt;RestTemplate&lt;/i&gt; can&amp;nbsp;establish&amp;nbsp;a connection to content provider, and in case that authorization process ends successful, retrieving &amp;nbsp;requested information.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&amp;lt;oauth:resource&amp;gt; defines &lt;b&gt;OAuth&lt;/b&gt; resources, in this case, the name of the client (remember that this value was configured in server side client details tag for granting access to &lt;b&gt;OAuth&lt;/b&gt; protocol). Also &lt;i&gt;userAuthorizationUri&lt;/i&gt; is defined. This is the &lt;i&gt;URI&lt;/i&gt; to which the user will be redirected if the user is ever needed to authorize access to the resource (this is an internal URI managed by &lt;b&gt;Spring Security OAuth&lt;/b&gt;). And finally &lt;i&gt;accessTokenUri&lt;/i&gt;, the URI &lt;b&gt;OAuth&lt;/b&gt;&amp;nbsp;provider endpoint that provides the access token (internal URI too).&lt;br /&gt;&lt;br /&gt;Also creating a consumer using &lt;b&gt;Spring Security OAuth&lt;/b&gt; is simple enough.&lt;br /&gt;&lt;br /&gt;Now I will explain the sequence of events that happens when a user wants to give access to &lt;i&gt;foo&lt;/i&gt; &lt;i&gt;company&lt;/i&gt; for retrieving its &lt;i&gt;Curriculum Vitae&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;First of all user connects to &lt;i&gt;foo&lt;/i&gt; website, and click on post &lt;i&gt;curriculum vitae&lt;/i&gt; link. Then &lt;i&gt;getCV&lt;/i&gt; method from &lt;i&gt;controller&lt;/i&gt; is called. This method calls &lt;i&gt;cvService&lt;/i&gt;, that at the same time creates a connection to resource &lt;i&gt;URI (CV)&lt;/i&gt; using &lt;i&gt;OAuth2RestTemplate&lt;/i&gt;. And this class acts as a &lt;i&gt;black box&lt;/i&gt;, from client side, you don't know exactly what this class will do but it returns your &lt;i&gt;Curriculum Vitae&lt;/i&gt; stored in &lt;i&gt;CV&lt;/i&gt; website. As you can imagine this class manages all workflow related to &lt;b&gt;OAuth&lt;/b&gt;, like managing tokens, executing required URL redirections to get permissions, ... and if all steps are performed successful, stored &lt;i&gt;Curriculum Vitae&lt;/i&gt; in &lt;i&gt;CV&lt;/i&gt; site will be sent to &lt;i&gt;foo company&lt;/i&gt; site.&lt;br /&gt;&lt;br /&gt;And that's all steps required to allow your site to act as &lt;i&gt;Service Provider&lt;/i&gt; using &lt;b&gt;OAuth2&lt;/b&gt; authorization protocol. Thanks of &lt;b&gt;Spring Security&lt;/b&gt; folks, it is much easier that you may think at first.&lt;br /&gt;&lt;br /&gt;Hope you find it useful.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/cv-EP.zip"&gt;Download ServerSide (CV)&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/fooCompany-EP.zip"&gt;Download ClientSide (fooCompany)&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2683579477578094710?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2683579477578094710/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2683579477578094710' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2683579477578094710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2683579477578094710'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/05/to-seek-out-new-life-and-new.html' title='To Seek Out New Life And New Civilizations, To Boldly Go Where No Man Has Gone Before (TNG Soundtrack - Star Trek)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-5214115582531369828</id><published>2011-04-20T19:50:00.000+02:00</published><updated>2011-04-20T19:50:22.038+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><category scheme='http://www.blogger.com/atom/ns#' term='test automation'/><category scheme='http://www.blogger.com/atom/ns#' term='WebDriver'/><category scheme='http://www.blogger.com/atom/ns#' term='JBehave'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='Selenium 2'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><title type='text'>Are You Locked Up In A World That's Been Planned Out For You? Are You Feeling Like A Social Tool Without A Use? (She - Green Day)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://jbehave.org/reference/stable/images/jbehave-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="80" src="http://jbehave.org/reference/stable/images/jbehave-logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;From &lt;b&gt;JBehave &lt;/b&gt;site: &lt;b&gt;JBehave &lt;/b&gt;is a framework for &lt;i&gt;Behaviour-Driven Development&lt;/i&gt; (BDD). &lt;b&gt;JBehave &lt;/b&gt;allows developers, QA and non-technical or business participants, to write stories in a plain text file with minimal restrictions about grammar. Then a &lt;i&gt;POJO &lt;/i&gt;is created for executing created story. This &lt;i&gt;POJO &lt;/i&gt;should have the typical &lt;i&gt;BDD &lt;/i&gt;structure &lt;i&gt;Given, When and Then&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.springsource.org/sites/all/themes/dotorg09/images/dotorg09_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.springsource.org/sites/all/themes/dotorg09/images/dotorg09_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;From &lt;b&gt;Springsource &lt;/b&gt;site: &lt;b&gt;Spring Framework&lt;/b&gt; is a &lt;i&gt;Java &lt;/i&gt;platform that provides comprehensive infrastructure support for developing &lt;i&gt;Java &lt;/i&gt;applications. &lt;b&gt;Spring &lt;/b&gt;handles the infrastructure so you can focus on your application.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-rCaHU2ebCpc/Ta0kUac9HdI/AAAAAAAAF-o/0L_AhL75J9A/s1600/selenium.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="48" src="http://1.bp.blogspot.com/-rCaHU2ebCpc/Ta0kUac9HdI/AAAAAAAAF-o/0L_AhL75J9A/s200/selenium.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;From &lt;b&gt;Selenium &lt;/b&gt;site: &lt;b&gt;Selenium &lt;/b&gt;is a suite of tools to automate web app testing across many platforms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We have three technologies &lt;b&gt;JBehave &lt;/b&gt;for &lt;i&gt;acceptance tests&lt;/i&gt;, &lt;b&gt;Selenium &lt;/b&gt;for &lt;i&gt;web application testing&lt;/i&gt; and &lt;b&gt;Spring &lt;/b&gt;dealing with &lt;i&gt;infrastructure&lt;/i&gt;. In this post I will talk about integrating &lt;b&gt;JBehave &lt;/b&gt;with&lt;b&gt;&amp;nbsp;Selenium 2&lt;/b&gt; and &lt;b&gt;Spring&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;For this example I have created a very simple web application using&lt;b&gt; Spring MVC&lt;/b&gt;. I know that business logic is not accurate to the reality, but it is simple enough to illustrate how to integrate all these technologies together.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have divided this post in three main subsections:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Integrating &lt;b&gt;JBehave&lt;/b&gt; with &lt;b&gt;Spring&lt;/b&gt;. There is no web application here, only business logic.&lt;/li&gt;&lt;li&gt;Integrating &lt;b&gt;Spring MVC&lt;/b&gt; with &lt;b&gt;Selenium 2&lt;/b&gt;. Only to show how easy is implementing automated tests with Selenium 2.&lt;/li&gt;&lt;li&gt;Integrating &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Selenium 2&lt;/b&gt;. Web application used in previous example but instead of using only &lt;b&gt;Selenium &lt;/b&gt;for automating testing, &lt;b&gt;JBehave &lt;/b&gt;instructs to &lt;b&gt;Selenium &lt;/b&gt;which steps should execute.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Application that I will use is a simple &lt;i&gt;TraderService&lt;/i&gt;, (explained in &lt;b&gt;JBehave &lt;/b&gt;page (&lt;a href="http://jbehave.org/reference/stable/"&gt;http://jbehave.org/reference/stable/&lt;/a&gt;)). This&amp;nbsp;&lt;i&gt;TraderService &lt;/i&gt;generates &lt;i&gt;Stocks&lt;/i&gt;, and if a&amp;nbsp;&lt;i&gt;Stock &lt;/i&gt;is traded below threshold, its alert status is &lt;u&gt;OFF &lt;/u&gt;and if it is traded above, alert status is &lt;u&gt;ON&lt;/u&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this tutorial I assume that you have a basic idea of &lt;b&gt;JBehave &lt;/b&gt;and &lt;b&gt;Spring&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Integrating &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Spring&lt;/b&gt;:&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;In this case no web GUI is used, we are going to use &lt;b&gt;JBehave&lt;/b&gt; for writing acceptance tests of business logic.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Basic &lt;/b&gt;classes are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;TradingService&lt;/i&gt;, that defines a method for creating stocks. &lt;i&gt;TradingServiceImpl &lt;/i&gt;is the implementation.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Stock&lt;/i&gt;, that contains stock information and logic about its status.&lt;/li&gt;&lt;li&gt;&lt;i&gt;StockAlertStatus &lt;/i&gt;is Stock status Enum.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Acceptance &lt;/b&gt;test part:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First of all we should create a &lt;i&gt;story&lt;/i&gt;. A &lt;i&gt;story &lt;/i&gt;is where stakeholders, developers... should say what they want the application do, and which are the expected results for given parameters. In our case a &lt;i&gt;story &lt;/i&gt;has been created for validating that alarm is &lt;u&gt;OFF &lt;/u&gt;if trade value is under threshold, and &lt;u&gt;ON &lt;/u&gt;otherwise.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931924.js?file=trader_alert_service.story"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The important parts of that file are:&amp;nbsp;&lt;i&gt;Scenario &lt;/i&gt;for describing what we are testing, all &lt;i&gt;symbols between &amp;lt;&amp;gt;&lt;/i&gt; that are used as variables, and &lt;i&gt;Examples&lt;/i&gt;&amp;nbsp;that are values injected to previous &lt;i&gt;"&amp;lt;&amp;gt;"&lt;/i&gt; variables. In this story file two examples are provided, so two executions will be produced, one for each row. As final note, &lt;i&gt;Given&lt;/i&gt;, &lt;i&gt;When&lt;/i&gt;, &lt;i&gt;Then&lt;/i&gt; words should be placed at start and are reserved words, also more than one &lt;i&gt;Given&lt;/i&gt;, &lt;i&gt;When &lt;/i&gt;or &lt;i&gt;Then &lt;/i&gt;could be used in each story.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next step, create a class that transforms a story written in &lt;i&gt;"natural language"&lt;/i&gt; to &lt;i&gt;code&lt;/i&gt;. We could say that this class is equivalent of creating a &lt;i&gt;junit &lt;/i&gt;class; In&amp;nbsp;&lt;b&gt;JBehave &lt;/b&gt;these classes&lt;b&gt;&amp;nbsp;&lt;/b&gt;are called &lt;i&gt;Steps&lt;/i&gt;. Because we are integrating with &lt;b&gt;Spring&amp;nbsp;&lt;/b&gt;an annotation called &lt;i&gt;Steps &lt;/i&gt;is created. This annotation extends from &lt;i&gt;Component &lt;/i&gt;annotation so &lt;b&gt;Spring &lt;/b&gt;&lt;i&gt;component-scan&lt;/i&gt; can wire up step classes too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931931.js?file=Steps.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And &lt;i&gt;Steps &lt;/i&gt;annotation is used in &lt;i&gt;TradingServiceSteps &lt;/i&gt;class.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931937.js?file=TradingServiceSteps.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In &lt;i&gt;TradingServiceSteps &lt;/i&gt;is where all magic occurs. This class is responsible of transforming story file to an execution. Let's see:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;@Steps&lt;/i&gt; because we want &lt;i&gt;Spring &lt;/i&gt;creates automatically this bean. &lt;i&gt;TradingService &lt;/i&gt;is the business logic we want to test, and is injected using &lt;i&gt;Autowire &lt;/i&gt;annotation. And finally one method for each &lt;i&gt;Given&lt;/i&gt;, &lt;i&gt;When&lt;/i&gt;, &lt;i&gt;Then&lt;/i&gt;. Explained quickly, when &lt;b&gt;JBehave &lt;/b&gt;finds an&amp;nbsp;&lt;i&gt;@Given&lt;/i&gt;, it searches into loaded stories for a phrase starting with &lt;i&gt;Given&lt;/i&gt;. After that checks if &lt;i&gt;@Given&lt;/i&gt; string value matches the &lt;i&gt;Given &lt;/i&gt;definition expressed in story file. If matches then inject the story parameters as method parameters, for example &lt;u&gt;STK1&lt;/u&gt; as string parameter, or &lt;u&gt;5&lt;/u&gt; as double threshold parameter. Moreover, in this case because we are using &lt;i&gt;Examples &lt;/i&gt;in our story file, &lt;i&gt;@Named&lt;/i&gt; annotation for each parameter is required. The named parameters allow the parameters to be injected using the table row values with the corresponding header name. Each parameter is converted from String to required parameter type.&lt;br /&gt;&lt;br /&gt;We have written stories, and how to execute them (&lt;i&gt;TradingServiceSteps &lt;/i&gt;class). &lt;b&gt;JBehave &lt;/b&gt;requires another class, that will be responsible of configurating it. Basically you should configure &lt;i&gt;Step&amp;nbsp;&lt;/i&gt;classes and story files location, and what kind of reports are generated.&lt;br /&gt;&lt;br /&gt;In our case, because we are integrating &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Spring&lt;/b&gt;, some information is provided using &lt;b&gt;Spring &lt;/b&gt;Injection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/931947.js?file=TraderIsAlertedStories.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;This class is where &lt;b&gt;JBehave &lt;/b&gt;is configured and is responsible for running all stories. Let's examine the most important lines:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;In line 1&lt;/i&gt; we specify a &lt;i&gt;JUnit &lt;/i&gt;runner for running &lt;b&gt;JBehave &lt;/b&gt;stories with &lt;b&gt;Spring&lt;/b&gt;.&lt;br /&gt;&lt;i&gt;In line 2&lt;/i&gt; we are configuring &lt;b&gt;JBehave &lt;/b&gt;with Enum parameter converter, see that &lt;i&gt;StockAlertStatus &lt;/i&gt;is an enum, because it is not a primitive parameter, a converter should be provided. &lt;b&gt;JBehave &lt;/b&gt;comes with some convertes, but we can implement ours too.&lt;br /&gt;&lt;i&gt;In line 3&lt;/i&gt; the embedder that we will use. This is the standard embedder for &lt;b&gt;JBehave&lt;/b&gt;. &lt;i&gt;Embedder &lt;/i&gt;represents an entry point to all of &lt;b&gt;JBehave's &lt;/b&gt;functionality that is embeddable into other launchers.&lt;br /&gt;And finally with &lt;i&gt;@UsingSpring&lt;/i&gt; we are providing two &lt;b&gt;Spring &lt;/b&gt;files, one where step classes are defined, and the other one where &lt;b&gt;JBehave &lt;/b&gt;is configured.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Configuration file is a standard &lt;b&gt;Spring &lt;/b&gt;file injecting required &lt;b&gt;JBehave &lt;/b&gt;parameters:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931953.js?file=configuration.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;This is a generic configuration file, that I use in all projects. You configure the output, the classloader for &lt;i&gt;Embedder &lt;/i&gt;and&amp;nbsp;prefix for parameters&lt;br /&gt;&lt;br /&gt;And finally a &lt;b&gt;Spring &lt;/b&gt;context file where all step classes are defined. And you know what, thanks of &lt;b&gt;Spring &lt;/b&gt;this is as simple as:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;script src="https://gist.github.com/932083.js?file=tradingService-acceptancetest.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;No magic, remember that each &lt;i&gt;Step &lt;/i&gt;class has an&lt;i&gt; @Steps&lt;/i&gt; annotation? Thanks of &lt;i&gt;component-scan&lt;/i&gt;, you don't have to define each &lt;i&gt;Step &lt;/i&gt;class in &lt;i&gt;@UsingSteps&lt;/i&gt;&amp;nbsp;annotation or using &lt;i&gt;&lt;bean&gt;&lt;/bean&gt;&lt;/i&gt; tags.&lt;br /&gt;&lt;br /&gt;Now run previous class as &lt;i&gt;JUnit&lt;/i&gt;, and reports with results are generated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Integrating &lt;b&gt;Spring MVC&lt;/b&gt; with &lt;b&gt;Selenium 2&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Selenium 2&lt;/b&gt; is a suite of tools to automate web app testing across many platforms. In this case&amp;nbsp;&lt;i&gt;WebDriver &lt;/i&gt;approach has been used. &lt;i&gt;WebDriver &lt;/i&gt;is an interface for&amp;nbsp;automating&amp;nbsp;tests in a programmatic way. &lt;b&gt;Selenium &lt;/b&gt;provides several implementations depending on browser where tests are run.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;For this example I have created an &lt;b&gt;Spring MVC&lt;/b&gt; application, that are composed of two pages, one form where all stock information is provided and a page where status of inserted stock is showed. Of course &lt;b&gt;Spring MVC&lt;/b&gt; controller for managing all information is also implemented.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Controller &lt;/i&gt;of this small application is:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931966.js?file=HomeController.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;showForm &lt;/i&gt;method is used for showing the form where user will write stock information. &lt;i&gt;submitForm &lt;/i&gt;method is called when submit button is pushed, and creates an stock and send to &lt;i&gt;showstatus &lt;/i&gt;page the status of stock.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;i&gt;StockForm &lt;/i&gt;is simply a class with three attributes (&lt;i&gt;stock&lt;/i&gt;, &lt;i&gt;threshold &lt;/i&gt;and &lt;i&gt;tradeAt &lt;/i&gt;price). No secret here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Form page is also so simply but I will show it because form information will be used for configuring &lt;b&gt;Selenium&lt;/b&gt;:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931974.js?file=newstock.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-RdralOZ0g5c/Ta8WNi1t05I/AAAAAAAAF-s/JMRMA3cGOJk/s1600/form_selenium.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="513" src="http://3.bp.blogspot.com/-RdralOZ0g5c/Ta8WNi1t05I/AAAAAAAAF-s/JMRMA3cGOJk/s640/form_selenium.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;Page for showing status:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931979.js?file=showstatus.jsp"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;WebDriver &lt;/i&gt;is used in &lt;i&gt;JUnit &lt;/i&gt;test for automatizing a sequence of events. In this case, the sequence will create an stock below threshold and assert that response page shows that alert status is &lt;u&gt;OFF&lt;/u&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931987.js?file=TraderIsAlertedSelenium.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931989.js?file=selenium-applicationContext.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Most important sections of previous &lt;i&gt;JSP &lt;/i&gt;are:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;JSP taglib&lt;/i&gt;s &amp;lt;&lt;i&gt;form:input path=""/&amp;gt;&lt;/i&gt;&amp;nbsp;like &amp;lt;&lt;i&gt;form:input path="name"/&amp;gt;&lt;/i&gt;&amp;nbsp;in form, and &amp;lt;&lt;i&gt;div id="result"&amp;gt;&lt;/i&gt;. These fields are important because they are used by &lt;b&gt;Selenium &lt;/b&gt;for filling form and asserting showed status.&lt;br /&gt;&lt;br /&gt;For example, in &lt;b&gt;Selenium &lt;/b&gt;class:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;WebElement name = driver.findElement(id("name"))&lt;/i&gt; returns a &lt;i&gt;"reference"&lt;/i&gt; to &lt;i&gt;&amp;lt;input id="name" type="text"&amp;gt;&lt;/i&gt; element and using &lt;i&gt;sendKeys &lt;/i&gt;method, you are sending keyboard chars to that component.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;WebElement element = driver.findElement(id("result"))&lt;/i&gt;, returns a &lt;i&gt;"reference"&lt;/i&gt; to &lt;i&gt;div&lt;/i&gt; element and using&lt;br /&gt;&lt;i&gt;assertThat(element.getText(), is(StockAlertStatus.OFF.name()));&lt;/i&gt;&amp;nbsp;&lt;i&gt;getText &lt;/i&gt;method, none tag characters of element are returned.&lt;br /&gt;&lt;br /&gt;Now running this test is as simple as running &lt;i&gt;TraderIsAlertedSelenium &lt;/i&gt;class as a simple &lt;i&gt;JUnit &lt;/i&gt;test class. When running this class a browser (&lt;i&gt;Firefox&lt;/i&gt; in this case) will be opened, and all programmed interactions will be executed on your screen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;At this point we just have to join both previous parts, and integration between &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Spring &lt;/b&gt;and &lt;b&gt;Selenium &lt;/b&gt;will be reality.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Integrating &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Selenium 2&lt;/b&gt; and &lt;b&gt;Spring&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;JBehave &lt;/b&gt;has a module called &lt;b&gt;JBehave-Web&lt;/b&gt;, that is used for integrating &lt;b&gt;JBehave &lt;/b&gt;with web pages. Base classes are &lt;i&gt;WebDriverProvider &lt;/i&gt;and &lt;i&gt;WebDriverPage&lt;/i&gt;. Both classes are used by &lt;b&gt;JBehave &lt;/b&gt;for abstracting from browser, and also for providing common methods to test webpages. In this example I won't use &lt;i&gt;jbehave-web&lt;/i&gt; for two reasons, first because &lt;b&gt;Selenium 2&lt;/b&gt; with &lt;i&gt;WebDriver &lt;/i&gt;offers a level of abstraction that is enough for this example, and secondly because &lt;i&gt;WebDriverPage &lt;/i&gt;is a class that implements some common funcionalities for testing, but it is abstract, I don't like using extension only for sharing common operations between classes, it is a bad practice (not discussed here), I prefer aggregation. So in this case I have&amp;nbsp;preferred&amp;nbsp;&amp;nbsp;implementing my class for implementing common&amp;nbsp;functionalities.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931992.js?file=PageUtils.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this case abstraction from browser is acquired using &lt;i&gt;WebDriver &lt;/i&gt;(&lt;b&gt;Selenium&lt;/b&gt;) interface. Moreover all common operations are implemented into this class. The idea of this class is to be used in several projects and for that reason a better design should be desired, but for current example is enough.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next group of classes are those that use &lt;i&gt;PageUtils &lt;/i&gt;object. I have created one class for each page that &lt;b&gt;Selenium &lt;/b&gt;should interact with. Acts as a facade to web.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example class for dealing with page containing form to insert new stock is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/931997.js?file=InsertStockPage.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Three operations can be executed in this page, the first one is open the page. Because &lt;i&gt;"insert a new stock"&lt;/i&gt; is accessed manually (in this case is the front page), an open method is provided with&amp;nbsp;&lt;i&gt;URL&lt;/i&gt;. Also a method for filling stock form and and another for submitting it are provided.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And finally a class that transforms an story written in &lt;i&gt;"natural language"&lt;/i&gt; to code (also known as &lt;i&gt;Steps &lt;/i&gt;class), this class would be the same used in first example (&lt;i&gt;TradingServiceSteps&lt;/i&gt;) but adapted for dealing with web pages (using previous classes).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/932000.js?file=TradingServiceWebSteps.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;See that there is no&amp;nbsp;differences&amp;nbsp;between this class and the one created in first example, but using web page interfaces instead of business objects.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next modified files are:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Story file:&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/932010.js?file=traderservice-web.story"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;that has been modified to use web terminology.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Spring file:&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/932018.js?file=selenium-applicationContext.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;that injects into &lt;i&gt;TradingServiceWebSteps &lt;/i&gt;required beans.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Configuration &lt;/i&gt;file used in first example is the same, and &lt;b&gt;Spring&lt;/b&gt; file for configuring &lt;b&gt;JBehave &lt;/b&gt;is the same too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In summary I can definitely say that integrating &lt;b&gt;JBehave &lt;/b&gt;with &lt;b&gt;Selenium 2&lt;/b&gt; and &lt;b&gt;Spring &lt;/b&gt;is not a difficult task, compared with the benefits that lead us having an &lt;i&gt;automated acceptance test platform&lt;/i&gt;. I wish you have found this post useful.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/JBehave-Example-EP.zip"&gt;Download Full Code&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-5214115582531369828?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/5214115582531369828/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=5214115582531369828' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5214115582531369828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/5214115582531369828'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/04/are-you-locked-up-in-world-thats-been.html' title='Are You Locked Up In A World That&apos;s Been Planned Out For You? Are You Feeling Like A Social Tool Without A Use? (She - Green Day)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-rCaHU2ebCpc/Ta0kUac9HdI/AAAAAAAAF-o/0L_AhL75J9A/s72-c/selenium.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-1210229646023589762</id><published>2011-04-15T18:52:00.001+02:00</published><updated>2011-04-15T18:54:36.774+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='AccessDecisionManager'/><category scheme='http://www.blogger.com/atom/ns#' term='Authorization'/><category scheme='http://www.blogger.com/atom/ns#' term='voter'/><category scheme='http://www.blogger.com/atom/ns#' term='spring security'/><category scheme='http://www.blogger.com/atom/ns#' term='web security'/><title type='text'>Everywhere I'm Looking Now I'm Surrounded By Your Embrace Baby I Can See Your Halo You Know You Are My Saving Grace (Halo - Beyonce)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;b&gt;Spring Security&lt;/b&gt; provides comprehensive security services for J2EE-based enterprise software applications.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;There are two important concepts in application security. &amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;Authentication &lt;/i&gt;is the process of establishing a principal is who they claim to be, generally that information comes in form of username/password.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;Authorization &lt;/i&gt;refers to the process of deciding whether a user is allowed to perform an action within your application.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;In &lt;b&gt;Spring Security&lt;/b&gt;, and as summary, we can say that two classes are&amp;nbsp;responsible&amp;nbsp;of implementing each concept:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;Main interface for &lt;i&gt;Authentication &lt;/i&gt;is &lt;i&gt;AuthenticationManager&lt;/i&gt;. The default implementation is &lt;i&gt;ProviderManager&lt;/i&gt;. This rather than handling request itself, it delegates it to a list of &lt;i&gt;AuthenticationProviders &lt;/i&gt;which each one tries to perform the authentication against its&amp;nbsp;back-end&amp;nbsp;with username and password provided. An example of providers is &lt;i&gt;DaoAuthenticationProvider&lt;/i&gt;, &lt;i&gt;LdapAuthenticationProvider&lt;/i&gt;...&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Main interface for &lt;i&gt;Authorization &lt;/i&gt;is &lt;i&gt;AccessDecisionManager&lt;/i&gt;. &lt;b&gt;Spring Security&lt;/b&gt; includes several &lt;i&gt;AccessDecisionManager &lt;/i&gt;implementations that are based on voting. Three &lt;i&gt;AccessDecisionManagers &lt;/i&gt;are provided: &lt;i&gt;AffirmativeBase &lt;/i&gt;(grants access if any voter returns an affirmative response), &lt;i&gt;ConsensusBased &lt;/i&gt;("Consensus" here means majority-rule (ignoring abstains) rather than unanimous agreement (ignoring abstains)), and &lt;i&gt;UnanimousBase &lt;/i&gt;(requires all voters to abstain or grant access). In fact voters are the most important concept of authorization process, because are the final&amp;nbsp;responsible&amp;nbsp;of granting or not access to a resource.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Imagine next problem, you have developed a website for an online television, where only during daylight programs are live broadcasted and recorded, and during night programs recorded during day are rebroadcasted. Because of bandwidth problem, only registered users with &lt;u&gt;ROLE_USER &lt;/u&gt;can watch live programs, but the rest of the world (registered or not) can watch at night the programs recorded during the day.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;There are many approaches for developing that requirement, but how about implementing a voter that votes affirmative when it is night and negative when it is day?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/921931.js?file=NightVoter.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;See that most important method is vote. This method receives the caller invoking method, the secured object and the configuration attributes associated with the method being invoked and only returns if it grants, if it denies or if it abstains access to resource. Because our requirements are as easy as comparing if it is day or night these attributes are not used.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;And I suppose you are wondering, "&lt;i&gt;Ok man so easy, but how I register this new voter to the AccessDecisionManagers object?&lt;/i&gt;". Well it is also easy, the only inconvenience is that &lt;i&gt;namespaces &lt;/i&gt;does not provide this feature and beans should be configured as old-school spring security files.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;script src="https://gist.github.com/921965.js?file=application-security.xml"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;u&gt;At line 1&lt;/u&gt; we are configuring the security to http calls as usually but instead of relying on default decision manager, we are referencing to an access decision defined below.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;u&gt;At line 5&lt;/u&gt;, an &lt;i&gt;AffirmativeBased &lt;/i&gt;decision manager is created, with two voters, one that will grant access if user have required role (&lt;u&gt;line 8&lt;/u&gt;) and another one that is &lt;b&gt;NightVoter &lt;/b&gt;implemented above granting only access if it is night.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;And finally &lt;i&gt;Authentication Manager&lt;/i&gt; beans with &lt;i&gt;inmemory &lt;/i&gt;approach.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;I think is a clean solution of an authorization problem, and also shows how &lt;b&gt;Spring Security&lt;/b&gt; can adapt to very different scenarios involving web security.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="https://github.com/downloads/maggandalf/Blog-Examples/NightVoter-Example-EP.zip"&gt;Download Example.&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-1210229646023589762?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/1210229646023589762/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=1210229646023589762' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1210229646023589762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/1210229646023589762'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/04/everywhere-im-looking-now-im-surrounded.html' title='Everywhere I&apos;m Looking Now I&apos;m Surrounded By Your Embrace Baby I Can See Your Halo You Know You Are My Saving Grace (Halo - Beyonce)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2065646156891305571</id><published>2011-04-10T18:37:00.000+02:00</published><updated>2011-04-10T18:37:37.032+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nullable equals'/><category scheme='http://www.blogger.com/atom/ns#' term='java.util.Objects'/><category scheme='http://www.blogger.com/atom/ns#' term='nullable hash'/><category scheme='http://www.blogger.com/atom/ns#' term='nullable toString'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk 7'/><title type='text'>Another Shot Of Whiskey Can't Stop Looking At The Door Wishing You'd Come Sweeping In The Way You Did Before (Lady Antebellum - Need You Now)</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.h-online.com/imgs/43/6/3/4/8/2/9/java_logo_no_txt_200-793e307756d06647.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://www.h-online.com/imgs/43/6/3/4/8/2/9/java_logo_no_txt_200-793e307756d06647.png" width="148" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;With new release of &lt;b&gt;JDK 7&lt;/b&gt;, a lot of really useful features has been developed, some of them I have write off before in this blog (&lt;a href="http://alexsotob.blogspot.com/2011/04/cos-only-thing-misplaced-was-direction.html"&gt;JSR 203&lt;/a&gt;&amp;nbsp;and &lt;a href="http://alexsotob.blogspot.com/2011/03/sa-zebra-que-passa-un-semafor-i-com-se.html"&gt;JSR 166y&lt;/a&gt;). In this post I am going to talk about one new small enhancement. This new feature is the addition of j&lt;b&gt;ava.util.Objects &lt;/b&gt;class. This class is similar to &lt;i&gt;java.util.Arrays&lt;/i&gt; or &lt;i&gt;java.util.Collections&lt;/i&gt; but for objects instead of &lt;i&gt;arrays&lt;/i&gt; or &lt;i&gt;collections&lt;/i&gt;.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This class offers nine methods grouped by four groups: &lt;i&gt;equality&lt;/i&gt;, &lt;i&gt;hashing&lt;/i&gt;, &lt;i&gt;nullables&lt;/i&gt;, and &lt;i&gt;toString&lt;/i&gt;. Let's examine all of them.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;compare(T a, T b, Comparator c):int&lt;/i&gt; =&amp;gt; Returns 0 if the arguments are identical and &lt;i&gt;c.compare(a, b)&lt;/i&gt; otherwise. Consequently, if both arguments are &lt;i&gt;null&lt;/i&gt; 0 is returned.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;deepEquals(Object a, Object b):boolean&lt;/i&gt; =&amp;gt; Returns true if the arguments are deeply equal to each other and false otherwise. Two null values are deeply equal. If both arguments are arrays, the algorithm in &lt;i&gt;Arrays.deepEquals&lt;/i&gt; is used to determine equality. Otherwise, equality is determined by using the equals method of the first argument. This operation is useful if you want to compare two objects and you don't know exactly if &lt;i&gt;Object&lt;/i&gt; is a "single" object or an&amp;nbsp;&lt;i&gt;array&lt;/i&gt;. This method manages this problem, and compares both instances correctly.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;equals(Object a, Object b):boolean&lt;/i&gt; =&amp;gt; Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument. And I suppose you are wondering "&lt;i&gt;nice but I have an equals method in object class&lt;/i&gt;". Yes you are right but look next example:&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/910329.js?file=ShowFooWithNull.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If &lt;i&gt;foo&lt;/i&gt; is &lt;i&gt;null&lt;/i&gt;, a &lt;i&gt;NullPointerException&lt;/i&gt; is thrown. One can argue that you should check for null input parameters, this is a simple example, but I am sure all of us sometimes we have received a &lt;i&gt;NullPointerException&lt;/i&gt; in an equals.&lt;br /&gt;&lt;br /&gt;But see that:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/911282.js?file=EqualsWithNullProtection.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Not And a Half&lt;/i&gt; is showed instead of throwing a &lt;i&gt;NullPointerException&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;hash(Object... values):int&lt;/i&gt; =&amp;gt; Generates a hash code for a sequence of input values. The hash code is generated as if all the input values were placed into an array, and that array were hashed by calling &lt;i&gt;Arrays.hashCode(Object[])&lt;/i&gt;. This method is really useful in&amp;nbsp;&lt;i&gt;DTO&lt;/i&gt; objects. For example &lt;i&gt;Hibernate&lt;/i&gt; "requires" that all objects implement &lt;i&gt;equals&lt;/i&gt; and &lt;i&gt;hashCode&lt;/i&gt;. It is typical that &lt;i&gt;DTOs&lt;/i&gt;&amp;nbsp;can contain lot of fields, take a look any of these classes how many lines of code can contain those&amp;nbsp;&lt;i&gt;hashCode&lt;/i&gt; methods.&amp;nbsp;But see how simple is using this method:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/911286.js?file=CalculateHash.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;hashCode(Object o):int &lt;/i&gt;=&amp;gt; Returns the hash code of a non-null argument and 0 for a null argument.&lt;br /&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;i&gt;requireNonNull(T obj):T&lt;/i&gt; =&amp;gt; Checks that the specified object reference is not null. This method is designed primarily for doing parameter validation in methods and constructors. If &lt;i&gt;obj&lt;/i&gt; variable is null a &lt;i&gt;NullPointerException&lt;/i&gt; is thrown. Look next example:&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/911594.js?file=RequireNotNullParameter.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I think it is a clean solution, avoid noise code, and it is more readable than&amp;nbsp;&lt;i&gt;if(foo == null) throw new NullPointerException();&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;requireNonNull(T obj, String message): T =&lt;/i&gt;&amp;gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;Checks that the specified object reference is not null and throws a customized &lt;i&gt;NullPointerException&lt;/i&gt; using message parameter, if it is.&lt;/li&gt;&lt;li&gt;&lt;i&gt;toString(Object o): String&lt;/i&gt; =&amp;gt; Returns the result of calling &lt;i&gt;toString&lt;/i&gt; for a non-null argument and "&lt;i&gt;null&lt;/i&gt;" for a null argument.&lt;/li&gt;&lt;li&gt;&lt;i&gt;toString(Object o, String nullDefault): String&lt;/i&gt; =&amp;gt; Returns the result of calling &lt;i&gt;toString&lt;/i&gt; on the first argument if the first argument is not null and returns the second argument otherwise. I find this method so useful for logging&amp;nbsp;porpoises. Sometimes you are going to log some information that &lt;u&gt;null value has a meaning&lt;/u&gt;. For example without using this class, a log line could be:&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/911604.js?file=LogNullParameter.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But would be more readable:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="https://gist.github.com/911608.js?file=LoggingWithObjectsToString.java"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I am sure &lt;i&gt;java.util.Objects&lt;/i&gt; would not go down in history as the best new feature added in &lt;b&gt;JDK 7&lt;/b&gt;, but honestly, I find it so useful and it will help me so much developing code even more readable. Enjoy it.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2065646156891305571?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2065646156891305571/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2065646156891305571' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2065646156891305571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2065646156891305571'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/04/another-shot-of-whiskey-cant-stop.html' title='Another Shot Of Whiskey Can&apos;t Stop Looking At The Door Wishing You&apos;d Come Sweeping In The Way You Did Before (Lady Antebellum - Need You Now)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-3176943558965473794</id><published>2011-04-07T19:38:00.001+02:00</published><updated>2011-04-07T19:40:07.651+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='JdbcTemplate'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa 2'/><category scheme='http://www.blogger.com/atom/ns#' term='Criteria API'/><category scheme='http://www.blogger.com/atom/ns#' term='type-safe queries'/><category scheme='http://www.blogger.com/atom/ns#' term='QueryDSL'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Come On Let's Twist Again Like We Did Last Summer Yea, Let's Twist Again Like We Did Last Year (Chubby Checker -  Let's Twist Again)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://hotsnow.fi/fi/files/imagecache/lead_image_thumbnail/works/images/querydsl_sym_l.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://hotsnow.fi/fi/files/imagecache/lead_image_thumbnail/works/images/querydsl_sym_l.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;JPA 2 Criteria API&lt;/i&gt; allows criteria queries to be constructed in a strongly-typed manner, using meta-model objects to provide type safety. This is a useful feature because when a change occurs in database, for example a rename of a field, your queries will not compile, and you will see the problem in compilation time instead of running time.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Yes I have already talked about in my previous post&amp;nbsp;&lt;a href="http://alexsotob.blogspot.com/2011/01/deep-inside-you-cry-cry-cry-dont-let.html"&gt;http://alexsotob.blogspot.com/2011/01/deep-inside-you-cry-cry-cry-dont-let.html&lt;/a&gt;&amp;nbsp;but there are an &lt;i&gt;API&lt;/i&gt; that do the same as &lt;i&gt;Criteria API&lt;/i&gt;, and is called &lt;b&gt;QueryDSL&lt;/b&gt;. &lt;b&gt;QueryDSL&lt;/b&gt;&amp;nbsp;is a framework which enables the construction of type-safe &lt;i&gt;SQL&lt;/i&gt;-like queries for multiple back-ends including &lt;i&gt;JPA&lt;/i&gt;, &lt;i&gt;JDO&lt;/i&gt; and &lt;i&gt;SQL&lt;/i&gt; in &lt;i&gt;Java&lt;/i&gt;. Working with &lt;i&gt;QueryDSL&lt;/i&gt; and &lt;i&gt;JPA&lt;/i&gt; is like working with &lt;i&gt;HibernateMetamodel Generator&lt;/i&gt; because &lt;b&gt;QueryDSL&lt;/b&gt; has an &lt;i&gt;Annotation Processor&lt;/i&gt; that generates &lt;i&gt;Meta-model&lt;/i&gt; information from &lt;i&gt;JPA 2&lt;/i&gt; annotated classes. So I suppose you are wondering, why I should use &lt;b&gt;QueryDSL&lt;/b&gt; instead of &lt;i&gt;JPA 2 Criteria API&lt;/i&gt;? In its site there are interesting posts about that &lt;a href="http://source.mysema.com/forum/mvnforum/viewthread_thread,49"&gt;http://source.mysema.com/forum/mvnforum/viewthread_thread,49&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What makes really different &lt;b&gt;QueryDSL&lt;/b&gt; from &lt;i&gt;JPA2 Criteria API&lt;/i&gt;, is that &lt;b&gt;QueryDSL&lt;/b&gt; also works with &lt;i&gt;JDBC&lt;/i&gt; applications. Yes you read it right, &lt;i&gt;JDBC&lt;/i&gt; applications can take benefit from &lt;b&gt;QueryDSL&lt;/b&gt;, and instead of creating queries as plain text, they can be constructed in a strongly-typed manner too.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Some of advantages of using &lt;b&gt;QueryDSL&lt;/b&gt; in &lt;i&gt;JDBC&lt;/i&gt; are:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;Code Completion in IDE.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Almost no syntactically invalid queries allowed (type-safe on all levels).&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Domain types and properties can be referenced safely (no Strings involved!).&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Incremental query definition is easier.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;If you visit its webpage you could see one example using &lt;b&gt;QueryDSL&lt;/b&gt; with &lt;i&gt;JPA&lt;/i&gt;, but also one for &lt;i&gt;JDBC&lt;/i&gt;. What I am going to explain is how to use &lt;b&gt;QueryDSL&lt;/b&gt; with &lt;i&gt;Spring Jdbc Template&lt;/i&gt;. Most of us, when we develop a &lt;i&gt;Spring&lt;/i&gt; application and want to use &lt;i&gt;JDBC&lt;/i&gt;, we use &lt;i&gt;JdbcTemplate&lt;/i&gt; class or one of its extensions. &amp;nbsp;For that reason I will explain how I use &lt;i&gt;JdbcTemplate&lt;/i&gt; with &lt;b&gt;QueryDSL&lt;/b&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;First of all I implement an extension of &lt;i&gt;JdbcTemplate&lt;/i&gt; class. I have called &lt;i&gt;QueryDSLJdbcTemplate&lt;/i&gt;. This class has a simple method called &lt;i&gt;queryForList(SQLQuery sqlQuery, RowMapper&lt;t&gt; rowMapper, Expression... expressions)&lt;/t&gt;&lt;/i&gt; and has three parameters, the first one is a &lt;b&gt;SQLQuery&lt;/b&gt; object, this is the main class where you define the query you want to execute (like &lt;i&gt;JPA 2 Criteria&lt;/i&gt;), the next one is a &lt;i&gt;RowMapper&lt;/i&gt; object as most of &lt;i&gt;JdbcTemplate&lt;/i&gt; methods use, and the third one is an array of &lt;i&gt;Expressions&lt;/i&gt;; these expressions represents each database fields we want to return as result, like &lt;i&gt;id&lt;/i&gt;, &lt;i&gt;name&lt;/i&gt;, &lt;i&gt;age&lt;/i&gt;, ....&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;Implementation of this method:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="http://snipt.org/embed/wplz"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;At line 4, we are attaching a connection to given &lt;b&gt;SQLQuery&lt;/b&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;At line 6, the query is executed, and result set is returned.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;At line 10, the result set is transformed to a list of required objects, using &lt;i&gt;RowMapper&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Next step is creating a query. In this example I will use an &lt;i&gt;Employee&lt;/i&gt; class that have two attributes, an &lt;i&gt;id&lt;/i&gt; and a &lt;i&gt;name&lt;/i&gt;. The query is finding an employee by name. So &lt;i&gt;EmployeeDAO&lt;/i&gt; looks like:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="http://snipt.org/embed/wplG"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Using &lt;i&gt;JPA&lt;/i&gt; you specify which database engine is used injecting &lt;i&gt;Database&lt;/i&gt; dialect. In our case it is a &lt;i&gt;JDBC&lt;/i&gt; application so we should configure &lt;b&gt;SQLQuery&lt;/b&gt; object with database engine used, so &lt;b&gt;QueryDSL&lt;/b&gt; generates query syntax correctly. This is done with line 1 and 2.&lt;br /&gt;&lt;br /&gt;Line 4 is an auto-generated class, similar to classes generated by &lt;i&gt;Hibernate Annotation Processor&lt;/i&gt;. It contains all meta-information of an entity.&lt;br /&gt;&lt;br /&gt;Line 5 is the query construction. See that we are not creating an &lt;i&gt;SQL&lt;/i&gt; string (&lt;i&gt;SELECT * FROM Employee as emp WHERE emp.name=?&lt;/i&gt;), but we are creating in a programmatic way. Look this line &lt;i&gt;qEmployee.name.eq(name)&lt;/i&gt; because if we change field &lt;i&gt;name&lt;/i&gt; to &lt;i&gt;fullName&lt;/i&gt;, our code will not compile (&lt;i&gt;qEmployee.name&lt;/i&gt; attribute does not exist now) meanwhile &lt;i&gt;SQL&lt;/i&gt; string approach will compile, but crashing in runtime.&lt;br /&gt;&lt;br /&gt;Line 7 is a simple &lt;i&gt;RowMapper&lt;/i&gt;, and there the parameter name is also not specified as string but as an object, where native queries were &lt;i&gt;rs.getString("name")&lt;/i&gt; and if name does not exists an &lt;i&gt;SQLExpcetion&lt;/i&gt; was thrown, now a compilation error would be thrown too.&lt;br /&gt;&lt;br /&gt;After &lt;i&gt;RowMapper&lt;/i&gt; definition, we are executing the find method. The last two attributes are the fields we are looking for. Between &lt;i&gt;SQL&lt;/i&gt; query and &lt;b&gt;QueryDSL&lt;/b&gt; expression you can identify the &lt;i&gt;FROM&lt;/i&gt; clause in both and the &lt;i&gt;WHERE&lt;/i&gt; clause in both, but not the &lt;i&gt;* of SELECT&lt;/i&gt;. This is the place where this information is passed.&lt;br /&gt;&lt;br /&gt;Last method is for extracting real column name to result set.&lt;br /&gt;&lt;br /&gt;Of course this is a basic implementation, for example &lt;i&gt;Dialect&lt;/i&gt; should be injected rather than created each time, &lt;i&gt;EmployeeRowMapper&lt;/i&gt; could not be an inner class, and &lt;i&gt;getParameterName&lt;/i&gt; should be in a &lt;i&gt;Util&lt;/i&gt; class, but because of clarity, all this code has been implemented in the same class.&lt;br /&gt;&lt;br /&gt;And I suppose you are still wondering what is &lt;i&gt;QEmployee&lt;/i&gt; class. &lt;i&gt;Employee&lt;/i&gt; class is a simple &lt;i&gt;DTO&lt;/i&gt; object. &lt;i&gt;QEmployee&lt;/i&gt; is where all meta-information of &lt;i&gt;Employee&lt;/i&gt; class is stored. In &lt;i&gt;JPA&lt;/i&gt; usually &lt;i&gt;JPA Providers&lt;/i&gt; have an &lt;i&gt;Annotation Provider&lt;/i&gt; that read annotated model classes and generates Meta-model classes. In &lt;i&gt;JDBC&lt;/i&gt;, there are no annotated model classes, but an alternative mechanism is provided for generating these classes. &lt;b&gt;QueryDSL&lt;/b&gt; provides an &lt;i&gt;ANT&lt;/i&gt;-task, a &lt;i&gt;Maven&lt;/i&gt;-Task, and a Plain &lt;i&gt;API&lt;/i&gt;. I will show you plain &lt;i&gt;API&lt;/i&gt; configuration and same values should be provided for &lt;i&gt;ANT&lt;/i&gt; and &lt;i&gt;Maven&lt;/i&gt; tasks.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;script src="http://snipt.org/embed/wplI"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;You must specify as input parameters, a connection to database and which schema contains business model. And as output parameters, which package should be generated meta-model classes, and root source code directory. The best approach for generating these classes is using &lt;i&gt;Maven&lt;/i&gt;, so before compile &lt;i&gt;goal&lt;/i&gt; is executed, all meta-data model is generated.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And &lt;i&gt;Spring Application Context&lt;/i&gt; class looks as simple as:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;script src="http://snipt.org/embed/wplJ"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Now you can take all benefits from using &lt;i&gt;DSL&lt;/i&gt; for queries in &lt;i&gt;JDBC&lt;/i&gt; applications.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-3176943558965473794?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/3176943558965473794/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=3176943558965473794' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3176943558965473794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/3176943558965473794'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/04/come-on-lets-twist-again-like-we-did.html' title='Come On Let&apos;s Twist Again Like We Did Last Summer Yea, Let&apos;s Twist Again Like We Did Last Year (Chubby Checker -  Let&apos;s Twist Again)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2883863296083342239</id><published>2011-04-01T19:29:00.000+02:00</published><updated>2011-04-01T19:29:34.602+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NIO 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr 203'/><category scheme='http://www.blogger.com/atom/ns#' term='FileWatcher'/><category scheme='http://www.blogger.com/atom/ns#' term='files operations'/><category scheme='http://www.blogger.com/atom/ns#' term='MIME type'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk 7'/><category scheme='http://www.blogger.com/atom/ns#' term='Glob'/><title type='text'>'Cos The Only Thing Misplaced Was Direction And I Found Direction There Is No Childhood's End  (Childhoods End - Marillion)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.taranfx.com/wp-content/uploads/java7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.taranfx.com/wp-content/uploads/java7.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;JSR 203&lt;/b&gt; is a new specification implemented in&lt;b&gt; JDK 7&lt;/b&gt;, and is about &lt;b&gt;NIO 2.0. JSR 203&lt;/b&gt; defines three points of improvement:&lt;/div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;Filesystem interface.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Complete Socket-Channel&amp;nbsp;Functionality.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Support for Asynchronous I/O.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In this post I will talk about filesystem interface, because there are new classes that implements some file&amp;nbsp;functionalities&amp;nbsp;that more often than not I had developed myself in projects. In summary we will take a look to &lt;i&gt;Path&lt;/i&gt; class and &lt;i&gt;Files&lt;/i&gt; class.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Path&lt;/i&gt; is "&lt;i&gt;an object that may be used to locate a file in a file system. It will typically represent a system dependent file path&lt;/i&gt;". Well in common language a path is the route to a resource. More or less like old &lt;i&gt;File&lt;/i&gt; class, in fact &lt;i&gt;java.io.File&lt;/i&gt; has a new method &lt;i&gt;toPath() &lt;/i&gt;that returns a&lt;i&gt; Path &lt;/i&gt;instance.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Files&lt;/i&gt; class is an utility class that implements common file operations like creating, finding (you say finding? yes), deleting, reading contents ...&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For me typical operations that are implemented in &lt;i&gt;Files&lt;/i&gt; class are:&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;* Delete a file (/tmp/test/sec.txt)&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;Path file = Paths.get("/tmp/test", "sec.txt");&lt;br /&gt;Files.delete(file);&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Files.delete&lt;/i&gt; method deleates passed &lt;u&gt;&lt;i&gt;file&lt;/i&gt;&lt;/u&gt; path, and that's important because with not empty directory a &lt;i&gt;DirectoryNotEmptyException&lt;/i&gt; is thrown.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And how about deleting a directory with contents? let me introduce another new concept. &lt;i&gt;FileVisitor&lt;/i&gt; interface. &lt;i&gt;Files&lt;/i&gt; class has a method for walking along all directories tree. This is useful if you wanted for example implements the &lt;i&gt;&lt;u&gt;tree&lt;/u&gt;&lt;/i&gt; &lt;i&gt;*nix&lt;/i&gt; command (prints all directory structure for given root directory). But in my case I will implement a complete delete function (&lt;i&gt;*nix&lt;/i&gt; equivalent command would be &lt;i&gt;&lt;u&gt;rm -Rf /tmp/test&lt;/u&gt;&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;script src="http://snipt.org/embed/wpgO"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Previous code is equivalent to command &lt;u&gt;&lt;i&gt;rm -Rf /tmp/test&lt;/i&gt;&lt;/u&gt;. &lt;i&gt;SimpleFileVisitor&lt;/i&gt; is an implementation of &lt;i&gt;FileVisitor&lt;/i&gt;. It implements default behavior for all &lt;i&gt;FileVisitor&lt;/i&gt; methods, and in this case we override &lt;i&gt;visitFile&lt;/i&gt; for deleting files. After all files of current directory are visited &lt;i&gt;postVisitDirectory&lt;/i&gt;&amp;nbsp;method is called and current directory can be deleted safetly. See that the result in this case is &lt;i&gt;CONTINUE&lt;/i&gt; (continuing walking through tree, but as you can imagine you have other options like &lt;i&gt;SKIP_SIBLINGS&lt;/i&gt;, &lt;i&gt;SKIP_SUBTREE&lt;/i&gt; or &lt;i&gt;TERMINATE&lt;/i&gt;).&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Copy a File&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;Files&lt;/i&gt; class has three main methods for copying files. It is important to note that you can copy files and directories, however files inside the directory are not copied, so the new directory is emptied even when the original directory contains files.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;Files.copy(source, target, REPLACE_EXISTING);&lt;/blockquote&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Moreover two methods are also present for copying files. &lt;i&gt;Files.copy(InputStream, Path, CopyOptions...)&lt;/i&gt; and &lt;i&gt;Files.copy(Path, OutputStream)&lt;/i&gt;. As you can imagine first method takes an &lt;i&gt;inputstream&lt;/i&gt; and copy its content into given &lt;i&gt;Path&lt;/i&gt;, and the second one, reads given &lt;i&gt;Path&lt;/i&gt; and sends file content to passed&amp;nbsp;&lt;i&gt;outputstream&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Same is applied for &lt;i&gt;Files.move(Path, Path, CopyOption...)&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For copying all directory structure with their files, a &lt;i&gt;FileVisitor&lt;/i&gt; could be implemented as in previous example.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Manage Metadata Information&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Two main classes are created for managing files&amp;nbsp;&lt;i&gt;metadata&lt;/i&gt;. One class for reading metadata attributes like &lt;i&gt;permissions&lt;/i&gt;, is &lt;i&gt;hidden&lt;/i&gt;, is &lt;i&gt;read-only&lt;/i&gt;, &lt;i&gt;owner&lt;/i&gt;, &lt;i&gt;modified-time&lt;/i&gt;, ... Because each &lt;i&gt;OS &lt;/i&gt;manages file attributes in different manner, an implementation of that class are provided for each OS. For example there is an implementation for &lt;i&gt;DOS &lt;/i&gt;systems, another one for &lt;i&gt;POSIX &lt;/i&gt;systems, or even a helper class for implemting yourself attributes reader.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Posix &lt;/i&gt;example for printing group which belongs given &lt;i&gt;Path:&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgnk"&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The other class is &lt;i&gt;FileStore&lt;/i&gt;. A &lt;i&gt;FileStore &lt;/i&gt;represents a storage pool, device, partition, volume, concrete file system or other implementation specific means of file storage.  This class is used for calculating disk usage.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgnl"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;* Reading, Writing, Random Access&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Files &lt;/i&gt;class has methods for creating &lt;i&gt;inputstreams&lt;/i&gt;, &lt;i&gt;outputstream&lt;/i&gt;, &lt;i&gt;readers&lt;/i&gt;, &lt;i&gt;channels&lt;/i&gt;, ... because this features are not new I won't explain extensively. For example for acquiring an &lt;i&gt;InputStream &lt;/i&gt;instance&amp;nbsp;&lt;i&gt;Files.newInputStream&lt;/i&gt;, &lt;i&gt;Files.newOutputStream&lt;/i&gt;, ...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;* Symbolic and Hard Link&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;With &lt;i&gt;NIO 2.0&lt;/i&gt; you can create a &lt;i&gt;symbolic link&lt;/i&gt; &lt;a href="http://en.wikipedia.org/wiki/Symbolic_link"&gt;http://en.wikipedia.org/wiki/Symbolic_link&lt;/a&gt; or a &lt;i&gt;hard link&lt;/i&gt;&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Hard_link"&gt;http://en.wikipedia.org/wiki/Hard_link&lt;/a&gt; from a path.&lt;br /&gt;&lt;br /&gt;Creating a &lt;i&gt;symbolic link&lt;/i&gt; to a directory:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgnn"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Creating a &lt;i&gt;hard link&lt;/i&gt; to a file:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgno"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;* Finding Files&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Sometimes my programs should find all files with extension &lt;i&gt;xml &lt;/i&gt;contained in a directory and manage them (for example create a &lt;i&gt;zip &lt;/i&gt;with them). Before java &lt;i&gt;NIO 2&lt;/i&gt;, a &lt;i&gt;FileFilter &lt;/i&gt;was created and then create a matcher for only selecting those with &lt;i&gt;xml &lt;/i&gt;extension. Now &lt;i&gt;PathMatcher &lt;/i&gt;class can be used instead of creating yourself matcher. This matcher accepts &lt;i&gt;Glob Syntax&lt;/i&gt; &lt;a href="http://en.wikipedia.org/wiki/Glob_(programming)"&gt;http://en.wikipedia.org/wiki/Glob_(programming)&lt;/a&gt; or &lt;i&gt;Regular Expression&lt;/i&gt;. &lt;i&gt;Glob &lt;/i&gt;syntax is easy to use and flexible and most of us have been used &amp;nbsp;(in console operations)&amp;nbsp;although we didn't know it was &lt;i&gt;Glob Syntax&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Let's implement the next *nix script &lt;i&gt;ls -R *.html&lt;/i&gt; in java.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgnp"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As you can see this implementation of &lt;i&gt;FileVisitor &lt;/i&gt;follows all directories structure finding all &lt;i&gt;html &lt;/i&gt;files. See that there are two important lines:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;matcher = FileSystems.getDefault().getPathMatcher("glob:*.html");&lt;/blockquote&gt;&lt;br /&gt;where we are creating a matcher that only returns true if file ends with &lt;i&gt;html&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;if (name != null &amp;amp;&amp;amp; matcher.matches(name))&lt;/blockquote&gt;&lt;br /&gt;that returns true if current file matches the the &lt;i&gt;glob &lt;/i&gt;condition.&lt;br /&gt;&lt;br /&gt;Thanks of &lt;i&gt;FileVisitor &lt;/i&gt;and &lt;i&gt;PathMatcher &lt;/i&gt;this routine can be reused for any kind of files (modifying &lt;i&gt;glob &lt;/i&gt;expression). Think now if you should do the same with &lt;i&gt;java.io.File&lt;/i&gt; class, you would create a &lt;i&gt;FileFilter &lt;/i&gt;where if you wanted to create a flexible solution you should create a &lt;i&gt;Pattern&amp;nbsp;Matcher&lt;/i&gt;, iterate over matches, and deal with recursive navigation&amp;nbsp;through&amp;nbsp;directory tree. See with &lt;i&gt;PathMatcher &lt;/i&gt;how easy is changing between selecting all files ending with &lt;i&gt;html &lt;/i&gt;extension to selecting all files starting with word '&lt;i&gt;Test&lt;/i&gt;'.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;* Watcher Service&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This new feature is really useful for receiving events when a directory has been changed by creation, modification or deletion of a file. Before &lt;b&gt;NIO 2.0&lt;/b&gt; you should create an "infinite-loop" that was watching if a new file was created. And this was done listening all files and comparing modification date or comparing with previous loop execution. Now this service automatizes all logic, and simply throws an event when registered change occurs.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/wpgog"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Two final notes, first is that events are only thrown for files not for directories, and second one, watch service is not recursive, so it will only throws an event in case of files created into &lt;i&gt;/tmp&lt;/i&gt; not &lt;i&gt;/tmp/my-directory&lt;/i&gt;. As with all java &lt;i&gt;NIO 2.0&lt;/i&gt; you have &lt;i&gt;FileVisitor&lt;/i&gt; interface for dealing with recursive directory tree.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Determine MIME Type&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If your application requires to know &lt;i&gt;MIME &lt;/i&gt;type, &lt;i&gt;Files &lt;/i&gt;class &amp;nbsp;has a &lt;i&gt;probeContentType&lt;/i&gt;. The implementation of this method is highly platform specific and is not infallible.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Path path = Paths.get("/tmp/dataset.xml");&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;System.out.println(Files.probeContentType(path));&lt;/blockquote&gt;&lt;br /&gt;It returns &lt;i&gt;text/xml.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;And those are all new features of &lt;i&gt;NIO 2&lt;/i&gt;&amp;nbsp;that have changed my developer life when I have to develop an application where managing files are required. I wish you find them as usually as I do.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2883863296083342239?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2883863296083342239/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2883863296083342239' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2883863296083342239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2883863296083342239'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/04/cos-only-thing-misplaced-was-direction.html' title='&apos;Cos The Only Thing Misplaced Was Direction And I Found Direction There Is No Childhood&apos;s End  (Childhoods End - Marillion)'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2970816639911916462</id><published>2011-03-31T19:17:00.000+02:00</published><updated>2011-03-31T19:17:15.299+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visits'/><category scheme='http://www.blogger.com/atom/ns#' term='japan'/><title type='text'>Teo Torriate Konomama Iko Aisuruhito Yo Shizukana Yoi Ni Hikario Tomoshi Itoshiki Oshieo Idaki</title><content type='html'>&lt;pre style="word-wrap: break-word;"&gt;&lt;div class="separator" style="clear: both; text-align: center; white-space: pre-wrap;"&gt;&lt;a href="http://www.designerterminal.com/wp-content/uploads/2011/03/PrayForJapanbyAlexanderWende.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://www.designerterminal.com/wp-content/uploads/2011/03/PrayForJapanbyAlexanderWende.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;This week I have reached &lt;u&gt;10K visits&lt;/u&gt;. I would like to say thank you to everyone who have read this blog.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Also I would like to dedicate to &lt;b&gt;Japanese people&lt;/b&gt;, and all heroes of &lt;i&gt;Fukushima&lt;/i&gt;, without them the disaster could have been worse. &lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;I wish I will reach &lt;/span&gt;&lt;u style="white-space: pre-wrap;"&gt;25K visits&lt;/u&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt; as soon as possible and I could explain it with better news.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="word-wrap: break-word;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ct5tUYxiDRM/TZS2vWcIL3I/AAAAAAAAF-g/BTTVuj4yZcM/s1600/_7060856.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-ct5tUYxiDRM/TZS2vWcIL3I/AAAAAAAAF-g/BTTVuj4yZcM/s640/_7060856.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify; white-space: pre-wrap;"&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; white-space: pre-wrap;"&gt;Alex.&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-2970816639911916462?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/2970816639911916462/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=2970816639911916462' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2970816639911916462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/2970816639911916462'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/03/teo-torriate-konomama-iko-aisuruhito-yo.html' title='Teo Torriate Konomama Iko Aisuruhito Yo Shizukana Yoi Ni Hikario Tomoshi Itoshiki Oshieo Idaki'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-ct5tUYxiDRM/TZS2vWcIL3I/AAAAAAAAF-g/BTTVuj4yZcM/s72-c/_7060856.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-8110726209721460439</id><published>2011-03-27T20:04:00.001+02:00</published><updated>2011-03-29T19:28:44.844+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='deploy'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework 3.1'/><category scheme='http://www.blogger.com/atom/ns#' term='verifier'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven Verifier Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>A Te Che Sei Il Mio Grande Amore Ed Mio Amore Grande</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;b&gt;Maven Verifier Plugin&lt;/b&gt;, is a &lt;i&gt;Maven Plugin&lt;/i&gt; that is used for verifying the existence of certain conditions into files content. These conditions are expressed in form of regular expression, so if regular expression is matched in defined resources content, no error is showed, if not, build fails and error message is shown indicating which file does not matches the given expression.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Why I find this plugin useful? Usually my projects have three execution environments, one for unit testing, another for integration/acceptance test and production one. As you can imagine, each one has its configuration, like database configuration. Each environment has a different database, for example unit testing has a &lt;i&gt;HSQL&lt;/i&gt; engine, while integration and production have a &lt;i&gt;PostgreSQL&lt;/i&gt;. For dealing with that problem I usually create three different &lt;i&gt;Spring&lt;/i&gt; files, each one loading required properties, and depending on environment, the &lt;i&gt;applicationContext&lt;/i&gt; is modified for importing required resources. Let's look another example, in my work, I develop planners for instruments, in integration tests, an emulator is used, while in acceptance tests and production, as you can imagine we are using a real instrument. For that reason, we must inject into our business objects, which driver to use (emulator driver or real driver), and as you can imagine two spring files are created and are imported into application context depending on the stage of building.&lt;br /&gt;&lt;br /&gt;The problem with changing importing files in &lt;i&gt;applicationContext&lt;/i&gt; depending on environment, resides that implies a manual human process, and because it is human, an error can occurs and delivery a version with incorrect configured application context. Meanwhile &lt;i&gt;Spring Framework 3.1&lt;/i&gt; is not released as stable version (&lt;i&gt;Spring Profiles&lt;/i&gt; would resolve that problem), &lt;b&gt;Maven Verifier Plugin&lt;/b&gt; can help us to avoid that problem.&lt;br /&gt;&lt;br /&gt;In our &lt;i&gt;Continuous Integration System&lt;/i&gt;, one of our steps before releasing a version is check that all configuration files are configured with correct values, keep in mind that I have showed only two examples, but some other values are changed between development environment and production environment, like time constants, file locations, log level ... Thanks of that plugin this checking procedure is executed automatically.&lt;br /&gt;&lt;br /&gt;Let's see an example:&lt;br /&gt;&lt;br /&gt;First of all &lt;i&gt;pom.xml&lt;/i&gt; must be configured for using &lt;b&gt;Maven Verifier Plugin&lt;/b&gt;:&lt;/div&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/woogn"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&amp;lt;verificationFile&amp;amp;gt&lt;/i&gt;; tag is where you configure which files should be verified and which rules should be applied.&lt;br /&gt;&lt;br /&gt;And &lt;i&gt;verifications-rules.xml&lt;/i&gt;:&lt;/div&gt;&lt;br /&gt;&lt;script src="http://snipt.org/embed/woogo"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In this example we are verifying that property-placeholder defined in &lt;i&gt;applicationContext.xml&lt;/i&gt; are loading properties from &lt;i&gt;META-INF/spring&lt;/i&gt; and not from any other location. Same approach can be used for verifying injected beans, constants, log level ... case that any verification does not matches, the build result would be a fail.&lt;br /&gt;&lt;br /&gt;Although I always though myself &lt;i&gt;"hey men this could not happen to me"&lt;/i&gt;, one day, and you don't know whyhappens, and you upload code not correctly configured, and when VVT department starts verifications, project starts to crash, and then all test protocol should be cancelled, you must change one line, upload one line change to repository, re-deploy all application, and start again.&lt;br /&gt;&lt;br /&gt;Since that day, I always create a regular expression for assuring that when my code is deployed for production, all configuration files contains correct values.&lt;br /&gt;&lt;br /&gt;When &lt;i&gt;Spring Framework 3.1&lt;/i&gt; sees the light all will be different, meanwhile and for legacy code, try &lt;b&gt;Maven Verifier Plugin&lt;/b&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19517292-8110726209721460439?l=www.lordofthejars.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.lordofthejars.com/feeds/8110726209721460439/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19517292&amp;postID=8110726209721460439' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8110726209721460439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19517292/posts/default/8110726209721460439'/><link rel='alternate' type='text/html' href='http://www.lordofthejars.com/2011/03/te-che-sei-il-mio-grande-amore-ed-mio.html' title='A Te Che Sei Il Mio Grande Amore Ed Mio Amore Grande'/><author><name>Alex</name><uri>http://www.blogger.com/profile/11632964711752480304</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/-vBf7y8IPFKE/Tsqlw9gitqI/AAAAAAAAGAg/f0ejFFgbd5s/s220/374063_10150961341500607_732300606_21877644_489573194_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19517292.post-2724948978188560777</id><published>2011-03-23T19:16:00.000+01:00</published><updated>2011-03-23T19:16:35.417+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phaser'/><category scheme='http://www.blogger.com/atom/ns#' term='java 1.7'/><category scheme='http://www.blogger.com/atom/ns#' term='openjdk 7'/><category scheme='http://www.blogger.com/atom/ns#' term='barrier'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr166y'/><category scheme='http://www.blogger.com/atom/ns#' term='java concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='fork-join'/><title type='text'>Sa Zebra Que Passa Un Semàfor I Com Se Desmunta Un Bidet, Cosmètics I Margaret Astor, Ja Sé Com S´escriu Juliette!!!</title><content type='html'>&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;b style="font-style: normal;"&gt;JDK 7&lt;/b&gt; is coming, yes finally it seems that will see the light, without some really nice features like &lt;i&gt;Closures&lt;/i&gt;, but with other nice improvements, like &lt;i&gt;NIO 2.0&lt;/i&gt;, &lt;i&gt;Project Coin&lt;/i&gt;, or &lt;i&gt;auto-close resources&lt;/i&gt;. One new features that I really like is the inclusion of new concurrency classes specified in &lt;b&gt;&lt;i&gt;&lt;a href="http://g.oswego.edu/dl/concurrency-interest/"&gt;jsr166y&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;. In this post I will summarize these new classes that can help us in parallel programming using &lt;i&gt;Java&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;Let's make a brief introduction of new classes and creates a simple example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;b style="font-style: normal;"&gt;Interface&lt;/b&gt; &lt;i&gt;TransfereQueue&lt;/i&gt; with its implementation &lt;i&gt;LinkedTransferQueue&lt;/i&gt;. &lt;i&gt;TransferQueue&lt;/i&gt; is a &lt;i&gt;BlockingQueue&lt;/i&gt; which producers may wait until consumer receives elements. Because it is also a &lt;i&gt;BlockingQueue&lt;/i&gt;, programmer can choose to wait until consumers receives elements (&lt;i&gt;TransferQueue.transfer()&lt;/i&gt;) or simply put the element without waiting as done in &lt;b&gt;&lt;i&gt;jsr166&lt;/i&gt;&lt;/b&gt; (&lt;i&gt;BlockingQueue.put()&lt;/i&gt;). This class should be used when your producer sometimes await receipt of elements, and sometimes it should only enqueue elements without waiting.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;An example where producer is blocked until consumer polls an element:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;iframe src="http://pastebin.com/embed_iframe.php?i=q5WYnhRE" style="border: none; height: 50%; width: 100%;"&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span style="color: black; font-style: normal; font-weight: normal;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;And the output is:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Before Transfer.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;&amp;lt;producer thread wait 5 seconds&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Before Consumer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World!!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;After Consumer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;After Transfer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span style="color: black; font-weight: normal;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;But what's happen if I change &lt;i&gt;transfer&lt;/i&gt; call to &lt;i&gt;put&lt;/i&gt; call? The output is:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span style="color: black; font-style: normal; font-weight: normal;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: x-small;"&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Before Transfer.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;After Transfer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;&amp;lt; producer thread wait 5 seconds&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Before Consumer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World!!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;After Consumer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="orphans: 2; widows: 2;"&gt;&lt;span style="color: black; font-style: normal; font-weight: normal;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Producer finishes its work just after enqueue Hello World message.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;&lt;b style="font-style: normal;"&gt;Class&lt;/b&gt; &lt;i&gt;Phaser&lt;/i&gt;. This class is like &lt;i&gt;CyclicBarrier&lt;/i&gt; class because it waits until all parties reach barrier point for continuing thread execution. The difference is that &lt;i&gt;Phaser&lt;/i&gt; class is more flexible. The number of parties are not static like &lt;i&gt;CycleBarrier&lt;/i&gt;, one can register and deregister dynamically at any time. Also each &lt;i&gt;Phaser&lt;/i&gt; has a &lt;i&gt;phase number&lt;/i&gt; which enables independent control of actions upon arrival at a phaser and upon awaiting others. New method like &lt;i&gt;arrive&lt;/i&gt;, &lt;i&gt;awaitAdvance&lt;/i&gt; are provided. In termination state &lt;i&gt;Phaser&lt;/i&gt; also provides a method for avoiding termination, this method by default returns true, meaning that when all parties reach the barrier point barrier is terminated, but overriding &lt;i&gt;onAdvance&lt;/i&gt; method you could modify this behavior, doing that all threads perform an iteration over its task.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Let's see an example of using &lt;i style="font-weight: normal;"&gt;Phaser&lt;/i&gt; as &lt;i style="font-weight: normal;"&gt;CountDownLatch&lt;/i&gt;, but as you notice some differences can be observed, first of all is that we initialize &lt;i style="font-weight: normal;"&gt;Phaser&lt;/i&gt; to 1 (self &lt;i style="font-weight: normal;"&gt;Thread&lt;/i&gt;) and then we register each parties dynamically. With &lt;i style="font-weight: normal;"&gt;CountDownLatch&lt;/i&gt; we should done the same but initializing statically to 15+1. &lt;i style="font-weight: normal;"&gt;arriveAndAwaitAdvance&lt;/i&gt; has the same behavior as we call &lt;i style="font-weight: normal;"&gt;CyclicBarrier.await&lt;/i&gt;, and &lt;i style="font-weight: normal;"&gt;getArrivedParties()&lt;/i&gt; returns how many parties have arrived to barrier point. See that in following example when second party arrives, does not call &lt;i style="font-weight: normal;"&gt;arriveAndAwaitAdvance()&lt;/i&gt; but calls &lt;i style="font-weight: normal;"&gt;arrive&lt;/i&gt;, this method notifies to &lt;i style="font-weight: normal;"&gt;Phaser&lt;/i&gt; that it has arrived to barrier point but it will not block, it is going to execute some extra logic, and only after that it will wait until all other parties have arrived to barrier point, calling method &lt;i style="font-weight: normal;"&gt;awaitAdvance&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: black; font-weight: normal;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;I suppose you are wondering what is the returning value of  &lt;i&gt;arrive&lt;/i&gt; method. &lt;i&gt;Phaser.arrive&lt;/i&gt; method is the responsible of notifying that thread has arrived to barrier point and returns immediately. And it returns a phaser number. &lt;i&gt;Phaser Number&lt;/i&gt; is an integer managed by &lt;i&gt;Phaser&lt;/i&gt; class, initially is 0 and each time &lt;u&gt;all&lt;/u&gt; parties arrive to a barrier point, that phaser number is incremented. &lt;i&gt;Phaser.awaitAdvance&lt;/i&gt; stops thread execution until current phase number has been incremented.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;iframe src="http://pastebin.com/embed_iframe.php?i=Wu79mwM1" style="border: none; height: 50%; width: 100%;"&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Output of previous program:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: x-small;"&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Hello World 2&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;Thread that prints Hello World 0 are executing Thread.sleep(5000) &amp;gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="western" lang="en-US" style="font-style: normal; font-weight: normal; orphans: 2; widows: 2;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 8&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 13&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 11&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span lang="en-US"&gt;Hello World 9&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span st
