<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkIBRXY8fyp7ImA9WhVUFUU.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576</id><updated>2012-05-21T09:09:14.877+03:00</updated><category term="rest" /><category term="movie" /><category term="java web start" /><category term="infinispan" /><category term="tortoisesvn" /><category term="hibernate" /><category term="blogger" /><category term="apache commons" /><category term="java" /><category term="forex" /><category term="spring framework" /><category term="jaxb" /><category term="spring" /><category term="freemind" /><category term="maven" /><category term="mindmap" /><category term="jnlp" /><category term="eclipse" /><category term="applet" /><category term="russian" /><category term="svn" /><title>Thinking about IT</title><subtitle type="html">Examples, solutions, recipes and thoughts about IT</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://azagorneanu.blogspot.com/" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/azagorneanu" /><feedburner:info uri="azagorneanu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>azagorneanu</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/azagorneanu" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fazagorneanu" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><entry gd:etag="W/&quot;DEUCQno7cSp7ImA9WhdVEUw.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-9117319928499066124</id><published>2011-09-15T22:49:00.000+03:00</published><updated>2011-09-15T22:51:03.409+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-15T22:51:03.409+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="jaxb" /><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>Configure Maven to generate classes from XML Schema using JAXB</title><content type="html">&lt;p&gt;In my &lt;a href="http://azagorneanu.blogspot.com/2011/09/crud-restful-services-using-spring.html"&gt;previous post&lt;/a&gt; I showed how to create RESTful services using Spring Framework. For representation of resources in XML I used JAXB and I followed the &lt;a href="http://en.wikipedia.org/wiki/Top%E2%80%93down_and_bottom%E2%80%93up_design"&gt;bottom-up&lt;/a&gt; approach (I wrote the Java classes and I let to generate XML/XSD from Java classes). In this post I will demonstrate how you can generate the same Java classes (&lt;code&gt;User&lt;/code&gt; and &lt;code&gt;UserList&lt;/code&gt;) from &lt;a href="http://en.wikipedia.org/wiki/XML_schema"&gt;XML Schema&lt;/a&gt; (XSD) during Maven build, therefore using a &lt;a href="http://en.wikipedia.org/wiki/Top%E2%80%93down_and_bottom%E2%80%93up_design"&gt;top-down&lt;/a&gt; approach. For generation of Java classes from XML Schema during Maven build I will use &lt;a href="http://java.net/projects/maven-jaxb2-plugin/pages/Home"&gt;Java.net Maven 2 JAXB 2 Plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Along with the default generation of Java classes from XML Schema using &lt;b&gt;&lt;code&gt;xjc&lt;/code&gt;&lt;/b&gt; tool, I will add the following customizations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Making all the generated classes to implement &lt;code&gt;Serializable&lt;/code&gt; (useful when you want to use classes with some remote services: RMI, EJB, etc).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;java.util.Calendar&lt;/code&gt; instead of &lt;code&gt;javax.xml.datatype.XMLGregorianCalendar&lt;/code&gt; for fields generated from elements of type &lt;code&gt;xs:dateTime&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Generated classes should also have a generated &lt;code&gt;toString()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Classes have to be annotated with &lt;code&gt;XmlRootElement&lt;/code&gt; (required by Spring Framework when classes are used to represent state in RESTful services).&lt;/li&gt;
&lt;li&gt;You can further enhance and customize the generation of Java classes using various &lt;a href="http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins"&gt;plugins&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Project sources are available for &lt;a href="http://azagorneanu.googlecode.com/svn/trunk/blog/zmeu-blog-maven-jaxb.zip"&gt;download&lt;/a&gt;. So let’s start, step by step:&lt;/p&gt;
&lt;a name='more'&gt;&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;Create Maven project. Below you can see the POM:
&lt;pre class="brush: xml;"&gt;
&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
    xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&amp;quot;&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;org.zmeu&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;zmeu-blog-maven-jaxb&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;ZMEU Blog Maven JAXB&amp;lt;/name&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;
                    &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;
                &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.jvnet.jaxb2.maven2&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-jaxb2-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;0.8.0&amp;lt;/version&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;schemaDirectory&amp;gt;src/main/resources/schema&amp;lt;/schemaDirectory&amp;gt;
                    &amp;lt;bindingDirectory&amp;gt;src/main/resources/schema&amp;lt;/bindingDirectory&amp;gt;
                    &amp;lt;generatePackage&amp;gt;org.zmeu.blog.jaxb&amp;lt;/generatePackage&amp;gt;
                    &amp;lt;strict&amp;gt;false&amp;lt;/strict&amp;gt;
                    &amp;lt;extension&amp;gt;true&amp;lt;/extension&amp;gt;
                    &amp;lt;plugins&amp;gt;
                        &amp;lt;plugin&amp;gt;
                            &amp;lt;groupId&amp;gt;org.jvnet.jaxb2_commons&amp;lt;/groupId&amp;gt;
                            &amp;lt;artifactId&amp;gt;jaxb2-basics&amp;lt;/artifactId&amp;gt;
                            &amp;lt;version&amp;gt;0.6.2&amp;lt;/version&amp;gt;
                        &amp;lt;/plugin&amp;gt;
                        &amp;lt;plugin&amp;gt;
                            &amp;lt;groupId&amp;gt;org.jvnet.jaxb2_commons&amp;lt;/groupId&amp;gt;
                            &amp;lt;artifactId&amp;gt;jaxb2-basics-annotate&amp;lt;/artifactId&amp;gt;
                            &amp;lt;version&amp;gt;0.6.2&amp;lt;/version&amp;gt;
                        &amp;lt;/plugin&amp;gt;
                    &amp;lt;/plugins&amp;gt;
                    &amp;lt;args&amp;gt;
                        &amp;lt;arg&amp;gt;-Xannotate&amp;lt;/arg&amp;gt;
                        &amp;lt;arg&amp;gt;-XtoString&amp;lt;/arg&amp;gt;
                    &amp;lt;/args&amp;gt;
                &amp;lt;/configuration&amp;gt;
                &amp;lt;executions&amp;gt;
                    &amp;lt;execution&amp;gt;
                        &amp;lt;id&amp;gt;generate&amp;lt;/id&amp;gt;
                        &amp;lt;goals&amp;gt;
                            &amp;lt;goal&amp;gt;generate&amp;lt;/goal&amp;gt;
                        &amp;lt;/goals&amp;gt;
                    &amp;lt;/execution&amp;gt;
                &amp;lt;/executions&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.jvnet.jaxb2_commons&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;jaxb2-basics-runtime&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;0.6.2&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Write XML Schema (&lt;code&gt;schema.xsd&lt;/code&gt;):
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;
&amp;lt;xs:schema version=&amp;quot;1.0&amp;quot; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;

    &amp;lt;xs:element name=&amp;quot;user&amp;quot; type=&amp;quot;user&amp;quot; /&amp;gt;
    &amp;lt;xs:element name=&amp;quot;userList&amp;quot; type=&amp;quot;userList&amp;quot; /&amp;gt;

    &amp;lt;xs:complexType name=&amp;quot;user&amp;quot;&amp;gt;
        &amp;lt;xs:all&amp;gt;
            &amp;lt;xs:element name=&amp;quot;id&amp;quot; type=&amp;quot;xs:long&amp;quot; minOccurs=&amp;quot;0&amp;quot; /&amp;gt;
            &amp;lt;xs:element name=&amp;quot;name&amp;quot; type=&amp;quot;xs:string&amp;quot; /&amp;gt;
            &amp;lt;xs:element name=&amp;quot;registrationDate&amp;quot; type=&amp;quot;xs:dateTime&amp;quot; /&amp;gt;
        &amp;lt;/xs:all&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;

    &amp;lt;xs:complexType name=&amp;quot;userList&amp;quot;&amp;gt;
        &amp;lt;xs:sequence&amp;gt;
            &amp;lt;xs:element name=&amp;quot;user&amp;quot; type=&amp;quot;user&amp;quot; minOccurs=&amp;quot;0&amp;quot; maxOccurs=&amp;quot;unbounded&amp;quot; /&amp;gt;
        &amp;lt;/xs:sequence&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
    
&amp;lt;/xs:schema&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Customize JAXB Bindings (&lt;code&gt;binding.xjb&lt;/code&gt;):
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;
&amp;lt;jaxb:bindings xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;
    xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
    xmlns:annox=&amp;quot;http://annox.dev.java.net&amp;quot; 
    xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd&amp;quot;
    version=&amp;quot;2.1&amp;quot;&amp;gt;
    &amp;lt;jaxb:globalBindings&amp;gt;
        &amp;lt;!-- Use java.util.Calendar instead of javax.xml.datatype.XMLGregorianCalendar for xs:dateTime --&amp;gt;
        &amp;lt;jaxb:javaType name=&amp;quot;java.util.Calendar&amp;quot; xmlType=&amp;quot;xs:dateTime&amp;quot;
                parseMethod=&amp;quot;javax.xml.bind.DatatypeConverter.parseDateTime&amp;quot; 
                printMethod=&amp;quot;javax.xml.bind.DatatypeConverter.printDateTime&amp;quot; /&amp;gt;

        &amp;lt;!-- Force all classes implements Serializable --&amp;gt;
        &amp;lt;xjc:serializable uid=&amp;quot;1&amp;quot; /&amp;gt;
    &amp;lt;/jaxb:globalBindings&amp;gt;

    &amp;lt;!-- Annotate the following classes with XmlRootElement --&amp;gt;
    &amp;lt;jaxb:bindings schemaLocation=&amp;quot;schema.xsd&amp;quot; node=&amp;quot;/xs:schema&amp;quot;&amp;gt;
        &amp;lt;jaxb:bindings node=&amp;quot;xs:complexType[@name='user']&amp;quot;&amp;gt;
            &amp;lt;annox:annotate&amp;gt;
                &amp;lt;annox:annotate annox:class=&amp;quot;javax.xml.bind.annotation.XmlRootElement&amp;quot; name=&amp;quot;user&amp;quot; /&amp;gt;
            &amp;lt;/annox:annotate&amp;gt;
        &amp;lt;/jaxb:bindings&amp;gt;
        &amp;lt;jaxb:bindings node=&amp;quot;xs:complexType[@name='userList']&amp;quot;&amp;gt;
            &amp;lt;annox:annotate&amp;gt;
                &amp;lt;annox:annotate annox:class=&amp;quot;javax.xml.bind.annotation.XmlRootElement&amp;quot; name=&amp;quot;userList&amp;quot; /&amp;gt;
            &amp;lt;/annox:annotate&amp;gt;
        &amp;lt;/jaxb:bindings&amp;gt;
    &amp;lt;/jaxb:bindings&amp;gt;
&amp;lt;/jaxb:bindings&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Run the build using &lt;b&gt;&lt;code&gt;mvn clean install&lt;/code&gt;&lt;/b&gt; command. Build must be successful. Generated classes will be located in &lt;code&gt;target/generated-sources/xjc&lt;/code&gt; directory. Below is a snippet from generated &lt;code&gt;User&lt;/code&gt; class:
&lt;pre class="brush: java;"&gt;

.....

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = &amp;quot;user&amp;quot;, propOrder = {})
@XmlRootElement(name = &amp;quot;user&amp;quot;)
public class User implements Serializable, ToString {
    private final static long serialVersionUID = 1L;
    
    protected Long id;
    
