<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-599554868473356802</id><updated>2012-02-24T00:40:24.078-08:00</updated><category term='Mockito'/><category term='JPA'/><category term='JBoss'/><category term='MVC'/><category term='Java EE'/><category term='Subversion'/><category term='REST'/><category term='ActiveMQ'/><category term='Log4j'/><category term='Oracle'/><category term='JAAS'/><category term='Garbage Collector'/><category term='SOAP'/><category term='OpenMQ'/><category term='EJB'/><category term='Locking'/><category term='Maven'/><category term='JAXB'/><category term='Java SE'/><category term='SpEL'/><category term='JMS'/><category term='JAX-WS'/><category term='CDI'/><category term='JGeometry'/><category term='JUnit'/><category term='Spring'/><category term='Glassfish'/><category term='DBUnit'/><category term='Multithreading'/><category term='Android'/><title type='text'>Another Double Espresso Please!</title><subtitle type='html'>Random mutterings, but mainly reminders for myself, on all things Java,</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://city81.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>27</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3845161203783297622</id><published>2012-01-31T03:11:00.000-08:00</published><updated>2012-02-03T00:34:30.540-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>Parallel Processing with ForkJoinPool</title><content type='html'>With the release of Java 7 came the new Executor Service, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ForkJoinPool&lt;/span&gt;. The class uses the notion of work-stealing threads which execute tasks which have been created by other tasks. Ultimately, this division of work will result in large problems becoming a series of smaller ones which will eventually result in one answer when all the tasks have completed their processing. &lt;br /&gt;&lt;br /&gt;This post will demonstrate this new threading feature by&amp;nbsp;an interpolation example. In this case, for two numbers with a given number of steps, the code will attempt to construct new points between those numbers using linear interpolation, and for simplicity using only&amp;nbsp;a number of steps divisible by 2. eg for the numbers&amp;nbsp;5 and 25 with a step number of 4, the generated sequence would be:&lt;br /&gt;&lt;br /&gt;[&lt;strong&gt;5.0&lt;/strong&gt;, 10.0, 15.0, 20.0, &lt;strong&gt;25.0&lt;/strong&gt;]&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;InterpolationService&lt;/span&gt; class below will contain an instance of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ForkJoinPool&lt;/span&gt; class. A &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ForkJoinPool&lt;/span&gt; instance can be created with an argument representing a target parallelism. This can either be supplied or left as the default which will be the number of processors ie&amp;nbsp; &lt;code&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Runtime.availableProcessors()&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;package com.city81.forkjoin;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;import java.util.concurrent.ForkJoinPool;&lt;br /&gt;import java.util.concurrent.ForkJoinTask;&lt;br /&gt;import java.util.concurrent.RecursiveTask;&lt;br /&gt;&lt;br /&gt;public class InterpolateService {&lt;br /&gt;&lt;br /&gt;    private final ForkJoinPool forkJoinPool;&lt;br /&gt;&lt;br /&gt;    public InterpolateService() {&lt;br /&gt;        forkJoinPool = new ForkJoinPool();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;Double&amp;gt; interpolate(double valueOne, double valueTwo, int steps) {&lt;br /&gt;        &lt;br /&gt;        ForkJoinTask&amp;lt;List&amp;lt;Double&amp;gt;&amp;gt; job = forkJoinPool.submit(&lt;br /&gt;            new InterpolateTask(valueOne, valueTwo, steps));&lt;br /&gt;        return job.join();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static class InterpolateTask &lt;br /&gt;        extends RecursiveTask&amp;lt;List&amp;lt;Double&amp;gt;&amp;gt; {&lt;br /&gt;&lt;br /&gt;        private final double valueOne;&lt;br /&gt;        private final double valueTwo;&lt;br /&gt;        private final int steps;&lt;br /&gt;        private static final int LOWEST_STEP = 2;&lt;br /&gt;&lt;br /&gt;        protected InterpolateTask(double valueOne, double valueTwo, int steps) {&lt;br /&gt;&lt;br /&gt;            this.valueOne = valueOne;&lt;br /&gt;            this.valueTwo = valueTwo;&lt;br /&gt;            this.steps = steps;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        protected List&amp;lt;Double&amp;gt; compute() {&lt;br /&gt;    &lt;br /&gt;            List&amp;lt;Double&amp;gt; interpolatedArray = new ArrayList&amp;lt;Double&amp;gt;();&lt;br /&gt;            double interpolatedValue = interpolate(valueOne, valueTwo);&lt;br /&gt;    &lt;br /&gt;            if (this.steps == LOWEST_STEP) {&lt;br /&gt;                interpolatedArray.add(valueOne);&lt;br /&gt;                interpolatedArray.add(interpolatedValue);&lt;br /&gt;                interpolatedArray.add(valueTwo);&lt;br /&gt;            } else {&lt;br /&gt;                InterpolateTask interpolateTask1 = &lt;br /&gt;                    new InterpolateTask(valueOne, interpolatedValue, (steps/2));&lt;br /&gt;                interpolateTask1.fork();&lt;br /&gt;                InterpolateTask interpolateTask2 = &lt;br /&gt;                    new InterpolateTask(interpolatedValue, valueTwo, (steps/2));&lt;br /&gt;                List&amp;lt;Double&amp;gt; interpolatedArrayTask2 = &lt;br /&gt;                    interpolateTask2.compute();&lt;br /&gt;                List&amp;lt;Double&amp;gt; interpolatedArrayTask1 = &lt;br /&gt;                    interpolateTask1.join();&lt;br /&gt;                interpolatedArray.addAll(&lt;br /&gt;                    interpolatedArrayTask1.subList(0, interpolatedArrayTask1.size() - 1));&lt;br /&gt;                interpolatedArray.addAll(interpolatedArrayTask2);&lt;br /&gt;            }&lt;br /&gt;            // System.out.println(interpolatedArray);&lt;br /&gt;            return interpolatedArray;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private double interpolate(&lt;br /&gt;            double valueOne, double valueTwo) {&lt;br /&gt;   &lt;br /&gt;            return ((valueTwo - valueOne) / 2.0) + valueOne;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        InterpolateService interpolateService = new InterpolateService();&lt;br /&gt;        List&amp;lt;Double&amp;gt; interpolatedArray = interpolateService.interpolate(5,25,4);&lt;br /&gt;        System.out.println(interpolatedArray);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;InterpolationService&lt;/span&gt; 's only public method &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;interpolate&lt;/span&gt;, takes two numbers and the number of steps. These are the parameters to construct an instance of our private static class &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;InterpolateTask&lt;/span&gt;. This class implements &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;RecursiveTask&lt;/span&gt; which can return a result when the compute method is called on the task. An alternative implementation (but not suitable for this example) would be &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;RecursiveAction&lt;/span&gt; whose compute method returns nothing.&lt;br /&gt;&lt;br /&gt;The constructed task is submitted to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ForkJoinPool&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;compute&lt;/span&gt; method is where the logic for subdividing the task resides. It decides whether the work it has to process is small enough to process now or whether it needs further division. In the case of our example, the task will determine a task small enough when the step size is 2. If not, it will create two sub tasks, dividing the step size each time.&lt;br /&gt;&lt;br /&gt;Eventually, all tasks will be of a small enough size to be completed. This&amp;nbsp;will result in the arrays being added together as the recursive task tree is traversed back up to the original task.&lt;br /&gt;&lt;br /&gt;This is not example of how to efficiently perform linear interpolation on&amp;nbsp;a set of numbers but&amp;nbsp;is just one example implementation of how to use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ForkJoinPool&lt;/span&gt; and its associated Task classes. Over time, hopefully this post can be updated to make the above code more efficient as well gathering metrics and&amp;nbsp;benchmarking against&amp;nbsp;other implementations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3845161203783297622?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3845161203783297622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2012/01/parallel-processing-with-forkjoinpool.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3845161203783297622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3845161203783297622'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2012/01/parallel-processing-with-forkjoinpool.html' title='Parallel Processing with ForkJoinPool'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-5487728089738122459</id><published>2012-01-27T00:38:00.000-08:00</published><updated>2012-02-03T01:09:06.390-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring MVC and RESTful Web Services</title><content type='html'>This post is a follow up to the &lt;a href="http://city81.blogspot.com/2011/11/spring-mvc-bare-essentials-example.html" target="_blank"&gt;Spring MVC Bare Essentials&lt;/a&gt; post and shows how a simple RESTful web service can be implemented using Spring MVC. It'll also show the different ways in which the controller services can be implemented and how the model can be rendered. &lt;br /&gt;&lt;br /&gt;The post will use the same classes and XML files as in the Bare Essentials post but change them to make the methods expoed by the controller RESTful. &lt;br /&gt;&lt;br /&gt;First of all, the&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ExampleController&lt;/span&gt; class will change to use web bind annotations which will mark the class and the methods within it with URL paths. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@Controller&lt;br /&gt;@RequestMapping("/controller")&lt;br /&gt;public class ExampleController {&lt;br /&gt;&lt;br /&gt;    @RequestMapping(value="message", method=RequestMethod.GET)&lt;br /&gt;&lt;br /&gt;    public ModelAndView getMessage() {&lt;br /&gt;        Message message = new Message("Spring MVC Rest Example");&lt;br /&gt;        ModelAndView modelAndView = new ModelAndView(&lt;br /&gt;            "example", "message", message);&lt;br /&gt;        return modelAndView;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;web.xml&lt;/span&gt; below shows the changes to the servlet mapping tag and in particular the url-pattern. This means our URLs will be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;em&gt;http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;app name&amp;gt;/&lt;strong&gt;example&lt;/strong&gt;/&amp;lt;request mapping&amp;gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;    &amp;lt;servlet-name&amp;gt;springMVCRESTExample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;    &amp;lt;url-pattern&amp;gt;/example/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In &lt;span style="font-family: inherit;"&gt;the servlet's context&lt;/span&gt; XML file, we'll auto detect the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ExampleController&lt;/span&gt; bean by using &lt;span style="font-family: Courier New;"&gt;context:component-scan&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; and then add the&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt; &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;BeanNameViewResolver&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; to interpret a view name as a bean name.&amp;nbsp;Finally, add a&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MarshallingView&lt;/span&gt; &lt;span style="font-family: inherit;"&gt;which will use JAX-B to marshall and unmarshall the&lt;/span&gt; &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;com.city81.spring.mvc.rest.domain.Message &lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;&lt;span style="font-family: inherit;"&gt;class&lt;/span&gt;. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;context:component-scan base-package=&amp;quot;com.city81.spring.mvc.rest&amp;quot; /&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.view.BeanNameViewResolver&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;example&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.xml.MarshallingView&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;        &amp;lt;bean class=&amp;quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;property name=&amp;quot;classesToBeBound&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;list&amp;gt;&lt;br /&gt;                    &amp;lt;value&amp;gt;com.city81.spring.mvc.rest.domain.Message&amp;lt;/value&amp;gt;&lt;br /&gt;                &amp;lt;/list&amp;gt;&lt;br /&gt;            &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;    &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Building a WAR and deploying to a container such as Tomcat would then enable you call the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;getMessage&lt;/span&gt; method of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ExampleController&lt;/span&gt; class with the URL:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Courier New;"&gt;&lt;em&gt;http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;app name&amp;gt;/&lt;strong&gt;example/controller/message&lt;/strong&gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An alternative to implementing the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;getMessage&lt;/span&gt; method is to use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@ModelAttribute&lt;/span&gt; instead the the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ModelView&lt;/span&gt; class as shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@RequestMapping(value = "message", method = RequestMethod.GET)&lt;br /&gt;public @ModelAttribute("example") Message getMessage() {&lt;br /&gt;    Message message = new Message("Spring MVC Rest Example");&lt;br /&gt;    return message;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another alternative is to use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;lt;mvc:annotation-driven /&amp;gt;&lt;/span&gt; which was introduced in&amp;nbsp;Spring 3. By adding it to the servlet's context XML file (in place of the beans &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;BeanNameViewResolver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MarshallingView&lt;/span&gt;), the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;getMessage&lt;/span&gt; method can then be implemented as show below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@RequestMapping(value="message", method = RequestMethod.GET)&lt;br /&gt;public @ResponseBody Message getMessage() {&lt;br /&gt;    Message message = new Message("Spring MVC Rest Example");&lt;br /&gt;    return message;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a very simple example that can be built upon to use&amp;nbsp;different RESTful methods.&amp;nbsp;There are also different ways in which XML can be rendered in the view and also different types that can be rendered eg&amp;nbsp;text. It is also worth considering&amp;nbsp;Spring Roo&amp;nbsp;if wanting to implement&amp;nbsp;a RESTful web service.&amp;nbsp;These will&amp;nbsp;hopefully be covered in further posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-5487728089738122459?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/5487728089738122459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2012/01/spring-mvc-and-restful-web-services.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/5487728089738122459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/5487728089738122459'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2012/01/spring-mvc-and-restful-web-services.html' title='Spring MVC and RESTful Web Services'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-8930104209297325059</id><published>2012-01-19T08:11:00.000-08:00</published><updated>2012-02-03T06:37:09.488-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='JAX-WS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>Using Maven to Generate Wrapped or Non-Wrapped SOAP Bindings</title><content type='html'>For a given WSDL, there&amp;nbsp;are several different ways to generate Java web service code (CXF, Axis2, etc..). And depending on certain settings within the WSDL file and settings used by the relevant build tool, there are different ways of exposing those services described in the WSDL.&lt;br /&gt;&lt;br /&gt;This post will briefly document the generating of&amp;nbsp;Java code for a WSDL using Maven and the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;jaxws wsimport&lt;/span&gt; plugin. It will also show the difference in the services exposed when using wrapped and non-wrapped bindings.&lt;br /&gt;&lt;br /&gt;Below is an extract from a pom.xml to generate the Java code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;jaxws-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.10&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;executions&amp;gt;&lt;br /&gt;        &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;                &amp;lt;goal&amp;gt;wsimport&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;                &amp;lt;wsdlFiles&amp;gt;&lt;br /&gt;                    &amp;lt;wsdlFile&amp;gt;City81SOAPService.wsdl&amp;lt;/wsdlFile&amp;gt;&lt;br /&gt;                &amp;lt;/wsdlFiles&amp;gt;&lt;br /&gt;                &amp;lt;bindingDirectory&amp;gt;${basedir}/src/wsdl&amp;lt;/bindingDirectory&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;generate-sources&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;&lt;br /&gt;        &amp;lt;/execution&amp;gt;&lt;br /&gt;    &amp;lt;/executions&amp;gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;         .........            &lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;        &amp;lt;sourceDestDir&amp;gt;&lt;br /&gt;            ${project.build.directory}/generated-sources/jaxws-wsimport&lt;br /&gt;        &amp;lt;/sourceDestDir&amp;gt;&lt;br /&gt;        &amp;lt;xnocompile&amp;gt;true&amp;lt;/xnocompile&amp;gt;&lt;br /&gt;        &amp;lt;verbose&amp;gt;true&amp;lt;/verbose&amp;gt;&lt;br /&gt;        &amp;lt;extension&amp;gt;true&amp;lt;/extension&amp;gt;&lt;br /&gt;        &amp;lt;catalog&amp;gt;${basedir}/src/jax-ws-catalog.xml&amp;lt;/catalog&amp;gt;                  &lt;br /&gt;    &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the below WSDL file, the wsimport plugin will generate the following classes:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;com\city81\soap\Balance.java&lt;br /&gt;com\city81\soap\City81SOAP.java&lt;br /&gt;com\city81\soap\City81SOAPImplService.java&lt;br /&gt;com\city81\soap\CreateCustomer.java&lt;br /&gt;com\city81\soap\CreateCustomerResponse.java&lt;br /&gt;com\city81\soap\CreateCustomerResponseType.java&lt;br /&gt;com\city81\soap\CreateStatus.java&lt;br /&gt;com\city81\soap\ObjectFactory.java&lt;br /&gt;com\city81\soap\package-info.java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;&lt;br /&gt;&amp;lt;wsdl:definitions name="City81SOAPService" targetNamespace=http://soap.city81.com/ xmlns:ns1=http://schemas.xmlsoap.org/wsdl/soap/http&lt;br /&gt;xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://soap.city81.com/"&lt;br /&gt;xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;wsdl:types&amp;gt;&lt;br /&gt;        &amp;lt;xsd:schema&amp;gt;&lt;br /&gt;            &amp;lt;xsd:import namespace="http://soap.city81.com/" schemaLocation="City81SOAPService.xsd" /&amp;gt;&lt;br /&gt;        &amp;lt;/xsd:schema&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:types&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;wsdl:message name="createCustomer"&amp;gt;&lt;br /&gt;        &amp;lt;wsdl:part name="params" element="tns:createCustomer"&amp;gt;&amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;    &amp;lt;wsdl:message name="createCustomerResponse"&amp;gt;&lt;br /&gt;        &amp;lt;wsdl:part name="params" element="tns:createCustomerResponse"&amp;gt;&amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;wsdl:portType name="City81SOAP"&amp;gt;&lt;br /&gt;        &amp;lt;wsdl:operation name="createCustomer"&amp;gt;&lt;br /&gt;            &amp;lt;wsdl:input message="tns:createCustomer"&amp;gt;&amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;            &amp;lt;wsdl:output message="tns:createCustomerResponse"&amp;gt;&amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;        &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:portType&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;wsdl:binding name="City81SOAPImplServiceSoapBinding" type="tns:City81SOAP"&amp;gt;&lt;br /&gt;        &amp;lt;soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /&amp;gt;&lt;br /&gt;        &amp;lt;wsdl:operation name="createCustomer"&amp;gt;&lt;br /&gt;            &amp;lt;soap:operation soapAction="http://soap.city81.com/createCustomer" /&amp;gt;&lt;br /&gt;            &amp;lt;wsdl:input&amp;gt;&lt;br /&gt;                &amp;lt;soap:body use="literal" /&amp;gt;&lt;br /&gt;            &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;            &amp;lt;wsdl:output&amp;gt;&lt;br /&gt;                &amp;lt;soap:body use="literal" /&amp;gt;&lt;br /&gt;            &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;        &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:binding&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;wsdl:service name="City81SOAPImplService"&amp;gt;&lt;br /&gt;        &amp;lt;wsdl:port binding="tns:City81SOAPImplServiceSoapBinding" name="City81SOAPImplPort"&amp;gt;&lt;br /&gt;            &amp;lt;soap:address location=http://localhost:8080/city81-soap/soap /&amp;gt;&lt;br /&gt;        &amp;lt;/wsdl:port&amp;gt;&lt;br /&gt;    &amp;lt;/wsdl:service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/wsdl:definitions&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the above settings, the generated &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;City81SOAP&lt;/span&gt; class will be as below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@WebService(name = "City81SOAP", targetNamespace = "http://soap.city81.com/")&lt;br /&gt;@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)&lt;br /&gt;@XmlSeeAlso({&lt;br /&gt;    ObjectFactory.class&lt;br /&gt;})&lt;br /&gt;public interface City81SOAP {&lt;br /&gt;&lt;br /&gt;    @WebMethod(action = "http://soap.city81.com/createCustomer")&lt;br /&gt;    @WebResult(name = "createCustomerResponse", targetNamespace = "http://soap.city81.com/", partName = "params")&lt;br /&gt;    public CreateCustomerResponse createCustomer(@WebParam(name = "createCustomer", targetNamespace = "http://soap.city81.com/", partName = "params") CreateCustomer params);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The binding style as can be seen from the &lt;span style="font-family: Courier New;"&gt;@SOAPBinding&lt;/span&gt;&amp;nbsp;annotation&amp;nbsp;&amp;nbsp;at the head of the class is BARE ie non-wrapped. The method's&amp;nbsp;args and return parameters are in each case represented as a single Java object. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;CreateCustomer&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;CreateCustomerResponse&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This has happened because in the pom.xml file, there is a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;bindingDirectory&lt;/span&gt; tag which points to a folder containing a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;binding.xml&lt;/span&gt; file. This file, shown below, has an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;enableWrapperStyle&lt;/span&gt; tag and the boolean value of false. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;bindings&lt;br /&gt;    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"&lt;br /&gt;    wsdlLocation="City81SOAPService.wsdl"&lt;br /&gt;    xmlns="http://java.sun.com/xml/ns/jaxws"&amp;gt;&lt;br /&gt;        &amp;lt;!-- Disable default wrapper style --&amp;gt;&lt;br /&gt;        &amp;lt;enableWrapperStyle&amp;gt;false&amp;lt;/enableWrapperStyle&amp;gt;        &lt;br /&gt;&amp;lt;/bindings&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If the boolean was true, or if there was no &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;bindingDirectory&lt;/span&gt; tag in the pom.xml file, then the default SOAP binding style would be used ie &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;WRAPPED&lt;/span&gt;. This would then result in the below generated &lt;span style="font-family: Courier New;"&gt;City81SOAP&lt;/span&gt; class:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@WebService(name = "City81SOAP", targetNamespace = "http://soap.city81.com/")&lt;br /&gt;@XmlSeeAlso({&lt;br /&gt;    ObjectFactory.class&lt;br /&gt;})&lt;br /&gt;public interface City81SOAP {&lt;br /&gt;&lt;br /&gt;    @WebMethod(action = "http://soap.city81.com/createCustomer")&lt;br /&gt;    @RequestWrapper(localName = "createCustomer", targetNamespace = "http://soap.city81.com/", className = "com.city81.soap.CreateCustomer")&lt;br /&gt;    @ResponseWrapper(localName = "createCustomerResponse", targetNamespace = "http://soap.city81.com/", className = "com.city81.soap.CreateCustomerResponse")&lt;br /&gt;    public void createCustomer(&lt;br /&gt;&lt;br /&gt;        @WebParam(name = "surname", targetNamespace = "")&lt;br /&gt;        String surname,&lt;br /&gt;        @WebParam(name = "firstName", targetNamespace = "")&lt;br /&gt;        String firstName,&lt;br /&gt;        @WebParam(name = "balance", targetNamespace = "")&lt;br /&gt;        Balance balance,&lt;br /&gt;        @WebParam(name = "customerId", targetNamespace = "", mode = WebParam.Mode.OUT)&lt;br /&gt;        Holder&amp;lt;String&amp;gt; customerId,&lt;br /&gt;        @WebParam(name = "status", targetNamespace = "", mode = WebParam.Mode.OUT)&lt;br /&gt;        Holder&amp;lt;CreateStatus&amp;gt; status);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The&amp;nbsp;method's&amp;nbsp;args are now individual Java objects and the&amp;nbsp;return parameters are&amp;nbsp;each&amp;nbsp;represented as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Holder&lt;/span&gt; objects with a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;WebParam.Mode.OUT&lt;/span&gt; value denoting they are return objects.&amp;nbsp;This means that return objects are set as opposed to actually being returned in the method's signature.&lt;br /&gt;&lt;br /&gt;Another way to specify bindings&amp;nbsp;other than using the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;binding.xml&lt;/span&gt; file is to embed the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;enableWrapperStyle&lt;/span&gt; as a child of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;portType&lt;/span&gt; but if a WSDL is from a third party, then having to change it every time a new version of the WSDL is released is open to errors.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;wsdl:portType name="City81SOAPImplService"&amp;gt;&lt;br /&gt;    &amp;lt;jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"&amp;gt;&lt;br /&gt;        &amp;lt;jaxws:enableWrapperStyle&amp;gt;false&amp;lt;/jaxws:enableWrapperStyle&amp;gt;&lt;br /&gt;    &amp;lt;/jaxws:bindings&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;&amp;lt;/wsdl:portType&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Back to the generated interfaces, and these of course need to be implemented. For an interface with a binding type of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;BARE&lt;/span&gt;, the implemented class would look like below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@WebService(targetNamespace = "http://soap.city81.com/", name = "City81SOAP", portName = "City81SOAPImplPort", serviceName = "City81SOAPImplService")&lt;br /&gt;@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.BARE)&lt;br /&gt;public class City81SOAPImpl implements City81SOAP {    &lt;br /&gt;&lt;br /&gt;    @Override   &lt;br /&gt;    public CreateCustomerResponse createCustomer(CreateCustomer createCustomer) {      &lt;br /&gt;        CreateCustomerResponse createCustomerResponse = &lt;br /&gt;            new CreateCustomerResponse();     &lt;br /&gt;         .....&lt;br /&gt;        return createCustomerResponse;  &lt;br /&gt;    } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-java"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;In the case of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;WRAPPED&lt;/span&gt; binding style, the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;SOAPBinding&lt;/span&gt; annotation would include &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;parameterStyle = SOAPBinding.ParameterStyle.WRAPPED&lt;/span&gt; and the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;createCustomer&lt;/span&gt; method would be as below:&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    public void createCustomer(&lt;br /&gt;        String surname,&lt;br /&gt;        String firstName,&lt;br /&gt;        Balance balance,&lt;br /&gt;        Holder&amp;lt;String&amp;gt; customerId,&lt;br /&gt;        Holder&amp;lt;CreateStatus&amp;gt; status) {&lt;br /&gt;    &lt;br /&gt;        customerId= new Holder&amp;lt;String&amp;gt;(&amp;quot;1&amp;quot;);&lt;br /&gt;        status = new Holder&amp;lt;CreateStatus&amp;gt;(CreateStatus.CREATE_PENDING);&lt;br /&gt;    }   &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-java"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;This post shows that there are different ways to ultimately achieve the same result.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code-java"&gt;&lt;span style="font-family: Arial;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-8930104209297325059?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/8930104209297325059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2012/01/using-maven-to-generate-wrapped-or-non.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8930104209297325059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8930104209297325059'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2012/01/using-maven-to-generate-wrapped-or-non.html' title='Using Maven to Generate Wrapped or Non-Wrapped SOAP Bindings'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-6619215658171750595</id><published>2011-11-29T06:06:00.000-08:00</published><updated>2012-02-06T05:28:56.334-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JAXB'/><category scheme='http://www.blogger.com/atom/ns#' term='JAX-WS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>JAX-WS, JAXB and Generics</title><content type='html'>When&amp;nbsp; JAXB 2.1 came along it&amp;nbsp;introduced a new annotation namely &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@XmlSeeAlso&lt;/span&gt;. It resolved the problem where at&amp;nbsp;runtime, JAX-WS would only know&amp;nbsp;about classes&amp;nbsp;bound by JAXB and not&amp;nbsp;sub classes of those which have been bound. &lt;br /&gt;&lt;br /&gt;By using &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@XmlSeeAlso&lt;/span&gt; on a class, sub types of the bound class can be listed thereby allowing them to be bound also and therefore reachable by JAX-WS when marshalling and unmarshalling.&lt;br /&gt;&lt;br /&gt;It can also be used to overcome the problem of using generics in a JAXB annotated class as the following simple example will describe. Given the below &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;LogFile&lt;/span&gt; class, it will only be marshalled/unmarshalled if the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;T&lt;/span&gt; at runtime is bound. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@XmlRootElement&lt;br /&gt;@XmlAccessorType(XmlAccessType.FIELD)&lt;br /&gt;public class LogFile&amp;lt;T&amp;gt; {&lt;br /&gt;&lt;br /&gt;    @XmlElement(name="logFileLine")&lt;br /&gt;    private List&amp;lt;T&amp;gt; logFileLines;&lt;br /&gt;&lt;br /&gt;    public LogFile() {&lt;br /&gt;        logFileLines = new ArrayList&amp;lt;T&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public LogFile(List&amp;lt;T&amp;gt; logFileLines) {&lt;br /&gt;        this.logFileLines = logFileLines;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;T&amp;gt; getLogFileLines() {&lt;br /&gt;        return logFileLines;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setLogFileLines(List&amp;lt;T&amp;gt; logFileLines) {&lt;br /&gt;        this.logFileLines = logFileLines;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void addLogFileLine(T logFileLine) {&lt;br /&gt;        this.logFileLines.add(logFileLine);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;LogFile&lt;/span&gt; contains a collection of eg &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Strings&lt;/span&gt; then this will work fine but if &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;T&lt;/span&gt; is a class not bound, eg &lt;span style="font-family: Courier New;"&gt;com.city81.domain.LogLine&lt;/span&gt;&amp;nbsp;then an error similar to below will be thrown:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class com.city81.domain.LogLine nor any of its super class is known to this context.]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To resolve this, the class &lt;span style="font-family: Courier New;"&gt;LogLine &lt;/span&gt;needs to be included the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@XmlSeeAlso&lt;/span&gt; annotation.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;@XmlRootElement&lt;br /&gt;@XmlAccessorType(XmlAccessType.FIELD)&lt;br /&gt;@XmlSeeAlso(LogLine.class)&lt;br /&gt;public class LogFile&amp;lt;T&amp;gt; {&lt;br /&gt;&lt;br /&gt;    ....&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This does of course mean you need to know what potential classes can be T before runtime but at least it means you can use Generics on JAXB annotated classes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-6619215658171750595?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/6619215658171750595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/11/jax-ws-jaxb-and-generics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6619215658171750595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6619215658171750595'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/11/jax-ws-jaxb-and-generics.html' title='JAX-WS, JAXB and Generics'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-4045741450183322273</id><published>2011-11-17T20:09:00.000-08:00</published><updated>2012-02-06T05:40:45.778-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='SpEL'/><title type='text'>Using Spring Expression Language for Server Specific Properties</title><content type='html'>&lt;span style="font-family: inherit;"&gt;Spring&lt;/span&gt; 3.0 introduced &lt;strong&gt;Spring Expression Language&lt;/strong&gt; (SpEL). This post will describe how to use SpEL to load property files which are different for each server your application runs on. It also describes how&amp;nbsp;server specific properties can used without having to use -D.&lt;br /&gt;&lt;br /&gt;The problem solved was how can a WAR be deployed onto different servers without having to package up a&amp;nbsp;server specific property file in each archive (or indeed bundle them all in the same WAR file.) Ideally, you would want to drop the WAR file into any environment without having to configure the container or amend the WAR, and if you wanted to change a property, you would change&amp;nbsp;the property&amp;nbsp;file on the server and redeploy the app (or dynamically refresh the cache of properties.)&lt;br /&gt;&lt;br /&gt;In this example, our application needs to access a different remote server registry for each env:&amp;nbsp;Dev, Test and Prod. (For ease in this example, our server names are the same as our envionments!) &lt;br /&gt;&lt;br /&gt;Therefore we have a properties file for each env/server (dev.properties, test.properties and prod.properties). Could have a local.properties file on each server but prefixing them with a server name helps distinguish them. An example property file is shown below:&lt;br /&gt;&lt;br /&gt;rmiRegistryHost=10.11.12.13&lt;br /&gt;rmiRegistryPort=1099&lt;br /&gt;&lt;br /&gt;We have a bean which requires these properties, so it's constructor args contain property placeholders:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;bean id="lookupService" class="com.city81.rmi.LookupService" scope="prototype"&amp;gt;&lt;br /&gt;  &amp;lt;constructor-arg index="0" value="${rmiRegistryHost}" /&amp;gt; &lt;br /&gt;  &amp;lt;constructor-arg index="1" value="${rmiRegistryPort}" /&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the above bean to be loaded, the properties need to be loaded themselves and this is done via the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;PropertyPlaceholderConfigurer&lt;/span&gt; class. The location and name of the server specific property file is added as one of the locations the configurer uses to search for properties. &lt;br /&gt;&lt;br /&gt;The file is in the same location on each server but in order to know what the name is, SpEL is used. By creating a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;java.net.InetAddress&lt;/span&gt; bean, we can access the hostName of the server the application is running on by using SpEL ie &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;#{inetAddress.hostName}.&lt;/span&gt; Therefore, this config doesn't have to change between environments.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;inetAddress&amp;quot; class=&amp;quot;java.net.InetAddress&amp;quot; factory-method=&amp;quot;getLocalHost&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;bean id=&amp;quot;propertyBean&amp;quot; class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;ignoreResourceNotFound&amp;quot; value=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;ignoreUnresolvablePlaceholders&amp;quot; value=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;list&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;file:/home/city81/resources/#{inetAddress.hostName}.properties&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/list&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a very specific example where the property files are prefixed with the server names but it shows how SpEL can be used to solve a problem which would have taken a lot more work pre Spring 3.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-4045741450183322273?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/4045741450183322273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/11/using-spring-expression-language-for.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4045741450183322273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4045741450183322273'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/11/using-spring-expression-language-for.html' title='Using Spring Expression Language for Server Specific Properties'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-4579397201988620531</id><published>2011-11-16T00:17:00.000-08:00</published><updated>2012-02-06T06:01:43.527-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring MVC - A Bare Essentials Example Using Maven</title><content type='html'>Spring's MVC is a request based framework like Struts but it clearly separates the presentation, request handling and model layers.&lt;br /&gt;&lt;br /&gt;In this post, I'll describe how to get the most simple of examples up and running using Maven, therefore providing a basis upon which to&amp;nbsp;add more features of Spring MVC like handler mappings, complex controllers, commons validator etc..&lt;br /&gt;&lt;br /&gt;Let's start with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;pom.xml&lt;/span&gt; file. This will package up the project as a war file and only&amp;nbsp;requires three dependencies namely the artifacts &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&lt;span style="font-size: small;"&gt;spring-webmvc,&amp;nbsp;servlet-api&lt;/span&gt; &lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;and &lt;/span&gt;jstl&lt;/span&gt;&lt;/span&gt;. The&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt; &lt;span style="font-size: small;"&gt;spring-webmvc&lt;/span&gt;&lt;/span&gt; artifact will pull in all the other required spring jars like core, web, etc.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;com.city81&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;spring-mvc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;&lt;br /&gt;    &amp;lt;build&amp;gt;&lt;br /&gt;        &amp;lt;plugins&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;version&amp;gt;2.1-beta-1&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;        &amp;lt;/plugins&amp;gt;&lt;br /&gt;    &amp;lt;/build&amp;gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;3.0.5.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;optional&amp;gt;false&amp;lt;/optional&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;javax.servlet&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;servlet-api&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;2.5&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;javax.servlet&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;jstl&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;1.2&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the scope of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;servlet-api&lt;/span&gt; is provided and&amp;nbsp;therefore excluded from the war file. If deployed as part of the war, there'll be conflict with the servlet jar of the container, and there'll be an error similar to the one below when deploying to&amp;nbsp;Tomcat:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;INFO: Deploying web application archive spring-mvc-0.0.1-SNAPSHOT.war&lt;br /&gt;15-Nov-2011 16:05:27 org.apache.catalina.loader.WebappClassLoader validateJarFile&lt;br /&gt;INFO: validateJarFile(C:\apache-tomcat-6.0.33\webapps\spring-mvc-0.0.1-SNAPSHOT\WEB-INF\lib\servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section&lt;br /&gt;&amp;nbsp;9.7.2. Offending class: javax/servlet/Servlet.class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;web.xml&lt;/span&gt; located in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;/webapp/WEB-INF&lt;/span&gt; folder:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns="http://java.sun.com/xml/ns/javaee"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; version="2.5"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;display-name&amp;gt;Spring MVC Example&amp;lt;/display-name&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;springMVCExample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;springMVCExample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;*.htm&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;        &amp;lt;welcome-file&amp;gt;home.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The context loader is a listener class called&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ContextLoaderListener&lt;/span&gt;. By default this will load the config in the /&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;WEB-INF/applicationContext.xml&lt;/span&gt; but you can specify more files by adding a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;contextConfigLocation&lt;/span&gt; param and list one or more xml files. For example,&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;context-param&gt;&lt;br /&gt;    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;    &lt;param-value&gt;/WEB-INF/example-persistence.xml&lt;br /&gt;        /WEB-INF/example-security.xml&lt;/param-value&gt;&lt;/context-param&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;applicationContext.xml&lt;/span&gt; file isn't present when not using a context param list, then the WAR won't deploy properly. An example empty &lt;span style="font-family: Courier New;"&gt;applicationContext.xml&lt;/span&gt; is below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &lt;br /&gt; xmlns:aop="http://www.springframework.org/schema/aop"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/context &lt;br /&gt;    http://www.springframework.org/schema/context/spring-context.xsd&lt;br /&gt;    http://www.springframework.org/schema/util &lt;br /&gt;    http://www.springframework.org/schema/util/spring-util.xsd&lt;br /&gt;    http://www.springframework.org/schema/beans&lt;br /&gt;    http://www.springframework.org/schema/beans/spring-beans.xsd&lt;br /&gt;    http://www.springframework.org/schema/aop    &lt;br /&gt;    http://www.springframework.org/schema/aop/spring-aop.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The servlet's configuration does not need to be explicitly specified as it can be loaded by following the same naming convention of the servlet, in this case &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;springMVCExample-servlet.xml&lt;/span&gt;. The servlet is the front controller which delegates requests to other parts of the system. &lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;servlet-mapping&lt;/span&gt; tags in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;web.xml&lt;/span&gt; denote what URLs the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;DispatcherServlet&lt;/span&gt; will handle. In this example HTML.&lt;br /&gt;&lt;br /&gt;Also included in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;web.xml&lt;/span&gt;&amp;nbsp;by way of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: x-small;"&gt;&lt;span style="font-size: small;"&gt;welcome-file&lt;/span&gt;, &lt;/span&gt;is a default home page. This doesn't have to be included but the page can be used to forward a request as can be seen later in the post.&lt;br /&gt;&lt;br /&gt;As mentioned previously, the servlet's config is in it's own XML file. This describes the mapping between the a URL and the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Controller&lt;/span&gt; which will handle the request. It also contains the a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ViewResolver&lt;/span&gt; which maps the view name in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ModelAndView&lt;/span&gt; to an actual view.&amp;nbsp;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;springMVCExample-servlet.xml&lt;/span&gt; is shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans  &lt;br /&gt;    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean name="/example.htm" class="com.city81.spring.mvc.ExampleController"&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&amp;gt;&lt;br /&gt;        &amp;lt;property name="prefix"&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;/WEB-INF/jsp/&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;property name="suffix"&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;.jsp&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt; &lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ExampleController&lt;/span&gt; class is shown below. It extends &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AbstractController&lt;/span&gt; therefore must implement the method&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&lt;span style="font-size: small;"&gt;handleRequestInternal(HttpServletRequest request, HttpServletResponse response&lt;/span&gt;).&lt;/span&gt; The return value of this method is a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ModelAndView&lt;/span&gt; object. This object is constructed by passing in the view name (example), the model name (message) and the model object (in this case&amp;nbsp;a&amp;nbsp;String)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;package com.city81.spring.mvc;&lt;br /&gt;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;import org.springframework.web.servlet.ModelAndView;&lt;br /&gt;import org.springframework.web.servlet.mvc.AbstractController;&lt;br /&gt;&lt;br /&gt;public class ExampleController extends AbstractController {&lt;br /&gt;  &lt;br /&gt;    protected ModelAndView handleRequestInternal(&lt;br /&gt;        HttpServletRequest request, HttpServletResponse response) &lt;br /&gt;            throws Exception {&lt;br /&gt;        ModelAndView modelAndView = new ModelAndView(&amp;quot;example&amp;quot;, &amp;quot;message&amp;quot;, &amp;quot;Spring MVC Example&amp;quot;);&lt;br /&gt;&lt;br /&gt;        return modelAndView;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The view jsp will then have the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;${message}&lt;/span&gt; value populated by the model object from the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ModelAndView&lt;/span&gt;. The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;example.jsp&lt;/span&gt; is below and resides in the&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt; &lt;span style="font-size: small;"&gt;/webapp/WEB-INF/jsp&lt;/span&gt;&lt;/span&gt; folder:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;%@ page contentType=&amp;quot;text/html;charset=UTF-8&amp;quot; language=&amp;quot;java&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;c&amp;quot; uri=&amp;quot;http://java.sun.com/jsp/jstl/core&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;    &amp;lt;head&amp;gt;&lt;br /&gt;        &amp;lt;title&amp;gt;Spring MVC Example&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;/head&amp;gt;&lt;br /&gt;    &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;h2&amp;gt;Welcome to the Example Spring MVC page&amp;lt;/h2&amp;gt;&lt;br /&gt;        &amp;lt;h3&amp;gt;The message text is:&amp;lt;/h3&amp;gt;&lt;br /&gt;        &amp;lt;p&amp;gt;${message}&amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As mentioned previously, a default home page can included in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;web.xml&lt;/span&gt; and instead of displaying html&amp;nbsp;etc., it&amp;nbsp;can be used to redirect requests to another URL. The below &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;home.jsp&lt;/span&gt; redirects requests to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;example.htm&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;%@ page contentType=&amp;quot;text/html;charset=UTF-8&amp;quot; language=&amp;quot;java&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;c&amp;quot; uri=&amp;quot;http://java.sun.com/jsp/jstl/core&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;c:redirect url=&amp;quot;/example.htm&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Deploying the above to a container like Tomcat should result in a page like the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-OHk0hIDpHgY/TsKaqFXK6PI/AAAAAAAAAGQ/8rRT_NLDrI4/s1600/SpringMVC.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="201" nda="true" src="http://2.bp.blogspot.com/-OHk0hIDpHgY/TsKaqFXK6PI/AAAAAAAAAGQ/8rRT_NLDrI4/s400/SpringMVC.bmp" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This is just the very basics of Spring MVC but&amp;nbsp;later posts, will expand on the framework and show how it can be used with, for example, web services like REST.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-4579397201988620531?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/4579397201988620531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/11/spring-mvc-bare-essentials-example.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4579397201988620531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4579397201988620531'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/11/spring-mvc-bare-essentials-example.html' title='Spring MVC - A Bare Essentials Example Using Maven'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-OHk0hIDpHgY/TsKaqFXK6PI/AAAAAAAAAGQ/8rRT_NLDrI4/s72-c/SpringMVC.bmp' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-8475998810224371704</id><published>2011-10-13T08:14:00.000-07:00</published><updated>2012-02-06T08:36:44.122-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring, JMS, Listener Adapters and Containers</title><content type='html'>In order to receive JMS messages, Spring provides the concept of message listener containers. These are beans that can be tied to receive messages that arrive at certain destinations. This post will examine the different ways in which containers can be configured.&lt;br /&gt;&lt;br /&gt;A simple example is below where the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;DefaultMessageListenerContianer&lt;/span&gt; has been configured to watch one queue (the property &lt;span style="font-family: Courier New;"&gt;jms.queue.name&lt;/span&gt;) and has a reference to a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;myMessageListener&lt;/span&gt; bean which implements the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MessageListener&lt;/span&gt; interface (ie &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;onMessage&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"&amp;gt;&lt;br /&gt;    &amp;lt;property name="connectionFactory" ref="connectionFactory" /&amp;gt; &lt;br /&gt;    &amp;lt;property name="destinationName" value="${jms.queue.name}" /&amp;gt; &lt;br /&gt;    &amp;lt;property name="messageListener" ref="myMessageListener" /&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is all very well but means that the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;myMessageListener&lt;/span&gt; bean will have to handle the JMS Message object and process accordingly depending upon the type of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;javax.jms.Message&lt;/span&gt; and its payload. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;if (message instanceof MapMessage) {&lt;br /&gt;    // cast, get object, do something&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An alternative is to use a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MessageListenerAdapter&lt;/span&gt;. This class abstracts away the above processing and leaves your code to deal with just the message's payload. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"&amp;gt;&lt;br /&gt;    &amp;lt;property name="connectionFactory" ref="connectionFactory" /&amp;gt;&lt;br /&gt;    &amp;lt;property name="destinationName" value="${jms.queue.name}" /&amp;gt;&lt;br /&gt;    &amp;lt;property name="messageListener" ref="myMessageAdapter" /&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="myMessageAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"&amp;gt;&lt;br /&gt;    &amp;lt;property name="delegate" ref="myMessageReceiverDelegate" /&amp;gt;&lt;br /&gt;    &amp;lt;property name="defaultListenerMethod" value="processMessage" /&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The delegate is a reference to a &lt;span style="font-family: Courier New;"&gt;myMessageReceiverDelegate &lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;bean which has one or more methods called&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;processMessage&lt;/span&gt;. It &lt;strong&gt;does not&lt;/strong&gt; need to implement the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MessageListener&lt;/span&gt; interface. This method can be overload to handle different payload types. Spring behind the scenes will determine which gets called. For example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public void processMessage(final HashMap message) {&lt;br /&gt;    // do something&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void processMessage(final String message) {&lt;br /&gt;    // do something&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the given approach though, only one queue can be tied&amp;nbsp;to the&amp;nbsp;container. Another approach is to tie many listeners (therefore many queues) to the one container, The below Spring XML, using the jms namespace, shows how two listeners for different queues can be tied to one container:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;jms:listener-container container-type="default" &lt;br /&gt;  connection-factory="connectionFactory" acknowledge="auto"&amp;gt;  &lt;br /&gt;    &amp;lt;jms:listener destination="${jms.queue.name1}" ref="myMessageReceiverDelegate" method="processMessage" /&amp;gt;  &lt;br /&gt;    &amp;lt;jms:listener destination="${jms.queue.name2}" ref="myMessageReceiverDelegate" method="processMessage" /&amp;gt;  &lt;br /&gt;&amp;lt;/jms:listener-container&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;myMessageReceiverDelegate &lt;/span&gt;bean is treated as an adapter&amp;nbsp;delegate, therefore &lt;strong&gt;does not&lt;/strong&gt; need to implement the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MessageListener&lt;/span&gt; interface. Each listener can have a different delegate but for the above example, all messages arriving at the two queues are processed by the one receiver bean ie &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;myMessageReceiverDelegate&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If there is a need to check the message type and extract the payload, then the listener can use a class which implements the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MessageListener&lt;/span&gt; interface (eg the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;myMessageListener&lt;/span&gt; bean used in the first example). The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;onMessage&lt;/span&gt; method will then be called when messages arrive at the specified destination:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;jms:listener-container container-type=&amp;quot;default&amp;quot; &lt;br /&gt;  connection-factory=&amp;quot;connectionFactory&amp;quot; acknowledge=&amp;quot;auto&amp;quot;&amp;gt;  &lt;br /&gt;    &amp;lt;jms:listener destination=&amp;quot;${jms.queue.name1}&amp;quot; ref=&amp;quot;myMessageListener&amp;quot; /&amp;gt;  &lt;br /&gt;    &amp;lt;jms:listener destination=&amp;quot;${jms.queue.name2}&amp;quot; ref=&amp;quot;myMessageListener&amp;quot; /&amp;gt;  &lt;br /&gt;&amp;lt;/jms:listener-container&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-8475998810224371704?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/8475998810224371704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/10/spring-jms-listener-adapters-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8475998810224371704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8475998810224371704'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/10/spring-jms-listener-adapters-and.html' title='Spring, JMS, Listener Adapters and Containers'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-4210220446152093331</id><published>2011-09-16T02:31:00.000-07:00</published><updated>2012-02-07T00:21:12.893-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='ActiveMQ'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring JMS with ActiveMQ</title><content type='html'>ActiveMq is&amp;nbsp;a powerful open source messaging broker, and is very easy and straightforward to use with Spring as the below classes and XML will prove. The example below is the bar minimum needed to get up and running with transactions and message converters.&lt;br /&gt;&lt;br /&gt;On the sending side, the ActiveMq connection factory needs to be created with the url of the broker. This in turn is used to create the Spring JMS connection factory and as no session cache property is supplied the default cache is one. The template is then used in turn to create the Message Sender class:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:amq="http://activemq.apache.org/schema/core" &lt;br /&gt; xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xmlns:tx="http://www.springframework.org/schema/tx"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;br /&gt;  http://www.springframework.org/schema/beans/spring-beans.xsd  &lt;br /&gt;  http://activemq.apache.org/schema/core &lt;br /&gt;  http://activemq.apache.org/schema/core/activemq-core-5.5.0.xsd  &lt;br /&gt;  http://www.springframework.org/schema/context &lt;br /&gt;  http://www.springframework.org/schema/context/spring-context.xsd  &lt;br /&gt;  http://www.springframework.org/schema/jms &lt;br /&gt;  http://www.springframework.org/schema/jms/spring-jms.xsd&lt;br /&gt;  http://www.springframework.org/schema/tx&lt;br /&gt;  http://www.springframework.org/schema/tx/spring-tx.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Activemq connection factory --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg index="0" value="${jms.broker.url}"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- ConnectionFactory Definition --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg ref="amqConnectionFactory" /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!--  Default Destination Queue Definition--&amp;gt;&lt;br /&gt;    &amp;lt;bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg index="0" value="${jms.queue.name}"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- JmsTemplate Definition --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"&amp;gt;&lt;br /&gt;        &amp;lt;property name="connectionFactory" ref="connectionFactory" /&amp;gt;&lt;br /&gt;        &amp;lt;property name="defaultDestination" ref="defaultDestination" /&amp;gt; &lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Message Sender Definition --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="messageSender" class="com.city81.jms.MessageSender"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg index="0" ref="jmsTemplate" /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An example sending class is below. It uses the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;convertandSend&lt;/span&gt; method of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;JmsTemplate&lt;/span&gt; class. As there is no destination arg, the message will be sent to the default destination which was set up in the XML file:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;import java.util.Map;&lt;br /&gt;import org.springframework.jms.core.JmsTemplate;&lt;br /&gt;&lt;br /&gt;public class MessageSender {&lt;br /&gt;&lt;br /&gt;    private final JmsTemplate jmsTemplate;&lt;br /&gt;&lt;br /&gt;    public MessageSender(final JmsTemplate jmsTemplate) {&lt;br /&gt;        this.jmsTemplate = jmsTemplate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void send(final Map map) {&lt;br /&gt;        jmsTemplate.convertAndSend(map);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On the receiving side, there needs to be a listener container. The simplest example of this is the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;SimpleMessageListenerContainer&lt;/span&gt;. This requires a connection factory, a destination (or destination name) and a message listener. &lt;br /&gt;&lt;br /&gt;An example&amp;nbsp;of the Spring configuration for the receiving messages is below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:amq="http://activemq.apache.org/schema/core"&lt;br /&gt;&lt;br /&gt; xmlns:jms="http://www.springframework.org/schema/jms"&lt;br /&gt; xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;br /&gt;  http://www.springframework.org/schema/beans/spring-beans.xsd  &lt;br /&gt;  http://activemq.apache.org/schema/core &lt;br /&gt;  http://activemq.apache.org/schema/core/activemq-core-5.5.0.xsd  &lt;br /&gt;  http://www.springframework.org/schema/context &lt;br /&gt;  http://www.springframework.org/schema/context/spring-context.xsd  &lt;br /&gt;  http://www.springframework.org/schema/jms &lt;br /&gt;  http://www.springframework.org/schema/jms/spring-jms.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Activemq connection factory --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg index="0" value="${jms.broker.url}"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- ConnectionFactory Definition --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg ref="amqConnectionFactory" /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;  &lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Message Receiver Definition --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="messageReceiver" class="com.city81.jms.MessageReceiver"&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean class="org.springframework.jms.listener.SimpleMessageListenerContainer"&amp;gt;&lt;br /&gt;        &amp;lt;property name="connectionFactory" ref="connectionFactory" /&amp;gt;&lt;br /&gt;        &amp;lt;property name="destinationName" value="${jms.queue.name}" /&amp;gt;&lt;br /&gt;        &amp;lt;property name="messageListener" ref="messageReceiver" /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The listening/receiving class needs to extend &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;javax.jms.MessageListener&lt;/span&gt; and implement the onMessage method:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;import javax.jms.MapMessage;&lt;br /&gt;import javax.jms.Message;&lt;br /&gt;import javax.jms.MessageListener;&lt;br /&gt;&lt;br /&gt;public class MessageReceiver implements MessageListener {&lt;br /&gt;&lt;br /&gt;    public void onMessage(final Message message) {&lt;br /&gt;        if (message instanceof MapMessage) {&lt;br /&gt;            final MapMessage mapMessage = (MapMessage) message;&lt;br /&gt;            // do something&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;To then send a message would be as simple as getting the sending bean from the bean factory as shown&amp;nbsp;in the below code:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    MessageSender sender = (MessageSender) factory.getBean(&amp;quot;messageSender&amp;quot;);&lt;br /&gt;    Map map = new HashMap();&lt;br /&gt;    map.put(&amp;quot;Name&amp;quot;, &amp;quot;MYNAME&amp;quot;);&lt;br /&gt;    sender.send(map);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Will try to expand and build up JMS and Spring articles with examples of using transactions and other brokers like MQSeries.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-4210220446152093331?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/4210220446152093331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/09/spring-jms-with-activemq.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4210220446152093331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4210220446152093331'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/09/spring-jms-with-activemq.html' title='Spring JMS with ActiveMQ'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-1389375065548941854</id><published>2011-06-06T02:26:00.000-07:00</published><updated>2012-02-07T00:26:55.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='DBUnit'/><title type='text'>JUnit, DBUnit and Oracle</title><content type='html'>As previously blogged, DBUnit is a powerful addition to your unit test armoury. Having used it with Oracle, there are a few nuances which are worth writing about and therefore remembering!&lt;br /&gt;&lt;br /&gt;When creating a connection to an Oracle database, DBUnit will populate a Map of table names. By default these will not be prefixed with the schema name. As a result, you can get duplicate table names. An example of an exception raised for the duplicate table WWV_FLOW_DUAL100 is shown below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;org.dbunit.database.AmbiguousTableNameException: WWV_FLOW_DUAL100&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;at org.dbunit.dataset.OrderedTableNameMap.add(OrderedTableNameMap.java:198)&lt;br /&gt;&amp;nbsp;at org.dbunit.database.DatabaseDataSet.initialize(DatabaseDataSet.java:231)&lt;br /&gt;&amp;nbsp;at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:281)&lt;br /&gt;&amp;nbsp;at org.dbunit.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:80)&lt;br /&gt;&amp;nbsp;at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:140)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To resolve this, set the database config property &lt;strong&gt;FEATURE_QUALIFIED_TABLE_NAMES&lt;/strong&gt; to be true. This will make sure all tables in the Map are unique. As a consequence of this, the table names in the XML data file will need to be prefixed with the schema name.&lt;br /&gt;&lt;br /&gt;Another useful database config property is &lt;strong&gt;PROPERTY_DATATYPE_FACTORY&lt;/strong&gt;. In the XML data file, if there are dates with the time element set then the time element will be ignored unless the database config property &lt;strong&gt;PROPERTY_DATATYPE_FACTORY&lt;/strong&gt; is set to &lt;strong&gt;new Oracle10DataTypeFactory()&lt;/strong&gt; (or the equivalent data factory for the version of Oracle being used.)&lt;br /&gt;&lt;br /&gt;An example of setting these values in a @BeforeClass annotated JUnit method is shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;@BeforeClass&lt;br /&gt;public static void loadDataset() throws Exception {&lt;br /&gt;&lt;br /&gt;    // database connection&lt;br /&gt;    ResourceCache resourceCache = ResourceCache.getInstance();&lt;br /&gt;    String driverClassString = resourceCache.getProperty(&amp;quot;datasource.driver.class.name&amp;quot;);&lt;br /&gt;    String databaseURL = resourceCache.getProperty(&amp;quot;datasource.url&amp;quot;);&lt;br /&gt;    String username = resourceCache.getProperty(&amp;quot;test.datasource.username&amp;quot;);&lt;br /&gt;    String password = resourceCache.getProperty(&amp;quot;test.datasource.password&amp;quot;);&lt;br /&gt;&lt;br /&gt;    Class driverClass = Class.forName(driverClassString);&lt;br /&gt;    Connection jdbcConnection = DriverManager.getConnection(databaseURL, username, password);              &lt;br /&gt;    connection = new DatabaseConnection(jdbcConnection);&lt;br /&gt;    DatabaseConfig config = connection.getConfig();&lt;br /&gt;    config.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);&lt;br /&gt;    config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new Oracle10DataTypeFactory());         &lt;br /&gt;        &lt;br /&gt;    FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();&lt;br /&gt;    flatXmlDataSetBuilder.setColumnSensing(true);&lt;br /&gt;    dataset = flatXmlDataSetBuilder.build(Thread.currentThread()&lt;br /&gt;        .getContextClassLoader()&lt;br /&gt;        .getResourceAsStream(&amp;quot;Test-dataset.xml&amp;quot;));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-1389375065548941854?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/1389375065548941854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/06/junit-dbunit-and-oracle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/1389375065548941854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/1389375065548941854'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/06/junit-dbunit-and-oracle.html' title='JUnit, DBUnit and Oracle'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-6495638785945057444</id><published>2011-05-04T05:42:00.000-07:00</published><updated>2012-02-07T00:56:14.961-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JGeometry'/><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Using Spring's StoredProcedure class with Oracle Spatial JGeometry</title><content type='html'>The Spring framework provides a neat wrapper class you can extend when you want to call a stored procedure. Sometimes though you need to extend to use a native connection because, for example, you need to pass an ORACLE Geometry type to the stored procedure.&lt;br /&gt;&lt;br /&gt;The below code wraps a Create_Geometry_Line stored procedure which takes&amp;nbsp;a geometry object. The calling code will use the executeMap method to pass in a&amp;nbsp;Map of in parameters. It converts the list of doubles (which represent the points of the line) to an object of type STRUCT.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;package uk.co.city81.persistence.dao.geometry;&lt;br /&gt;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;import java.sql.Types;&lt;br /&gt;import java.util.Map;&lt;br /&gt;&lt;br /&gt;import oracle.jdbc.OracleTypes;&lt;br /&gt;import oracle.spatial.geometry.JGeometry;&lt;br /&gt;import oracle.sql.STRUCT;&lt;br /&gt;&lt;br /&gt;import org.springframework.dao.DataAccessException;&lt;br /&gt;import org.springframework.jdbc.core.JdbcTemplate;&lt;br /&gt;import org.springframework.jdbc.core.SqlOutParameter;&lt;br /&gt;import org.springframework.jdbc.core.SqlParameter;&lt;br /&gt;import org.springframework.jdbc.object.StoredProcedure;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class CreateGeometryLineDAO extends StoredProcedure {&lt;br /&gt;&lt;br /&gt;    private Connection nativeConn = null;&lt;br /&gt;&lt;br /&gt;    public static final String CREATE_GEOMETRY_LINE = "geometry_pkg.Create_Geometry_Line";&lt;br /&gt;&lt;br /&gt;    // Constructor&lt;br /&gt;    public CreateGeometryLineDAO(JdbcTemplate jdbcTemplate) {&lt;br /&gt;        setJdbcTemplate(jdbcTemplate);&lt;br /&gt;        setFunction(true);&lt;br /&gt;        setSQL();&lt;br /&gt;        declareParameter(new SqlOutParameter("l_Return", Types.INTEGER));&lt;br /&gt;        declareInParameters();&lt;br /&gt;        declareOutParameters();&lt;br /&gt;        compile();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Get the native connection&lt;br /&gt;    protected Connection getNativeConn() throws SQLException {  &lt;br /&gt;        if ((nativeConn == null) || nativeConn.isClosed()) {&lt;br /&gt;            nativeConn = this.getJdbcTemplate().getNativeJdbcExtractor()&lt;br /&gt;                .getNativeConnection(this.getJdbcTemplate()&lt;br /&gt;                .getDataSource().getConnection());&lt;br /&gt;        }&lt;br /&gt;        return nativeConn;   &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void declareInParameters() {&lt;br /&gt;        declareParameter(new SqlParameter("p_geom_data",OracleTypes.STRUCT)); &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void declareOutParameters() {&lt;br /&gt;        // declare out params&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void setSQL() {&lt;br /&gt;        setSql(CREATE_GEOMETRY_LINE);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Execute the stored procedure&lt;br /&gt;     * &lt;br /&gt;     * @param inParamMap a map of the stored procedure parameters&lt;br /&gt;     */&lt;br /&gt;    public Map executeMap(Map inParamMap) {&lt;br /&gt;        Map outParamMap = null;&lt;br /&gt;        try {  &lt;br /&gt;            if (inParamMap.get("p_geom_data") != null) {&lt;br /&gt;                java.util.List&amp;lt;Double&amp;gt; ordinates &lt;br /&gt;                    = (java.util.List&amp;lt;Double&amp;gt;) inParamMap.get("p_geom_data");&lt;br /&gt;                double[] ordinateDoubles = new double[ordinates.size()];&lt;br /&gt;                int count = 0;&lt;br /&gt;                for (Double ordinate : ordinates) {&lt;br /&gt;                    ordinateDoubles[count] = ordinate.doubleValue();&lt;br /&gt;                    count++;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                int[] elemInfo = new int[]{1,2,1};&lt;br /&gt;                JGeometry j_geom = new JGeometry(&lt;br /&gt;                    JGeometry.GTYPE_CURVE,8307, elemInfo,ordinateDoubles);        &lt;br /&gt;                STRUCT obj = JGeometry.store(j_geom, getNativeConn());&lt;br /&gt;                inParamMap.put("p_geom_data", obj);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            outParamMap = super.execute(inParamMap);&lt;br /&gt;&lt;br /&gt;        } catch (DataAccessException daex) {&lt;br /&gt;            // throw exception&lt;br /&gt;        } catch (SQLException e) {&lt;br /&gt;            // throw exception&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return outParamMap;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The jdbcTemplate can be injected into the DAO's constructor. The extracts from the context xml are below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;datasource&amp;quot; class=&amp;quot;org.springframework.jdbc.datasource.DriverManagerDataSource&amp;quot; &lt;br /&gt;        destroy-method=&amp;quot;close&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;driverClassName&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;oracle.jdbc.OracleDriver&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;url&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;jdbc:oracle:thin:@server:port:db&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;username&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;username&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;password&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;password&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;nativeJdbcExtractor&amp;quot; class=&amp;quot;org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor&amp;quot; &lt;br /&gt;      lazy-init=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jdbcTemplate&amp;quot; class=&amp;quot;org.springframework.jdbc.core.JdbcTemplate&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;dataSource&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;ref bean=&amp;quot;datasource&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;nativeJdbcExtractor&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;ref bean=&amp;quot;nativeJdbcExtractor&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;createGeometryLineDAO&amp;quot; class=&amp;quot;uk.co.city81.persistence.dao.geometry.CreateGeometryLineDAO&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg ref=&amp;quot;jdbcTemplate&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-6495638785945057444?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/6495638785945057444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/05/using-springs-storedprocedure-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6495638785945057444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6495638785945057444'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/05/using-springs-storedprocedure-class.html' title='Using Spring&apos;s StoredProcedure class with Oracle Spatial JGeometry'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3378072465381562476</id><published>2011-04-15T02:31:00.000-07:00</published><updated>2012-02-07T01:16:05.753-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='JAAS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>JAAS, EJB Security and Glassfish</title><content type='html'>With EJBs you can specify security by using annotations from the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;javax.annotation.security&lt;/span&gt; package. The below article describes how to setup security on a bean and access the methods of the bean via an annotation or via JAAS which has been setup on Glassfish.&lt;br /&gt;&lt;br /&gt;The below bean class only allows the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MANAGER&lt;/span&gt; role access to use the services exposed. In this case, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;findCustomerByAccountNumber.&lt;/span&gt; (The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AccessRoles.MANAGER&lt;/span&gt; resolves to a string so if the string changes the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;CustomerServiceBean&lt;/span&gt; doesn't have to change.)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@RolesAllowed(AccessRoles.MANAGER)&lt;br /&gt;@Stateless(mappedName = JndiResourceName.CUSTOMER_SERVICE)&lt;br /&gt;@Remote(CustomerService.class)&lt;br /&gt;public class CustomerServiceBean implements CustomerService {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Customer findCustomerByAccountNumber(String accountNumber) {&lt;br /&gt;        Customer customer = null;&lt;br /&gt;        // do stuff to find customer&lt;br /&gt;        return customer;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To call the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;findCustomerByAccountNumber&lt;/span&gt;, the code can use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@RunAs &lt;/span&gt;annotation as described below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;    @RunAs(AccessRoles.MANAGER)&lt;br /&gt;    public void verifyCustomer(String accountNumber) {&lt;br /&gt;        // do stuff &lt;br /&gt;        Customer customer = &lt;br /&gt;            customerService.findCustomerByAccountNumber(String accountNumber);&lt;br /&gt;        // do more stuff &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But what if the roles calling the verify method can vary ie &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;MANAGERS, OPERATORS, ADMIN.&lt;/span&gt; In this scenario, we would want to authenticate the 'caller' before accessing the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;findCustomerByAccountNumber&lt;/span&gt; method. A solution to this would be to use JAAS (Java Authentication and Authorization Service.)&lt;br /&gt;&lt;br /&gt;The principal of this is to create realms and have users and groups in the realm. There are a few steps involved which are described as follows:&lt;br /&gt;&lt;br /&gt;Firstly, the app server (in this example Glassfish) needs to create a realm and the below describes how to do this using the command line. It assumes connection pools, user and group database tables have been created and populated, and that the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;flexiblejdbcrealm-0.4.jar &lt;/span&gt;is in the Glassfish lib dir:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;asadmin --host&amp;nbsp; delete-auth-realm customer-realm&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;asadmin --host&amp;nbsp; create-auth-realm --classname=org.wamblee.glassfish.auth.FlexibleJdbcRealm --property="jaas.context=customerJdbcRealm:datasource.jndi=&lt;br /&gt;jdbc/Customer:sql.password=select password from customeruser where username\=?:sql.groups=select g.groupname from customergroup g inner join user_group ug on g.id\=ug.group_id inner join customeruser u on ug.user_id\=u.id where u.username\=?:password.digest=MD5:password.encoding=BASE64" customer-realm&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;asadmin --host&amp;nbsp; --user admin set server-config.security-service.activate-default-principal-to-role-mapping=true&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;asadmin --host&amp;nbsp; set-log-level javax.enterprise.system.core.security=INFO&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;asadmin --host&amp;nbsp; set-log-level org.wamblee.glassfish.auth=INFO&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;login.conf &lt;/span&gt;needs to have the below added to it:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;customerJdbcRealm {com.mypackage.auth.CustomerLoginModule required;}&lt;/div&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;CustomerLoginModule&lt;/span&gt; class extends &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;FlexibleJdbcLoginModule &lt;/span&gt;and gives us the ability to intercept the login/authentication calls if we so wish. In this case, any login exceptions are being logged:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class CustomerLoginModule extends FlexibleJdbcLoginModule implements LoginModule {&lt;br /&gt;&lt;br /&gt;    private static final Logger SECURITY_LOGGER = Logger.getLogger("com.mypackage");&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void authenticate() throws javax.security.auth.login.LoginException {&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            super.authenticate();&lt;br /&gt;        } catch(LoginException le){&lt;br /&gt;            SECURITY_LOGGER.error("Authentication failed for " &lt;br /&gt;                + _username + ". " + le.getMessage());&lt;br /&gt;            throw le;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can now change the verify method to authenticate before calling the 'secure'&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;findCustomerByAccountNumber&lt;/span&gt; method:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    private ProgrammaticLoginInterface programmaticLogin = &lt;br /&gt;        new ProgrammaticLogin();&lt;br /&gt;&lt;br /&gt;    public void verifyCustomer(String accountNumber) {&lt;br /&gt;        Customer customer = null;&lt;br /&gt;        boolean loginSuccessful = programmaticLogin.login(&amp;quot;manager&amp;quot;, &amp;quot;password&amp;quot;, &amp;quot;customer-realm&amp;quot;, true);  &lt;br /&gt;&lt;br /&gt;        if (loginSuccessful) { &lt;br /&gt;            customer = customerService.findCustomerByAccountNumber(String accountNumber);&lt;br /&gt;        } else {&lt;br /&gt;            // throw exception &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The call to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ProgrammaticLogin&lt;/span&gt; instance attempts to use the supplied name and password directly to login to the current realm. If successful, a security context is created for that user and is used by the EJB when checking what roles are allowed to call it.&lt;br /&gt;&lt;br /&gt;For example purposes, the above &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;verifyCustomer&lt;/span&gt; method has the name and password hard coded but in reality these values could be obtained from a login web page or other such authentication mechanisms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3378072465381562476?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3378072465381562476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/04/jaas-ejb-security-and-glassfish.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3378072465381562476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3378072465381562476'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/04/jaas-ejb-security-and-glassfish.html' title='JAAS, EJB Security and Glassfish'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-2830853819488088950</id><published>2011-03-31T04:10:00.000-07:00</published><updated>2012-02-07T03:01:17.717-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>Portable Global JNDI Names and Maven</title><content type='html'>With the advent of the EJB 3.1 specification, the JNDI names for session beans have become portable via the java:global namespace. &lt;br /&gt;&lt;br /&gt;As described on the Glassfish EJB FAQ page (&lt;a href="http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#What_is_the_syntax_for_portable_global_"&gt;http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#What_is_the_syntax_for_portable_global_&lt;/a&gt;) the syntax for the global namespace is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;java:global[/&amp;lt;app-name&amp;gt;]/&amp;lt;module-name&amp;gt;/&amp;lt;bean-name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where the app-name is the ear name (if the app is deployed as an ear), the module-name the ejb jar or war name and the bean-name the session bean name. Note that names are unqualified and minus the extension.&lt;br /&gt;&lt;br /&gt;Given the syntax an example of using the portable JNDI name using the @EJB annotation would be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@EJB(lookup=&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "java:global/customer-ear/customer-1-0-0/CustomerServiceBean")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The JNDI name may now be portable but the above code would not be reusable if the customer jar name changed. It is quite often the case that jars will have versions in their name eg &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;customer-1-0-0.jar&lt;/span&gt; and you would not want to change your code everytime there was a new release of the customer jar so you need to change the module name in the lookup.&lt;br /&gt;&lt;br /&gt;One option would be to rename the jar when building the ear file so the module name defaults to the jar name. To do this in Maven would be to explicitly add the ejbModule to the ear plugin as shown below. The name of the jar is what is specified in the bundleFileName tag.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;    &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;maven-ear-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;2.4&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;configuration&amp;gt;&lt;br /&gt;            &amp;lt;generateApplicationXml&amp;gt;true&amp;lt;/generateApplicationXml&amp;gt;&lt;br /&gt;            &amp;lt;archive&amp;gt;&lt;br /&gt;                &amp;lt;manifest&amp;gt;&lt;br /&gt;                    &amp;lt;addClasspath&amp;gt;true&amp;lt;/addClasspath&amp;gt;&lt;br /&gt;                &amp;lt;/manifest&amp;gt;&lt;br /&gt;            &amp;lt;/archive&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;6&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;defaultLibBundleDir&amp;gt;lib&amp;lt;/defaultLibBundleDir&amp;gt;&lt;br /&gt;            &amp;lt;earSourceDirectory&amp;gt;resources&amp;lt;/earSourceDirectory&amp;gt;&lt;br /&gt;            &amp;lt;modules&amp;gt;&lt;br /&gt;                &amp;lt;ejbModule&amp;gt;&lt;br /&gt;                    &amp;lt;groupId&amp;gt;com.mybank.customer&amp;lt;/groupId&amp;gt;&lt;br /&gt;                    &amp;lt;artifactId&amp;gt;customer-server&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                    &amp;lt;bundleFileName&amp;gt;customer.jar&amp;lt;/bundleFileName&amp;gt;&lt;br /&gt;                &amp;lt;/ejbModule&amp;gt;&lt;br /&gt;            &amp;lt;/modules&amp;gt;&lt;br /&gt;        &amp;lt;/configuration&amp;gt;&lt;br /&gt;    &amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The lookup would then be as below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@EJB(lookup=&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "java:global/customer-ear/customer/CustomerServiceBean")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means the code containing the injection point doesn't have to change with the names of the jars.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-2830853819488088950?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/2830853819488088950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/portable-global-jndi-names-and-maven.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2830853819488088950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2830853819488088950'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/portable-global-jndi-names-and-maven.html' title='Portable Global JNDI Names and Maven'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-1679610837709293357</id><published>2011-03-31T04:09:00.000-07:00</published><updated>2011-03-31T04:11:08.531-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>Java Collections and Threading</title><content type='html'>In the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.util.concurrent&lt;/span&gt; package, there exist several collection classes which aid the development of thread safe code. Below is a brief overview of the five most useful classes and a comparison of them with the some collection that exist in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.util&lt;/span&gt; package.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentHashMap&amp;lt;K,V&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.util.HashMap&lt;/span&gt; is a collection which holds key value pairs but it is not synchronised. If multiple threads are accessing such a collection, the keys and values being put into the collection may not be visible to those threads calling get. A solution would be to create a synchronised version by calling the static method &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Collections.synchronizedMap()&lt;/span&gt; but this would 'lock' all operations on the Map.&lt;br /&gt;&lt;br /&gt;Another solution would be to use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentHashMap&amp;lt;K,V&amp;gt;&lt;/span&gt;. The idea behind this class is that only the bucket that holds the data being accessed is 'locked'. This allows (more often than not) the get operation to work without blocking. Note that using an iterator obtained from the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentHashMap&lt;/span&gt; will not reflect map modifications since getting the iterator. Therefore the iterator will not throw &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentModificationException&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentSkipListMap&amp;lt;K,V&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.util.concurrent.ConcurrentSkipListMap&lt;/span&gt; offers similar functionality to the above class but it maintains a sorted order (either the natural order or the order based on using a Comparator.) It also provides methods like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ceilingKey&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;lowerEntry&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tailMap&lt;/span&gt;. Because of the ordering, insertion can be slower than that of a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentHashMap&lt;/span&gt; but iterating over the collection would be faster.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentSkipListSet&amp;lt;E&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Similar to the above but is a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;NavigableSet&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CopyOnWriteArrayList&amp;lt;E&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.util.ArrayList&lt;/span&gt; is a collection which holds a resizable list of entries but it is not synchronised. As with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentHashMap&lt;/span&gt;, a solution would be to create a synchronised version by calling the static method &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Collections.synchronizedList()&lt;/span&gt; but this would 'lock' all operations on the List. Another solution would be to use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CopyOnWriteArrayList&amp;lt;E&amp;gt;&lt;/span&gt; and this is best suited to lists where reads are frequent and writes are infrequent. It works by making a change to a copy of the list and then replacing the existing list with the modified copy.. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CopyOnWriteArraySet&amp;lt;E&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Similar to the above but is a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Set&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-1679610837709293357?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/1679610837709293357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/java-collections-and-threading.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/1679610837709293357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/1679610837709293357'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/java-collections-and-threading.html' title='Java Collections and Threading'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3897586958577923478</id><published>2011-03-25T07:36:00.000-07:00</published><updated>2012-02-07T03:07:59.566-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>Thread-safe and lock free variables</title><content type='html'>The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;java.util.concurrent.atomic&lt;/span&gt; package contains classes which aim to ease concurrency concerns in multithreaded applications. They offer better performance than using synchronisation because its operations on fields do not require locking.&lt;br /&gt;&lt;br /&gt;The classes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicBoolean, AtomicInteger, AtomicLong&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicReference&lt;/span&gt; enable the primitives &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;boolean&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;int, long&lt;/span&gt; and an object reference to be atomically updated. They all provide utility methods like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;compareAndSet&lt;/span&gt; which takes an expected value and the update value and returns false if the expected value doesn't equal (==) the current value. The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicInteger&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicLong&lt;/span&gt; classes also provide atomic pre and post decrement/increment methods like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;getAndIncrement&lt;/span&gt; or &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;incrementAndGet&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;An example use of one of the 'scalar' atomic classes is shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class IdentifierGenerator {&lt;br /&gt;&lt;br /&gt;    private AtomicLong seed = new AtomicLong(0);&lt;br /&gt;&lt;br /&gt;    public long getNextIdentifier() {&lt;br /&gt;        return seed.getAndIncrement();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;int&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;long&lt;/span&gt; primitives, and also object references can be held in arrays where the elements are atomically updated namely &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicIntegerArray&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicLongArray&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicReferenceArray&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;There also exists field updater classes namely &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicIntegerFieldUpdater&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicLongFieldUpdater&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;AtomicReferenceFieldUpdater&lt;/span&gt;. With these classes you can still use the methods on the class but use the updater class to manage the field that requires atomic access via methods like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;compareAndSet&lt;/span&gt;. Note that because of this, atomcity isn't guaranteed. &lt;br /&gt;&lt;br /&gt;These are abstract classes and the below (contrived!) example shows how an instance would be created:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    public void setBalance(Customer customer, int exisitngBalance, &lt;br /&gt;        int newBalance) {&lt;br /&gt;&lt;br /&gt;        AtomicIntegerFieldUpdater&amp;lt;Customer&amp;gt; balanceAccessor &lt;br /&gt;            = AtomicIntegerFieldUpdater.newUpdater(&lt;br /&gt;        Customer.class, &amp;quot;balance&amp;quot;); &lt;br /&gt;        balanceAccessor.compareAndSet(customer, exisitngBalance, newBalance);&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3897586958577923478?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3897586958577923478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/thread-safe-and-lock-free-variables.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3897586958577923478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3897586958577923478'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/thread-safe-and-lock-free-variables.html' title='Thread-safe and lock free variables'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3892049326890521470</id><published>2011-03-24T04:57:00.000-07:00</published><updated>2011-03-24T07:22:56.700-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Garbage Collector'/><title type='text'>Weak and Soft References and the Garbage Collector</title><content type='html'>&lt;span lang="EN"&gt;Java uses the Garbage Collector to manage memory. It does this by freeing up memory no longer needed by the application ie memory used by objects that are not referenced anymore, in other words, objects that are ‘unreachable’.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span lang="EN"&gt;&lt;/span&gt;&lt;span lang="EN"&gt;Typically, objects are strongly referenced so they remain in memory until no longer reachable, &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span lang="EN"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Customer customer = new Customer(); &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;but there are certain scenarios where you’d want to keep references to objects and also allow them to be garbage collected if needs be eg when memory is at a premium. A solution to this problem is to use Reference Objects. &lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;There are three concrete implementations of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.lang.ref.Reference&amp;lt;T&amp;gt;&lt;/span&gt; class: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakReference&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SoftReference&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PhantomReference&lt;/span&gt;.&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;Objects held only by a WeakReference are deemed to be weakly reachable and are therefore eligible for garbage collection. An example of creating a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakReference&lt;/span&gt; is below:&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakReference&amp;lt;Customer&amp;gt; weakCustomer = new &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WeakReference&amp;lt;Customer&amp;gt;(customer);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;To obtain the customer object held by the weak reference, you would call &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;weakCustomer.get()&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.&lt;/span&gt; This will always return the customer object unless the garbage collecter has deemed the object to be weakly reachable and therefore has freed it from memory. In that case, calling the get method will return null;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;If you want to hold a collection of the objects that can be garbage collected, then you can use a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakHashMap&lt;/span&gt;. This collection uses weak references as keys, so when the key becomes garbage collected, the entry for that key in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakHashMap&lt;/span&gt; gets removed. This collection class isn’t synchronized so use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Collections.synchronizedMap&lt;/span&gt; for a synchronized version, but be beware that whether synchronized or not, the size of the Map may decrease over time as the garbage collector removes entries, so an iterator may return &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ConcurrentModificationException&lt;/span&gt;.&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;A &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SoftReference&lt;/span&gt; holds onto the object more strongly than a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeakReference&lt;/span&gt; and if memory is not a problem the garbage collector will not free up the memory used by objects held by a soft reference.&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;You can also create another type of reference to an object, a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PhantomReference&lt;/span&gt;. Calling the get method on such a reference will always return null though thereby preventing you&amp;nbsp;from ‘resurrecting’ the object. &amp;nbsp;It’s only real use is when you pass a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ReferenceQueue&lt;/span&gt; into the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PhantomReference&lt;/span&gt; constructor. &lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;You can pass a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ReferenceQueue&lt;/span&gt; into the constructor of all the Reference types. It enables you to keep track of objects which have been garbage collected. When the object’s &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;finalize&lt;/span&gt; method is called, the object will be placed on the reference queue. This process is called ‘enqueuing’. You then know when it was removed from memory. &lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;In the case of a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PhantomReference&lt;/span&gt;, passing in a null &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ReferenceQueue&lt;/span&gt; would be a pointless exercise, rendering the creation of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PhantomReference&lt;/span&gt; useless.&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3892049326890521470?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3892049326890521470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/weak-and-soft-references-and-garbage.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3892049326890521470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3892049326890521470'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/weak-and-soft-references-and-garbage.html' title='Weak and Soft References and the Garbage Collector'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3849859568852904068</id><published>2011-03-08T02:01:00.000-08:00</published><updated>2012-02-07T05:03:14.462-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='DBUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Testing JPA Entities using DBUnit</title><content type='html'>DBUnit is a powerful testing tool that allows you to put your database into a known state in between tests. A common problem (and one of poor test design) is where a test changes the state of an object and this state affects the testing of objects in later tests. Each test should be independent and tests within a suite should be able to run in any order. This post will aim to describe the code needed to setup a database before each run of a JUnit test method.&lt;br /&gt;&lt;br /&gt;The below class has three key methods:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;initEntityManager()&lt;/b&gt; - this method is annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@BeforeClass&lt;/span&gt; so will only be called once for this test and called before any tests are run. The method will create an entity manager, get a connection to an instance of the in memory Java database HSQL and then populate it by reading in the flat xml database record structure that is contained in the file test-dataset.xml. For alternative dataset formats please visit &lt;a href="http://www.dbunit.org/apidocs/org/dbunit/dataset/IDataSet.html"&gt;http://www.dbunit.org/apidocs/org/dbunit/dataset/IDataSet.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;closeEntityManager()&lt;/b&gt; - this method is annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@AfterClass&lt;/span&gt; so will only be called once for this test and called after all the tests have been run. The method will close down the entity manager and the entity manager connection factory.&lt;/li&gt;&lt;li&gt;&lt;b&gt;cleanDB() &lt;/b&gt;- this method is annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;@Before&lt;/span&gt; and will be called before every test method call. The call to&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;DatabaseOperation.CLEAN_INSERT.execute&lt;/span&gt; will clean the database tables and insert the records from the dataset xml file. Database operations other than &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;CLEAN_INSERT&lt;/span&gt; are described below:&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UPDATE &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; updates the database using the data in the dataset.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inserts the data in the dataset into the database.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DELETE &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; deletes only the data in the dataset from the database.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DELETE_ALL deletes all rows of tables present in the specified dataset.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TRUNCATE&amp;nbsp;&amp;nbsp; truncate tables listed in the dataset.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; REFRESH&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; refreshes the database using the data in the dataset.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NONE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; does what it says, nothing.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;import org.dbunit.database.DatabaseConfig;&lt;br /&gt;import org.dbunit.database.DatabaseConnection;&lt;br /&gt;import org.dbunit.database.IDatabaseConnection;&lt;br /&gt;import org.dbunit.dataset.IDataSet;&lt;br /&gt;import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;&lt;br /&gt;import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory;&lt;br /&gt;import org.dbunit.operation.DatabaseOperation;&lt;br /&gt;import org.hibernate.impl.SessionImpl;&lt;br /&gt;import org.junit.AfterClass;&lt;br /&gt;import org.junit.Before;&lt;br /&gt;import org.junit.BeforeClass;&lt;br /&gt;import javax.persistence.EntityManager;&lt;br /&gt;import javax.persistence.EntityManagerFactory;&lt;br /&gt;import javax.persistence.Persistence;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;public class JPATest {&lt;br /&gt;&lt;br /&gt;    protected static EntityManagerFactory entityManagerFactory;&lt;br /&gt;    protected static EntityManager entityManager;&lt;br /&gt;    protected static IDatabaseConnection connection;&lt;br /&gt;    protected static IDataSet dataset;&lt;br /&gt;&lt;br /&gt;    @BeforeClass&lt;br /&gt;    public static void initEntityManager() throws Exception {&lt;br /&gt;        entityManagerFactory = Persistence.createEntityManagerFactory("PersistenceUnit");&lt;br /&gt;        entityManager = entityManagerFactory.createEntityManager();&lt;br /&gt;        connection = new DatabaseConnection(((SessionImpl)(entityManager.getDelegate())).connection());&lt;br /&gt;        connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());&lt;br /&gt;&lt;br /&gt;        FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();&lt;br /&gt;        flatXmlDataSetBuilder.setColumnSensing(true);&lt;br /&gt;        dataset = flatXmlDataSetBuilder.build(&lt;br /&gt;        Thread.currentThread().getContextClassLoader().getResourceAsStream("test-dataset.xml"));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @AfterClass&lt;br /&gt;    public static void closeEntityManager() {&lt;br /&gt;        entityManager.close();&lt;br /&gt;        entityManagerFactory.close();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Before&lt;br /&gt;    public void cleanDB() throws Exception {&lt;br /&gt;        DatabaseOperation.CLEAN_INSERT.execute(connection, dataset);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testAUsefulMethod() throws Exception {&lt;br /&gt;        // .... test code&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An example structure of the dataset.xml is shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;&lt;br /&gt;&amp;lt;dataset&amp;gt;&lt;br /&gt;    &amp;lt;customer id="1" surname="SURNAME" firstName="FIRSTNAME" middleName="MIDDLENAME" personalAccount="true"/&amp;gt;&lt;br /&gt;    &amp;lt;customer id="2" surname="SURNAME" firstName="FIRSTNAME" personalAccount="true" balance="100000.00/&amp;gt;&lt;br /&gt;&amp;lt;/dataset&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One point of note is that when deleting database records using DBUnit the same rules apply as if you were using SQL. You will not be able to delete a record if its primary key is a foreign key on another table. An example in Flat XML for a Customer class that has many Addresses would be:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;&lt;br /&gt;&amp;lt;dataset&amp;gt;&lt;br /&gt;    &amp;lt;customer/&amp;gt;&lt;br /&gt;    &amp;lt;address/&amp;gt;&lt;br /&gt;    &amp;lt;customer_address/&amp;gt;&lt;br /&gt;&amp;lt;/dataset&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, there are many useful methods on IDataSet and ITable interfaces. An example being to obtain the number of records of a particular table:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;int customerRecordCount = dataset.getTable(&amp;quot;Customer&amp;quot;).getRowCount();&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3849859568852904068?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3849859568852904068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/testing-jpa-entities-using-dbunit.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3849859568852904068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3849859568852904068'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/testing-jpa-entities-using-dbunit.html' title='Testing JPA Entities using DBUnit'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-4751415634338134388</id><published>2011-03-07T08:38:00.000-08:00</published><updated>2011-03-07T08:39:26.827-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenMQ'/><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>Useful JMS-related Glassfish and OpenMq commands</title><content type='html'>Below are a few Glassfish JMS admin commands and some useful OpenMQ commands (to query, purge and list) which can be be used in scripts to perform tasks as opposed to performing the same procedures via the Glassfish or OpenMQ admin consoles:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Glassfish JMS Commands&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;To clear previous JMS setup&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin delete-jms-resource &amp;lt;JMS_TOPIC_RESOURCE_NAME&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin delete-jms-resource &amp;lt;JMS_TOPIC_CONNECTION_FACTORY_NAME&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To create the JMS Topic Connection factory&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin create-jms-resource --restype=javax.jms.TopicConnectionFactory --property transaction-support=LocalTransaction --description="JMS Topic Connection Factory." &amp;lt;JMS_TOPIC_CONNECTION_FACTORY_NAME&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To create the JMS Topic resource&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin create-jms-resource --restype=javax.jms.Topic --description="JMS Topic" &amp;lt;JMS_TOPIC_RESOURCE_NAME&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To list JMS resources&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin list-jms-resources&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;OpenMQ Commands&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Query the JMS resources&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;imqcmd query bkr&amp;nbsp; -b &amp;lt;host&amp;gt;:&amp;lt;port&amp;gt; -passfile &amp;lt;password file&amp;gt; -u &amp;lt;user name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Purge the Topic (or Queue)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;imqcmd purge dst -f -passfile &amp;lt;password file&amp;gt; -n &amp;lt;topic name&amp;gt; -t t -b &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; -u &amp;lt;user name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;List the message rate and packet flow&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;imqcmd list dst -passfile &amp;lt;password file&amp;gt; -b &amp;lt;host&amp;gt;:&amp;lt;port&amp;gt; -u &amp;lt;user name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An example output from the list command would be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Listing all the destinations on the broker specified by:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Primary Port&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;localhost&amp;nbsp;&amp;nbsp;&amp;nbsp; 7676&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-----------------------------------------------------------------------------------------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Producers&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Consumers&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Msgs&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total&amp;nbsp; Wildcard&amp;nbsp; Total&amp;nbsp; Wildcard&amp;nbsp; Count&amp;nbsp; Remote&amp;nbsp; UnAck&amp;nbsp; Avg Size&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-----------------------------------------------------------------------------------------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JMSTopic&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Topic&amp;nbsp; RUNNING&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mq.sys.dmq&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Queue&amp;nbsp; RUNNING&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 171&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5273.322&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-4751415634338134388?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/4751415634338134388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/useful-jms-related-glassfish-and-openmq.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4751415634338134388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/4751415634338134388'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/useful-jms-related-glassfish-and-openmq.html' title='Useful JMS-related Glassfish and OpenMq commands'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-264083904931663664</id><published>2011-03-03T22:51:00.000-08:00</published><updated>2011-03-03T22:51:38.776-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Locking'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Pessimistic and Optimistic Locking in JPA 2.0</title><content type='html'>A most welcome addition to JPA 2.0 was the introduction of pessimistic locking. This allows the entity manager (or query) to lock a database record thereby preventing other transactions from changing the same record. This will ensure data consistency but at a performance cost so for each entity you need to ask yourself what is the chance of contention?&lt;br /&gt;&lt;br /&gt;Let's look at the two approaches in more detail:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Optimistic Locking&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Optimistic locking is the preferred approach when modifying entities that are infrequently updated. Optimistic locking can be explicit as will be shown later or implicit by using a version attribute. A version attribute is an attribute which has been annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Version&lt;/span&gt;. This attribute will then get incremented when the transaction commits. The below class shows an example of its usage:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.io.Serializable;&lt;br /&gt;import javax.persistence.Column;&lt;br /&gt;import javax.persistence.EntityManager;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.MappedSuperclass;&lt;br /&gt;import javax.persistence.PersistenceContext;&lt;br /&gt;import javax.persistence.Version;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@MappedSuperclass&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;public abstract class BaseEntity implements Serializable {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final long serialVersionUID = 1L;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final int ID_LENGTH=36;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Id&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Column(length = ID_LENGTH)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String id;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Version&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int versionNumber;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // etc ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;There are two optimistic lock modes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;OPTIMISTIC or READ - locks the entity when the transaction reads it for entities wit a version &lt;/li&gt;&lt;li&gt;OPTIMISTIC_FORCE_INCREMENT or WRITE - locks the entity when the transaction reads it for entities with a version and increments the version attribute&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Pessimistic Locking&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Pessimistic locking can be applied to all entities regardless of whether they have a version attribute or not.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;There are three pessimistic lock modes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PESSIMISTIC_READ - locks the entity when the transaction reads it and allows reads from other transactions&lt;/li&gt;&lt;li&gt;PESSIMISTIC_WRITE - locks the entity when the transaction updates it but does not allow reads, updates or deletes from other transactions&lt;/li&gt;&lt;li&gt;PESSIMISTIC_FORCE_INCREMENT - locks the entity when the transaction reads it and increments the version attribute (if present)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;There are many different ways to implement a pessimistic or optimistic lock using the Entity Manager and Query interfaces as shown in the example classes below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.io.Serializable;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.util.List;&lt;br /&gt;import javax.enterprise.context.ApplicationScoped;&lt;br /&gt;import javax.inject.Named;&lt;br /&gt;import javax.persistence.EntityManager;&lt;br /&gt;import javax.persistence.LockModeType;&lt;br /&gt;import javax.persistence.PersistenceContext;&lt;br /&gt;import javax.persistence.Query;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@Named("customerManager")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@ApplicationScoped&lt;br /&gt;public class CustomerManager implements Serializable {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PersistenceContext&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private EntityManager entityManager;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setName(String id, String name) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer customer =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entityManager.find(Customer.class, id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entityManager.lock(customer,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LockModeType.OPTIMISTIC_FORCE_INCREMENT&lt;/b&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.setName(name);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Customer findCustomer(String id) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return entityManager.find(Customer.class, id,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LockModeType.OPTIMISTIC&lt;/b&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Customer&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; applyBankCharges(String id, Double charges) {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer customer =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entityManager.find(Customer.class, id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.setBalance(customer.getBalance() - charges);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (customer.getBalance() &amp;lt; 0.0) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // overwrite changes and return the refreshed&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and locked object&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entityManager.refresh(customer,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LockModeType.PESSIMISTIC_WRITE&lt;/b&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return customer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public List&amp;lt;Customer&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; findCustomerByPartialName(String partialName) {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Query query = entityManager.createQuery(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "SELECT c FROM Customer c WHERE c.name" +&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; " LIKE :partialName").&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setParameter("partialName", partialName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; query.setLockMode(&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LockModeType.PESSIMISTIC_FORCE_INCREMENT&lt;/b&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return query.getResultList();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.LockModeType;&lt;br /&gt;import javax.persistence.NamedQuery;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;@Entity&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@NamedQuery(name = "findByNameQuery",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; query = "SELECT c FROM Customer c WHERE c.name LIKE :name",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lockMode = &lt;b&gt;LockModeType.PESSIMISTIC_FORCE_INCREMENT&lt;/b&gt;)&lt;br /&gt;public class Customer extends BaseEntity {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String name;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Double balance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setName(String name) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.name = name;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Double getBalance() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.balance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setBalance(Double balance) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.balance = balance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif; font-size: small;"&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;Finally, a word on exceptions. If a PessimisticLockException or an OptimisticLockException are thrown then the transaction is rolled back as they are both RuntimeExceptions.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-264083904931663664?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/264083904931663664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/03/pessimistic-and-optimistic-locking-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/264083904931663664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/264083904931663664'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/03/pessimistic-and-optimistic-locking-in.html' title='Pessimistic and Optimistic Locking in JPA 2.0'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-762682228167739580</id><published>2011-02-17T02:15:00.000-08:00</published><updated>2011-02-17T05:30:41.976-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='JAX-WS'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>Generating Web Services from WSDLs using Maven and deploying to Glassfish</title><content type='html'>This blog post aims to cover generating Java classes from WSDLs using Maven and it also covers a problem with web annotations when deploying to an app server.&lt;br /&gt;&lt;br /&gt;There are many different ways to generate Java classes for a given wsdl file (and associated xsds). One of those ways is to use the JAX-WS &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wsimport&lt;/span&gt; tool. Amongst the classes that the tool can generate are the service endpoint interface and the service class. &lt;br /&gt;&lt;br /&gt;When using Maven, you can use the&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; jaxws-maven-plugin &lt;/span&gt;and the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wsimport&lt;/span&gt; goal. The plugin will read a WSDL file (from the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/src/wsdl&lt;/span&gt; directory unless otherwise specified via the wsdlLocation tag) and generate the Java classes. The plugins sections from a pom.xml is shown below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;plugins&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;plugin&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;artifactId&amp;gt;jaxws-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version&amp;gt;1.10&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;executions&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;execution&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;goals&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;goal&amp;gt;wsimport&amp;lt;/goal&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/goals&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;configuration&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsdlFiles&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsdlFile&amp;gt;Customer.wsdl&amp;lt;/wsdlFile&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsdlFiles&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;staleFile&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${project.build.directory}/jaxws/stale/Customer.stale&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/staleFile&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id&amp;gt;wsimport-generate-Customer&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/execution&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/executions&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependencies&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;groupId&amp;gt;javax.xml&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;artifactId&amp;gt;webservices-api&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version&amp;gt;${javax.xml.version}&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;groupId&amp;gt;com.sun.xml.bind&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;artifactId&amp;gt;jaxb-xjc&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version&amp;gt;${jaxb-xjc.version}&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;groupId&amp;gt;com.sun.xml.ws&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;artifactId&amp;gt;jaxws-rt&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version&amp;gt;${jaxws-rt.version}&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependencies&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;configuration&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sourceDestDir&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${project.build.directory}/generated-sources/jaxws-wsimport&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/sourceDestDir&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xnocompile&amp;gt;true&amp;lt;/xnocompile&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;verbose&amp;gt;true&amp;lt;/verbose&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension&amp;gt;true&amp;lt;/extension&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;catalog&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${basedir}/src/jax-ws-catalog.xml&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/catalog&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/plugin&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/plugins&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The generated web service class will look like the class below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@WebService(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = "Customer",&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; targetNamespace = "http://&amp;lt;package&amp;gt;/Customer")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@SOAPBinding(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameterStyle = SOAPBinding.ParameterStyle.BARE)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public interface Customer {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param body&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @WebMethod(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operationName = "AddCustomer",&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; action = "http://&amp;lt;package&amp;gt;/Customer/AddCustomer")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void addCustomer(&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @WebParam(name = "AddCustomer",&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; targetNamespace = "http://&amp;lt;package&amp;gt;/Customer",&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; partName = "body")&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; AddCustomer body);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Given the above interface, a class can be written to implement the above generated interface as shown below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@WebService(name = Customer.NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; targetNamespace = Customer.TARGET_NAMESPACE,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; portName = Customer.PORT_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceName = Customer.SERVICE_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wsdlLocation = Customer.WSDL_LOCATION_URL)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@BindingType(value = Customer.SOAP12_OVER_HTTP)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@SchemaValidation()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class CustomerWebService implements Customer {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String NAME = "Customer";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String TARGET_NAMESPACE&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = TARGET_NAMESPACE_URL + NAME;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String PORT_NAME = NAME + "SOAP";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String SERVICE_NAME = NAME;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String WSDL_LOCATION_URL&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = WSDL_LOCATION_PATH + NAME + ".wsdl";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static final String SOAP12_OVER_HTTP&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = "http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @WebMethod(operationName = "AddCustomer")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void addCustomer(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @WebParam(name = "AddCustomer",&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; targetNamespace = "http://&amp;lt;package&amp;gt;/Customer",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; partName = "body")&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; AddCustomer body) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do something&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having built an ear file containing the web service, you can then deploy it. To deploy to eg Glassfish v3.0.1, you can use the following command:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;asadmin --host &amp;lt;server&amp;gt; --port &amp;lt;port&amp;gt; --interactive=false --echo=true --terse=true deploy &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--name customer-ear --force=false --precompilejsp=false --verify=false --enabled=true --generatermistubs=false --availabilityenabled=false &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--keepreposdir=false --keepfailedstubs=false --logReportedErrors=true --help=false ./customer-ear.ear&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One point to note is that the below implementation of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addCustomer&lt;/span&gt; method would compile...&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; @Override&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void addCustomer(AddCustomer body) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do something&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;... but it would not inherit the Web annotations and would result in the below error when deploying the ear:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;com.sun.enterprise.admin.cli.CommandException: remote failure: Exception while loading the app : java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: javax.servlet.ServletException&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Exception while invoking class com.sun.enterprise.web.WebApplication start method : java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: javax.servlet.ServletException&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Web annotations need to be explicitly replicated in the concrete class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-762682228167739580?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/762682228167739580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/02/generating-web-services-from-wsdls.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/762682228167739580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/762682228167739580'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/02/generating-web-services-from-wsdls.html' title='Generating Web Services from WSDLs using Maven and deploying to Glassfish'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-2700704807403677361</id><published>2011-02-16T05:38:00.000-08:00</published><updated>2011-02-16T05:51:47.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><title type='text'>Subversion Reminders - Branching, Merging and Rollbacks</title><content type='html'>Below are a few Subversion reminders on how to branch, merge and rollback changes.&lt;br /&gt;&lt;br /&gt;To create a branch from the HEAD of the trunk:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn copy http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/branches/&amp;lt;branch name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can add a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-m &amp;lt;comment&amp;gt; &lt;/span&gt;onto the operation to provide a reason for the branch.&lt;br /&gt;&lt;br /&gt;To delete a branch:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn delete http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/branches/&amp;lt;branch name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If for some reason you want to include changes from the trunk post-branch, then you can use the merge command from the branch root directory. A useful precursor to this is to use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;dry run &lt;/span&gt;argument as below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;svn merge --dry-run -r2602:HEAD http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/trunk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NOTE: 2602 is non-inclusive i.e. revisions merged will start from 2603 onwards. &lt;br /&gt;&lt;br /&gt;Now do the actual merge:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn merge -r2602:HEAD http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/trunk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No doubt there will be conflicts so once resolved in your favourite IDE, check the changes in.&lt;br /&gt;&lt;br /&gt;The above commands assume you noted down the revision number (2602) when branching. If not known, then from the branch root directory, execute the below command:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;svn log -v --stop-on-copy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To merge branch changes into the trunk, the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merge&lt;/span&gt; command can be used in similar fashion from the trunk root directory:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn merge -r2602:HEAD http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/branches/&amp;lt;branch name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to rollback commited changes, then you can use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merge&lt;/span&gt; command with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-r&lt;/span&gt; argument:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn merge -r10:9 http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/trunk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To rollback a commit that took place a while ago and others that have been committed since, use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merge&lt;/span&gt; command again:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn merge -r7:5 http://&amp;lt;server&amp;gt;/&amp;lt;svn repo&amp;gt;/&amp;lt;svn project&amp;gt;/trunk&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NOTE: Note that this will revert revisions 7 and 6. Revision 5 is the target revision that we want to keep.&lt;br /&gt;&lt;br /&gt;Many thanks to Rob Legg of Asset Source Ltd for the above summary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-2700704807403677361?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/2700704807403677361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/02/subversion-reminders-branching-merging.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2700704807403677361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2700704807403677361'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/02/subversion-reminders-branching-merging.html' title='Subversion Reminders - Branching, Merging and Rollbacks'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-8727466520233410316</id><published>2011-02-14T07:17:00.000-08:00</published><updated>2011-03-02T13:10:27.109-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java SE'/><category scheme='http://www.blogger.com/atom/ns#' term='Mockito'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>Unit testing managed beans using Mockito</title><content type='html'>Mockito is a powerful testing framework which is ideal for unit testing managed beans. It allows developers to mock existing classes thereby enabling the behaviour of those classes to be manipulated by the developer depending upon what the aim of the test is.&lt;br /&gt;&lt;br /&gt;A simple managed bean which is to be tested is below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.io.Serializable;&lt;br /&gt;import java.math.BigDecimal;&lt;br /&gt;import javax.annotation.Named;&lt;br /&gt;import javax.enterprise.context.ApplicationScoped;&lt;br /&gt;import javax.inject.Inject;&lt;br /&gt;&lt;br /&gt;@Named("customerManager")&lt;br /&gt;@ApplicationScoped&lt;br /&gt;public class CustomerManager implements Serializable {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final long serialVersionUID = 1L;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AccountManager accountManager;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Inject&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setAccountManager(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; final AccountManager accountManager) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.accountManager = accountManager;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public boolean isInCredit() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean inCredit = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal currentAccountBalance =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.accountManager.getBalance(AccountType.CURRENT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal depositAccountBalance =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.accountManager.getBalance(AccountType.DEPOSIT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal accountBalance =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new BigDecimal(currentAccountBalance.doubleValue())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .add(depositAccountBalance);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (accountBalance.compareTo(BigDecimal.ZERO) &amp;gt; 0) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inCredit = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return inCredit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The test class for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CustomerManager&lt;/span&gt; could include various scenarios depending on what is returned by the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AccountManager&lt;/span&gt; class. An example test class is below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.math.BigDecimal;&lt;br /&gt;import org.junit.Before;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;import static org.mockito.Mockito.mock;&lt;br /&gt;import static org.mockito.Mockito.verify;&lt;br /&gt;import static org.mockito.Mockito.when;&lt;br /&gt;import static org.mockito.Mockito.any;&lt;br /&gt;import static org.mockito.Mockito.times;&lt;br /&gt;import static junit.framework.Assert.assertTrue;&lt;br /&gt;&lt;br /&gt;public class CustomerManagerTest {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private CustomerManager customerManager;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AccountManager mockAccountManager =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mock(AccountManager.class);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Before&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setUp() throws Exception {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customerManager = new CustomerManager();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customerManager.setAccountManager(mockAccountManager);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void testPositiveBalance() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal positiveAmount&amp;nbsp; = new BigDecimal(1000.00);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(mockAccountManager.getBalance(((AccountType)any())))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(positiveAmount);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean inCredit = customerManager.isInCredit();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertTrue(inCredit);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verify(mockAccountManager, times(2))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .getBalance((AccountType)any());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;when&lt;/span&gt; is mocking calls to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AccountManager&lt;/span&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getBalance&lt;/span&gt; method for any given parameter of type &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AccountType&lt;/span&gt;. As the method should have been called twice (once for CURRENT and once for DEPOSIT), the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;verify&lt;/span&gt; call can determine the number of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getBalance&lt;/span&gt; method invocations. A more fine grained test equivalent of the above could be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void testPositiveBalance() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal positiveAmount&amp;nbsp; = new BigDecimal(1000.00);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(mockAccountManager.getBalance(AccountType.CURRENT))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(positiveAmount);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(mockAccountManager.getBalance(AccountType.DEPOSIT))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(positiveAmount);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean inCredit = customerManager.isInCredit();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertTrue(inCredit);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verify(mockAccountManager)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .getBalance(AccountType.CURRENT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verify(mockAccountManager)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .getBalance(AccountType.DEPOSIT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The argument matchers are more explicit in the above and could also return different results if needs be.&lt;br /&gt;&lt;br /&gt;It is also possible to mock consecutive calls to a method so the same argument can generate a different return object. Using the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getBalance&lt;/span&gt; example, the first call could return 1000.0 and the next 2000.0.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal positiveAmount1&amp;nbsp; = new BigDecimal(1000.00);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal positiveAmount2&amp;nbsp; = new BigDecimal(2000.00);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(mockAccountManager.getBalance(((AccountType)any())))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(positiveAmount1)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(positiveAmount2);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It is also possible to partially mock real objects using the spy method. If a real &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AccountManager&lt;/span&gt; object had been created and set, then the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getBalance&lt;/span&gt; method could have be stubbed as shown below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;import java.math.BigDecimal;&lt;br /&gt;import org.junit.Before;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;import static org.mockito.Mockito.verify;&lt;br /&gt;import static org.mockito.Mockito.when;&lt;br /&gt;import static org.mockito.Mockito.any;&lt;br /&gt;import static org.mockito.Mockito.spy;&lt;br /&gt;import static org.mockito.Mockito.times;&lt;br /&gt;import static junit.framework.Assert.assertTrue;&lt;br /&gt;&lt;br /&gt;public class CustomerManagerTest {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private CustomerManager customerManager;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AccountManager accountManager = new AccountManager();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Before&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setUp() throws Exception {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customerManager = new CustomerManager();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void testPositiveBalance() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AccountManager spyAccountManager = spy(accountManager);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customerManager.setAccountManager(spyAccountManager);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BigDecimal postiveAmount&amp;nbsp; = new BigDecimal(1000.00);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(spyAccountManager.getBalance(((AccountType)any())))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .thenReturn(postiveAmount);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean inCredit = customerManager.isInCredit();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertTrue(inCredit);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verify(spyAccountManager, times(2))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .getBalance((AccountType)any());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are many more features to the Mockito framework than described here (throwing exceptions, stubbing void methods, etc..) and http://mockito.org/ is a good starting point.&lt;br /&gt;&lt;br /&gt;Finally, you can also use annotations to declare mock objects. An alternative to using &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AccountManager mockAccountManager =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mock(AccountManager.class);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;would be to use the @Mock annotation as below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Mock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AccountManager mockAccountManager;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and in the setup method initialise them by the following command:&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MockitoAnnotations.initMocks(this);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-8727466520233410316?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/8727466520233410316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/02/unit-testing-managed-beans-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8727466520233410316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/8727466520233410316'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/02/unit-testing-managed-beans-using.html' title='Unit testing managed beans using Mockito'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-2990607502928157510</id><published>2011-02-08T03:47:00.000-08:00</published><updated>2011-02-10T00:49:00.908-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>JPA Entity Lifecycle Callback and Listener Annotations</title><content type='html'>Within the javax.persistence package there are annotations that may be applied to methods of an entity or a mapped superclass to specify that the annotated method must be called for a certain lifecycle event. A lifecycle event being either: Persist, Update, Remove or Load. and each event has a Pre or Post event.&lt;br /&gt;&lt;br /&gt;Listeners can also have methods annotated with a lifecycle event. Listeners can be used to hold the business logic that would otherwise be in the entities (or another layer.) This enables the entities to be just POJOs. It also means that the testing of the business logic can be done in isolation.&lt;br /&gt;&lt;br /&gt;Below is an example of using lifecycle events to populate an &lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;id&lt;/span&gt;&lt;/span&gt; var and also populate a &lt;span style="font-size: small;"&gt;lastUpdated&lt;/span&gt; var, in a mapped superclass:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@MappedSuperclass&lt;br /&gt;public abstract class BaseEntity implements Serializable {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final long serialVersionUID = 1L;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final int ID_LENGTH=36;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Id&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Column(length = ID_LENGTH)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String id;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Temporal(TemporalType.TIMESTAMP)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Column(updatable = false)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Date dateCreated;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Temporal(TemporalType.TIMESTAMP)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Date lastModified;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // constructor(s)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PreUpdate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void updateLastModified () {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lastModified = new Date();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PrePersist&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void generateUUID() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id = java.util.UUID.randomUUID().toString();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dateCreated = new Date();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lastModified = new Date();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .....&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An simple example of using a Listener could be where an entity has a transient var that needs to be populated after the entity has been persisted, updated or loaded.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;public class AvailableCreditListener {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PostLoad&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PostPersist&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @PostUpdate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void calculateAvailableCredit{Account account) {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; account.setAvailableCredit(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; account.getBalance().add(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; account.getOverdraftLimit()));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The entity class would be annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@EntityListeners&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;@EntityListeners({AvailableCreditListener.class})&lt;br /&gt;public class AccountEntity extends BaseEntity {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private BigDecimal balance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private BigDecimal overdraftLimit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Transient&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private BigDecimal availableCredit;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // getters and setters&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Finally, instead of annotations, an XMl mapping file can be used and deployed with the application to specify default listeners. (This mapping file is referenced by the persistence.xml file.) But an entity can use the @ExcludeDefaultListeners annotation if it does not want to use the default listeners.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;@ExcludeDefaultListeners&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;@Entity&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;public class AccountEntity extends BaseEntity {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-2990607502928157510?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/2990607502928157510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/02/jpa-entity-lifecycle-callback-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2990607502928157510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/2990607502928157510'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/02/jpa-entity-lifecycle-callback-and.html' title='JPA Entity Lifecycle Callback and Listener Annotations'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-5729021604420943505</id><published>2011-02-01T07:05:00.000-08:00</published><updated>2011-02-10T00:48:50.693-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='CDI'/><title type='text'>Loose Coupling using CDI</title><content type='html'>&lt;span style="font-size: small;"&gt;A key to n-tier architectures is notion of loose coupling and CDI enables this between classes in Java EE 6.&lt;br /&gt;&lt;br /&gt;By using the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Inject&lt;/span&gt; annotation, you can specify an injection point in a class. The below example uses the annotation on a setter method.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Inject&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setCustomer(Customer customer) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.customer = customer;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It could equally be used on a field as below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Inject&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer customer;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It is possible that more than one implementation of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Customer&lt;/span&gt; class exists so to resolve this problem at runtime, qualifiers are used. They provide the ability to 'qualify' what gets injected. an example qualifier is below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.inject.Qualifier;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.Documented;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.ElementType;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.Retention;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.RetentionPolicy;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.Target;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Documented&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Qualifier&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Retention(RetentionPolicy.RUNTIME)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public @interface TradeCustomerQualifier {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;TradeCustomer&lt;/span&gt; class would be enhanced to use the qualifier by way of an annotation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@TradeCustomerQualifier&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Named("tradeCustomer")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@ApplicationScoped&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class TradeCustomer extends Customer {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ......&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An example of using the qualifier is below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Inject&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setCustomer(@TradeCustomerQualifier Customer customer) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.customer = customer;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally, in order for CDI to bootstrap, there'll need to be a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;beans.xml&lt;/span&gt; file in the META-INF folder (for jars and in the WEB-INF for web applications.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;beans xmlns="http://java.sun.com/xml/ns/javaee"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-5729021604420943505?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/5729021604420943505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/02/loose-coupling-using-cdi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/5729021604420943505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/5729021604420943505'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/02/loose-coupling-using-cdi.html' title='Loose Coupling using CDI'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3990680869128163765</id><published>2011-01-27T05:30:00.000-08:00</published><updated>2011-02-10T00:48:39.951-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='CDI'/><title type='text'>Extending Bean Functionality using Interceptors</title><content type='html'>&lt;span style="font-size: small;"&gt;A key part of the Java EE 6 platform is CDI (Context and Dependency Injection) and CDI supports two ways of extending bean functionality: interceptors and decorators. &lt;br /&gt;&lt;br /&gt;For this post, we'll concentrate on interceptors and provide an example of implementing a cross-cutting concern across multiple beans ie logging.&lt;br /&gt;&lt;br /&gt;An example of an interceptor which extracts the user value from the SessionContext for logging is shown below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.apache.log4j.MDC;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.interceptor.AroundInvoke;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.interceptor.InvocationContext;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.io.Serializable;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public final class AuditLoggingInterceptor implements Serializable {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected static final String MDC_USER = "user";&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected static final String UNAUTHENTICATED_USER =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Unauthenticated User";&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected static final String NULL_USER =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Authenticated User Name is Null";&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final long serialVersionUID = 1L;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private SessionContext sessionContext;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@AroundInvoke&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Object captureUser(InvocationContext context)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throws Exception {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MDC.put(MDC_USER, determineUsername());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return context.proceed();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }catch(Exception e){&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // handle exception&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }finally {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MDC.remove(MDC_USER);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Inject the calling Session Context.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param sessionContext context the current invocation&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Resource&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setSessionContext(SessionContext sessionContext) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.sessionContext = sessionContext;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SessionContext getSessionContext() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sessionContext;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Determine what the username should be based on the session context.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @return the username&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected String determineUsername() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String username = NULL_USER;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (sessionContext != null) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try{&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (sessionContext.getCallerPrincipal() == null) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; username = UNAUTHENTICATED_USER;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; username =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sessionContext.getCallerPrincipal().getName();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }catch(NullPointerException npe){&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // handle exception&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return username;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The above interceptor implements a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;captureUser&lt;/span&gt; method which is marked with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@AroundInvoke &lt;/span&gt;annotation. This ensures that the method is invoked around the business methods for the classes that&amp;nbsp; the interceptor is bound to.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.apache.log4j.Logger;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.interceptor.Interceptors;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.ejb.Remote;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import javax.ejb.Stateless;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Interceptors({AuditLoggingInterceptor.class})&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Stateless(mappedName = JndiResourceName.BUSINESS_SERVICE)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Remote(BusinessService.class)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class BusinessServiceBean implements BusinessService {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final Logger LOGGER =&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Logger.getLogger(BusinessServiceBean .class);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void doSomething() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOGGER.info("BusinessServiceBean.doSomething ()");&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do something&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;doSomething&lt;/span&gt; method is invoked on the business service, the method will be wrapped by captureUser method. The log4j class &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MDC&lt;/span&gt; (Mapped Diagnostic Context) will set the user key in the context map to be the caller principal name from the session context. This value will be used when the info&amp;nbsp; message is logged. When the method completes, the user value is removed from the context.&lt;br /&gt;&lt;br /&gt;The entry in the log4j.properties file so that the MDC value gets picked up is below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;log4j.appender.AUDITROLLINGFILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}&amp;nbsp; [%X{user}] %c{1} [%p] %m%n&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To exclude a class's methods from being 'intercepted' then the business methods can be annotated with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@ExcludeClassInterceptors.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3990680869128163765?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3990680869128163765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/01/extending-bean-functionality-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3990680869128163765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3990680869128163765'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/01/extending-bean-functionality-using.html' title='Extending Bean Functionality using Interceptors'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3477845893101521069</id><published>2011-01-22T12:39:00.000-08:00</published><updated>2011-02-10T00:48:28.224-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Second Level Caching</title><content type='html'>JPA has two levels of caching. The first level of caching is the persistence context (which can be either transaction scoped or extended.), and the second level of caching, introduced in JPA 2.0, sites in between the entity manager and the database. &lt;br /&gt;&lt;br /&gt;With second level caching entities not found in the persistence context will be loaded from the second level cache, and if not found there, from the database. The ideal type of entity to live in the second level cache are those that are rarely updated, or those that are constantly read.&lt;br /&gt;&lt;br /&gt;To mark an entity as requiring caching, you can use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Cacheable&lt;/span&gt; annotation as below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Entity&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;@Cacheable(true)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Person {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Id @GeneratedValue&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Long id;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String name;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // etc ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To override the provider-specific defaults for managing cached entities, you can set the &lt;b&gt;shared-cache-mode&lt;/b&gt; value in the persistence.xml. The possible values are below:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ALL- all entities are cached&lt;/li&gt;&lt;li&gt;DISABLE_SELECTIVE - all entities cached apart from those with the annotation &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Cacheable(false)&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;ENABLE_SELECTIVE - only entities with the annotation &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Cacheable(true)&lt;/span&gt;&lt;/b&gt; are cached&lt;/li&gt;&lt;li&gt;NONE - no caching for the persistence unit&lt;/li&gt;&lt;li&gt;UNSPECIFIED - provider-specific default&lt;/li&gt;&lt;/ul&gt;JPA 2.0 also introdcued the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Cache&lt;/span&gt; interface which can be used to evict or invalidate entities in the second level cache. It can claso be used to check whether ot not an entity exisits in the cache as well.&lt;br /&gt;&lt;br /&gt;Finally, you cannot implement a caching strategy without also considering a locking strategy (but that's for another post!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3477845893101521069?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3477845893101521069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/01/second-level-caching.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3477845893101521069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3477845893101521069'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/01/second-level-caching.html' title='Second Level Caching'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-6122039255670619185</id><published>2011-01-21T03:12:00.000-08:00</published><updated>2012-02-03T01:33:10.806-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>CriteriaBuilder and Dynamic Queries in JPA 2.0</title><content type='html'>A major new feature of Java EE 6 is JPA 2.0 and in particular the addition of the Criteria API which provides the ability to dynamically construct object-based queries. &lt;br /&gt;&lt;br /&gt;This resolves some of the problems which arise when building dynamic native queries. The below example shows how to find customer entities with two search parameters:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public List&amp;lt;CustomerEntity&amp;gt; findCustomers(&lt;br /&gt;    final String firstName, final String surname) {&lt;br /&gt;&lt;br /&gt;    StringBuilder queryBuilder = new StringBuilder(&lt;br /&gt;        "select c from Customer where ");&lt;br /&gt;    List&amp;lt;String&amp;gt; paramList = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;    paramList.add(" upper(c.firstName) like '%?%'"&lt;br /&gt;        .replace("?", firstName.toUpperCase()));&lt;br /&gt;    paramList.add(" upper(c.surname) like '%?%'"&lt;br /&gt;        .replace("?", surname.toUpperCase()));&lt;br /&gt;&lt;br /&gt;    Iterator itr = paramList.iterator();&lt;br /&gt;    while(itr.hasNext()) {&lt;br /&gt;        queryBuilder.append(itr.next());&lt;br /&gt;        if (itr.hasNext()) {&lt;br /&gt;            queryBuilder.append(" and ");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    final Query query = entityManager.createNativeQuery(&lt;br /&gt;        queryBuilder.toString());&lt;br /&gt;&lt;br /&gt;    List&amp;lt;Object&amp;gt; resultList = (List&amp;lt;Object&amp;gt;)query.getResultList();&lt;br /&gt;&lt;br /&gt;    // iterate, cast, populate and return a list&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The problem with the above is that it is not type safe and involves iterating over a List of Object where those Objects are themselves Object arrays. Also should Customer contain any child elements, these would have to be retrieved in a separate call.&lt;br /&gt;&lt;br /&gt;Using the CriteriaBuilder, the same results can be achieved as shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public List&amp;lt;CustomerEntity&amp;gt; findCustomers(final String firstName, final String surname) {&lt;br /&gt;&lt;br /&gt;    CriteriaBuilder builder = entityManager.getCriteriaBuilder();&lt;br /&gt;    CriteriaQuery&amp;lt;CustomerEntity&amp;gt; query = builder.createQuery(CustomerEntity.class);&lt;br /&gt;    Root&amp;lt;CustomerEntity&amp;gt; cust = query.from(CustomerEntity.class);&lt;br /&gt;    query.select(cust);&lt;br /&gt;&lt;br /&gt;    List&amp;lt;Predicate&amp;gt; predicateList = new ArrayList&amp;lt;Predicate&amp;gt;();&lt;br /&gt;&lt;br /&gt;    Predicate firstNamePredicate, surnamePredicate;&lt;br /&gt;&lt;br /&gt;    if ((firstName != null) &amp;amp;&amp;amp; (!(firstName.isEmpty()))) {&lt;br /&gt;        firstNamePredicate = builder.like(&lt;br /&gt;            builder.upper(cust.&amp;lt;String&amp;gt;get("firstName")), "%"+firstName.toUpperCase()+"%");&lt;br /&gt;        predicateList.add(firstNamePredicate);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if ((surname != null) &amp;amp;&amp;amp; (!(surname.isEmpty()))) {&lt;br /&gt;        surnamePredicate = builder.like(&lt;br /&gt;            builder.upper(cust.&amp;lt;String&amp;gt;get("surname")), "%"+surname.toUpperCase()+"%");&lt;br /&gt;        predicateList.add(surnamePredicate);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    Predicate[] predicates = new Predicate[predicateList.size()];&lt;br /&gt;    PredicateList.toArray(predicates);&lt;br /&gt;    query.where(predicates);&lt;br /&gt;&lt;br /&gt;    return entityManager.createQuery(query).getResultList();&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There is some type safety in the above but it can be furthered tied down by using the metamodel class for the entity, by using the metamodel class's public static members instead of text strings for the entity's attributes. The code would now look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;    firstNamePredicate = builder.like(&lt;br /&gt;        builder.upper(cust.get(CustomerEntity_.firstName)),&lt;br /&gt;            &amp;quot;%&amp;quot;+firstName.toUpperCase()+&amp;quot;%&amp;quot;);&lt;br /&gt;&lt;br /&gt;    surnamePredicate = builder.like(&lt;br /&gt;        builder.upper(cust.get(CustomerEntity_.surname)), &lt;br /&gt;            &amp;quot;%&amp;quot;+surname.toUpperCase()+&amp;quot;%&amp;quot;); &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Having built metamodel classes using Maven, it's questionable whether it's a worthwhile exercise as any mistakes in the text based approach to finding attribute names should be flagged up by comprehensive unit testing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-6122039255670619185?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/6122039255670619185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/01/criteriabuilder-and-dynamic-queries-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6122039255670619185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/6122039255670619185'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/01/criteriabuilder-and-dynamic-queries-in.html' title='CriteriaBuilder and Dynamic Queries in JPA 2.0'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-599554868473356802.post-3289353213028141843</id><published>2011-01-21T03:08:00.000-08:00</published><updated>2011-02-12T11:26:11.323-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mockito'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>Java Blogging and Tweeting</title><content type='html'>The idea behind this blog is to remind myself of all the useful bits of code I come across whilst working on projects and contracts. On numerous occasions, I've spent hours resolving problems on one contract only to hit the same problems on another so by putting nuggets of Java code up on the web, I should have no excuse in spending hours resolving the same problems I've encountered before. It'll also be retrospective and not just about problems I come across on current contracts, so if I can remember useful stuff from the past then I'll post about those too.&lt;br /&gt;&lt;br /&gt;The posts may stray into the realms of build tools like Maven, test frameworks like Mockito, application servers like Glassfish and JBoss, and platforms like Android but in the main it'll be about Core and Enterprise Java. &lt;br /&gt;&lt;br /&gt;As for the Twiiter account, there will&amp;nbsp;be tweets about new blog posts plus me&amp;nbsp;writing down all those daft thoughts that enter your head whilst staring out of the window at work. Also in&amp;nbsp;amongst the tweets&amp;nbsp;will&amp;nbsp;the odd football rant about the ups and downs of Swansea City !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/599554868473356802-3289353213028141843?l=city81.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://city81.blogspot.com/feeds/3289353213028141843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://city81.blogspot.com/2011/01/java-blogging-and-tweeting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3289353213028141843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/599554868473356802/posts/default/3289353213028141843'/><link rel='alternate' type='text/html' href='http://city81.blogspot.com/2011/01/java-blogging-and-tweeting.html' title='Java Blogging and Tweeting'/><author><name>Geraint Jones</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