    @XmlElement(required = true)
    protected String name;
    
    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = &amp;quot;dateTime&amp;quot;)
    protected Calendar registrationDate;

    .....

}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;You are done!&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-9117319928499066124?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/h3fjax-oui5ZOIdE3xiNyD8aEHA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h3fjax-oui5ZOIdE3xiNyD8aEHA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/h3fjax-oui5ZOIdE3xiNyD8aEHA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h3fjax-oui5ZOIdE3xiNyD8aEHA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=a4oGpuQuRTA:OXW52E2mH8A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=a4oGpuQuRTA:OXW52E2mH8A:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=a4oGpuQuRTA:OXW52E2mH8A:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=a4oGpuQuRTA:OXW52E2mH8A:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=a4oGpuQuRTA:OXW52E2mH8A:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=a4oGpuQuRTA:OXW52E2mH8A:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/a4oGpuQuRTA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/9117319928499066124/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/09/configure-maven-to-generate-classes.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/9117319928499066124?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/9117319928499066124?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/a4oGpuQuRTA/configure-maven-to-generate-classes.html" title="Configure Maven to generate classes from XML Schema using JAXB" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/09/configure-maven-to-generate-classes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMFRnwzfyp7ImA9WhdVEUw.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-5759948269151812918</id><published>2011-09-14T23:28:00.000+03:00</published><updated>2011-09-15T22:53:37.287+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-15T22:53:37.287+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="rest" /><category scheme="http://www.blogger.com/atom/ns#" term="spring framework" /><category scheme="http://www.blogger.com/atom/ns#" term="jaxb" /><title>CRUD RESTful services using Spring Framework</title><content type="html">&lt;p&gt;In this post I will show how to build &lt;a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt; (&lt;b&gt;C&lt;/b&gt;reate, &lt;b&gt;R&lt;/b&gt;ead, &lt;b&gt;U&lt;/b&gt;pdate, &lt;b&gt;D&lt;/b&gt;elete) &lt;a href="http://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST&lt;/a&gt;-ful (&lt;b&gt;Re&lt;/b&gt;presentational &lt;b&gt;S&lt;/b&gt;tate &lt;b&gt;T&lt;/b&gt;ransfer) services using &lt;a href="http://www.springsource.org/"&gt;Spring Framework&lt;/a&gt;. Spring Framework version used in this example is 3.0.6.RELEASE. &lt;a href="http://tomcat.apache.org/"&gt;Apache Tomcat&lt;/a&gt; version used for testing the web services is 6.0.29 (default Tomcat version used by &lt;a href="http://mojo.codehaus.org/tomcat-maven-plugin/"&gt;Tomcat Maven Plugin&lt;/a&gt; of &lt;a href="http://maven.apache.org/"&gt;Apache Maven&lt;/a&gt; 2.2.1). Project sources are available for &lt;a href="http://azagorneanu.googlecode.com/svn/trunk/blog/zmeu-blog-spring-rest.zip"&gt;download&lt;/a&gt;. So let’s start, step by step:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First we have to define the resource on which the CRUD operation will be performed and how this resource will be represented. In our example we will use a resource that represents a User. The resource will be represented using &lt;a href="http://en.wikipedia.org/wiki/XML"&gt;XML&lt;/a&gt; (E&lt;b&gt;x&lt;/b&gt;tensible &lt;b&gt;M&lt;/b&gt;arkup &lt;b&gt;L&lt;/b&gt;anguage). At the end of the post I will show how you can switch the resource representation to &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; (&lt;b&gt;J&lt;/b&gt;ava&lt;b&gt;S&lt;/b&gt;cript &lt;b&gt;O&lt;/b&gt;bject &lt;b&gt;N&lt;/b&gt;otation) or any other supported form.&lt;/li&gt;
&lt;li&gt;Create a Maven project. We will use Maven for project management and build. Maven POM is shown below:
&lt;a name='more'&gt;&lt;/a&gt;
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;project xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&amp;quot;
    xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;org.zmeu&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;zmeu-blog-spring-rest&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;
    &amp;lt;name&amp;gt;ZMEU Blog Spring REST&amp;lt;/name&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;pluginManagement&amp;gt;
            &amp;lt;plugins&amp;gt;
                &amp;lt;plugin&amp;gt;
                    &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;configuration&amp;gt;
                        &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;
                        &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;
                    &amp;lt;/configuration&amp;gt;
                &amp;lt;/plugin&amp;gt;
            &amp;lt;/plugins&amp;gt;
        &amp;lt;/pluginManagement&amp;gt;
    &amp;lt;/build&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-web&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;3.0.6.RELEASE&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;3.0.6.RELEASE&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.commons&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;commons-lang3&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;3.0&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;!-- Logging dependencies --&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.slf4j&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;slf4j-api&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.6.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.slf4j&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;slf4j-log4j12&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.6.1&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;log4j&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;log4j&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.2.16&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;!-- Testing dependencies --&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.testng&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;testng&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;6.2&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Write &lt;code&gt;User&lt;/code&gt; class that will represent our resource. Due to fact that we have decided to represent our resource using XML, we will annotate our class using &lt;a href="http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding"&gt;JAXB&lt;/a&gt; (&lt;b&gt;J&lt;/b&gt;ava &lt;b&gt;A&lt;/b&gt;rchitecture for &lt;b&gt;X&lt;/b&gt;ML &lt;b&gt;B&lt;/b&gt;inding) annotations. When JAXB is used, Spring requires java classes to be annotated with &lt;code&gt;@XmlRootElement&lt;/code&gt; (see &lt;code&gt;&lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.html"&gt;Jaxb2RootElementHttpMessageConverter&lt;/a&gt;&lt;/code&gt;). If you are using Java 6 then you don’t have to do anything special because Java 6 is coming already with JAXB2, otherwise you will have to &lt;a href="http://weblogs.java.net/blog/kohsuke/archive/2006/01/jaxb_jars_are_a.html"&gt;include dependencies to JAXB&lt;/a&gt; into your project. You can see below the &lt;code&gt;User.java&lt;/code&gt; listing:
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.domain;

import java.util.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = &amp;quot;userType&amp;quot;)
@XmlRootElement(name = &amp;quot;user&amp;quot;)
public class User {
    private long id;
    private String name;
    private Date registrationDate;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    @Override
    public String toString() {
        ToStringBuilder builder = new ToStringBuilder(this);
        builder.append(&amp;quot;id&amp;quot;, getId());
        builder.append(&amp;quot;name&amp;quot;, getName());
        builder.append(&amp;quot;registrationDate&amp;quot;, getRegistrationDate());
        return builder.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof User)) {
            return false;
        }
        User other = (User) obj;
        EqualsBuilder equalsBuilder = new EqualsBuilder();
        equalsBuilder.append(getId(), other.getId());
        return equalsBuilder.isEquals();
    }
    
    @Override
    public int hashCode() {
        HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
        hashCodeBuilder.append(getId());
        return hashCodeBuilder.toHashCode();
    }
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;In order to represent a list of users we will create a new class &lt;code&gt;UserList.java&lt;/code&gt;
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.domain;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = &amp;quot;userListType&amp;quot;)
@XmlRootElement(name = &amp;quot;userList&amp;quot;)
public class UserList {
    private List&amp;lt;User&amp;gt; users = new ArrayList&amp;lt;User&amp;gt;();

    public UserList() {}

    public UserList(List&amp;lt;User&amp;gt; users) {
        this.users = users;
    }

    @XmlElement(name = &amp;quot;user&amp;quot;)
    public List&amp;lt;User&amp;gt; getUsers() {
        return users;
    }

    public void setUsers(List&amp;lt;User&amp;gt; users) {
        this.users = users;
    }
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Write a Spring service that will provide CRUD operations for our resource. In our case this is a simple service which uses a &lt;code&gt;java.util.Map&lt;/code&gt; for storage. Normally this should be a service that performs some validations and delegates the persistence activities to a &lt;a href="http://en.wikipedia.org/wiki/Data_access_object"&gt;DAO&lt;/a&gt; (Data Access Object). First define the interface &lt;code&gt;UserService.java&lt;/code&gt;:
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.service;

import java.util.Collection;

import org.zmeu.blog.spring.rest.domain.User;

public interface UserService {
    User create(User user);

    User read(long userId);

    User update(User user);

    User delete(long userId);

    Collection&amp;lt;User&amp;gt; list();
}
&lt;/pre&gt;
And after the implementation &lt;code&gt;UserServiceImpl.java&lt;/code&gt;:
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.service;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Service;
import org.zmeu.blog.spring.rest.domain.User;

@Service
public class UserServiceImpl implements UserService {
    private final AtomicLong USER_ID_SEQ = new AtomicLong();
    private final ConcurrentMap&amp;lt;Long, User&amp;gt; usersMap = new ConcurrentHashMap&amp;lt;Long, User&amp;gt;();
    
    @Override
    public User create(User user) {
        user.setId(USER_ID_SEQ.incrementAndGet());
        usersMap.put(user.getId(), user);
        return user;
    }

    @Override
    public User read(long userId) {
        return usersMap.get(userId);
    }

    @Override
    public User update(User user) {
        User updatedUser = usersMap.replace(user.getId(), user);
        Validate.isTrue(updatedUser != null, &amp;quot;Unable to find user with id: &amp;quot; + user.getId());
        return updatedUser;
    }

    @Override
    public User delete(long userId) {
        User removedUser = usersMap.remove(userId);
        Validate.isTrue(removedUser != null, &amp;quot;Unable to find user with id: &amp;quot; + userId);
        return removedUser;
    }

    @Override
    public Collection&amp;lt;User&amp;gt; list() {
        return usersMap.values();
    }
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Write a Spring MVC controller that will do the actual work required by a RESTful service. Our controller maps to the following locations:
&lt;table border="1" cellspacing="0" cellpading="5" width="100%"&gt;
&lt;tr align="center"&gt;
&lt;td width="45%"&gt;&lt;b&gt;URL&lt;/b&gt;&lt;/td&gt;
&lt;td width="20%"&gt;&lt;b&gt;HTTP Method&lt;/b&gt;&lt;/td&gt;
&lt;td width="35%"&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http://host:port/servletContextPath/users&lt;/td&gt;
&lt;td align="center"&gt;GET&lt;/td&gt;
&lt;td&gt;Retrieves the user list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http://host:port/servletContextPath/users&lt;/td&gt;
&lt;td align="center"&gt;POST&lt;/td&gt;
&lt;td&gt;Creates a new user.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http://host:port/servletContextPath/users/12&lt;/td&gt;
&lt;td align="center"&gt;GET&lt;/td&gt;
&lt;td&gt;Retrieves user with id = 12.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http://host:port/servletContextPath/users/12&lt;/td&gt;
&lt;td align="center"&gt;PUT&lt;/td&gt;
&lt;td&gt;Updates user with id = 12.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http://host:port/servletContextPath/users/12&lt;/td&gt;
&lt;td align="center"&gt;DELETE&lt;/td&gt;
&lt;td&gt;Deletes user with id = 12.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
Below you can see &lt;code&gt;UserController.java&lt;/code&gt; source code:
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.controller;

import java.util.ArrayList;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.zmeu.blog.spring.rest.domain.User;
import org.zmeu.blog.spring.rest.domain.UserList;
import org.zmeu.blog.spring.rest.service.UserService;

@Controller
@RequestMapping(value = &amp;quot;/users&amp;quot;)
public class UserController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public User create(@RequestBody User user) {
        LOGGER.info(&amp;quot;Creating new user {}&amp;quot;, user);
        return userService.create(user);
    }

    @RequestMapping(value = &amp;quot;/{userId}&amp;quot;, method = RequestMethod.GET)
    @ResponseBody
    public User read(@PathVariable(value = &amp;quot;userId&amp;quot;) long userId) {
        LOGGER.info(&amp;quot;Reading user with id {}&amp;quot;, userId);
        User user = userService.read(userId);
        Validate.isTrue(user != null, &amp;quot;Unable to find user with id: &amp;quot; + userId);
        return user;
    }

    @RequestMapping(value = &amp;quot;/{userId}&amp;quot;, method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void update(@PathVariable(value = &amp;quot;userId&amp;quot;) long userId, @RequestBody User user) {
        LOGGER.info(&amp;quot;Updating user with id {} with {}&amp;quot;, userId, user);
        Validate.isTrue(userId == user.getId(), &amp;quot;userId doesn't match URL userId: &amp;quot; + user.getId());
        userService.update(user);
    }

    @RequestMapping(value = &amp;quot;/{userId}&amp;quot;, method = RequestMethod.DELETE)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void delete(@PathVariable(value = &amp;quot;userId&amp;quot;) long userId) {
        LOGGER.info(&amp;quot;Deleting user with id {}&amp;quot;, userId);
        userService.delete(userId);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public UserList list() {
        LOGGER.info(&amp;quot;Listing users&amp;quot;);
        return new UserList(new ArrayList&amp;lt;User&amp;gt;(userService.list()));
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public String handleClientErrors(Exception ex) {
        LOGGER.error(ex.getMessage(), ex);
        return ex.getMessage();
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public String handleServerErrors(Exception ex) {
        LOGGER.error(ex.getMessage(), ex);
        return ex.getMessage();
    }
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Configure Spring. As you already observed, we used annotations all over, so Spring configuration is minimal (&lt;code&gt;applicationContext.xml&lt;/code&gt;).
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot; 
        xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
        xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot; 
        xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;
        xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd
                            http://www.springframework.org/schema/mvc 
                            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;

    &amp;lt;context:component-scan base-package=&amp;quot;org.zmeu.blog.spring.rest&amp;quot; /&amp;gt;

    &amp;lt;mvc:annotation-driven /&amp;gt;

&amp;lt;/beans&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Configure web application. Our &lt;code&gt;web.xml&lt;/code&gt; configuration is also minimal. You can see that we only registered the Spring MVC &lt;code&gt;DispatcherServlet&lt;/code&gt; and added the &lt;code&gt;Log4jConfigListener&lt;/code&gt; for logging.
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; 
        xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; 
        xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
        xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee 
                            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;

    &amp;lt;context-param&amp;gt;
        &amp;lt;param-name&amp;gt;log4jConfigLocation&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;classpath:log4j.properties&amp;lt;/param-value&amp;gt;
    &amp;lt;/context-param&amp;gt;
    &amp;lt;listener&amp;gt;
        &amp;lt;listener-class&amp;gt;org.springframework.web.util.Log4jConfigListener&amp;lt;/listener-class&amp;gt;
    &amp;lt;/listener&amp;gt;

    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;DispatcherServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
        &amp;lt;init-param&amp;gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
            &amp;lt;param-value&amp;gt;classpath:applicationContext.xml&amp;lt;/param-value&amp;gt;
        &amp;lt;/init-param&amp;gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;DispatcherServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;

&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Build the project. From command line, run &lt;b&gt;&lt;code&gt;mvn clean install&lt;/code&gt;&lt;/b&gt; command from the directory where &lt;code&gt;pom.xml&lt;/code&gt; is located. Build must be successful.&lt;/li&gt;
&lt;li&gt;Deploy the resulted web application. Run &lt;b&gt;&lt;code&gt;mvn tomcat:run&lt;/code&gt;&lt;/b&gt; from command line from the same location.&lt;/li&gt;
&lt;li&gt;Test and consume RESTful services. Below you can see the class that is testing our RESTful services. I used &lt;a href="http://testng.org/"&gt;TestNG&lt;/a&gt; testing framework (&lt;a href="http://junit.org/"&gt;JUnit&lt;/a&gt; can be used as well). Tests that are shown below can be used as an example of how to consume RESTful services. All tests are disabled by default &lt;code&gt;@Test(enabled = false)&lt;/code&gt;. You have to enable them. This is done in order to skip tests execution at the build time. Tests should be run only after deploying the web application. In order to execute the tests, run &lt;b&gt;&lt;code&gt;mvn test&lt;/code&gt;&lt;/b&gt; command.
&lt;pre class="brush: java;"&gt;
package org.zmeu.blog.spring.rest.controller;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.zmeu.blog.spring.rest.domain.User;
import org.zmeu.blog.spring.rest.domain.UserList;

@Test(enabled = false)
public class UserControllerTest {
    private static final String REST_SERVICE_URL = &amp;quot;http://localhost:8080/zmeu-blog-spring-rest/users&amp;quot;;
    private RestTemplate restTemplate;

    @BeforeClass
    protected void beforeClass() {
        restTemplate = new RestTemplate();
    }

    public void create() {
        createAndAssertUser();
    }

    public void read() {
        User createdUser = createAndAssertUser();
        User user = restTemplate.getForObject(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, User.class, createdUser.getId());
        assertUser(user, createdUser);
    }

    public void update() {
        User user = createAndAssertUser();
        user.setName(&amp;quot;Updated user name&amp;quot;);
        restTemplate.put(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, user, user.getId());
        User updatedUser = restTemplate.getForObject(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, User.class, user.getId());
        assertUser(updatedUser, user);
    }

    public void updateIncorrectUrl() {
        User user = createAndAssertUser();
        user.setName(&amp;quot;Updated user name&amp;quot;);
        try {
            restTemplate.put(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, user, user.getId() + 1);
            fail(&amp;quot;Expecting HttpClientErrorException: 400 Bad Request&amp;quot;);
        } catch (HttpClientErrorException e) {
            assertEquals(e.getStatusCode(), HttpStatus.BAD_REQUEST);
        }
    }

    public void delete() {
        User createdUser = createAndAssertUser();
        restTemplate.delete(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, createdUser.getId());
        try {
            restTemplate.getForObject(REST_SERVICE_URL + &amp;quot;/{userId}&amp;quot;, User.class, createdUser.getId());
            fail(&amp;quot;Expecting HttpClientErrorException: 400 Bad Request&amp;quot;);
        } catch (HttpClientErrorException e) {
            assertEquals(e.getStatusCode(), HttpStatus.BAD_REQUEST);
        }
    }

    public void list() {
        UserList initialUsers = restTemplate.getForObject(REST_SERVICE_URL, UserList.class);
        User createdUser = createAndAssertUser();
        UserList users = restTemplate.getForObject(REST_SERVICE_URL, UserList.class);
        List&amp;lt;User&amp;gt; createdUsers = new ArrayList&amp;lt;User&amp;gt;(users.getUsers());
        createdUsers.removeAll(initialUsers.getUsers());
        assertEquals(createdUsers.size(), 1);
        assertUser(createdUsers.get(0), createdUser);
    }

    private User createAndAssertUser() {
        User user = new User();
        user.setId(0);
        user.setName(&amp;quot;User name&amp;quot;);
        user.setRegistrationDate(new Date());
        return createAndAssertUser(user);
    }

    private User createAndAssertUser(User user) {
        User createdUser = restTemplate.postForObject(REST_SERVICE_URL, user, User.class);
        assertUserNoId(createdUser, user);
        return createdUser;
    }

    private void assertUserNoId(User actual, User expected) {
        assertTrue(actual.getId() &amp;gt; 0);
        assertEquals(actual.getName(), expected.getName());
        assertEquals(actual.getRegistrationDate(), expected.getRegistrationDate());
    }

    private void assertUser(User actual, User expected) {
        assertTrue(actual.getId() &amp;gt; 0);
        assertEquals(actual.getName(), expected.getName());
        assertEquals(actual.getRegistrationDate(), expected.getRegistrationDate());
    }
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Testing our RESTful services using web browser:
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-T3m79ql8L-8/TnD7Kre8PDI/AAAAAAAAD9Q/JoKjSCWyIHk/s1600/spring-rest-read-user.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="272" src="http://4.bp.blogspot.com/-T3m79ql8L-8/TnD7Kre8PDI/AAAAAAAAD9Q/JoKjSCWyIHk/s640/spring-rest-read-user.png" width="640" alt="RESTful service. Retrieve user by id." title="RESTful service. Retrieve user by id. "/&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Retrieve user with id = 12&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-3t2mA8dHRxo/TnD7Lg8WanI/AAAAAAAAD9U/lHPePlNgwh8/s1600/spring-rest-read-user-list.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="436" src="http://3.bp.blogspot.com/-3t2mA8dHRxo/TnD7Lg8WanI/AAAAAAAAD9U/lHPePlNgwh8/s640/spring-rest-read-user-list.png" width="640" alt="RESTful service. Retrieve user list." title="RESTful service. Retrieve user list." /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Retrieve user list&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/li&gt;
&lt;li&gt;Changing the representation of your resources from XML to JSON is very easy. No changes are required to be done in controllers or client side. You have to perform the following actions only:
&lt;ul&gt;
&lt;li&gt;Add the following dependency to &lt;code&gt;pom.xml&lt;/code&gt;:
&lt;pre class="brush: xml;"&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.codehaus.jackson&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jackson-mapper-asl&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.8.5&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Remove all JAXB annotations from data-type classes (&lt;code&gt;User.java&lt;/code&gt; and &lt;code&gt;UserList.java&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
Taking an arbitrary Java object returned from a controller handler method and converting it into a client-pleasing representation is a job for one of &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/http/converter/HttpMessageConverter.html"&gt;Spring’s HTTP message converters&lt;/a&gt;. Spring comes with a variety of message converters: XML, JSON, Atom, RSS, binary, String, etc (see all classes implementing &lt;code&gt;HttpMessageConverter&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;You are done!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;IMPORTANT:&lt;/b&gt;&lt;/u&gt; Although Spring 3 supports validation of arguments and return types for Spring MVC controllers using &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR-303&lt;/a&gt; (Bean validation), it &lt;a href="http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal#jsr303"&gt;doesn’t work in case of RESTful controllers&lt;/a&gt; (see also bugs &lt;a href="https://jira.springsource.org/browse/SPR-6709"&gt;SPR-6709&lt;/a&gt; and &lt;a href="https://jira.springsource.org/browse/SPR-6928"&gt;SPR-6928&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Also you can have a look at the following related articles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.infoq.com/articles/springmvc_jsx-rs"&gt;A Comparison of Spring MVC and JAX-RS&lt;/a&gt; (from InfoQ).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal"&gt;Using Spring 3.0 MVC for RESTful web services&lt;/a&gt; (describes some existing issues along with solutions).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/"&gt;Spring 3 Type Conversion and Validation&lt;/a&gt; (from SpringSource TeamBlog)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nocturnsoft.com/devblog/?p=1520"&gt;rest-based services with spring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://azagorneanu.blogspot.com/2011/09/configure-maven-to-generate-classes.html"&gt;Configure Maven to generate classes from XML Schema using JAXB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-5759948269151812918?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ex5OPrGWR06hKbMfruI7-k34bEU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ex5OPrGWR06hKbMfruI7-k34bEU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ex5OPrGWR06hKbMfruI7-k34bEU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ex5OPrGWR06hKbMfruI7-k34bEU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=ZZ1LL5-dVRg:Tr6fuKlPxfs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=ZZ1LL5-dVRg:Tr6fuKlPxfs:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=ZZ1LL5-dVRg:Tr6fuKlPxfs:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=ZZ1LL5-dVRg:Tr6fuKlPxfs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=ZZ1LL5-dVRg:Tr6fuKlPxfs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=ZZ1LL5-dVRg:Tr6fuKlPxfs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/ZZ1LL5-dVRg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/5759948269151812918/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/09/crud-restful-services-using-spring.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/5759948269151812918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/5759948269151812918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/ZZ1LL5-dVRg/crud-restful-services-using-spring.html" title="CRUD RESTful services using Spring Framework" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-T3m79ql8L-8/TnD7Kre8PDI/AAAAAAAAD9Q/JoKjSCWyIHk/s72-c/spring-rest-read-user.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/09/crud-restful-services-using-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UMQXg4eCp7ImA9WhdQGU4.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-8844364488993075657</id><published>2011-08-21T17:59:00.003+03:00</published><updated>2011-08-21T18:08:00.630+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T18:08:00.630+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="movie" /><title>Девственность</title><content type="html">&lt;table border="0"&gt;&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Название:&lt;/b&gt; Девственность&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Жанр:&lt;/b&gt; Документальный&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Год выпуска:&lt;/b&gt; 2009&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Производство:&lt;/b&gt; Россия&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Режиссер:&lt;/b&gt; Виталий Манский&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Продолжительность:&lt;/b&gt; 86 мин.&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;
&lt;div style="text-align:center;"&gt;&lt;iframe src="http://vkontakte.ru/video_ext.php?oid=53398356&amp;id=145433207&amp;hash=d5537fd1a192e892&amp;hd=1" width="607" height="360" frameborder="0"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;a name='more'&gt;&lt;/a&gt;
&lt;br/&gt;&lt;hr/&gt;&lt;br/&gt;
&lt;b&gt;Закрытый показ (Первый Канал): Девственность (2009) + обсуждение – 154 мин.&lt;/b&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;div style="text-align:center;"&gt;&lt;iframe src="http://vkontakte.ru/video_ext.php?oid=18231579&amp;id=154439710&amp;hash=599bb5b6ac916f79&amp;hd=1" width="607" height="360" frameborder="0"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-8844364488993075657?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/twxjpiqXDnKqpOnez_gCUM_D41w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/twxjpiqXDnKqpOnez_gCUM_D41w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/twxjpiqXDnKqpOnez_gCUM_D41w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/twxjpiqXDnKqpOnez_gCUM_D41w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=gOPAlQXhWpY:GhEI1QKIZsA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=gOPAlQXhWpY:GhEI1QKIZsA:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=gOPAlQXhWpY:GhEI1QKIZsA:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=gOPAlQXhWpY:GhEI1QKIZsA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=gOPAlQXhWpY:GhEI1QKIZsA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=gOPAlQXhWpY:GhEI1QKIZsA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/gOPAlQXhWpY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/8844364488993075657/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/08/blog-post.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8844364488993075657?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8844364488993075657?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/gOPAlQXhWpY/blog-post.html" title="Девственность" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/08/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAESXo5eSp7ImA9WhdRF0k.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-7870815597823181378</id><published>2011-08-07T22:51:00.000+03:00</published><updated>2011-08-07T22:51:48.421+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T22:51:48.421+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="apache commons" /><title>How to generate equals(), hashCode(), toString() and compareTo() using Apache Commons Lang in Eclipse</title><content type="html">&lt;p&gt;&lt;a href="http://commons.apache.org/"&gt;Apache Commons&lt;/a&gt; project represents a set of reusable Java components. &lt;a href="http://commons.apache.org/lang/"&gt;Apache Commons Lang&lt;/a&gt; is one of the Apache Commons components. It provides much needed additions to the standard JDK's &lt;code&gt;java.lang&lt;/code&gt; package. One of its packages, &lt;a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang3/builder/package-summary.html"&gt;org.apache.commons.lang3.builder&lt;/a&gt; contains a set of very useful builders that helps in creating consistent &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt;, &lt;code&gt;toString()&lt;/code&gt; and &lt;code&gt;compareTo()&lt;/code&gt; methods.&lt;/p&gt;
&lt;p&gt;In this post, I will show how to generate &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt;, &lt;code&gt;toString()&lt;/code&gt; and &lt;code&gt;compareTo()&lt;/code&gt; methods using Apache Commons Lang builders in Eclipse. For demonstrations I will use the latest stable release - &lt;a href="http://commons.apache.org/lang/api-3.0/index.html"&gt;Apache Commons Lang 3.0&lt;/a&gt;. Note that Lang 3.0 uses a different package (&lt;code&gt;org.apache.commons.lang3&lt;/code&gt;) than its predecessors (&lt;code&gt;org.apache.commons.lang&lt;/code&gt;). All the examples presented in this post will work also with the previous Apache Commons Lang releases; just change the package name from &lt;code&gt;lang3&lt;/code&gt; to &lt;code&gt;lang&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Native Support&lt;/h3&gt;
&lt;p&gt;Eclipse supports out of the box generation of &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt; and &lt;code&gt;toString()&lt;/code&gt; methods. But only the generation of &lt;code&gt;toString()&lt;/code&gt; can be configured to use different builders. Below is shown how to configure Eclipse to use &lt;a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang3/builder/ToStringBuilder.html"&gt;ToStringBuilder&lt;/a&gt; to generate &lt;code&gt;toString()&lt;/code&gt; methods.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;&lt;b&gt;Prerequisites:&lt;/b&gt; Eclipse project is configured to include Apache Commons Lang jar in classpath. We have a class with 2 fields named &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;number&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;i&gt;Generate toString()&lt;/i&gt; wizard (from menu select &lt;i&gt;Source -&gt; Generate toString()…&lt;/i&gt;).&lt;/li&gt;
&lt;li&gt;Choose &lt;i&gt;Custom toString() builder&lt;/i&gt; option from &lt;i&gt;Code Style&lt;/i&gt; drop down and press &lt;i&gt;Configure…&lt;/i&gt; button as it is shown below.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-f4IxTCSRzIA/Tj7dNXzrqmI/AAAAAAAAD8o/fK0YN1S7Q4Y/s1600/eclipse-generate-tostring.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-f4IxTCSRzIA/Tj7dNXzrqmI/AAAAAAAAD8o/fK0YN1S7Q4Y/s400/eclipse-generate-tostring.png" width="366" title="Eclipse generate toString()" alt="Eclipse generate toString()"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Using &lt;i&gt;Browse…&lt;/i&gt; button select &lt;code&gt;org.apache.commons.lang3.builder.ToStringBuilder&lt;/code&gt; as &lt;i&gt;Builder Class&lt;/i&gt; and press &lt;i&gt;OK&lt;/i&gt;.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-2mMpZTkKmqo/Tj7dNxZiwQI/AAAAAAAAD8s/JbdR29P1vSI/s1600/eclipse-generate-tostring-config-cutom-builder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="196" src="http://3.bp.blogspot.com/-2mMpZTkKmqo/Tj7dNxZiwQI/AAAAAAAAD8s/JbdR29P1vSI/s400/eclipse-generate-tostring-config-cutom-builder.png" width="400" title="Eclipse generate toString() with custom builder" alt="Eclipse generate toString() with custom builder"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Press &lt;i&gt;OK&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Eclipse will generate the &lt;code&gt;toString()&lt;/code&gt; method. It should look similar to this one:
&lt;pre class="brush: java;"&gt;
@Override
public String toString() {
    ToStringBuilder builder = new ToStringBuilder(this);
    builder.append(&amp;quot;string&amp;quot;, string);
    builder.append(&amp;quot;number&amp;quot;, number);
    return builder.toString();
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Eclipse will save your settings, so next time you will not have to repeat these steps again. Just open &lt;i&gt;Generate toString()&lt;/i&gt; wizard and hit &lt;i&gt;OK&lt;/i&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Custom Templates&lt;/h3&gt;
&lt;p&gt;As I mentioned earlier, only &lt;code&gt;toString()&lt;/code&gt; generation can be customized in Eclipse. Still, we can configure Eclipse to generate &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt; and &lt;code&gt;compareTo()&lt;/code&gt; using Apache Commons Lang builders by using Eclipse templates.&lt;/p&gt;
&lt;p&gt;Templates are little pieces of code with defined placeholders. Each template has a name, which serves as a shortcut to the template itself. You type the name, press &lt;i&gt;CTRL + SPACE&lt;/i&gt; and it will be expanded. In order to access Eclipse templates open &lt;i&gt;Window -&gt; Preferences&lt;/i&gt; and select &lt;i&gt;Java -&gt; Editor -&gt; Templates&lt;/i&gt;. Now you can create new templates, edit existing ones or import directly ready templates.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-RIzFH0s8KnM/Tj7dORo71QI/AAAAAAAAD8w/XnXRA1h5wDk/s1600/eclipse-preferences-java-templates.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="492" src="http://3.bp.blogspot.com/-RIzFH0s8KnM/Tj7dORo71QI/AAAAAAAAD8w/XnXRA1h5wDk/s640/eclipse-preferences-java-templates.png" width="640" title="Eclipse Preferences - Java Templates" alt="Eclipse Preferences - Java Templates"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Following is a list of templates that will allow you to generate &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt;, &lt;code&gt;compareTo()&lt;/code&gt; and even &lt;code&gt;toString()&lt;/code&gt; using Apache Commons Lang builders.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;hashCode()&lt;/code&gt;&lt;/b&gt; template
&lt;pre class="brush: java;"&gt;
@Override
public int hashCode() {
    ${builderType:newType(org.apache.commons.lang3.builder.HashCodeBuilder)} ${builder:newName(builderType)} = new ${builderType}();
    ${builder}.append(${field});${cursor}
    return ${builder}.toHashCode();
}
&lt;/pre&gt;
This is how it will look like in Eclipse:
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-Fiq4ezCn2ts/Tj7dOzV4cJI/AAAAAAAAD80/maXBa_c_xfs/s1600/eclipse-preferences-java-templates-hashcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="364" src="http://3.bp.blogspot.com/-Fiq4ezCn2ts/Tj7dOzV4cJI/AAAAAAAAD80/maXBa_c_xfs/s640/eclipse-preferences-java-templates-hashcode.png" width="640" title="Eclipse Preferences - Java hashCode() template" alt="Eclipse Preferences - Java hashCode() template"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;equals()&lt;/code&gt;&lt;/b&gt; template
&lt;pre class="brush: java;"&gt;
@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (!(obj instanceof ${enclosing_type})) {
        return false;
    }
    ${enclosing_type} other = (${enclosing_type}) obj;
    ${builderType:newType(org.apache.commons.lang3.builder.EqualsBuilder)} ${builder:newName(builderType)} = new ${builderType}();
    ${builder}.append(${field}, other.${field});${cursor}
    return ${builder}.isEquals();
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;compareTo()&lt;/code&gt;&lt;/b&gt; template
&lt;pre class="brush: java;"&gt;
@Override
public int compareTo(${enclosing_type} o) {
    ${builderType:newType(org.apache.commons.lang3.builder.CompareToBuilder)} ${builder:newName(builderType)} = new ${builderType}();
    ${builder}.append(${field}, o.${field});${cursor}
    return ${builder}.toComparison();
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;toString()&lt;/code&gt;&lt;/b&gt; template
&lt;pre class="brush: java;"&gt;
@Override
public String toString() {
    ${builderType:newType(org.apache.commons.lang3.builder.ToStringBuilder)} ${builder:newName(builderType)} = new ${builderType}(this, ${:newType(org.apache.commons.lang3.builder.ToStringStyle)}.${DEFAULT_STYLE});
    ${builder}.append(&amp;quot;${field}&amp;quot;, ${field});${cursor}
    return ${builder}.toString();
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also you can easily import all the above templates using &lt;i&gt;Import…&lt;/i&gt; button from the following file &lt;a href="http://azagorneanu.googlecode.com/svn/trunk/blog/eclipse/eclipse-templates-apache-commons.xml"&gt;eclipse-templates-apache-commons.xml&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After you defined the templates, you can start using them through Content Assist (&lt;i&gt;CTRL + SPACE&lt;/i&gt;). Start typing the name of template in editor and then press &lt;i&gt;CTRL + SPACE&lt;/i&gt;. Choose the required template and press &lt;i&gt;ENTER&lt;/i&gt;.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-ZZZ9c2at-qo/Tj7dMzj2LWI/AAAAAAAAD8k/D2vkxOwn1iQ/s1600/eclipse-content-assist-templates-hashcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://4.bp.blogspot.com/-ZZZ9c2at-qo/Tj7dMzj2LWI/AAAAAAAAD8k/D2vkxOwn1iQ/s640/eclipse-content-assist-templates-hashcode.png" width="640" title="Eclipse Content Assist with hashCode() template" alt="Eclipse Content Assist with hashCode() template"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Customize the variables names and fields that should be included in the builder. Append more fields if it’s required. You have to get at the end something like this:&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
@Override
public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(number);
    builder.append(string);
    return builder.toHashCode();
}
&lt;/pre&gt;
&lt;p&gt;End.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-7870815597823181378?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YdqB17RQOAwdXQ69griTllIRsR0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YdqB17RQOAwdXQ69griTllIRsR0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YdqB17RQOAwdXQ69griTllIRsR0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YdqB17RQOAwdXQ69griTllIRsR0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WKgCwWtHgS4:Vv-UUT_NtNk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WKgCwWtHgS4:Vv-UUT_NtNk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=WKgCwWtHgS4:Vv-UUT_NtNk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WKgCwWtHgS4:Vv-UUT_NtNk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WKgCwWtHgS4:Vv-UUT_NtNk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=WKgCwWtHgS4:Vv-UUT_NtNk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/WKgCwWtHgS4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/7870815597823181378/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/08/how-to-generate-equals-hashcode.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7870815597823181378?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7870815597823181378?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/WKgCwWtHgS4/how-to-generate-equals-hashcode.html" title="How to generate equals(), hashCode(), toString() and compareTo() using Apache Commons Lang in Eclipse" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-f4IxTCSRzIA/Tj7dNXzrqmI/AAAAAAAAD8o/fK0YN1S7Q4Y/s72-c/eclipse-generate-tostring.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/08/how-to-generate-equals-hashcode.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUFQnY9eSp7ImA9WhdREUk.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-2831315770129971616</id><published>2011-07-31T23:27:00.001+03:00</published><updated>2011-07-31T23:30:13.861+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-31T23:30:13.861+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="hibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="infinispan" /><title>How to register Infinispan listeners in Spring when using Infinispan as 2LC for Hibernate</title><content type="html">&lt;p&gt;In this post I will show how to register &lt;a href="http://www.jboss.org/infinispan"&gt;Infinispan&lt;/a&gt; listeners in &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt; when Infinispan is used as second level cache (2LC) for &lt;a href="http://hibernate.org/"&gt;Hibernate&lt;/a&gt;. So let’s start:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Annotate your entity classes as cacheable. Pay attention to the cache region name (&lt;code&gt;"cache_name"&lt;/code&gt;) specified in the &lt;code&gt;region&lt;/code&gt; attribute of &lt;code&gt;Cache&lt;/code&gt; annotation.
&lt;pre class="brush: java;"&gt;
@Entity
@Cache(region = &amp;quot;cache_name&amp;quot;, usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Cacheable
@Table(name = &amp;quot;ENTITY_TABLE&amp;quot;)
public class MyEntity implements Serializable {
    // entity fields
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Write your custom &lt;code&gt;InfinispanRegionFactory&lt;/code&gt; as it is shown below. It extends from Hibernate &lt;code&gt;InfinispanRegionFactory&lt;/code&gt; and its logic is very simple. The only thing which it does is to register listeners after its start. Pay attention to the named cache (&lt;code&gt;"cache_name"&lt;/code&gt;) to which listeners are registered. It should be the same as the cache region name used by your entities. &lt;a name='more'&gt;&lt;/a&gt;
&lt;pre class="brush: java;"&gt;
public class CustomInfinispanRegionFactory extends InfinispanRegionFactory {
    private Set&amp;lt;Object&amp;gt; listeners;

    public CustomInfinispanRegionFactory() {
    }

    public CustomInfinispanRegionFactory(Properties props) {
        super(props);
    }

    public void setListeners(Set&amp;lt;Object&amp;gt; listeners) {
        this.listeners = listeners;
    }

    @Override
    public void start(Settings settings, Properties properties) throws CacheException {
        super.start(settings, properties);
        for(Object listener : listeners) {
            // add listener to named cache
            getCacheManager().getCache(&amp;quot;cache_name&amp;quot;).addListener(listener);
            // add listener to cache manager
            getCacheManager().addListener(listener);
        }
    }
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Write your cache &lt;a href="http://docs.jboss.org/infinispan/4.0/apidocs/org/infinispan/notifications/Listener.html"&gt;Listener&lt;/a&gt;. You can find more information about Infinispan listeners &lt;a href="https://docs.jboss.org/author/display/ISPN/Listeners+and+Notifications"&gt;here&lt;/a&gt;.
&lt;pre class="brush: java;"&gt;
@Listener
public class TestCacheListener {
    @CacheStarted
    public void cacheStarted(Event event) {
          System.out.println(&amp;quot;Cache started. Details = &amp;quot; + event);
    }

    @CacheStopped
    public void cacheStopped(Event event) {
          System.out.println(&amp;quot;Cache stopped. Details = &amp;quot; + event);
    }

    @CacheEntryCreated
    @CacheEntryModified
    @CacheEntryRemoved
    public void handle(Event event) {
        System.out.println(&amp;quot;Cache entry modified. Details = &amp;quot; + event);
    }
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Configure Hibernate and Infinispan in Spring. Register your listener. You can find more information about using Infinispan as 2LC in Hibernate &lt;a href="https://docs.jboss.org/author/display/ISPN/Using+Infinispan+as+JPA-Hibernate+Second+Level+Cache+Provider"&gt;here&lt;/a&gt;.
&lt;pre class="brush: xml;"&gt;
&amp;lt;bean id=&amp;quot;sessionFactory&amp;quot; class=&amp;quot;org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;dataSource&amp;quot; /&amp;gt;
        &amp;lt;property name=&amp;quot;packagesToScan&amp;quot; value=&amp;quot;org.zmeu.blog.persistence.entity&amp;quot; /&amp;gt;
        &amp;lt;property name=&amp;quot;hibernateProperties&amp;quot;&amp;gt;
            &amp;lt;props&amp;gt;
                &amp;lt;prop key=&amp;quot;hibernate.cache.use_second_level_cache&amp;quot;&amp;gt;true&amp;lt;/prop&amp;gt;
                &amp;lt;prop key=&amp;quot;hibernate.cache.infinispan.cfg&amp;quot;&amp;gt;cache-config.xml&amp;lt;/prop&amp;gt;
            &amp;lt;/props&amp;gt;
        &amp;lt;/property&amp;gt;
        &amp;lt;property name=&amp;quot;cacheRegionFactory&amp;quot; ref=&amp;quot;cacheRegionFactory&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;cacheRegionFactory&amp;quot; class=&amp;quot;com.xtrader.persistence.cache.CustomInfinispanRegionFactory&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;listeners&amp;quot;&amp;gt;
        &amp;lt;set&amp;gt;
            &amp;lt;ref bean=&amp;quot;listener&amp;quot;/&amp;gt;
        &amp;lt;/set&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;listener&amp;quot; class=&amp;quot;org.zmeu.blog.persistence.cache.TestCacheListener&amp;quot;/&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Define the named cache (&lt;code&gt;"cache_name"&lt;/code&gt;) inside Infinispan configuration cache (&lt;code&gt;cache-config.xml&lt;/code&gt;).
&lt;pre class="brush: xml;"&gt;
&amp;lt;namedCache name=&amp;quot;cache_name&amp;quot;&amp;gt;
    &amp;lt;!--  named cache configurations --&amp;gt;
&amp;lt;/namedCache&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;You are done!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For this example I used: Spring 3.0.5, Hibernate 3.6.5 and Infinispan 4.2.1.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-2831315770129971616?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/leSY0tiMzrivR2Si6-sbT1nkEHw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/leSY0tiMzrivR2Si6-sbT1nkEHw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/leSY0tiMzrivR2Si6-sbT1nkEHw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/leSY0tiMzrivR2Si6-sbT1nkEHw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WhRg4XlVVbw:ZvA8XbL7waU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WhRg4XlVVbw:ZvA8XbL7waU:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=WhRg4XlVVbw:ZvA8XbL7waU:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WhRg4XlVVbw:ZvA8XbL7waU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=WhRg4XlVVbw:ZvA8XbL7waU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=WhRg4XlVVbw:ZvA8XbL7waU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/WhRg4XlVVbw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/2831315770129971616/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/how-to-register-infinispan-listeners-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/2831315770129971616?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/2831315770129971616?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/WhRg4XlVVbw/how-to-register-infinispan-listeners-in.html" title="How to register Infinispan listeners in Spring when using Infinispan as 2LC for Hibernate" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/how-to-register-infinispan-listeners-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08GRXo7fyp7ImA9WhdRF08.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-8229328232631744318</id><published>2011-07-31T13:53:00.002+03:00</published><updated>2011-08-07T17:03:44.407+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T17:03:44.407+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><title>How to extract type arguments from parameterized (generic) class</title><content type="html">&lt;p&gt;A nice thing about parameterized classes in Java is that you can extract and access information about class type arguments at runtime (for an explanation about parameters and arguments see &lt;a href="http://en.wikipedia.org/wiki/Parameter_%28computer_science%29#Parameters_and_arguments"&gt;Parameters and arguments&lt;/a&gt;). Let’s say that we have an abstract parameterized superclass that has a method which provides some common functionality to all its subclasses. And inside that method we wanted to know what is the class type argument specified by the subclass.&lt;p&gt;
&lt;pre class="brush: java;"&gt;
public abstract class GenericAbstractSuperclass&amp;lt;T&amp;gt; {
    public void foo() {
        // here we wanted to know what is the class type argument
    }
}

public class GenericClass1 extends GenericAbstractSuperclass&amp;lt;Integer&amp;gt; {
    // subclass methods
}

public class GenericClass2 extends GenericAbstractSuperclass&amp;lt;String&amp;gt; {
    // subclass methods
}
&lt;/pre&gt;
&lt;p&gt;In above example, method &lt;code&gt;foo()&lt;/code&gt; has to access class type argument. In case of &lt;code&gt;GenericClass1&lt;/code&gt; it has to get &lt;code&gt;Integer&lt;/code&gt; and in case of &lt;code&gt;GenericClass2&lt;/code&gt; it has to get &lt;code&gt;String&lt;/code&gt;. Below is listed a utility class that can accomplish this.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;
&lt;pre class="brush: java;"&gt;
/**
 * Generics utility class.
 * 
 * @author Andrei Zagorneanu
 * @since 2011-07-31
 * @see &amp;lt;a href=&amp;quot;http://azagorneanu.blogspot.com&amp;quot;&amp;gt;http://azagorneanu.blogspot.com&amp;lt;/a&amp;gt;
 */
public class Generics {
    private Generics() {
        // empty, in order to avoid instantiation
    }

    public static &amp;lt;T&amp;gt; Class&amp;lt;T&amp;gt; extractTypeArgumentFromClass(Class&amp;lt;?&amp;gt; parameterizedClass)
            throws IllegalArgumentException {
        return extractTypeArgumentFromClass(parameterizedClass, 0);
    }

    public static &amp;lt;T&amp;gt; Class&amp;lt;T&amp;gt; extractTypeArgumentFromClass(Class&amp;lt;?&amp;gt; parameterizedClass,
            int argumentNumber) throws IllegalArgumentException {
        ParameterizedType parameterizedType = extractParameterizedTypeFromClass(parameterizedClass);
        if (parameterizedType == null) {
            throw new IllegalArgumentException(
                    &amp;quot;Class and any of its superclasses are not parameterized.&amp;quot;);
        }
        return (Class&amp;lt;T&amp;gt;) getActualTypeArgument(parameterizedType, argumentNumber);
    }

    private static Type getActualTypeArgument(ParameterizedType parameterizedType,
            int argumentNumber) throws IllegalArgumentException {
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        if (typeArguments.length == 0) {
            throw new IllegalArgumentException(&amp;quot;Class is not parameterized.&amp;quot;);
        }
        if (argumentNumber &amp;lt; 0 &amp;#124;&amp;#124; typeArguments.length &amp;lt;= argumentNumber) {
            throw new IllegalArgumentException(&amp;quot;Invalid argumentNumber.&amp;quot;);
        }
        return typeArguments[argumentNumber];
    }

    public static ParameterizedType extractParameterizedTypeFromClass(Class&amp;lt;?&amp;gt; parameterizedClass) {
        Type genericSuperclass = parameterizedClass.getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            return (ParameterizedType) genericSuperclass;
        }
        if (genericSuperclass != null) {
            return extractParameterizedTypeFromClass((Class&amp;lt;?&amp;gt;) genericSuperclass);
        }
        return null;
    }

    public static &amp;lt;T&amp;gt; Class&amp;lt;T&amp;gt; extractTypeArgumentFromInterface(Class&amp;lt;?&amp;gt; parameterizedClass)
            throws IllegalArgumentException {
        return extractTypeArgumentFromInterface(parameterizedClass, 0);
    }

    public static &amp;lt;T&amp;gt; Class&amp;lt;T&amp;gt; extractTypeArgumentFromInterface(Class&amp;lt;?&amp;gt; parameterizedClass,
            int argumentNumber) throws IllegalArgumentException {
        ParameterizedType parameterizedType = extractParameterizedTypeFromInterface(parameterizedClass);
        if (parameterizedType == null) {
            throw new IllegalArgumentException(
                    &amp;quot;Class and any of its interfaces are not parameterized.&amp;quot;);
        }
        return (Class&amp;lt;T&amp;gt;) getActualTypeArgument(parameterizedType, argumentNumber);
    }

    private static ParameterizedType extractParameterizedTypeFromInterface(
            Class&amp;lt;?&amp;gt; parameterizedClass) {
        Type[] genericInterfaces = parameterizedClass.getGenericInterfaces();
        for (Type genericInterface : genericInterfaces) {
            if (genericInterface instanceof ParameterizedType) {
                return (ParameterizedType) genericInterface;
            }
            ParameterizedType parameterizedType = extractParameterizedTypeFromInterface((Class&amp;lt;?&amp;gt;) genericInterface);
            if (parameterizedType != null) {
                return parameterizedType;
            }
        }
        return null;
    }
}
&lt;/pre&gt;
&lt;p&gt;This class provides methods for extracting type arguments from classes and from interfaces as well. The only use case which is not supported directly is when a class extends from a superclass that implements a parameterized interface. In this case, you will not be able to extract type argument from the class directly. Still, you can extract the class type argument using &lt;code&gt;extractTypeArgumentFromInterface(parameterizedClass.getSuperclass())&lt;/code&gt;. Here, we first extracted the superclass and then we used it to extract the type argument from its interface.&lt;/p&gt;
&lt;p&gt;Class source code can be found &lt;a href="http://azagorneanu.googlecode.com/svn/trunk/blog/generics/Generics.java"&gt;here&lt;/a&gt;. Unit tests source code can be found &lt;a href="http://azagorneanu.googlecode.com/svn/trunk/blog/generics/GenericsTest.java"&gt;here&lt;/a&gt;. Unit tests represent also a good example of class usage.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Update (07-Aug-2011):&lt;/u&gt;&lt;/b&gt; Recently a new major release of &lt;a href="http://commons.apache.org/lang/"&gt;Apache Commons Lang&lt;/a&gt; was released - &lt;a href="http://commons.apache.org/lang/upgradeto3_0.html"&gt;Apache Commons Lang 3.0&lt;/a&gt;. Among new utility classes that were added, you will find a new &lt;a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang3/reflect/TypeUtils.html"&gt;TypeUtils&lt;/a&gt; class, which provides utility methods for working with generic types (including retrieval of type arguments from parameterized classes).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-8229328232631744318?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MRvDegd6XRznYCQ2nzMCWJZLSFk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MRvDegd6XRznYCQ2nzMCWJZLSFk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MRvDegd6XRznYCQ2nzMCWJZLSFk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MRvDegd6XRznYCQ2nzMCWJZLSFk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=lEWaFZwNeJY:GTYUI0bniG8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=lEWaFZwNeJY:GTYUI0bniG8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=lEWaFZwNeJY:GTYUI0bniG8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=lEWaFZwNeJY:GTYUI0bniG8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=lEWaFZwNeJY:GTYUI0bniG8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=lEWaFZwNeJY:GTYUI0bniG8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/lEWaFZwNeJY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/8229328232631744318/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/how-to-extract-type-arguments-from.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8229328232631744318?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8229328232631744318?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/lEWaFZwNeJY/how-to-extract-type-arguments-from.html" title="How to extract type arguments from parameterized (generic) class" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/how-to-extract-type-arguments-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcERHc6fSp7ImA9WhVTFk8.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-7376413346567023452</id><published>2011-07-25T21:35:00.002+03:00</published><updated>2012-03-01T19:13:25.915+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-01T19:13:25.915+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><title>java.math.BigDecimal performance</title><content type="html">&lt;p&gt;These days I had to do some monetary calculations in Java. This reminded me again about primitive &lt;code&gt;double&lt;/code&gt; type and that it is absolutely the worst thing you can use when dealing with money. As you know, primitive &lt;code&gt;double&lt;/code&gt; don't necessarily give you the right value, only the value that can be stored in a binary number format (any decimal number is represented by an approximated value). Whilst, &lt;code&gt;java.math.BigDecimal&lt;/code&gt; gives you the required precision, its performance is very poor comparable to primitive types.&lt;/p&gt;
&lt;p&gt;Below are few simple tests that are measuring &lt;code&gt;BigDecimal&lt;/code&gt; performance based on a simple computation &lt;code&gt;x&lt;sup&gt;2&lt;/sup&gt; + y&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt; which is performed in a loop 250000 times. In order to exclude the JVM warm-up cost, each test was executed 10 times. The execution time was calculated as average of all executions except first execution &lt;code&gt;(exec&lt;sub&gt;2&lt;/sub&gt; + exec&lt;sub&gt;3&lt;/sub&gt; + … + exec&lt;sub&gt;10&lt;/sub&gt;) / 9&lt;/code&gt;.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;Test &lt;code&gt;BigDecimal&lt;/code&gt; computations (execution average time: ~ &lt;b&gt;767 ms&lt;/b&gt;)
&lt;pre class="brush: java;"&gt;
BigDecimal bd = null;
for (double x = 0.5; x &amp;lt;= 500; x += 0.5) {
    for (double y = 0.5; y &amp;lt;= 500; y += 0.5) {
      bd = BigDecimal.valueOf(x).pow(2).add(BigDecimal.valueOf(y).pow(2));
    }
}
&lt;/pre&gt;
We got around &lt;b&gt;0.003 ms&lt;/b&gt; per computation. Not bad, but wait to see how fast primitive &lt;code&gt;double&lt;/code&gt; is. Next test will show us how much time we spend on creation of &lt;code&gt;BigDecimal&lt;/code&gt; objects.
&lt;/li&gt;
&lt;li&gt;Test &lt;code&gt;BigDecimal&lt;/code&gt; constructions (execution average time: ~ &lt;b&gt;468 ms&lt;/b&gt;)
&lt;pre class="brush: java;"&gt;
for (double x = 0.5; x &amp;lt;= 500; x += 0.5) {
  for (double y = 0.5; y &amp;lt;= 500; y += 0.5) {
    BigDecimal.valueOf(x);
    BigDecimal.valueOf(y);
  }
}
&lt;/pre&gt;
As you can see, only construction of initial operands (&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;) took around &lt;b&gt;61%&lt;/b&gt; of computation time. We can assume that rest 39% are also spent on &lt;code&gt;BigDecimal&lt;/code&gt; object creations (results of &lt;code&gt;pow()&lt;/code&gt; and &lt;code&gt;add()&lt;/code&gt; operations). Knowing that &lt;code&gt;BigDecimal&lt;/code&gt; objects are immutable, let’s see how much we can gain by caching &lt;code&gt;BigDecimal&lt;/code&gt; instances.
&lt;/li&gt;
&lt;li&gt;Test &lt;code&gt;BigDecimal&lt;/code&gt; computations with cache (execution average time: ~ &lt;b&gt;309 ms&lt;/b&gt;)
&lt;pre class="brush: java;"&gt;
BigDecimal bd = null;
for (double x = 0.5; x &amp;lt;= 500; x += 0.5) {
  for (double y = 0.5; y &amp;lt;= 500; y += 0.5) {
    BigDecimal bigDecimal1 = cache.get(x);
    BigDecimal bigDecimal2 = cache.get(y);
    bd = bigDecimal1.pow(2).add(bigDecimal2.pow(2));
  }
}
&lt;/pre&gt;
Cache was prepared as follows:
&lt;pre class="brush: java;"&gt;
Map&amp;lt;Double, BigDecimal&amp;gt; cache = new HashMap&amp;lt;Double, BigDecimal&amp;gt;();
for (double x = 0.5; x &amp;lt;= 500; x += 0.5) {
  cache.put(x, BigDecimal.valueOf(x));
}
&lt;/pre&gt;
As you can see, caching &lt;code&gt;BigDecimal&lt;/code&gt; gives a performance boost. Now it’s time to see how the primitive &lt;code&gt;double&lt;/code&gt; type is performing.
&lt;/li&gt;
&lt;li&gt;Test &lt;code&gt;double&lt;/code&gt; computations (execution average time: ~ &lt;b&gt;2 ms&lt;/b&gt;)
&lt;pre class="brush: java;"&gt;
double d = 0.0;
for (double x = 0.5; x &amp;lt;= 500; x += 0.5) {
  for (double y = 0.5; y &amp;lt;= 500; y += 0.5) {
    d = x * x + y * y;
  }
}
&lt;/pre&gt;
Computation speed is great but unfortunately floating point numbers cannot be used for monetary calculations.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;font size="+1"&gt;&lt;b&gt;Performance Improvement to &lt;code&gt;BigDecimal&lt;/code&gt;&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Java SE 6 Update 25 made some performance improvements for &lt;code&gt;BigDecimal&lt;/code&gt;. Following is the excerpt from &lt;a href="http://www.oracle.com/technetwork/java/javase/6u25releasenotes-356444.html"&gt;Java SE 6 Update 25 Release Notes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;Improvements have been made to class BigDecimal enhancing its performance by thirty percent. BigDecimal is enabled by specifying &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt; command option.&lt;/blockquote&gt;
&lt;p&gt;I repeated all the above tests with &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt; option. Below is the table with results:&lt;/p&gt;
&lt;table width="100%" cellspacing="0" cellpadding="5" border="1"&gt;
&lt;tr align="center"&gt;&lt;td rowspan="2" width="25%"&gt;&lt;b&gt;Test&lt;/b&gt;&lt;/td&gt;&lt;td colspan="2" width="50%"&gt;&lt;b&gt;Average Exec Time&lt;/b&gt;&lt;/td&gt;&lt;td rowspan="2" width="25%"&gt;&lt;b&gt;Performance Boost&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="center"&gt;&lt;td width="25%"&gt;&lt;b&gt;Normal&lt;/b&gt;&lt;/td&gt;&lt;td width="25%"&gt;&lt;b&gt;-XX:+AggressiveOpts&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="center"&gt;&lt;td&gt;&lt;code&gt;BigDecimal&lt;/code&gt; computations&lt;/td&gt;&lt;td&gt;767 ms&lt;/td&gt;&lt;td&gt;644 ms&lt;/td&gt;&lt;td&gt;16%&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="center"&gt;&lt;td&gt;&lt;code&gt;BigDecimal&lt;/code&gt; constructions&lt;/td&gt;&lt;td&gt;468 ms&lt;/td&gt;&lt;td&gt;394 ms&lt;/td&gt;&lt;td&gt;16%&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="center"&gt;&lt;td&gt;&lt;code&gt;BigDecimal&lt;/code&gt; computations with cache&lt;/td&gt;&lt;td&gt;309 ms&lt;/td&gt;&lt;td&gt;309 ms&lt;/td&gt;&lt;td&gt;0%&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="center"&gt;&lt;td&gt;&lt;code&gt;double&lt;/code&gt; computations&lt;/td&gt;&lt;td&gt;2 ms&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Results speak themselves, &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt; option gave us &lt;b&gt;16%&lt;/b&gt; performance improvement. It’s not a 30% improvement but still it is something, if we take into account that we just added a JVM option. The most interesting thing is that we got 0% performance improvement for the test which uses cache and the performance improvement of &lt;code&gt;BigDecimal&lt;/code&gt; computations test and &lt;code&gt;BigDecimal&lt;/code&gt; constructions test are the same. This leads me to think that improvements were made mostly for &lt;code&gt;BigDecimal&lt;/code&gt; objects creation.&lt;/p&gt;
&lt;p&gt;Regarding &lt;code&gt;BigDecimal&lt;/code&gt; I would like also to remind you about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;BigDecimal(double)&lt;/code&gt; constructor. The recommended constructor is &lt;code&gt;BigDecimal(String)&lt;/code&gt;, or in case you want to convert an existing double into a &lt;code&gt;BigDecimal&lt;/code&gt; you can use &lt;code&gt;BigDecimal.valueOf(double)&lt;/code&gt; static method.&lt;/li&gt;
&lt;li&gt;When dividing always specify a &lt;code&gt;RoundingMode&lt;/code&gt;. Instead of &lt;code&gt;divide(BigDecimal)&lt;/code&gt; use &lt;code&gt;divide(BigDecimal, RoundingMode)&lt;/code&gt;. This has to be done in order to avoid &lt;code&gt;ArithmeticException&lt;/code&gt;. Below is an excerpt from &lt;code&gt;BigDecimal&lt;/code&gt; &lt;a href="http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html"&gt;javadoc&lt;/a&gt;:
&lt;blockquote&gt;In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an &lt;code&gt;ArithmeticException&lt;/code&gt; is thrown.&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the end, I want to say that for my task I used neither &lt;code&gt;double&lt;/code&gt; nor &lt;code&gt;BigDecimal&lt;/code&gt;. I used primitive &lt;code&gt;long&lt;/code&gt; type and I stored money as cents, pennies (or the equivalent, of course). The choice was done because of performance reasons. I had to do many very simple computations but very often.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Update (05-Aug-2011):&lt;/u&gt;&lt;/b&gt; Be aware of &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7070134"&gt;bug&lt;/a&gt;, recently discovered in Java 7 which is also applicable for Java 6 in case when the following JVM options are used: &lt;code&gt;-XX:+OptimizeStringConcat&lt;/code&gt; or &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt;. More information &lt;a href="http://www.infoq.com/news/2011/08/java7-hotspot"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Update (01-Mar-2012):&lt;/u&gt;&lt;/b&gt; Bug was fixed in &lt;a href="http://www.oracle.com/technetwork/java/javase/6u29-relnotes-507960.html"&gt;Java 6 update 29&lt;/a&gt; and &lt;a href="http://www.oracle.com/technetwork/java/javase/7u1-relnotes-507962.html"&gt;Java 7 update 1&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-7376413346567023452?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MBeJCmHm3ED8WTA5GmZfS7BfUeU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MBeJCmHm3ED8WTA5GmZfS7BfUeU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MBeJCmHm3ED8WTA5GmZfS7BfUeU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MBeJCmHm3ED8WTA5GmZfS7BfUeU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=PpkpyMIFgwQ:v9pzBcLk1S4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=PpkpyMIFgwQ:v9pzBcLk1S4:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=PpkpyMIFgwQ:v9pzBcLk1S4:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=PpkpyMIFgwQ:v9pzBcLk1S4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=PpkpyMIFgwQ:v9pzBcLk1S4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=PpkpyMIFgwQ:v9pzBcLk1S4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/PpkpyMIFgwQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/7376413346567023452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/javamathbigdecimal-performance.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7376413346567023452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7376413346567023452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/PpkpyMIFgwQ/javamathbigdecimal-performance.html" title="java.math.BigDecimal performance" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/javamathbigdecimal-performance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cMRnY6cSp7ImA9WhdTEkU.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-8291959186150632058</id><published>2011-07-10T12:11:00.000+03:00</published><updated>2011-07-10T12:11:27.819+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-10T12:11:27.819+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="tortoisesvn" /><category scheme="http://www.blogger.com/atom/ns#" term="svn" /><title>Where to store JavaScript and CSS files for Blogger</title><content type="html">&lt;p&gt;If you are a &lt;a href="http://www.blogger.com/"&gt;Blogger&lt;/a&gt; user, then you already know that currently there is no possibility to upload your custom JavaScript and CSS files. You have to host your files somewhere else and then link them in your blog template. One of the places where you can host your custom JavaScript, CSS and any type of files is &lt;a href="http://code.google.com/"&gt;Google Code&lt;/a&gt;. Google Code, is a free platform to host Open Sources Projects.&lt;/p&gt;
&lt;p&gt;You can just simply upload your files and hotlink to them. Main issue in this simple task is that it’s working for JavaScript files but it doesn’t work when hot linking to CSS or Image files. The reason is that, by default when we upload any file to Google Code, it is served as &lt;b&gt;text-plain&lt;/b&gt; &lt;a href="http://en.wikipedia.org/wiki/Mime-type"&gt;mime-type&lt;/a&gt;. This works with JavaScript files but not with CSS, Image files or HTML files.&lt;/p&gt;
&lt;p&gt;Below is a small tutorial showing how to create a new project on Google Code, how to use an &lt;a href="http://en.wikipedia.org/wiki/Apache_Subversion"&gt;SVN&lt;/a&gt; client to upload new files to it and how to set the mime-type for these files.&lt;/p&gt;
&lt;a name='more'&gt;&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="http://code.google.com/hosting/"&gt;http://code.google.com/hosting/&lt;/a&gt; and create a new Google Code project in case you don’t have one already.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-DaVSyECgEhs/Thlixd7AlaI/AAAAAAAAD5g/p_uzPFVlANY/s1600/google-code-project-hosting.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Google Code Project Hosting" border="0" height="225" src="http://4.bp.blogspot.com/-DaVSyECgEhs/Thlixd7AlaI/AAAAAAAAD5g/p_uzPFVlANY/s400/google-code-project-hosting.png" title="Google Code Project Hosting" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Make sure that you have selected &lt;b&gt;Subversion&lt;/b&gt; as Version Control system.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-sX-xk_RdD-I/ThlnxyQAGvI/AAAAAAAAD5w/Olg9MnnZtoI/s1600/google-code-create-new-project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Google Code Create New Project" border="0" height="265" src="http://3.bp.blogspot.com/-sX-xk_RdD-I/ThlnxyQAGvI/AAAAAAAAD5w/Olg9MnnZtoI/s400/google-code-create-new-project.png" title="Google Code Create New Project" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Note down your repository URL, username and password. We will need these details in the next steps when we will use an SVN client to upload files to repository.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-3BiEjRW9vWs/ThlnyuR-HrI/AAAAAAAAD50/A7OyGDdsLP8/s1600/google-code-source-page.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Google Code Source Page" border="0" height="130" src="http://1.bp.blogspot.com/-3BiEjRW9vWs/ThlnyuR-HrI/AAAAAAAAD50/A7OyGDdsLP8/s400/google-code-source-page.png" title="Google Code Source Page" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Install an SVN client. In this example we are using &lt;a href="http://tortoisesvn.net/"&gt;TortoiseSVN&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Right click where ever you are working on Windows Explorer and lunch TortoiseSVN &lt;b&gt;Repo-browser&lt;/b&gt;.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-vQd7lnQpB4I/Thln8fq-jBI/AAAAAAAAD6E/wHTlcg6P9ho/s1600/tortoisesvn-repobrowser-menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser Menu" border="0" height="400" src="http://1.bp.blogspot.com/-vQd7lnQpB4I/Thln8fq-jBI/AAAAAAAAD6E/wHTlcg6P9ho/s400/tortoisesvn-repobrowser-menu.png" title="TortoiseSVN Repo-browser Menu" width="396" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Enter you repository URL, then username and password (from step no. 3).
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-1TR8FWM5_wg/ThloAyKKCJI/AAAAAAAAD6Q/s7Sa6CgysUg/s1600/tortoisesvn-repobrowser-url.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser URL" border="0" height="123" src="http://1.bp.blogspot.com/-1TR8FWM5_wg/ThloAyKKCJI/AAAAAAAAD6Q/s7Sa6CgysUg/s400/tortoisesvn-repobrowser-url.png" title="TortoiseSVN Repo-browser URL" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Repo-browser lets you browse, add, remove and edit files from your SVN repository.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-y_UnGqBocNU/Thln15R1YyI/AAAAAAAAD54/wyfc7dusiEU/s1600/tortoisesvn-repobrowser-addfile-menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser Add File Menu" border="0" height="238" src="http://1.bp.blogspot.com/-y_UnGqBocNU/Thln15R1YyI/AAAAAAAAD54/wyfc7dusiEU/s400/tortoisesvn-repobrowser-addfile-menu.png" title="TortoiseSVN Repo-browser Add File Menu" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;After you have uploaded the files to repository, you can set their &lt;b&gt;mime-type&lt;/b&gt;. Right-click on a file and select &lt;b&gt;Show properties&lt;/b&gt; from context-menu.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-7m_JP8B7CB4/Thln-Qnsm5I/AAAAAAAAD6M/lQnkQ805yFk/s1600/tortoisesvn-repobrowser-props-menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser Properties Menu" border="0" height="242" src="http://1.bp.blogspot.com/-7m_JP8B7CB4/Thln-Qnsm5I/AAAAAAAAD6M/lQnkQ805yFk/s400/tortoisesvn-repobrowser-props-menu.png" title="TortoiseSVN Repo-browser Properties Menu" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Using &lt;b&gt;Properties&lt;/b&gt; dialog you can add, remove and edit file’s properties.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-UHpDjPpB4Nk/Thln9J14vGI/AAAAAAAAD6I/JBMkqEHDbGY/s1600/tortoisesvn-repobrowser-props.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser Properties" border="0" height="203" src="http://1.bp.blogspot.com/-UHpDjPpB4Nk/Thln9J14vGI/AAAAAAAAD6I/JBMkqEHDbGY/s400/tortoisesvn-repobrowser-props.png" title="TortoiseSVN Repo-browser Properties" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-6ThZ9iH7LS0/Thln3EjpAFI/AAAAAAAAD58/2zX64urQEBU/s1600/tortoisesvn-repobrowser-add-props.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TortoiseSVN Repo-browser Add Properties" border="0" height="281" src="http://4.bp.blogspot.com/-6ThZ9iH7LS0/Thln3EjpAFI/AAAAAAAAD58/2zX64urQEBU/s320/tortoisesvn-repobrowser-add-props.png" title="TortoiseSVN Repo-browser Add Properties" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;You are done uploading. Get the file URL by doing left click on the file you want to hot link from the repository browser and select and copy the URL. Just replace the &lt;b&gt;https&lt;/b&gt; with &lt;b&gt;http&lt;/b&gt; and you are done. Now you have got the URL to hot link. Use it where ever you like.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-A1DroDByUNU/Thln4O3XlgI/AAAAAAAAD6A/irCtXKue0Cc/s1600/tortoisesvn-repobrowser-file-url.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="http://1.bp.blogspot.com/-A1DroDByUNU/Thln4O3XlgI/AAAAAAAAD6A/irCtXKue0Cc/s400/tortoisesvn-repobrowser-file-url.png" width="400" alt="TortoiseSVN Repo-browser File URL" title="TortoiseSVN Repo-browser File URL" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-8291959186150632058?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MS3kkVhosuMpOnUXnG7Y1PAF7CU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MS3kkVhosuMpOnUXnG7Y1PAF7CU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MS3kkVhosuMpOnUXnG7Y1PAF7CU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MS3kkVhosuMpOnUXnG7Y1PAF7CU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=xZvn0q1zo_8:W36v4C7YBAI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=xZvn0q1zo_8:W36v4C7YBAI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=xZvn0q1zo_8:W36v4C7YBAI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=xZvn0q1zo_8:W36v4C7YBAI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=xZvn0q1zo_8:W36v4C7YBAI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=xZvn0q1zo_8:W36v4C7YBAI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/xZvn0q1zo_8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/8291959186150632058/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/where-to-store-javascript-and-css-files.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8291959186150632058?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/8291959186150632058?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/xZvn0q1zo_8/where-to-store-javascript-and-css-files.html" title="Where to store JavaScript and CSS files for Blogger" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-DaVSyECgEhs/Thlixd7AlaI/AAAAAAAAD5g/p_uzPFVlANY/s72-c/google-code-project-hosting.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/where-to-store-javascript-and-css-files.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcMQXwzfyp7ImA9WhdTEkU.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-5337760555590494300</id><published>2011-07-09T16:14:00.001+03:00</published><updated>2011-07-10T11:38:00.287+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-10T11:38:00.287+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mindmap" /><category scheme="http://www.blogger.com/atom/ns#" term="forex" /><title>Forex Mind Map</title><content type="html">&lt;p&gt;After studying Forex &lt;b&gt;School of Pipsology&lt;/b&gt; from &lt;a href="http://www.babypips.com/"&gt;http://www.babypips.com/&lt;/a&gt; I made a Forex mind map. It includes &lt;i&gt;Forex Basics&lt;/i&gt; section and some topics from &lt;i&gt;Elementary School&lt;/i&gt; section.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-Muvn5qVFogc/ThhSRe14moI/AAAAAAAAD5c/BaxvxIgCLAQ/s1600/forex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;
&lt;img border="0" height="302" src="http://4.bp.blogspot.com/-Muvn5qVFogc/ThhSRe14moI/AAAAAAAAD5c/BaxvxIgCLAQ/s640/forex.png" width="640" alt="Forex Mind Map" title="Forex Mind Map"/&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;You can find the mind map here: &lt;a href="https://sites.google.com/site/azagorneanu/mm/forex"&gt;https://sites.google.com/site/azagorneanu/mm/forex&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;b&gt;You can browse Forex Mind Map using one of the following:&lt;/b&gt;&lt;/p&gt;
&lt;div class="nostyle" style="text-align: center;"&gt;
&lt;a href="https://sites.google.com/site/azagorneanu/mm/forex/forex-applet" target="_blank"&gt;&lt;img alt="Java Applet" height="64" src="https://sites.google.com/site/azagorneanu/images/java-applet-button.png" title="Java Applet" width="140" /&gt;&lt;/a&gt;
&lt;span style="margin: 5px;"&gt;&amp;nbsp;&lt;/span&gt;
&lt;a href="https://sites.google.com/site/azagorneanu/mm/forex/forex-mm.jnlp?attredirects=0"&gt;&lt;img alt="Java Web Start" height="64" src="https://sites.google.com/site/azagorneanu/images/java-web-start-button.png" title="Java Web Start" width="140" /&gt;&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/8369030687505463576-5337760555590494300?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/d03OuTY3p5REDKxCgKcQekZO5Z4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d03OuTY3p5REDKxCgKcQekZO5Z4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/d03OuTY3p5REDKxCgKcQekZO5Z4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d03OuTY3p5REDKxCgKcQekZO5Z4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=uAiqNDf-fiY:X6_v_N3uxuk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=uAiqNDf-fiY:X6_v_N3uxuk:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=uAiqNDf-fiY:X6_v_N3uxuk:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=uAiqNDf-fiY:X6_v_N3uxuk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=uAiqNDf-fiY:X6_v_N3uxuk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=uAiqNDf-fiY:X6_v_N3uxuk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/uAiqNDf-fiY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/5337760555590494300/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/forex-mind-map.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/5337760555590494300?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/5337760555590494300?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/uAiqNDf-fiY/forex-mind-map.html" title="Forex Mind Map" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-Muvn5qVFogc/ThhSRe14moI/AAAAAAAAD5c/BaxvxIgCLAQ/s72-c/forex.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/forex-mind-map.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQHSXo_cCp7ImA9WhZaGEQ.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-457073964883297915</id><published>2011-07-05T22:48:00.002+03:00</published><updated>2011-07-05T23:05:38.448+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-05T23:05:38.448+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="java web start" /><category scheme="http://www.blogger.com/atom/ns#" term="applet" /><title>Java Applet and Java Web Start buttons</title><content type="html">&lt;p&gt;I want to say from the beginning that I'm not a designer and I never had such skills, but still I decided to make some buttons for Java Applet and Java Web Start. You can see below what I did:&lt;/p&gt;
&lt;p class="nostyle" style="text-align:center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-OnnPS2_ePK0/ThNpXYd8jKI/AAAAAAAAD48/dCP2O51S70k/s1600/java-applet-button.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="64" width="140" src="http://3.bp.blogspot.com/-OnnPS2_ePK0/ThNpXYd8jKI/AAAAAAAAD48/dCP2O51S70k/s400/java-applet-button.png" title="Java Applet Button" alt="Java Applet Button"/&gt;&lt;/a&gt;
&lt;span style="margin:5px;"&gt;&amp;nbsp;&lt;/span&gt;
&lt;a href="http://1.bp.blogspot.com/-DHqQb8T_Jck/ThNppH97iYI/AAAAAAAAD5E/iW-WbPTb3fk/s1600/java-web-start-button.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="64" width="140" src="http://1.bp.blogspot.com/-DHqQb8T_Jck/ThNppH97iYI/AAAAAAAAD5E/iW-WbPTb3fk/s400/java-web-start-button.png" title="Java Web Start Button" alt="Java Web Start Button"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The Java Coffee Cup logo is a registered trademark of Sun Microsystems, Inc. in the United States and other countries.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-457073964883297915?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5iBhIn5Jd_xhjnTWczkm7y0b4mQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5iBhIn5Jd_xhjnTWczkm7y0b4mQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5iBhIn5Jd_xhjnTWczkm7y0b4mQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5iBhIn5Jd_xhjnTWczkm7y0b4mQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=DYX2QOMUhI4:tbE5QK5H8Ks:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=DYX2QOMUhI4:tbE5QK5H8Ks:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=DYX2QOMUhI4:tbE5QK5H8Ks:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=DYX2QOMUhI4:tbE5QK5H8Ks:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=DYX2QOMUhI4:tbE5QK5H8Ks:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=DYX2QOMUhI4:tbE5QK5H8Ks:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/DYX2QOMUhI4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/457073964883297915/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/07/java-applet-and-java-web-start-buttons.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/457073964883297915?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/457073964883297915?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/DYX2QOMUhI4/java-applet-and-java-web-start-buttons.html" title="Java Applet and Java Web Start buttons" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-OnnPS2_ePK0/ThNpXYd8jKI/AAAAAAAAD48/dCP2O51S70k/s72-c/java-applet-button.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/07/java-applet-and-java-web-start-buttons.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AMSX4-fip7ImA9WhZaGEQ.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-7467673837539248762</id><published>2011-06-19T12:33:00.020+03:00</published><updated>2011-07-05T22:56:28.056+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-05T22:56:28.056+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jnlp" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="java web start" /><category scheme="http://www.blogger.com/atom/ns#" term="freemind" /><category scheme="http://www.blogger.com/atom/ns#" term="applet" /><category scheme="http://www.blogger.com/atom/ns#" term="mindmap" /><title>Export FreeMind mind map as Java Applet</title><content type="html">&lt;p&gt;&lt;a href="http://freemind.sourceforge.net/"&gt;FreeMind&lt;/a&gt; is a free &lt;a href="http://en.wikipedia.org/wiki/Mind_map"&gt;mind-mapping&lt;/a&gt; software written in Java. In this post I will show how to export FreeMind mind maps as Java Applet, describe issues which you can encounter during this process and give some hints on a how to better package exported mind maps.&lt;/p&gt;
&lt;p&gt;Let’s start with creating a test mind map. Suppose we have the following mind map:&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-iHJOlRrQdrI/Tf2zhd2jcLI/AAAAAAAAD38/8DBgBrE3sBg/s1600/test-partial-mm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="336" src="http://3.bp.blogspot.com/-iHJOlRrQdrI/Tf2zhd2jcLI/AAAAAAAAD38/8DBgBrE3sBg/s640/test-partial-mm.png" width="640" title="Test Mind Map" alt="Test Mind Map"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;FreeMind has plenty of options for exporting mind maps. For example the image which you see above was created using Export as PNG option (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File -&amp;gt; Export -&amp;gt; As PNG…&lt;/span&gt;). Your next question might be: Why to export mind maps as Java Applet if there are so many other options? Here is the answer. Even if FreeMind has many options for exporting mind maps, most of them are not suitable for publishing on the Internet (especially for big mind maps). Starting with FreeMind 0.9.0 two new export options were added: &lt;b&gt;Flash&lt;/b&gt; and &lt;b&gt;Java Applet&lt;/b&gt;. These two options can be used to bring mind maps into the Internet.&lt;/p&gt;
&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;The difference between these two is that Java Applet looks exactly like maps on the screen of FreeMind but needs longer to be loaded (This can be fixed by deploying the Java Applet using Java Web Start technology. I will describe how it can be done below.). Flash application is very fast but it has a totally different look and feel and &lt;i&gt;doesn’t support rich formatted text&lt;/i&gt;. You can see here how it looks like:&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-ojpML8IyY0s/Tf23qeiw9vI/AAAAAAAAD4U/BNQWPeECxH4/s1600/test-flash-mm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="598" src="http://4.bp.blogspot.com/-ojpML8IyY0s/Tf23qeiw9vI/AAAAAAAAD4U/BNQWPeECxH4/s640/test-flash-mm.png" width="640" title="Test Mind Map exported as Flash" alt="Test Mind Map exported as Flash"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;There a two ways for exporting mind maps as Java Applet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Using FreeMind export menu&lt;/b&gt;. Go to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File -&amp;gt; Export -&amp;gt; As Java Applet…&lt;/span&gt; and choose the destination file name, let’s say &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Test.html&lt;/span&gt;. After clicking OK go to the directory where you saved the file. You will see the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Test.html&lt;/span&gt; file and a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Test.html_files&lt;/span&gt; directory. Here, there is a small issue, at least in my case. In order to make it work, you have to edit Test.html file and specify the page title. Replace the tag &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;title/&amp;gt;&lt;/span&gt; with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;title&amp;gt;Test Mind Map&amp;lt;/title&amp;gt;&lt;/span&gt;. That’s it, save the file and open it in the browser. Now the applet should start.
You will find quickly that images which are used in the mind map itself (inserted using option &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Insert -&amp;gt; Image…&lt;/span&gt;) are not displayed by the applet. This is because images were not exported together with the map. In order to fix this you have to follow the following rules:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Store all the images used inside your mind map in one directory (e.g. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;files&lt;/span&gt; or &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;images&lt;/span&gt;) which is located in the same directory with mind map file (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;*.mm&lt;/span&gt;). This will ensure that all the paths to images are relative (e.g. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;files/image1.png&lt;/span&gt;).&lt;/li&gt;
&lt;li&gt;After the export, manually copy the directory with all the images used in your mind map to same location where mind map file (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;*.mm&lt;/span&gt;) resides. In our case &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Test.html_files&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Manually&lt;/b&gt;. As you can see from the previous option, there are many manual steps to do in order to make it work. Due to this you can consider to configure the FreeMind Browser Applet manually. This is not complicated at all. You can find preconfigured templates at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$FREEMIND_HOME/browse&lt;/span&gt; where &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$FREEMIND_HOME&lt;/span&gt; is the home directory of FreeMind. The only thing you have to change is the following line:
&lt;pre class="brush: html;"&gt;
&amp;lt;param name="browsemode_initial_map" value="./freemind.mm"&amp;gt;
&lt;/pre&gt;
Put your mind map file instead of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;freemind.mm&lt;/span&gt; and you are done. Also don’t forget about images. In case you are using images inside your mind map the procedure is the same one as described in previous topic.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now it’s time to deploy the Applet on Internet. First problem which you will encounter trying to deploy the Applet is what to do with the images. It’s not very comfortable to carry all these images one by one and upload them. In order to solve this problem, &lt;b&gt;we can package our mind map file (*.mm) together with all the images as one jar file&lt;/b&gt;. Run the following command inside the directory where mind map file is located (we assume that directory with images is located also there):&lt;/p&gt;
&lt;pre class="brush: text;"&gt;
jar –cvf test-mm-freemind.jar *
&lt;/pre&gt;
&lt;p&gt;After this, change the HTML applet tag as follows:&lt;/p&gt;
&lt;pre class="brush: html;"&gt;
&amp;lt;applet code="freemind.main.FreeMindApplet.class" width="100%" height="100%"
    archive="https://sites.google.com/site/azagorneanu/freemind/freemind-browser.jar,https://sites.google.com/site/azagorneanu/mm/test/test-mm-freemind.jar"&amp;gt;
  &amp;lt;param name="type" value="application/x-java-applet;version=1.4"&amp;gt;
  &amp;lt;param name="scriptable" value="false"&amp;gt;
  &amp;lt;param name="modes" value="freemind.modes.browsemode.BrowseMode"&amp;gt;
  &amp;lt;param name="browsemode_initial_map" value="jar:https://sites.google.com/site/azagorneanu/mm/test/test-mm-freemind.jar!/test.mm"&amp;gt;
  &amp;lt;param name="initial_mode" value="Browse"&amp;gt;
  &amp;lt;param name="selection_method" value="selection_method_direct"&amp;gt; 
  &amp;lt;p style="text-align:center;font-weight:bold;text-decoration:underline;"&amp;gt;
    FreeMind Browser Java Applet. You have to install Java Plug-in in order to see it.
  &amp;lt;/p&amp;gt;
&amp;lt;/applet&amp;gt;
&lt;/pre&gt;
&lt;p&gt;For including an Applet into a Google Sites page you can use Embed Gadget (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Insert -&amp;gt; More Gadgets -&amp;gt; Featured -&amp;gt; Embed Gadget&lt;/span&gt;) and paste the above snippet into.&lt;/p&gt;
&lt;p&gt;As I mentioned above it is possible to deploy FreeMind Browser Applet using Java Web Start. This can give you a speed boost in case you are experiencing problems with Applets. Doing this is very easy and requires only the configuration of one XML file with &lt;b&gt;JNLP (Java Network Launching Protocol)&lt;/b&gt; extension. Below you can see how &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test-mm-freemind.jnlp&lt;/span&gt; file looks like:&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;jnlp spec="1.0+" codebase="https://sites.google.com/site/azagorneanu/mm/test/" href="test-mm-freemind.jnlp"&amp;gt;
  &amp;lt;information&amp;gt;
    &amp;lt;title&amp;gt;Test FreeMind MindMap&amp;lt;/title&amp;gt;
    &amp;lt;vendor&amp;gt;FreeMind &amp;amp; Andrei Zagorneanu&amp;lt;/vendor&amp;gt;
    &amp;lt;description&amp;gt;Test MindMap by Andrei Zagorneanu&amp;lt;/description&amp;gt;
    &amp;lt;description kind="short"&amp;gt;
            Test FreeMind MindMap [http://freemind.sourceforge.net/]
            prepared by Andrei Zagorneanu [http://azagorneanu.blogspot.com/]
    &amp;lt;/description&amp;gt;
    &amp;lt;homepage href="http://azagorneanu.blogspot.com/"/&amp;gt;
    &amp;lt;icon href="https://sites.google.com/site/azagorneanu/freemind/freemind-icon.png" width="128" height="128"/&amp;gt;
  &amp;lt;/information&amp;gt;
  &amp;lt;resources&amp;gt;
    &amp;lt;j2se version="1.4+" /&amp;gt;
      &amp;lt;jar href="https://sites.google.com/site/azagorneanu/freemind/freemind-browser.jar" /&amp;gt;
      &amp;lt;jar href="https://sites.google.com/site/azagorneanu/mm/test/test-mm-freemind.jar" /&amp;gt;
  &amp;lt;/resources&amp;gt;
  &amp;lt;applet-desc name="FreeMind Browser" width="1200" height="700" main-class="freemind.main.FreeMindApplet"&amp;gt;
    &amp;lt;param name="type" value="application/x-java-applet;version=1.4" /&amp;gt;
    &amp;lt;param name="scriptable" value="false" /&amp;gt;
    &amp;lt;param name="modes" value="freemind.modes.browsemode.BrowseMode" /&amp;gt;
    &amp;lt;param name="browsemode_initial_map" value="jar:https://sites.google.com/site/azagorneanu/mm/test/test-mm-freemind.jar!/test.mm" /&amp;gt;
    &amp;lt;param name="initial_mode" value="Browse" /&amp;gt;
    &amp;lt;param name="selection_method" value="selection_method_direct" /&amp;gt;
  &amp;lt;/applet-desc&amp;gt;
&amp;lt;/jnlp&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, this file has to be uploaded along with other jar files and then used inside a link (anchor) as follows:&lt;/p&gt;
&lt;pre class="brush: html;"&gt;
&amp;lt;a href="/site/azagorneanu/mm/test/test-mm-freemind.jnlp"&amp;gt;Browse using Java Web Start&amp;lt;/a&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After clicking on link, choose &lt;b&gt;Open&lt;/b&gt; option or save the file to your computer and then open it. The FreeMind browser should start.&lt;/p&gt;
&lt;p&gt;Here &lt;a href="https://sites.google.com/site/azagorneanu/mm/test"&gt;https://sites.google.com/site/azagorneanu/mm/test&lt;/a&gt; you can find deployed both versions (Applet and Java Web Start) of our Test mind map.&lt;/p&gt;
&lt;p style="text-align:center"&gt;&lt;b&gt;You can browse Test Mind Map using one of the following:&lt;/b&gt;&lt;/p&gt;
&lt;p style="text-align:center" class="nostyle"&gt;
&lt;a href="https://sites.google.com/site/azagorneanu/mm/test/test-applet" target="_blank"&gt;&lt;img alt="Java Applet" src="https://sites.google.com/site/azagorneanu/images/java-applet-button.png" title="Java Applet" height="64" width="140"&gt;&lt;/a&gt;
&lt;span style="margin:5px"&gt;&amp;nbsp;&lt;/span&gt;
&lt;a href="https://sites.google.com/site/azagorneanu/mm/test/test-mm-freemind.jnlp?attredirects=0"&gt;&lt;img alt="Java Web Start" src="https://sites.google.com/site/azagorneanu/images/java-web-start-button.png" title="Java Web Start" height="64" width="140"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Make sure that you have installed Java Plug-in for your browser. In case your browser is 32-bit (x86) you have to install a version of Java also for 32-bit. For example for Firefox 4 you have to install a 32-bit version of Java. For a 64-bit browser you will need a 64-bit java. You can download latest java from &lt;a href="http://java.com/"&gt;http://java.com/&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-7467673837539248762?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pzZ3t6hDnbBb0b0LJgXpQkaHyaU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pzZ3t6hDnbBb0b0LJgXpQkaHyaU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pzZ3t6hDnbBb0b0LJgXpQkaHyaU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pzZ3t6hDnbBb0b0LJgXpQkaHyaU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=372DDC5nnYU:Z5YNmDrYSsE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=372DDC5nnYU:Z5YNmDrYSsE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=372DDC5nnYU:Z5YNmDrYSsE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=372DDC5nnYU:Z5YNmDrYSsE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=372DDC5nnYU:Z5YNmDrYSsE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=372DDC5nnYU:Z5YNmDrYSsE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/372DDC5nnYU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/7467673837539248762/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2011/06/export-freemind-mind-map-as-java-applet.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7467673837539248762?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7467673837539248762?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/372DDC5nnYU/export-freemind-mind-map-as-java-applet.html" title="Export FreeMind mind map as Java Applet" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-iHJOlRrQdrI/Tf2zhd2jcLI/AAAAAAAAD38/8DBgBrE3sBg/s72-c/test-partial-mm.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2011/06/export-freemind-mind-map-as-java-applet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8GRHwyfip7ImA9WhdTEkw.&quot;"><id>tag:blogger.com,1999:blog-8369030687505463576.post-7373928620152625542</id><published>2006-08-29T10:53:00.013+03:00</published><updated>2011-07-09T16:07:05.296+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-09T16:07:05.296+03:00</app:edited><title>Test</title><content type="html">Test&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8369030687505463576-7373928620152625542?l=azagorneanu.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zzu_WuoF2VLjFisFZTW0ntHVdy8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zzu_WuoF2VLjFisFZTW0ntHVdy8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zzu_WuoF2VLjFisFZTW0ntHVdy8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zzu_WuoF2VLjFisFZTW0ntHVdy8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=Smt3O1rX0yc:b7S9v5KigAw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=Smt3O1rX0yc:b7S9v5KigAw:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=Smt3O1rX0yc:b7S9v5KigAw:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=Smt3O1rX0yc:b7S9v5KigAw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/azagorneanu?a=Smt3O1rX0yc:b7S9v5KigAw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/azagorneanu?i=Smt3O1rX0yc:b7S9v5KigAw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/azagorneanu/~4/Smt3O1rX0yc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://azagorneanu.blogspot.com/feeds/7373928620152625542/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://azagorneanu.blogspot.com/2006/08/test.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7373928620152625542?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8369030687505463576/posts/default/7373928620152625542?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/azagorneanu/~3/Smt3O1rX0yc/test.html" title="Test" /><author><name>Andrei Zagorneanu</name><uri>https://profiles.google.com/113804023413479646909</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-ATfb_xNoiIg/AAAAAAAAAAI/AAAAAAAAD2I/YaTNU1UPlBY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://azagorneanu.blogspot.com/2006/08/test.html</feedburner:origLink></entry></feed>

