<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thought Forge</title>
	<atom:link href="http://thoughtforge.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://thoughtforge.net</link>
	<description></description>
	<lastBuildDate>Tue, 13 Jul 2010 09:46:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Patterns of Agile Practice Adoption</title>
		<link>http://thoughtforge.net/2010/07/13/patterns-of-agile-practice-adoption/</link>
		<comments>http://thoughtforge.net/2010/07/13/patterns-of-agile-practice-adoption/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 09:46:47 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=812</guid>
		<description><![CDATA[&#8220;Patterns of Agile Practice Adoption&#8221; is another book from InfoQ that describes potential ways in which Agile practices could be adopted individually and as clusters of practices that complement one another.  As with Domain Driven Development Quickly, this book can be freely downloaded (registration required).
Part 1 – Business Value, Smells, and an adoption Strategy
This part [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;<a href="http://www.infoq.com/minibooks/agile-patterns" target="_blank">Patterns of Agile Practice Adoption</a>&#8221; is another book from InfoQ that describes potential ways in which Agile practices could be adopted individually and as clusters of practices that complement one another.  As with <a href="http://www.infoq.com/minibooks/domain-driven-design-quickly" target="_blank">Domain Driven Development Quickly</a>, this book can be freely downloaded (registration required).<span id="more-812"></span></p>
<p><strong>Part 1 – Business Value, Smells, and an adoption Strategy</strong></p>
<p>This part of the book focuses on the reasons why one might consider adopting agile practices.  It starts by looking at the value that agile practices can bring to the business, follows on by suggesting problems that agile practices could address and finishes by describing how to adopt agile practices.</p>
<p><span style="text-decoration: underline;">Business Value</span></p>
<p>Agile practices have the potential to deliver value to the business in a number of areas and your business might be more sensitive in one or more of these areas.  The areas discussed include:</p>
<div id="_mcePaste">
<ul>
<li>Reduce time to market</li>
<li>Increase value to market</li>
<li>Increase quality to market</li>
<li>Increase flexibility</li>
<li>Increase visibility</li>
<li>Reduce cost</li>
<li>Increase product lifetime</li>
</ul>
</div>
<p>A useful exercise is presented at the end of this section to help one determine which areas are more important to your business.</p>
<p><span style="text-decoration: underline;">Smells</span></p>
<p>We, as developers, are used to discussing code smells but probably less used to discussing smells in our development methodology or practices.  This section discusses “Business smells” and “Process smells”.  Business smells are smells that affect the business and are visible to customers while process smells are only visible to the development team.  I’ve listed the smells discussed below:</p>
<p>Business Smells</p>
<div id="_mcePaste">
<ul>
<li>Delivering new features to the customer takes too long.</li>
<li>Features are not used by the customer.</li>
<li>Software is not useful to the customer.</li>
<li>Software is too expensive to build.</li>
</ul>
</div>
<p>Process Smells</p>
<div id="_mcePaste">
<ul>
<li>Us vs Them.</li>
<li>Customer asks for everything including the kitchen sink.</li>
<li>Direct and regular customer input is unrealistic.</li>
<li>Lack of visibility.</li>
<li>Bottlenecked resources.</li>
<li>Churning projects.</li>
<li>Hundreds of bugs in bug-tracker.</li>
<li>Hardening phase needed at end of release cycle.</li>
<li>Integration is infrequent.</li>
</ul>
</div>
<p>Again, a useful exercise is presented at the end of the section that asks one to discover, investigate and rank smells within the organisation.</p>
<p><span style="text-decoration: underline;">Adopting Agile Practices</span></p>
<p>An awareness of agile practices is assumed as business values are related to corresponding agile practices that could potentially enhance the ability to deliver these values.  Similarly, smells are related to corresponding agile practices that could potentially address the smell.</p>
<p>Advice is then delivered on how to use the information presented to develop a tailored agile adoption strategy.  This advice can be summarised as follows:</p>
<div id="_mcePaste">
<ul>
<li>Be business-value focused.</li>
<li>Be goal oriented.</li>
<li>Adopt iteratively.</li>
<li>Be agile about your adoption.</li>
<li>Use a test-driven adoption strategy. (i.e. validate your results)</li>
</ul>
</div>
<p><strong>Part 2 – The Patterns</strong></p>
<p>As with any pattern language, the patterns presented adopt a standard layout.  The layout presents:</p>
<div id="_mcePaste">
<ul>
<li>Name: Pattern name</li>
<li>Description: Brief description.</li>
<li>Business Value: Business values pattern effects.</li>
<li>Sketch: Narrative of pattern use.</li>
<li>Context: Environment where the pattern may be applied.</li>
<li>Forces: Elaboration of specific environmental conditions acting on the pattern.</li>
<li>Therefore: Full pattern description.</li>
<li>Adoption: Adoption guide.</li>
<li>But: Negative consequences.</li>
</ul>
</div>
<p><span style="text-decoration: underline;">Automated Developer Tests</span></p>
<p>This pattern describes a set of tests that are maintained by developers to reduce the occurrence and/or cost of bug, increase confidence when refactoring and increase decoupling.  The tests are then executed automatically as part of a continuous integration process.</p>
<p><span style="text-decoration: underline;">Test-Last Development</span></p>
<p>This pattern describes writing automated developer tests after the code has been written.  Tests tend to conform to the initial implementation rather than the requirements (if they differ).</p>
<p><span style="text-decoration: underline;">Test-First Development</span></p>
<p>This pattern describes writing automated developer tests before the code has been written.  Testing in this way is more effective than Test-Last Development but harder to adopt.  Tests conform to the requirements as no code exists.</p>
<p><span style="text-decoration: underline;">Refactoring</span></p>
<p>This pattern describes changing the structure of code without changing the behaviour.</p>
<p><span style="text-decoration: underline;">Continuous Integration</span></p>
<p>This pattern describes the practice of performing a clean build, deploy and execution of unit and integration tests every time a code change is committed to the source repository.</p>
<p><span style="text-decoration: underline;">Simple Design</span></p>
<p>This pattern describes resisting over engineering a solution and extending a design only when required.  Add more flexible\complex designs only when needed to avoid the cost of complex software until the benefit is necessary.</p>
<p><span style="text-decoration: underline;">Functional Tests</span></p>
<p>This pattern describes executable requirements that can be used as functional tests.  These functional tests represent the requirements of the user and when complete indicate the requirement is done.  Some useful examples are provided to clarify what functional tests are.</p>
<p><span style="text-decoration: underline;">Collective Code Ownership</span></p>
<p>This pattern describes code ownership where no one individual or set of individuals has exclusive ownership of a section of the code base.</p>
<p><strong>Part 3 – Clusters of Practices</strong></p>
<p>Clusters, as described in this book, are groups of agile practices that build upon or complement each other such as the cluster of practices are greater than the sum of their parts.</p>
<p><span style="text-decoration: underline;">Evolutionary Design</span></p>
<p>This cluster describes a set of practices that support an evolutionary design process.  These practices include Automated Developer Tests, Refactoring and Simple Design.</p>
<p><span style="text-decoration: underline;">Test-driven Development</span></p>
<p>This cluster describes a set of practices that focuses on developer tests.  These practices are primarily Evolutionary Design, Collective Code Ownership and Continuous Integration.  The primary practices in turn include others resulting in the inclusion of many of the practices described.</p>
<p>Again the sketch is very useful in that it narrates a very real illustration of adopting this cluster of practices.</p>
<p><span style="text-decoration: underline;">Test-driven Requirements</span></p>
<p>This cluster describes a set of practices that focuses on testable requirements.  These practices are Functional Tests, Customer Part Of Team and Continuous Integration.</p>
<p><strong>Thoughts</strong></p>
<p>The first part of the book deals with the first problem when trying to adopt agile practices and that is to get buy in from the stakeholders.  What is the business getting from this transition? What are the business owners getting?  What are the developers getting?  All questions that need to be answered before you can start to transition to agile practices.  The transition is not an easy one and so you will need committed stakeholders.</p>
<p>The section on smells relates the problems that the business is experiencing to those of the development teams and vice versa which is really useful in clarifying possible cause and effect.</p>
<p>I recently read <a href="http://thoughtforge.net/2010/06/29/the-pragmatic-programmer/" target="_blank">The Pragmatic Programmer</a> and I like the way the material presented similarly to a pattern language i.e. short, concise and well organised.  Presenting them as patterns also leads a developer familiar with patterns to understand how they can be applied, as guidance rather than absolute right or wrong.</p>
<p>The “Sketch” narrative in the patterns section enhances the understanding of the pattern.  I like this story telling approach and it is similar in style to the <a href="http://xprogramming.com/category/kate-oneal" target="_blank">Kate Oneal</a> stories by <a href="http://xprogramming.com" target="_blank">Ron Jefferies</a>.</p>
<p>The difficulty of non-consistent architecture when applying evolutionary design is very real and although it is addressed in the book, it is a problem that will always be difficult to address.  Communication and collaboration can be the key but then you have the potential problem of too much communication.  The “Divide After You Conquer” technique is one I have seen work well in the past and this is the approach I would tend to take.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/07/13/patterns-of-agile-practice-adoption/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Domain Driven Development Quickly</title>
		<link>http://thoughtforge.net/2010/07/05/domain-driven-development-quickly/</link>
		<comments>http://thoughtforge.net/2010/07/05/domain-driven-development-quickly/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 09:06:41 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=803</guid>
		<description><![CDATA[With the advent and popularity of the EJB specification, developers spent more and more time focusing on learning and adhering to specifications and less time focusing on good design principles and OO development techniques.  “Domain Driven Design” by Eric Evans attempted to reverse this trend by refocusing on the most important aspect of software design, [...]]]></description>
			<content:encoded><![CDATA[<p>With the advent and popularity of the EJB specification, developers spent more and more time focusing on learning and adhering to specifications and less time focusing on good design principles and OO development techniques.  “Domain Driven Design” by Eric Evans attempted to reverse this trend by refocusing on the most important aspect of software design, i.e. representing the business domain within the software.</p>
<p>“<a href="http://www.infoq.com/minibooks/domain-driven-design-quickly" target="_blank">Domain Driven Development Quickly</a>” is a book from InfoQ that summarises the material presented in Eric Evans’ Domain-Driven Design book.  It can be downloaded freely in PDF format (requires registration).<span id="more-803"></span></p>
<p><strong>Chapter Summary</strong></p>
<p><strong>What is Domain Driven Development</strong></p>
<p>An introduction to domain driven development is presented by first discussing the general nature of software development.  An example and discussion of the solution domain follows.</p>
<p>The value of reflecting the (abstract) business domain in code is discussed.  An overview is provided of how the model is developed from initial discussions with domain knowledge experts.  A high level explanation of how the domain model evolves and is used to convey knowledge among interested parties is then given.</p>
<p>The Waterfall Model receives some criticism because of the absence of a feedback loop from business expert to analyst to developer.  Agile methodologies on the other hand receive praise for their iterative nature.</p>
<p>Finally, a worked example of building a domain model for a flight control system is presented. The role of the software modeller and knowledge expert is described as is their interaction during the development of the domain model.</p>
<p><strong>The Ubiquitous Language</strong></p>
<p>This chapter begins by describing the need for a common language through which the software and knowledge experts communicate.  The domain model is described as the basis for this common language as it is the place where software meets the domain.  This language is known as the Ubiquitous Language because it is the common language used for all communications related to the project.</p>
<p>An approach to creating a language is described through a hypothetical dialog between a software developer and a domain expert in the flight control system project.  Mechanisms to document the domain model include UML and it is recommended that non-trivial domain models are captured in many smaller UML documents with annotations where appropriate.</p>
<p><strong>Model-Driven Development</strong></p>
<p>Sometimes difficulties occur in translating a domain model into a model that can be implemented in code.  For this reason it is advised that the developers participate in the domain modelling process to ensure that the domain model can be implemented in code and is consistent with that derived during analysis.</p>
<p>The most important patterns for model driven design are covered and include the following;</p>
<p><span style="text-decoration: underline;">Layered Architecture</span></p>
<p>This pattern advocates partitioning a complex program into cohesive layers, specifically User Interface, Application Layer, Domain Layer and Infrastructure Layer.</p>
<p><span style="text-decoration: underline;">Entities</span></p>
<p>This pattern illustrates the use of objects that maintain a consistent and universal identity throughout the system.</p>
<p><span style="text-decoration: underline;">Value Objects</span></p>
<p>A Value Object is described as an object that is used to describe certain aspects of a domain but that does not possess an identity.  Value Objects are often immutable.  Money is a common example of a Value Object.</p>
<p><span style="text-decoration: underline;">Services</span></p>
<p>A Service is described as an object that contains functionality that is exhibited by the domain but not easily mapped to objects.  An example is given of a money transfer between two accounts; does this behaviour belong in the sending or receiving account?</p>
<p><span style="text-decoration: underline;">Modules</span></p>
<p>Modules are a way to organise related concepts in order to reduce complexity.</p>
<p><span style="text-decoration: underline;">Aggregates</span></p>
<p>“An Aggregate is a group of associated objects which are considered as one unit with regard to data changes.”  An example of a Customer and Address is given were the Address is immutable and changes are made through the Customer e.g. customer.setAddress(String line1..).</p>
<p><span style="text-decoration: underline;">Factories</span></p>
<p>A Factory encapsulates complex creational functionality allowing clients to create Aggregates without exposing the construction mechanism.</p>
<p>The Factory Method and Abstract Factory patterns are review from the perspective of domain modelling.</p>
<p><span style="text-decoration: underline;">Repositories</span></p>
<p>Repositories are objects used to obtain references to Entities, usually from a database or another persistent data store.  The Repository interface will be pure domain model and so should not imply a specific persistence store.</p>
<p><strong>Refactoring Toward Deeper Insight</strong></p>
<p>This section begins by discussing refactoring the domain model when new concepts or insight occur.  It then goes on to talk about breakthrough moments when a significant (in terms of understanding) change is required to the model.  Breakthroughs occur generally when some implicit knowledge becomes explicit and this occurs naturally when exploring concepts with domain experts.  They can also occur when contradictions are highlighted or through reading material on the domain.</p>
<p>The usefulness of making the Constraint, Process and Specification concepts explicit is also discussed.  I particularly like the Specification concept which is used to test an object to check if an object satisfies certain criteria.</p>
<p><strong>Preserving Model Integrity</strong></p>
<p>This section deals with preserving the integrity of the model when a project involves large or multiple teams.  The model can become disjointed and the consistency of the model can suffer.  The suggested solution is to create several independent modules that are well integrated.  This allows each model to evolve, as long as it adheres to its contract, and the interaction between models to remain unaffected.</p>
<p>A number of techniques to help maintain model integrity are presented as follows:</p>
<p><span style="text-decoration: underline;">Bounded Context</span></p>
<p>The bounded context defines a specific meaning for each model and the language used within.  The meaning is used consistently within the model and by other models interacting with the model.</p>
<p><span style="text-decoration: underline;">Continuous Integration</span></p>
<p>Continuous integration suggests frequent build and test cycles to detect inconsistencies between interdependent models.</p>
<p><span style="text-decoration: underline;">Context Map</span></p>
<p>This extract from the book describes this concept very concisely: “The context map is a document that outlines different bounded contexts and the relationships between them.”</p>
<p><span style="text-decoration: underline;">Shared Kernel</span></p>
<p>A shared kernel is a model sub-section that is shared between multiple models.</p>
<p><span style="text-decoration: underline;">Customer-Supplier</span></p>
<p>Customer-supplier describes a relationship between two models when one model utilises another significantly.</p>
<p><span style="text-decoration: underline;">Conformist</span></p>
<p>Conformist describes when a supplier has no motivation to evolve a model in collaboration with a customer and so the customer must conform to all changes in the supplier’s model.</p>
<p><span style="text-decoration: underline;">Anticorruption Layer</span></p>
<p>The anticorruption layer is a subsection of a model that is consistent with the model but represents concepts from and interacts with another external model.</p>
<p><span style="text-decoration: underline;">Separate Ways</span></p>
<p>Separate ways describes what happens when the benefits of integrating two models are outweighed by the cost.  The two models diverge and cease to maintain any commonality.</p>
<p><span style="text-decoration: underline;">Open Host Service</span></p>
<p>Open host service describes when a single supplier model is utilised by multiple customer models using a single common interface.  The interface is expanded and refactored to meet the needs new integration requirements.</p>
<p><span style="text-decoration: underline;">Distillation</span></p>
<p>Distillation is the process of talking a large domain model and extracting the essence of the model into a core domain model.  Elements of the model that do not form the core domain model will be captured in generic sub-domains.</p>
<p><strong>DDD Matters Today: An Interview with Eric Evans</strong></p>
<p>An interesting interview with Eric Evens is included at the end of this book.  The interview is best distilled by presenting the questions of the interviewer.  They are as follows:</p>
<p><em>Why is Domain Driven Design as important today as ever?</em></p>
<p><em>Technology platforms are continually evolving.  How does Domain Driven Design fit in?</em></p>
<p><em>What’s been happening in the Domain Driven Design community since you’ve written your book?</em></p>
<p><em>Do you have any advice for people trying to learn Domain Driven Design today?</em></p>
<p><strong>Thoughts</strong></p>
<p>I like the emphasis placed on developing the Ubiquitous Language and totally agree with its value to a project in creating a common vocabulary.</p>
<p>I agree with the vast majority of the material but I’m not sure that I agree with the suggestion that a repository interface should use a “Specification” to define complex criteria for Entity search.  More often than not, the specification tempts developers to couple data access knowledge to the Application Layer.  I see this as similar to using criteria queries defined within the Application Layer and in my opinion this breaks encapsulation.  I much prefer strongly typed search interfaces with methods such as findActiveByName, findByColourAndLength etc.  I guess I could accept the Specification approach if the Specification deals with pure domain model (i.e. Entities and/or Value Objects) and does not have pseudo JPA SQL.</p>
<p>The interview with Eric is excellent and if you don’t have time to read the entire book I would recommend at least reading the interview.  The answers were insightful and provided a good summary of the past and future of domain driven development.</p>
<p>Overall, there is much to take away from this book and I will certainly be focusing more on trying to apply some of the concepts, in particular the Specification concept.  It’s a no-brainer to read this book.  It is full of relevant, current and well presented material.  It is freely available and is a good investment of time.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/07/05/domain-driven-development-quickly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Pragmatic Programmer</title>
		<link>http://thoughtforge.net/2010/06/29/the-pragmatic-programmer/</link>
		<comments>http://thoughtforge.net/2010/06/29/the-pragmatic-programmer/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 10:07:32 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=763</guid>
		<description><![CDATA[If you are a software developer, The Pragmatic Programmer is not just a book but an arm around your shoulder, the mentor that you never had.  It has rightly earned its place on the bookshelf of every self respecting software developer in the land.  First published in 1999, it is as relevant today as ever.
Ron [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/Pragmatic-Programmer-Andrew-Hunt/dp/020161622X%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D020161622X"><img class="alignright" src="http://ecx.images-amazon.com/images/I/41HXiIojloL._SL160_.jpg" alt="" width="127" height="160" /></a>If you are a software developer, The Pragmatic Programmer is not just a book but an arm around your shoulder, the mentor that you never had.  It has rightly earned its place on the bookshelf of every self respecting software developer in the land.  First published in 1999, it is as relevant today as ever.</p>
<p>Ron Jefferies said about this book <em>“As with any such book, much of the advice is something you already know. Much of it is also something you have forgotten to focus on lately.”</em> You may or may not learn anything new, but this book will remind you what is important.<span id="more-763"></span></p>
<p><strong> Chapter Summary</strong></p>
<p><strong>Chapter 1 – A Pragmatic Philosophy</strong></p>
<p>“Software Entropy” is compared to the “Broken Window Theory” and some causes and consequences are discussed.  This is a very useful analogy and comparable to technical debt as used by some agile methodologies.</p>
<p>The knowledge portfolio is a very useful concept and it never ceases to amaze me how little software “professionals” invest in their development.  Join a “big 4” accountancy firm and you will be mentored through an intensive training programme; medical and legal professionals are required to earn “continued professional development” (CPD) points and yet some software developers aspire to be considered “professional” without “Investing in their Knowledge Portfolio”.  It’s not all one way though; the knowledge portfolio needs to be valued more by those employing software “professionals”.</p>
<p>One of the sentences that stood out when discussing communication was the following: “This isn’t communicating: it’s just talking, and it’s annoying”.  How true this is and it’s the role of a strong meeting facilitator (Scrum master etc.) to ensure that participants are communicating and not just talking.  The same goes for email groups and so many things besides.</p>
<p><strong> Chapter 2 – A Pragmatic Approach</strong></p>
<p>“The Evils of Duplication” highlights the areas were duplication can (and does) occur, the consequences and how to best avoid duplication.  This includes requirements and design documentation as well as code.</p>
<p>The recommendation to have in built “Reversibility” not only reinforces the OO principles of encapsulation and programming to interfaces but goes further by suggesting that these be applied at an architectural level.  Of course this process has a limit and some decisions will always be difficult to reverse.</p>
<p>“Tracer Bullets” are described as end-to-end implementations of a subset of functionality that is built upon to deliver the complete solution.  I guess this is similar to what is often referred to as “spikes” except that Tracer Bullets are incorporated in the complete solution.</p>
<p>The use and abuse of prototypes are discussed along with some decisions to make when considering prototyping.  The choice of using “Tracer Bullets” as opposed to prototypes is also covered.</p>
<p>Tips and techniques for estimating are explored along with some insightful thoughts on how people interpret estimates.  For example, an estimate of 16 weeks or 4 months is the same (approximately) in terms of duration but the latter suggests a greater degree of uncertainty.</p>
<p><strong> Chapter 3 – The Basic Tools</strong></p>
<p>Stepping out of the IDE used to be something that every developer did frequently.  Now it is less common and we are reminded of the power and flexibility of shell commands.</p>
<p>Source control systems have evolved significantly over the past few years and we are reminded why we use source control and where its value lies.  Useful stuff if you are trying to make a case to move away from your current source control system.  While migrating source can be challenging, I’m often surprised at the inertia in this area when the benefits are substantial.</p>
<p>In football, commentators often talk about “playing the percentages” and this concept is used to discuss debugging and root cause analysis.  Look in the most likely places first (i.e. your own code) and you will find bugs faster.  The tendency to point somewhere else must be overcome.  Other useful practices such as feeding bugs back in to regression testing are discussed.</p>
<p>Code generation is discussed and importantly how it violates the DRY principle to check in code generated by active code generators.  This is something I see often and it is normally accompanied by some justification.  With the flexibility and power of today’s build tools, I feel there is no justification for checking in actively generated code.</p>
<p><strong> Chapter 4 – Pragmatic Paranoia</strong></p>
<p>Design by contract (DBC) is introduced in the context of method contracts.  Of course, these days when DBC is discussed we are usually referring to web services but more fundamental is the contract of our methods.  Assertions are a good tool for enforcing method contracts and some of the subtleties of using assertions are discussed.</p>
<p>The other sections on exceptions and resource management are probably well known to most nowadays as there is a greater awareness of these subjects.</p>
<p><strong> Chapter 5 – Bend, or Break</strong></p>
<p>Coupling is explained and a description of using the Law of Demeter to reduce coupling for functions is given.  It was interesting to have this laid out in black and white.  The sort of knowledge one should absorb and apply without thinking (although it’s useful to work through the thought process).</p>
<p>The benefits of meta-data driven programming are extolled although again I would say that programmers are more aware of this type of programming and the trade-offs that at the time the book was written.</p>
<p>Temporal coupling (as pointed out by the author) is often forgotten, or not given enough focus (even in today’s world of multi-threaded, distributed systems) during system design.  A solid understanding of the temporal coupling within a system will make opportunities for improved concurrency more visible.</p>
<p>The Model-View-Controller pattern, Observer pattern and Publish-Subscribe paradigm are discussed in the context of reduced coupling.  Additional reading is necessary for the reader to fully grasp the concepts being presented.</p>
<p>Blackboards or shared-spaces are discussed along with their potential to reduce coupling.  I recently took an agent oriented programming course so this material was very familiar.</p>
<p><strong>Chapter 6 – While You Are Coding</strong></p>
<p>I found the first paragraph in this chapter very striking as I have had many experiences that reinforce the point.  This paragraph states:</p>
<p><em>“Conventional wisdom says that once a project is in the coding phase, the work is mostly mechanical, transcribing the design into executable statements.  We think this attitude is the single biggest reason that many programs are ugly, inefficient, poorly structured, unmaintainable, and just plain wrong.”</em></p>
<p>The emergence of Agile methodologies has gone some way to increase the awareness of this point by pushing design closer to implementation but this problem has not gone away.</p>
<p>An overview of how to estimate algorithm speed is provided and some guidance is provided to apply these techniques.  As is stated, this is not something that most developers have to be overly concerned about but all should have an appreciation and awareness of the effect different algorithms can have on performance.</p>
<p>Refactoring and unit testing are then discussed.  Developers are a lot more aware of these subjects than when the book was originally written but nevertheless the sections provide a useful refresher.</p>
<p>A section on wizards or “Evil Wizards” describes the potential hazards of using wizards and adopting code that you may have little understanding of.</p>
<p><strong>Chapter 7 – Before The Project</strong></p>
<p>Pragmatic approaches to determining and documenting requirements are discussed along with some common mistakes.</p>
<p>“Solving Impossible Puzzles” encourages use to take a step back, look at the puzzle we are trying to solve, try to solve it in other ways or perhaps it is not a problem we need to solve after all.</p>
<p>“Circles and Arrows” reminds us to take what is useful from formal methods and leave behind those things that are not.</p>
<p><strong>Chapter 8 – Pragmatic Projects</strong></p>
<p>Previous techniques are revisited with a focus on how their characteristics change when applied to a team of programmers.</p>
<p>Automation is then covered in some detail including code/documentation generation as well as automated build, test, coverage etc.</p>
<p>“Ruthless Testing” encourages programmers to think about the value of testing, add tests that are valuable and test the tests.  When a bug slips through the net test suits should be enhanced to reduce the chance of future occurrences.</p>
<p>“It’s all Writing” outlines the importance of writing documentation in a way that adheres to the DRY principle and that follows the same pragmatic approach taken when writing code.</p>
<p><strong>Thoughts</strong></p>
<p>Each section describes a pragmatic practice that one might adopt in an attempt to improve working practice and performance.  In the foreword by Ward Cunningham, Ward compares the presentation of the material to that of pattern languages.  This is because each section is described concisely with “Related Sections” and “Challenges”.  This worked out great for me because I want bite sized nuggets of information to read on my daily commute.  I am never forced to put the book down in the middle of a section as they are short enough to read quickly and independent enough that they can be read in any order.</p>
<p>As with its follow up ‘Pragmatic Thinking &amp; Learning’, ‘The Pragmatic Programmer’ is littered with relevant quotes.  Again, I have highlighted some of my favourites below:</p>
<p>Benjamin Franklin, <em>“An investment in knowledge always pays the best interest.”</em></p>
<p>Mae West, <em>“I believe it is better to be looked over than it is to be overlooked.”</em></p>
<p>Emil-Auguste Chartier, <em>“Nothing is more dangerous than an idea if it’s the only one you have.”</em></p>
<p>Woody Allen, <em>“When everybody actually is out to get you, paranoia is just good thinking.”</em></p>
<p>Ralph Waldo Emerson, <em>“Nothing astonishes men so much as common sense and plain dealing.”</em></p>
<p>If you want to read a book that just makes sense then this is the book you have been looking for.  You will find yourself repeating “how true” over and over again until the point when you ask “This stuff is so obvious.  Why have I not thought of this before and why are we not acting upon it.”  Well here is your chance to redeem yourself; pick up a copy, read it, then apply it.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/06/29/the-pragmatic-programmer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pragmatic Thinking &amp; Learning</title>
		<link>http://thoughtforge.net/2010/06/10/pragmatic-thinking-learning/</link>
		<comments>http://thoughtforge.net/2010/06/10/pragmatic-thinking-learning/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 15:18:46 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=751</guid>
		<description><![CDATA[Recently, I have taken to reading books concerned more with process of software development than the nuts and bolts of working with one language/framework/methodology or another.  The Pragmatic Programmer is one such popular book that inspired a whole range of such books under The Pragmatic Bookshelf label.  Another book under this label is &#8220;Pragmatic Thinking [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/Pragmatic-Thinking-Learning-Refactor-Programmers/dp/1934356050%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1934356050"><img class="alignright" src="http://ecx.images-amazon.com/images/I/51xArZnegaL._SL160_.jpg" alt="" width="134" height="160" /></a>Recently, I have taken to reading books concerned more with process of software development than the nuts and bolts of working with one language/framework/methodology or another.  The Pragmatic Programmer is one such popular book that inspired a whole range of such books under The Pragmatic Bookshelf label.  Another book under this label is &#8220;Pragmatic Thinking &amp; Learning&#8221; by Andy Hunt.<span id="more-751"></span></p>
<p><strong>Chapter Summary</strong></p>
<p><strong>Chapter 1 &#8211; Introduction</strong></p>
<p>The context for the book is set and importantly, Andy highlights that while this book discusses the material and techniques with a focus on programming, it is not specific to programming.  Indeed, I purchased the book hoping to improve the effectiveness of my studying techniques generally and the techniques covered have wide applicability.  Andy also summarises the material and how it will be presented.</p>
<p><strong>Chapter 2 &#8211; Journey from Novice to Expert</strong></p>
<p>The five stages of the Dreyfus model of Skill Acquisition are explored.  Examples of how the Dreyfus model can be used (and abused) are presented in the section “Herding Racehorses and Racing Sheep”.  It’s a very useful title in that it invokes a strong image of poor utilisation of specialised resources.</p>
<p><strong>Chapter 3 &#8211; This is Your Brain</strong></p>
<p>The nature of human learning is explored and distinctions are made between the “left-brain” (L-mode) and the “right-brain” (R-mode).  Andy describes L-mode thinking as the process of linear thinking that provides us with analytic, rational and logical abilities.  He describes R-mode thinking as the process of rich thinking that provides us with synthetic and intuitive abilities.  Andy describes the importance of both modes of thinking and how to stimulate both, paying particular attention to R-mode given that it provides functions important to the expert practitioner.</p>
<p><strong>Chapter 4 &#8211; Get in Your Right Mind</strong></p>
<p>Techniques for engaging the “right-brain” are explored along with which mode is appropriate to which activity.  Often, to accomplish a goal both modes are required and this is demonstrated by a story about rock climbing that was particularly appropriate.</p>
<p><strong>Chapter 5 &#8211; Debug Your Mind</strong></p>
<p>Further insight is given into how we think, the processes we undertake and the flaws (or features) of our thought process.  “To be forewarned is to be forearmed” and so to be aware of the flaws in our thought process is to impart the ability to compensate for such flaws.  One such flaw was that of anchoring which was demonstrated during a lecture I recently attended.  A group were asked to write down an estimate for a piece of work and then asked to call out the estimate to the group.  It was demonstrated that people altered their estimate as others in the group made their own estimate known.  The discussion on generational affinity was also very insightful and very easy to relate to my own experience.</p>
<p><strong>Chapter 6 &#8211; Learn Deliberately</strong></p>
<p>Applied techniques to learning are described including SMART objectives, Pragmatic Investment Plans, study groups, SQ3R (Survey, Question, Read, Recite, and Review) and Mind Maps.  Andy also describes how he personally uses these techniques and what he feels works well.</p>
<p><strong>Chapter 7 &#8211; Gain Experience</strong></p>
<p>The famous catch 22 situation of needing experience to attain a role that provides experience comes to mind.  Other methods of gaining experience are discussed along with which experiences are more important than others.  Andy then discusses how to approach learning through exploration and the importance of learning through mistakes.  This includes the characteristics of an environment that facilitates this type of learning (source control etc.).  The advantages and disadvantages of leveraging existing knowledge to attain new knowledge are covered.</p>
<p><strong>Chapter 8 &#8211; Manage Focus</strong></p>
<p>The importance of maintaining focus and the cost of switching focus are explored.  Practical techniques to reduce interruption are introduced.  Techniques range from meditation to simple things like managing desktop and telephone (IM, internet&#8230;) interruptions.  Project teams rules of engagement are introduced as rules to reduce interruptions within project teams.</p>
<p>Knowledge management techniques such as wiki’s etc are discussed with reference to how Andy uses such techniques to develop his own knowledge and ideas.</p>
<p><strong>Chapter 9 &#8211; Beyond Expertise</strong></p>
<p>A parting note from Andy on possible next steps presented as a way to apply the knowledge attained through the book.</p>
<p><strong>Thoughts</strong></p>
<p>The “Next Actions” serve as a very useful prompt to not only read and learn the material but to apply it while it is fresh in your mind (thus reinforcing it).  This is very important with this type of material.</p>
<p>The numerous quotations sprinkled throughout the book encapsulated the essence of the material and planted a seed of thought from which to explore the material more thoroughly.  Here are some quotes which I found particularly relevant:</p>
<p><em>John Muir: &#8220;When we try to pick out anything by itself, we find it hitched to everything else in the universe.&#8221;</em></p>
<p><em>Albert Einstein: &#8220;We can&#8217;t solve problems by using the same kind of thinking we used when we created them.&#8221;</em></p>
<p><em>Mark Twain: “We should be careful to get out of an experience only the wisdom that is in it and stop there; least we be like the cat that sits on a hot stove-lid; he will never sit on a hot stove-lid again – and that is well; but also he will never sit on a cold one anymore.”</em></p>
<p><em>James Joyce: “A man’s errors are his portals to discovery.”</em></p>
<p><em>John Anthony Ciardi: “A good question is never answered.  It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of idea.”</em></p>
<p>While these quotes are insightful to me, I can&#8217;t help think that for some, nothing short of writing them on a stick and hitting them on the head will have people consider them in the same light.</p>
<p>I found the anecdotes throughout the book particularly useful in explaining sometimes difficult concepts.  The tips provide suggestions to apply the techniques and are enumerated at the end of the book in a number of tear out cards.</p>
<p>Overall, the book was a good read, packed with practical suggestions of how to apply the material to enhance one’s thinking and learning capacity.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/06/10/pragmatic-thinking-learning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Soul of a New Machine</title>
		<link>http://thoughtforge.net/2010/05/07/the-soul-of-a-new-machine/</link>
		<comments>http://thoughtforge.net/2010/05/07/the-soul-of-a-new-machine/#comments</comments>
		<pubDate>Fri, 07 May 2010 11:15:38 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=747</guid>
		<description><![CDATA[I am currently undertaking an MSc in Advanced Software Engineering at UCD, Dublin and recently took a module on &#8216;Software Engineering Process Frameworks&#8217;.  As part of the pre-reading for this module the class were asked to read Tracey Kidder&#8217;s &#8216;The Soul of a New Machine&#8217;.
The book chronicles the experience of an engineering team struggling to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/Soul-New-Machine-Modern-Library/dp/0679602615%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0679602615"><img class="alignright" src="http://ecx.images-amazon.com/images/I/41SU3tRaepL._SL160_.jpg" alt="" width="109" height="160" /></a>I am currently undertaking an MSc in Advanced Software Engineering at UCD, Dublin and recently took a module on &#8216;Software Engineering Process Frameworks&#8217;.  As part of the pre-reading for this module the class were asked to read Tracey Kidder&#8217;s &#8216;The Soul of a New Machine&#8217;.</p>
<p>The book chronicles the experience of an engineering team struggling to design and develop a new computer under huge pressure, both internal and external.</p>
<p>This is not the sort of book I would ordinarily pick up and read as I normally find myself reading books on specific technologies, frameworks or methodologies.  I must admit that I enjoyed the book and found that despite being published in 1981, Tracey Kidder&#8217;s observations on the way the organisation approached projects and the associated challenges were very familiar.</p>
<p>It was most striking that I have worked with many characters similar to those portrayed in the book.  Kidder&#8217;s observations on, and reasoning about, their behaviour was very insightful.  Kidder also focused on how the individual team members collaborated and the intricate personal relationships within the group.</p>
<p>Overall, an extremely interesting case study of people, process and practice and how they interact in a knowledge based industry.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/05/07/the-soul-of-a-new-machine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Profiling Aspect with Spring AOP and AspectJ</title>
		<link>http://thoughtforge.net/2010/03/28/creating-a-profiling-aspect-with-spring-aop-and-aspectj/</link>
		<comments>http://thoughtforge.net/2010/03/28/creating-a-profiling-aspect-with-spring-aop-and-aspectj/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 20:40:19 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Spring AOP]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=713</guid>
		<description><![CDATA[As I have mentioned previously, there are several utilities that I often find myself reusing when I join a new project.  One of these utilities is the Logging or Tracing Aspect that I have previously discussed while the other is an aspect that facilitates a rudimentary profiling of the application code.
I first got the idea [...]]]></description>
			<content:encoded><![CDATA[<p>As I have mentioned previously, there are several utilities that I often find myself reusing when I join a new project.  One of these utilities is the <a href="http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/" target="_blank">Logging or Tracing Aspect</a> that I have previously discussed while the other is an aspect that facilitates a rudimentary profiling of the application code.</p>
<p>I first got the idea for such a profiling aspect from the Spring Framework user guide which presents a basic implementation in the Spring AOP section.  I subsequently observed a more sophisticated implementation developed by <a href="http://cowboysmall.com/" target="_blank">Jerry Kiely</a>, who I occasionally have the pleasure of working with.</p>
<p>In what follows, I will present an implementation of a profiling aspect and explain how this can be utilised using Spring and AspectJ Load Time Weaving.</p>
<p><span id="more-713"></span></p>
<p><strong>Task and Task Timer Implementation</strong></p>
<p>The profiling aspect will record the start time and end time of each method invocation thus allowing more valuable statistics to be derived at a later point in time.  To make this functionality reusable, we will develop more abstract TaskTimer and Task implementations.</p>
<p>The Task represents any action for which we require timing metrics and records the task name, start time and end time.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.task;

public class Task {
&nbsp;&nbsp;
&nbsp;&nbsp;private Long endTime;
&nbsp;&nbsp;
&nbsp;&nbsp;private String name;
&nbsp;&nbsp;
&nbsp;&nbsp;private Long startTime;
&nbsp;&nbsp;
&nbsp;&nbsp;public Task(String name, Long startTime) {
&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;
&nbsp;&nbsp;&nbsp;&nbsp;this.startTime = startTime;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public long getDuration() {
&nbsp;&nbsp;&nbsp;&nbsp;return endTime - startTime;
&nbsp;&nbsp;}

&nbsp;&nbsp;public Long getEndTime() {
&nbsp;&nbsp;&nbsp;&nbsp;return endTime;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void setEndTime(Long endTime) {
&nbsp;&nbsp;&nbsp;&nbsp;this.endTime = endTime;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public String getName() {
&nbsp;&nbsp;&nbsp;&nbsp;return name;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public Long getStartTime() {
&nbsp;&nbsp;&nbsp;&nbsp;return startTime;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Task.java</p>
</div>
<p></br><br />
The TaskTimer provides a simple stack based timer implementation that allows one to start a named task, stop a task and obtain a list of all completed tasks.  When a  named task is started, it is pushed onto the stack and when a task is stopped, it is popped off the stack and the end time is set.  The task is then added to a list of completed tasks for futher analysis at a later point in time.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.task;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class TaskTimer {

&nbsp;&nbsp;private List&lt;Task&gt; completedTasks = new ArrayList&lt;Task&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;private Long endTime;
&nbsp;&nbsp;
&nbsp;&nbsp;private String id;
&nbsp;&nbsp;
&nbsp;&nbsp;private Long startTime;
&nbsp;&nbsp;
&nbsp;&nbsp;private Stack&lt;Task&gt; taskStack = new Stack&lt;Task&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;public TaskTimer(String id) {
&nbsp;&nbsp;&nbsp;&nbsp;this.id = id;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public long getTaskCount() {
&nbsp;&nbsp;&nbsp;&nbsp;return taskStack.size();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public long getTotalDuration() {
&nbsp;&nbsp;&nbsp;&nbsp;return endTime - startTime;
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public String printSummary() {
&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer summary = new StringBuffer(shortSummary());
&nbsp;&nbsp;&nbsp;&nbsp;summary.append(&#039;\n&#039;);

&nbsp;&nbsp;&nbsp;&nbsp;TaskSummaryVisitor taskSummaryVisitor = new TaskSummaryVisitor(getTotalDuration());
&nbsp;&nbsp;&nbsp;&nbsp;for (Task task: completedTasks) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;taskSummaryVisitor.visit(task);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;summary.append(taskSummaryVisitor.printTaskSummaries());
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return summary.toString();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public String shortSummary() {
&nbsp;&nbsp;&nbsp;&nbsp;return &quot;TaskTimer &#039;&quot; + this.id + &quot;&#039;: running time (millis) = &quot; + getTotalDuration();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void start(String name) {
&nbsp;&nbsp;&nbsp;&nbsp;Long startTime = System.currentTimeMillis();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (taskStack.isEmpty()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.startTime = startTime;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;taskStack.push(new Task(name, startTime));
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void stop() {
&nbsp;&nbsp;&nbsp;&nbsp;Long endTime = System.currentTimeMillis();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Task currentTask = taskStack.pop();
&nbsp;&nbsp;&nbsp;&nbsp;currentTask.setEndTime(endTime);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (taskStack.isEmpty()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.endTime = endTime;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;completedTasks.add(currentTask);
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : TaskTimer.java</p>
</div>
<p></br><br />
The TaskTimer is not an exhaustive implementation (no checks for end of stack etc.) so if you intend to reuse this you should certainly adapt it further.</p>
<p>I notice a <a href="http://jira.springframework.org/browse/SPR-2739" target="_blank">JIRA issue</a> requesting that Spring add similar functionaliy to the StopWatch class.</p>
<p><strong>The Profiling Aspect</strong></p>
<p>As with the Logging Aspect, the Profiling Aspect uses the @Aspect approach to defining the aspect, advice and pointcuts.</p>
<p>The first thing you will notice is a ThreadLocal reference to a TaskTimer.  This ensures the method profile metrics from different threads are not interleaved.  It is more that likely that one will want to look at profiling information from a single thread at a time.</p>
<p>The aspect contains a single piece of around advice that creates a task name, starts the task timer, invokes the method and stops the task timer.  This is fairly trivial and the only point of interest to draw your attention to is the point where the profiling metrics are output to the logging system.</p>
<p>Effectively, on completion of the method that initiates the profiling, the profiling metrics will be output to the logging system.  If you consider a Servlet based application you could imagine the profiling beginning on the Servlet service method, and the profiling information being logged on the completion of the service method.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import net.thoughtforge.task.TaskTimer;

import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public abstract class ProfilingAspect {

&nbsp;&nbsp;&nbsp;&nbsp;private ProfilerThreadLocal profilerThreadLocal = new ProfilerThreadLocal();

&nbsp;&nbsp;&nbsp;&nbsp;@Pointcut
&nbsp;&nbsp;&nbsp;&nbsp;public abstract void profilingPointcut();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@Around(&quot;profilingPointcut()&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;public Object doProfiling(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String taskName = createTaskName(proceedingJoinPoint);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TaskTimer taskTimer = profilerThreadLocal.get();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;taskTimer.start(taskName);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return proceedingJoinPoint.proceed();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} finally {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;taskTimer.stop();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (taskTimer.getTaskCount() == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doLogging(proceedingJoinPoint.getTarget().getClass(), taskTimer.printSummary());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;profilerThreadLocal.remove();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;private String createTaskName(ProceedingJoinPoint proceedingJoinPoint) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new StringBuffer(proceedingJoinPoint.getTarget().getClass().getName())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append(&quot;.&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append(proceedingJoinPoint.getSignature().getName())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.toString();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;private void doLogging(Class&lt;? extends Object&gt; clazz, String prettyPrint) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.getLog(clazz).info(&quot;\n\n&quot; + prettyPrint + &quot;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;private class ProfilerThreadLocal extends ThreadLocal&lt;TaskTimer&gt; {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected TaskTimer initialValue() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new TaskTimer(Thread.currentThread().getName());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : ProfilingAspect.java</p>
</div>
<p></br><br />
<strong>Specifying the Pointcut</strong></p>
<p>As with the Logging Aspect, the Profiling Aspect pointcut expression selects methods annotated with a specific annotation (the Profilable annotation).  This obviously prohibits profiling code which you cannot modify (i.e. add the annotation) so you will probably want to use other criteria within the pointcut expression.</p>
<p>By default, Spring uses proxy based aspect orientated programming (AOP) which limits us to applying aspects to Spring beans (look at the spring documentation for further discussion).  An alternative to proxy based AOP is to use AspectJ Load Time Weaving (LTW) which instruments the code when loaded by the class loader.</p>
<p>To enable LTW, a configuration file (aop.xml) must be placed in a META-INF directory on the classpath.  Within the aop.xml file, the aspect and the classes to be weaved must be specified.  The pointcut expression can also be specified but I will leave this for you to look into.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;!DOCTYPE aspectj PUBLIC &quot;-//AspectJ//DTD//EN&quot; &quot;http://www.eclipse.org/aspectj/dtd/aspectj.dtd&quot;&gt;

&lt;aspectj&gt;
&nbsp;&nbsp;&lt;weaver&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- only weave classes in our application-specific packages --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;include within=&quot;net.thoughtforge.service.*&quot;/&gt;
&nbsp;&nbsp;&lt;/weaver&gt;
&nbsp;&nbsp;&lt;aspects&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- weave in just this aspect --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;concrete-aspect name=&quot;profilingAspect&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;extends=&quot;net.thoughtforge.aspect.ProfilingAspect&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;pointcut name=&quot;profilingPointcut&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression=&quot;execution(* *(..)) &amp;amp;&amp;amp; @annotation(net.thoughtforge.aspect.Profilable)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/concrete-aspect&gt;
&nbsp;&nbsp;&lt;/aspects&gt;
&lt;/aspectj&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : aop.xml</p>
</div>
<p></br><br />
The other thing that needs to be done is to instruct the JVM to have AspectJ perform the LTW when a class is loaded.  To do this specify the following JVM parameter (inserting your own path):</p>
<p>-javaagent:{path-to}\spring-agent-2.5.6.jar</p>
<p>Specifying the spring agent as opposed to the AspectJ agent has some advantages discussed within the Spring documentation.</p>
<p><strong>Testing the Profiling Aspect</strong></p>
<p>In this instance, rather than create a unit test to test the Profiling Aspect, I have created one to demonstrate it in action.  I created a simple service annotated with the Profilable annotation.  Invocations of methods within this service will be profiled and the profiling metrics will be output by the logging framework.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import net.thoughtforge.service.ExampleService;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-aspect.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-service.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext.xml&quot; })
public class ProfilingAspectTest {

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;public ExampleService exampleService;

&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void doSomething() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;exampleService.doSomething();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void doSomethingWithSomething() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;exampleService.doSomethingWithSomething();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void doSomethingWithSomethingFiftyTimes() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;exampleService.doSomethingWithSomethingFiftyTimes();
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : ProfilingAspectTest.java</p>
</div>
<p></br><br />
Executing the profiling aspect test results in the following logging output:</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
TaskTimer &#039;main&#039;: running time (millis) = 109

-------------------------------------------------------------------------------------------------
Invocations&nbsp;&nbsp;Total Time(%)&nbsp;&nbsp;Total Time(ms)&nbsp;&nbsp;Min Time&nbsp;&nbsp;Max Time&nbsp;&nbsp;Average Time(ms)&nbsp;&nbsp;Task Name
-------------------------------------------------------------------------------------------------
00001&nbsp;&nbsp;&nbsp;&nbsp;100%&nbsp;&nbsp;&nbsp;&nbsp;00109&nbsp;&nbsp;&nbsp;&nbsp;00109&nbsp;&nbsp;&nbsp;&nbsp;00109&nbsp;&nbsp;&nbsp;&nbsp;00109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.doSomething

TaskTimer &#039;main&#039;: running time (millis) = 63

-------------------------------------------------------------------------------------------------
Invocations&nbsp;&nbsp;Total Time(%)&nbsp;&nbsp;Total Time(ms)&nbsp;&nbsp;Min Time&nbsp;&nbsp;Max Time&nbsp;&nbsp;Average Time(ms)&nbsp;&nbsp;Task Name
-------------------------------------------------------------------------------------------------
00001&nbsp;&nbsp;&nbsp;&nbsp;002%&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.getSomething
00001&nbsp;&nbsp;&nbsp;&nbsp;100%&nbsp;&nbsp;&nbsp;&nbsp;00063&nbsp;&nbsp;&nbsp;&nbsp;00063&nbsp;&nbsp;&nbsp;&nbsp;00063&nbsp;&nbsp;&nbsp;&nbsp;00063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.doSomethingWithSomething

TaskTimer &#039;main&#039;: running time (millis) = 4027

-------------------------------------------------------------------------------------------------
Invocations&nbsp;&nbsp;Total Time(%)&nbsp;&nbsp;Total Time(ms)&nbsp;&nbsp;Min Time&nbsp;&nbsp;Max Time&nbsp;&nbsp;Average Time(ms)&nbsp;&nbsp;Task Name
-------------------------------------------------------------------------------------------------
00001&nbsp;&nbsp;&nbsp;&nbsp;100%&nbsp;&nbsp;&nbsp;&nbsp;04027&nbsp;&nbsp;&nbsp;&nbsp;04027&nbsp;&nbsp;&nbsp;&nbsp;04027&nbsp;&nbsp;&nbsp;&nbsp;04027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.doSomethingWithSomethingFiftyTimes
00050&nbsp;&nbsp;&nbsp;&nbsp;001%&nbsp;&nbsp;&nbsp;&nbsp;00050&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.getSomething
00050&nbsp;&nbsp;&nbsp;&nbsp;098%&nbsp;&nbsp;&nbsp;&nbsp;03966&nbsp;&nbsp;&nbsp;&nbsp;00079&nbsp;&nbsp;&nbsp;&nbsp;00095&nbsp;&nbsp;&nbsp;&nbsp;00079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.thoughtforge.service.ExampleService.doSomethingWithSomething
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : Logging Output</p>
</div>
<p></br><br />
This article should act as a starting point for exploring Spring AOP and AspectJ further.  You can download the <a href="http://thoughtforge.net/wp-content/uploads/2010/03/spring-profiling-aspect.zip" target="_blank">profiling aspect code</a> and play around with Proxy based AOP and LTW, specifying the pointcut expression in the aop.xml file or within code etc.<br />
</br><br />
Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/03/28/creating-a-profiling-aspect-with-spring-aop-and-aspectj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jBPM Developer Guide</title>
		<link>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/</link>
		<comments>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 19:26:23 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[jBPM]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=697</guid>
		<description><![CDATA[Business Process Management (BPM) has been around in one guise or another for quite a while now and most people have had some exposure to its many facets.   With so much promised, it is easy to see why it has generated so much interest.
jBPM is an open source BPM framework from JBoss that has [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/jBPM-Developer-Guide-M-Salatino/dp/1847195687%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1847195687"><img class="alignright" src="http://ecx.images-amazon.com/images/I/512%2B3zYKyiL._SL160_.jpg" alt="" width="130" height="160" /></a>Business Process Management (BPM) has been around in one guise or another for quite a while now and most people have had some exposure to its many facets.   With so much promised, it is easy to see why it has generated so much interest.</p>
<p>jBPM is an open source BPM framework from JBoss that has matured into a real alternative to the many other BPM offerings.   The &#8216;jBPM Developer Guide&#8217; introduces to its readers the main artifacts of BPM and what is involved in implementing typical jBPM solution.</p>
<p>The book begins by providing a background to BPM and how it can be leveraged to deliver benefit to the business.   This includes an introduction to processes, tasks and process management (Business Process Management or BAM).   As any good book should, terminologies that are associated with BPM are introduced and defined.   Thankfully, the definitions are void of the usual marketing hype.</p>
<p>With the help of an example, graph orientated programming (GOP) is then introduced and its relevance to jBPM discussed.   Specifically the Node, Transition and Process Definition concepts are covered before the author works through sample implementations of each.   Wait states (asynchronous system interactions and human tasks) and automatic nodes are compared before process execution is demonstrated through a sample process execution engine implementation.</p>
<p>The book goes on to give some background to the jBPM project and covers the setup of tools to be used throughout the remainder of the book (Maven, MySql, Eclipse etc.).  It outlines how to install jBPM from a distribution and from source.  I used the installer to install the version used for the examples (3.2.6.SP1).</p>
<p>Two example process projects are then created using the eclipse designer plugin and then the maven plugin to contrast both approaches.   Use of the &#8216;Graphical Process Editor&#8217; is also demonstrated.</p>
<p>The jPDL language is then explored in greater depth describing in detail the XML\Class definitions of the process, the various node types (Node, Start State, End State, State, Decision), transitions and the execution token.  As an example (recruitment) process is automated with the jBPM framework.   This is achieved iteratively adding more detail in each stage.</p>
<p>Process instance persistence is discussed in depth.   This includes details on how and when process definition amd process instance persistence occurs.   A brief review is given of the jBPM API to interact with the database and the jBPM\Hibernate persistence configuration.</p>
<p>Human Task&#8217;s are explained including details on input data, task action and output data.   The distinction between a TaskNode and Task is also made.  A brief introduction to the jBPM Identity module is provided during a discussion about task assignment before demonstrating an example process.</p>
<p>The transactional behaviour of jBPM is then discussed along with a more detailed discussion on variable mappings and task assignment.  Process variables and the type&#8217;s of information stored in process variables are explained and the specific API for variable manipulation is covered in brief, along with the variable persistence and hierarchy.  These concepts are demonstrated with a concrete example.</p>
<p>More advanced node types are covered in this chapter including Fork and Join nodes, Super state nodes, Process state nodes and the Email node.  Variable mapping strategies as discussed in depth and related to the Process State node.</p>
<p>Further examples of using Super state nodes and Process state nodes are covered in addition to asynchronous execution and the JobExecutor.   The examples focused on the asynchronous execution are thorough and provide a good understanding of this process.</p>
<p>The book finished by discussing the use of jBPM within a JEE environment.   In particular, JTA, Data Source&#8217;s, the CommandServiceBean, the JobExecutor and JMS and finally Timers and reminders.</p>
<p>My overall impression of the book was that it relayed the key information required to get up and running with jBPM.  The author was clearly knowledgeable in the subject and provided useful examples to complement the concept&#8217;s being discussed.  I liked the fact that the author gives details on installing the developer tools as it allows the reader to follow along with the examples.</p>
<p>The only negative comment I can make was that I found the poor construction of sentences and awkward use of English a little distracting.  It reads as a book that was translated into  English from another language.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Logging Aspect with Spring AOP and AspectJ</title>
		<link>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/</link>
		<comments>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 22:56:17 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Spring AOP]]></category>
		<category><![CDATA[Spring Framework]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=665</guid>
		<description><![CDATA[After working in software development for a number of years, one tends  to build up a repository of useful code examples and utilities.  I&#8217;m  certainly no different in this regard and go one step further by  maintaining a hosted Subversion repository to keep such code examples safe and sound (and readily accessible).
One [...]]]></description>
			<content:encoded><![CDATA[<p>After working in software development for a number of years, one tends  to build up a repository of useful code examples and utilities.  I&#8217;m  certainly no different in this regard and go one step further by  maintaining a <a id="t2cy" title="hosted" href="http://wush.net/" target="_blank">hosted</a> <a id="ei2i" title="Subversion" href="http://subversion.tigris.org/" target="_blank">Subversion</a> repository to keep such code examples safe and sound (and readily accessible).</p>
<p>One such code example that I often turn to is a  logging aspect implemented using <a id="mk0m" title="Spring" href="http://www.springsource.org/" target="_blank">Spring</a> AOP and <a id="ol95" title="AspectJ" href="http://www.eclipse.org/aspectj/" target="_blank">AspectJ</a>.   This logging aspect traces method entry and exit which proves very  useful if you need to perform root cause analysis in pre-production environments.</p>
<p>In what follows, I&#8217;m going to share this code  example.  I have also made the <a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-tracing-aspect.zip" target="_blank">logging aspect source code</a> available for download.</p>
<p>I have assumed you have a reasonable grasp of  Aspect Orientated Programming concepts and terminologies.<br />
<span id="more-665"></span><br />
<strong>The  Logger</strong></p>
<p>There are a few options to choose from when  considering a logging framework and these have evolved over the years so  it is probably best to abstract the logging framework from the aspect.   For this purpose, I have implemented a simple logging interface and log level enum.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.logger;

public interface Logger {

&nbsp;&nbsp;&nbsp;&nbsp;boolean isLogLevel(LogLevel logLevel, Class&lt;?&gt; clazz);

&nbsp;&nbsp;&nbsp;&nbsp;void log(LogLevel logLevel, Class&lt;?&gt; clazz, Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String pattern, Object... arguments);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Logger.java</p>
</div>
<p><br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.logger;

public enum LogLevel {
&nbsp;&nbsp;DEBUG,
&nbsp;&nbsp;ERROR,
&nbsp;&nbsp;FATAL,
&nbsp;&nbsp;INFO,
&nbsp;&nbsp;TRACE,
&nbsp;&nbsp;WARN
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : LogLevel.java</p>
</div>
<p><br/></p>
<p>In  the majority of cases, I end up using the <a id="z1n2" title="Commons  Logging" href="http://commons.apache.org/logging/" target="_blank">Commons Logging</a> framework and so have included this  implementation of the Logger in the source download.</p>
<p>You  may decide that this level of abstraction is overkill and that you are  willing to commit to using a specific logging framework.  When making  this decision, keep in mind that you will be specifying the log level  throughout your code base.</p>
<p><strong>The Logging Aspect</strong></p>
<p>I am  going to use the @Aspect approach to implement the logging aspect which  is to say I will use annotations to specify the advice.  I want the  logging aspect to log the method name, argument values, return value and  any exception thrown so I will use the @Before, @AfterThrowing and  @AfterReturning annotations.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@Before(value = &quot;@annotation(trace)&quot;, argNames = &quot;joinPoint, trace&quot;)
&nbsp;&nbsp;public void before(JoinPoint joinPoint, Loggable loggable) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (ArrayUtils.isEmpty(joinPoint.getArgs())) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, BEFORE_STRING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, joinPoint.getArgs()));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, BEFORE_WITH_PARAMS_STRING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, joinPoint.getArgs()));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : @Before Code Snippet</p>
</div>
<p><br/></p>
<p>The  &#8216;Before&#8217; advice simply logs (at the appropriate log level) the method  name and the toString value of all arguments (if any).  &#8216;Before&#8217; advice  executes when a join point is reached.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@AfterThrowing(value = &quot;@annotation(net.thoughtforge.aspect.Loggable)&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throwing = &quot;throwable&quot;, argNames = &quot;joinPoint, throwable&quot;)
&nbsp;&nbsp;public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();
&nbsp;&nbsp;&nbsp;&nbsp;logger.log(LogLevel.ERROR, clazz, throwable, AFTER_THROWING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throwable.getMessage(), constructArgumentsString(clazz,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;joinPoint.getArgs()));
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : @AfterThrowing Code Snippet</p>
</div>
<p><br/></p>
<p>The &#8216;AfterThrowing&#8217; advice logs the method name,  exception message and the toString value of all arguments (if any).   &#8216;AfterThrowing&#8217; advice executes after a method exits by throwing an  exception.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@AfterReturning(value = &quot;@annotation(trace)&quot;, returning = &quot;returnValue&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argNames = &quot;joinPoint, trace, returnValue&quot;)
&nbsp;&nbsp;public void afterReturning(JoinPoint joinPoint, Loggable loggable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object returnValue) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();

&nbsp;&nbsp;&nbsp;&nbsp;if (joinPoint.getSignature() instanceof MethodSignature) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MethodSignature signature = (MethodSignature) joinPoint
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getSignature();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;?&gt; returnType = signature.getReturnType();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (returnType.getName().compareTo(&quot;void&quot;) == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, AFTER_RETURNING_VOID,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name, constructArgumentsString(clazz, returnValue));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, AFTER_RETURNING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, returnValue));
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : @AfterReturning Code Snippet</p>
</div>
<p><br/></p>
<p>The  &#8216;AfterReturning&#8217; advice logs the method name and the toString value of  the returned value (if any).  &#8216;AfterReturning&#8217; advice executes after a  method exits normally.</p>
<p>You will notice that I log the toString  value to identify objects.  I routinely use the Apache Commons  ToStringBuilder to create the toString value.   I find this particularly  useful when working with persistent entities as it allows me to clearly  identify the entity.</p>
<p>Another possible implementation that avoids using the toString method is to use the Apache Commons ReflectionToStringBuilder within the logging aspect to create a string representation of the object being logged.</p>
<p>If you are writing your own toString  implementations (the Commons implementation is perfectly adequate) and  are implementing an object with complex properties be aware of recursive  invocations that may result in a stack overflow exception.</p>
<p><strong>Specifying  the Pointcut</strong></p>
<p>A pointcut expression is an expression that  specifies where in the code the advice will be applied.  With AspectJ,  you can create a pointcut by specifying package, class and method  attributes among other things.  I find the easiest way to specify a  pointcut for the logging aspect is by matching methods that have a  specific annotation.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import net.thoughtforge.logger.LogLevel;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {

&nbsp;&nbsp;&nbsp;&nbsp;LogLevel value();
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : Loggable.java</p>
</div>
<p><br/></p>
<p>As you can see,  the Loggable annotation has one property that specifies the log level at  which the log statement should be output.  Using the annotation means  that developers never need to alter the pointcut expression to add or  remove methods to the pointcut.  A developer only has to add the annotation to a method to have the logging aspect applied.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.bean;

import java.util.Date;

import net.thoughtforge.aspect.Loggable;
import net.thoughtforge.logger.LogLevel;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.stereotype.Component;

@Component(value = &quot;simpleBean&quot;)
public class SimpleBean {

&nbsp;&nbsp;private Date dateProperty;

&nbsp;&nbsp;private Integer integerProperty;

&nbsp;&nbsp;private String stringProperty;

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public Date getDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setDateProperty(final Date dateProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateProperty = dateProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public Integer getIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return integerProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setIntegerProperty(final Integer integerProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.integerProperty = integerProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public String getStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return stringProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setStringProperty(final String stringProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.stringProperty = stringProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String toString() {
&nbsp;&nbsp;&nbsp;&nbsp;return new ToStringBuilder(this).append(&quot;dateProperty&quot;, dateProperty)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append(&quot;integerProperty&quot;, integerProperty).append(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;stringProperty&quot;, stringProperty).toString();
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 7 : SimpleBean.java</p>
</div>
<p><br/></p>
<p>The SimpleBean and SimpleBeanSubclass are for  demonstration purposes.  You can see that each method is annotated with  the @Loggable annotation and the log level is set to TRACE.  You can  obviously use different log levels for different methods as required.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.bean;

import java.math.BigDecimal;

import net.thoughtforge.aspect.Loggable;
import net.thoughtforge.logger.LogLevel;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.stereotype.Component;

@Component(value = &quot;simpleBeanSubclass&quot;)
public class SimpleBeanSubclass extends SimpleBean {

&nbsp;&nbsp;private BigDecimal decimalProperty;

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public BigDecimal getDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return decimalProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setDecimalProperty(final BigDecimal decimalProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.decimalProperty = decimalProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String toString() {
&nbsp;&nbsp;&nbsp;&nbsp;return new ToStringBuilder(this).append(&quot;decimalProperty&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decimalProperty).appendSuper(super.toString()).toString();
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 8 : SimpleBeanSubclass.java</p>
</div>
<p><br/></p>
<p>Also note the use of the  ToStringBuilder to create the toString value.  You may choose to use the  ReflectionToStringBuilder or some other mechanism.</p>
<p><strong>Testing  the Logging Aspect</strong></p>
<p>One way to test the logging aspect is to  simply have a test invoke instrumented methods and observe the log  statements produced.  This is a useful exercise but requires manual  intervention to determine if the test was successful.</p>
<p>In order to  create an automated test for the logging aspect, I needed to create a  mock logger that simulates the actions of a logger and allows me to  interrogate the log statements produced.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.mock.logger;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.thoughtforge.logger.LogLevel;
import net.thoughtforge.logger.Logger;

import org.springframework.stereotype.Component;

@Component
public class MockLogger implements Logger {

&nbsp;&nbsp;private Map&lt;Class&lt;?&gt;, LogLevel&gt; logLevelMap =
&nbsp;&nbsp;&nbsp;&nbsp;new HashMap&lt;Class&lt;?&gt;, LogLevel&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;private Map&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt; messages = new HashMap&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;public boolean isLogLevel(LogLevel logLevel,&nbsp;&nbsp;Class&lt;?&gt; clazz) {
&nbsp;&nbsp;&nbsp;&nbsp;boolean result = false;

&nbsp;&nbsp;&nbsp;&nbsp;switch (logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case DEBUG:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.DEBUG);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case ERROR:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.ERROR);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FATAL:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.FATAL);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case INFO:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.INFO);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case TRACE:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.TRACE);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case WARN:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.WARN);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = false;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return result;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void log(LogLevel logLevel,&nbsp;&nbsp;Class&lt;?&gt; clazz,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Throwable throwable,&nbsp;&nbsp;String pattern,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;switch (logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case DEBUG:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case ERROR:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FATAL:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatal(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case INFO:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case TRACE:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case WARN:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;warn(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void debug(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.DEBUG, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.DEBUG, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void error(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.ERROR, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.ERROR, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void fatal(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.FATAL, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.FATAL, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void info(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.INFO, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.INFO, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void trace( Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.TRACE, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.TRACE, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void warn( Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.WARN, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.WARN, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private String format( String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;return MessageFormat.format(pattern, arguments);
&nbsp;&nbsp;}

&nbsp;&nbsp;public void resetLoggers() {
&nbsp;&nbsp;&nbsp;&nbsp;messages = new HashMap&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt;();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public List&lt;LogMessage&gt; getMessages(Class&lt;?&gt; clazz) {
&nbsp;&nbsp;&nbsp;&nbsp;if (messages.get(clazz) == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;messages.put(clazz, new ArrayList&lt;LogMessage&gt;());
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return messages.get(clazz);
&nbsp;&nbsp;}

&nbsp;&nbsp;private boolean isLogLevelEnabled(Class&lt;?&gt; clazz, LogLevel logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;return logLevelMap.get(clazz) != null &amp;&amp; logLevelMap.get(clazz).equals(logLevel);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void setLogLevel(Class&lt;?&gt; clazz, LogLevel logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;logLevelMap.put(clazz, logLevel);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public class LogMessage {
&nbsp;&nbsp;&nbsp;&nbsp;private LogLevel logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;private String message;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;private Throwable throwable;

&nbsp;&nbsp;&nbsp;&nbsp;public LogMessage(LogLevel logLevel, String message, Throwable throwable) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this(logLevel, message);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.throwable = throwable;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public LogMessage(LogLevel logLevel, String message) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.logLevel = logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.message = message;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public LogLevel getLogLevel() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public String getMessage() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return message;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public Throwable getThrowable() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return throwable;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 9 : MockLogger.java</p>
</div>
<p><br/></p>
<p>The  logging aspect test utilises the MockLogger and makes assertions about  the log statements produced.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import java.math.BigDecimal;

import junit.framework.Assert;
import net.thoughtforge.bean.SimpleBean;
import net.thoughtforge.bean.SimpleBeanSubclass;
import net.thoughtforge.logger.LogLevel;
import net.thoughtforge.mock.logger.MockLogger;
import net.thoughtforge.mock.logger.MockLogger.LogMessage;

import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-aspect.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-logger.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext.xml&quot; })
public class LoggingAspectTest {

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;private MockLogger logger;
&nbsp;&nbsp;
&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value = &quot;simpleBean&quot;)
&nbsp;&nbsp;public SimpleBean simpleBean;

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;public SimpleBeanSubclass simpleBeanSubclass;

&nbsp;&nbsp;@Before
&nbsp;&nbsp;public void before() {
&nbsp;&nbsp;&nbsp;&nbsp;logger.setLogLevel(SimpleBean.class, LogLevel.TRACE);
&nbsp;&nbsp;&nbsp;&nbsp;logger.setLogLevel(SimpleBeanSubclass.class, LogLevel.TRACE);
&nbsp;&nbsp;&nbsp;&nbsp;logger.resetLoggers();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetDateProperty() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setDateProperty(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateUtils.parseDate(&quot;01/01/2010&quot;, new String[] {&quot;dd/MM/yyyy&quot;}));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDateProperty &gt; with params Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDateProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setIntegerProperty(100);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setIntegerProperty &gt; with params 100 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setStringProperty(&quot;stringProperty&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setStringProperty &gt; with params stringProperty ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setStringProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getDateProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDateProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDateProperty &gt; returning Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getIntegerProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getIntegerProperty &gt; returning 100 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getStringProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getStringProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getStringProperty &gt; returning stringProperty ]&quot;);
&nbsp;&nbsp;}

&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetDateProperty() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setDateProperty(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateUtils.parseDate(&quot;01/01/2010&quot;, new String[] {&quot;dd/MM/yyyy&quot;}));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDateProperty &gt; with params Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDateProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setDecimalProperty(new BigDecimal(&quot;0.25&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDecimalProperty &gt; with params 0.25 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDecimalProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setIntegerProperty(100);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setIntegerProperty &gt; with params 100 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setStringProperty(&quot;stringProperty&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setStringProperty &gt; with params stringProperty ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setStringProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getDateProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDateProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDateProperty &gt; returning Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getDecimalProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDecimalProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDecimalProperty &gt; returning 0.25 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getIntegerProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getIntegerProperty &gt; returning 100 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getStringProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getStringProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getStringProperty &gt; returning stringProperty ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;private void assertEquals(LogMessage logMessage, LogLevel logLevel, String message) {
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(logLevel, logMessage.getLogLevel());
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(message, logMessage.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 10 : LoggingAspectTest.java</p>
</div>
<p><br/></p>
<p>The  test is not exhaustive but suffices to test the general operation of  the logging aspect.</p>
<p><strong>Final Word</strong></p>
<p>Hopefully you found  my example useful but I will finish by saying that there are many  choices that I made in deciding on this approach.</p>
<p>A strong  argument could be made for the use of XML configuration as opposed to  the @Aspect approach which allows you greater control over the execution  of the advice without modifying code.  This would be particularly relevant in an environment where performance was a major focus.  I  personally have found that the control provided by logging frameworks to  enable and disable particular loggers is sufficient in most environments.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Web Form Validation with JBoss RichFaces and Hibernate Validator</title>
		<link>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/</link>
		<comments>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 21:02:09 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Rich Faces]]></category>
		<category><![CDATA[Spring Webflow]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=634</guid>
		<description><![CDATA[Last month I posted about Building a Dynamic Tree with JBoss RichFaces and Spring Web Flow.  Since then, I have received a few requests to demonstrate how to implement validation within the modal dialog.  There are several internet resources that already deal with this but none that provide a complete working example so [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I posted about <a href="http://thoughtforge.net/2010/01/19/building-a-dynamic-tree-with-jboss-richfaces-and-spring-web-flow/" target="_blank">Building a Dynamic Tree with JBoss RichFaces and Spring Web Flow</a>.  Since then, I have received a few requests to demonstrate how to implement validation within the modal dialog.  There are several internet resources that already deal with this but none that provide a complete working example so I decided I would do just that.</p>
<p>You can download the <a href="http://thoughtforge.net/wp-content/uploads/2010/02/richfaces-modaldialog-ajax-validation.zip" target="_self">source code</a> in the form of a Maven project and follow along.</p>
<p><strong>Hibernate Validator Dependencies</strong></p>
<p>First step is to add the <a href="https://www.hibernate.org/412.html" target="_blank">Hibernate Validator</a> dependency to the project pom.  I have used Hibernate Validator 4.0.0.GA because it is a JSR 303 compliant implementation.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;dependency&gt;
&nbsp;&nbsp;&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
&nbsp;&nbsp;&lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
&nbsp;&nbsp;&lt;version&gt;4.0.0.GA&lt;/version&gt;
&nbsp;&nbsp;&lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Hibernate Validator Dependency</p>
</div>
<p><br/><br />
<span id="more-634"></span><br />
<strong>Annotating the Model Class</strong></p>
<p>JSR 303 allows for the specification of validation constraints via Annotations and\or XML.  The Hibernate Validator documentation has recently been updated to include details on specifying the validation.xml if you prefer to use XML.</p>
<p>For this example I am going to use Annotations to specify a &#8216;Size&#8217; constraint on the name and description properties of the Organisation class.  These are basic constraints but they will suffice for demonstration purposes.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.validation.constraints.Size;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(&quot;prototype&quot;)
public class Organisation implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = -2023156931701914562L;

&nbsp;&nbsp;private List&lt;Organisation&gt; children;
&nbsp;&nbsp;
&nbsp;&nbsp;@Size(min=3, max=200, message=&quot;Description must be between 3 and 200 characters in length.&quot;)
&nbsp;&nbsp;private String description;
&nbsp;&nbsp;
&nbsp;&nbsp;@Size(min=3, max=50, message=&quot;Name must be between 3 and 50 characters in length.&quot;)
&nbsp;&nbsp;private String name;

&nbsp;&nbsp;private Organisation parent;
&nbsp;&nbsp;
&nbsp;&nbsp;public void addChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() == null || !child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(this);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&lt;Organisation&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!children.contains(child)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.add(child);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void removeChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() != null &amp;&amp; child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(null);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (children != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.remove(child);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;public List&lt;Organisation&gt; getChildren() {
&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&lt;Organisation&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return Collections.unmodifiableList(children);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public String getDescription() {
&nbsp;&nbsp;&nbsp;&nbsp;return description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDescription(String description) {
&nbsp;&nbsp;&nbsp;&nbsp;this.description = description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getName() {
&nbsp;&nbsp;&nbsp;&nbsp;return name;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setName(String name) {
&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;
&nbsp;&nbsp;}

&nbsp;&nbsp;public Organisation getParent() {
&nbsp;&nbsp;&nbsp;&nbsp;return parent;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setParent(Organisation parent) {
&nbsp;&nbsp;&nbsp;&nbsp;this.parent = parent;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : Organisation.java</p>
</div>
<p><br/><br />
<strong>Applying the Constraints</strong></p>
<p>Of course, as annotations do nothing in and of themselves, I need to invoke the validator to apply the constraints.  RichFaces provides 3 components that invoke either the Hibernate or JSR 303 bean validator during the JSF &#8216;Process Validations&#8217; phase.</p>
<p>I wanted to validate the Organisation name and description properties.  These are set within the &#8216;addChildModalPanel&#8217; and updated within the &#8216;editChildModalPanel&#8217;.  The validations are applied to each in exactly the same way.</p>
<p>To apply validations to the name and description &#8216;inputText&#8217; fields I added a child  field.  Adding this child component results in the validator being invoked during the &#8216;Process Validations&#8217; phase.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 100px; width: 100%;">
<pre><pre>
&lt;h:inputText value=&quot;#{addChildOrganisation.name}&quot;&gt;
&nbsp;&nbsp;&lt;rich:beanValidator/&gt;
&lt;/h:inputText&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : rich:beanValidator</p>
</div>
<p><br/><br />
If the validation fails, messages are added to the FacesContext and will be displayed using the  component.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;rich:messages&gt;
&nbsp;&nbsp;&lt;f:facet name=&quot;errorMarker&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGroup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:graphicImage value=&quot;/image/error.gif&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;&nbsp;&nbsp;&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGroup&gt;
&nbsp;&nbsp;&lt;/f:facet&gt;
&lt;/rich:messages&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : rich:messages</p>
</div>
<p><br/><br />
Displaying Validation Messages within the Modal Dialog</p>
<p>Finally, I needed to keep the Modal Dialog from closing when validation failures occured.  This is achieved by modifying the a4j:commandButton as shown below.  It is worth highlighting that each <rich:modalPanel> has its own <h:form> and this is very important (as highlighted in the JBoss RichFaces documentation).</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;a4j:commandButton action=&quot;addChildModalPanelConfirm&quot;
&nbsp;&nbsp;&nbsp;&nbsp;value=&quot;Ok&quot;
&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;if (#{!facesContext.messages.hasNext()}) {Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)};&quot;
&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : a4j:commandButton</p>
</div>
<p><br/><br />
What I ended up with was a really intuitive and responsive UI with appropriate validations.  It was an interesting exercise especially due to the intricacies of the  component.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Marshalling XML with Spring WS and JAXB</title>
		<link>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/</link>
		<comments>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 22:21:09 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[Spring Web Services]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=610</guid>
		<description><![CDATA[The &#8216;object-relational impedance mismatch&#8217; is a well documented set of conceptual and technical difficulties that are often encountered when a relational database management system is being used by a program written in an object-oriented programming language.  A similar impedance mismatch exists when XML is used by a program written in an object-oriented programming language.
Many [...]]]></description>
			<content:encoded><![CDATA[<p>The &#8216;object-relational impedance mismatch&#8217; is a well documented set of conceptual and technical difficulties that are often encountered when a relational database management system is being used by a program written in an object-oriented programming language.  A similar impedance mismatch exists when XML is used by a program written in an object-oriented programming language.</p>
<p>Many popular &#8216;Object-Relational Mapping&#8217; (ORM) frameworks exist that address the object-relational impedance mismatch and no doubt helped to inspire the evolution of &#8216;Object-XML Mapping&#8217; (OXM) frameworks to address the object-xml impedance mismatch.</p>
<p>For the Java community, there are a number of OXM frameworks from which to choose (<a href="http://www.castor.org/" target="_blank">Castor</a>, <a href="http://xstream.codehaus.org/" target="_blank">XStream</a>, <a href="http://jibx.sourceforge.net/" target="_blank">JiBX</a>, <a href="https://jaxb.dev.java.net/" target="_blank">JAXB</a>) with each having particular strengths and weaknesses.  The standard OXM framework for Java is JAXB.</p>
<p>In the following I work through a simple example that demonstrates object to XML marshalling (and demarshalling) using <a href="http://www.springsource.org/about" target="_blank">Spring</a>, <a href="http://static.springsource.org/spring-ws/sites/1.5/" target="_blank">Spring WS</a> and JAXB (and later <a href="http://community.jboss.org/wiki/JAXBIntroductions" target="_blank">JAXB Introductions</a>!)</p>
<p>I have provided Maven projects for download so you can follow along:</p>
<p><a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-springws-jaxb.zip" target="_blank">Spring OXM and JAXB Source Download</a><br />
<a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-springws-jaxb-introductions.zip" target="_blank">Spring OXM, JAXB and JAXB Introductions Download</a><br />
<span id="more-610"></span><br />
<strong>The Model</strong></p>
<p>The model object that I have used for this example is a simple object representing a &#8216;Person&#8217;.  The class contains only simple attributes.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(
&nbsp;&nbsp;&nbsp;&nbsp;name=&quot;Person&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;namespace=&quot;http://thoughtforge.net/model&quot;)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public class Person implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = 8465162879793776395L;

&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private BigDecimal weight;

&nbsp;&nbsp;public Calendar getDateOfBirth() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDateOfBirth(Calendar dateOfBirth) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateOfBirth = dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;return firstName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setFirstName(String firstName) {
&nbsp;&nbsp;&nbsp;&nbsp;this.firstName = firstName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public BigDecimal getHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setHeight(BigDecimal height) {
&nbsp;&nbsp;&nbsp;&nbsp;this.height = height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;return lastName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setLastName(String lastName) {
&nbsp;&nbsp;&nbsp;&nbsp;this.lastName = lastName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public BigDecimal getWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return weight;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setWeight(BigDecimal weight) {
&nbsp;&nbsp;&nbsp;&nbsp;this.weight = weight;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Person.java</p>
</div>
<p><br/><br />
As you can see from the listing, the class is annotated with JAXB annotations that are fairly self explanatory.  I will leave it to you to look up the precise definition and consequence of these annotations (which can be found on the JAXB Reference Implementation website).</p>
<p><strong>The XML Schema (XSD)</strong></p>
<p>JAXB does not require an XML schema (a default schema can be generated), but for this example (and always on commercial projects) I have explicitly specified a schema in order to include type restrictions.  It is important to remember that the XSD forms the contract between XML producers and consumers (marshaller and unmarshaller) and should be as detailed as possible.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;xsd:schema xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
&nbsp;&nbsp;targetNamespace=&quot;http://thoughtforge.net/model&quot;
&nbsp;&nbsp;xmlns:tns=&quot;http://thoughtforge.net/model&quot;
&nbsp;&nbsp;attributeFormDefault=&quot;unqualified&quot;
&nbsp;&nbsp;elementFormDefault=&quot;qualified&quot;
&nbsp;&nbsp;version=&quot;1.0&quot;&gt;

&nbsp;&nbsp;&lt;xsd:element name=&quot;Person&quot; type=&quot;tns:Person&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;xsd:complexType name=&quot;Person&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;dateOfBirth&quot; type=&quot;xsd:dateTime&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;firstName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:string&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:maxLength value=&quot;50&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;height&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:decimal&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:fractionDigits value=&quot;2&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;lastName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:string&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:maxLength value=&quot;50&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;weight&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:decimal&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:fractionDigits value=&quot;2&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;
&nbsp;&nbsp;&lt;/xsd:complexType&gt;
&lt;/xsd:schema&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : person.xsd</p>
</div>
<p><br/><br />
<strong>The Marshaller Abstraction</strong></p>
<p>Rather than use the Spring Marshaller/Unmarshaller interface directly, I often use an abstraction for the Marshaller.  The abstraction I used here is very simple and of course would not be practical for use with large XML files as it does not support streaming etc.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

public interface Marshaller {

&nbsp;&nbsp;String marshal(Object object);

&nbsp;&nbsp;Object unmarshal(String string);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : Marshaller.java</p>
</div>
<p><br/><br />
The implementation of the marshaller delegates to a Spring JAXB marshaller.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

import java.io.StringWriter;

import javax.xml.transform.stream.StreamResult;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.xml.transform.StringSource;

@Component(value=&quot;marshaller&quot;)
public class Jaxb2Marshaller implements Marshaller {

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value=&quot;jaxb2Marshaller&quot;)
&nbsp;&nbsp;private org.springframework.oxm.jaxb.Jaxb2Marshaller marshaller;
&nbsp;&nbsp;
&nbsp;&nbsp;public String marshal(Object object) {
&nbsp;&nbsp;&nbsp;&nbsp;final StringWriter out = new StringWriter();
&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(object, new StreamResult(out));
&nbsp;&nbsp;&nbsp;&nbsp;return out.toString();
&nbsp;&nbsp;}

&nbsp;&nbsp;public Object unmarshal(String string) {
&nbsp;&nbsp;&nbsp;&nbsp;return marshaller.unmarshal(new StringSource(string));
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : Jaxb2Marshaller.java</p>
</div>
<p><br/><br />
<strong>The Configuration</strong></p>
<p>Using Spring to define a JAXB marshaller is relatively straight forward as the listing shows.  I have specified the classes to be bound and the XML schema.  If the XML schema is specified, the marshaller will instruct the XML parser to validate XML against the schema.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
&nbsp;&nbsp;xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

&nbsp;&nbsp;&lt;context:component-scan base-package=&quot;net.thoughtforge.marshaller&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;bean id=&quot;jaxb2Marshaller&quot; class=&quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;classesToBeBound&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;net.thoughtforge.model.Person&lt;/value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;schema&quot; value=&quot;classpath:schema/person.xsd&quot;/&gt;
&nbsp;&nbsp;&lt;/bean&gt;
&lt;/beans&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : applicationContext-marshaller.xml</p>
</div>
<p><br/><br />
<strong>The Test</strong></p>
<p>The following test is not exhaustive but demonstrates the marshalling and unmarshalling of a Person object.  It also demonstrates XML schema validation occurring during the marshalling and unmarshalling process.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

import java.math.BigDecimal;
import java.util.Calendar;

import net.thoughtforge.model.Person;

import org.apache.commons.lang.text.StrBuilder;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;classpath:applicationContext/applicationContext-*.xml&quot;})
public class Jaxb2MarshallerTest {

&nbsp;&nbsp;private static final String MARSHALLED_PERSON =
&nbsp;&nbsp;&nbsp;&nbsp;&quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot; standalone=\&quot;yes\&quot;?&gt;&lt;Person xmlns=\&quot;http://thoughtforge.net/model\&quot;&gt;&lt;dateOfBirth&gt;1965-01-01T00:00:00Z&lt;/dateOfBirth&gt;&lt;firstName&gt;Joe&lt;/firstName&gt;&lt;height&gt;1.85&lt;/height&gt;&lt;lastName&gt;Bloggs&lt;/lastName&gt;&lt;weight&gt;12.2&lt;/weight&gt;&lt;/Person&gt;&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;private static Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;private static String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;private static BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;private static String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;private static BigDecimal weight;
&nbsp;&nbsp;
&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value=&quot;marshaller&quot;)
&nbsp;&nbsp;private Jaxb2Marshaller marshaller;

&nbsp;&nbsp;@BeforeClass
&nbsp;&nbsp;public static void beforeClass() {
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth = Calendar.getInstance();
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.clear();
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.DATE, 1);
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.MONTH, Calendar.JANUARY);
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.YEAR, 1965);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;firstName = &quot;Joe&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;height = new BigDecimal(&quot;1.85&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;lastName = &quot;Bloggs&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;weight = new BigDecimal(&quot;12.2&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPerson() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;String xml = marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertNotNull(xml);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(MARSHALLED_PERSON, xml);
&nbsp;&nbsp;}

&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(new StrBuilder(firstName).appendPadding(50, &#039;0&#039;).toString());
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;First name length restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;is not facet-valid with respect to maxLength &#039;50&#039;&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height.add(new BigDecimal(&quot;0.1111&quot;)));
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;Height precision restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;the number of fraction digits has been limited to 2&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(new StrBuilder(lastName).appendPadding(50, &#039;0&#039;).toString());
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;First name length restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;is not facet-valid with respect to maxLength &#039;50&#039;&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight.add(new BigDecimal(&quot;0.1111&quot;)));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;Weight precision restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;the number of fraction digits has been limited to 2&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void unmarshallPerson() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = (Person) marshaller.unmarshal(MARSHALLED_PERSON);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertNotNull(person);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertTrue(dateOfBirth.compareTo(person.getDateOfBirth()) == 0);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(firstName, person.getFirstName());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(height, person.getHeight());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(lastName, person.getLastName());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(weight, person.getWeight());
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : Jaxb2MarshallerTest.java</p>
</div>
<p><br/><br />
<strong>Removing JAXB Annotations</strong></p>
<p>If you are using the reference implementation of JAXB you are required to use annotations to map objects to XML.  As I mentioned in a previous post, I&#8217;m not a fan of using annotations for the purpose of mapping objects to some other format (relational database or XML or A.N. Other).  I find it creates code clutter especially in instances were entity model classes are mapped to both a relational database and XML (using JAXB).  In modular projects, it also creates unnecessary dependencies on the model module.</p>
<p>Luckily, some bright spark came along and created JAXB Introductions which allows you to define the mapping of objects to XML in an XML file.  I&#8217;m not going to regurgitate the information on the JAXB Introductions website but I will outline the modifications I had to make to allow me to use JAXB Introductions with the example above.</p>
<p>First, I added the maven dependency to the project.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;jboss.jaxbintros&lt;/groupId&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;jboss-jaxb-intros&lt;/artifactId&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;1.0.1.GA&lt;/version&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dependency&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 7 : JAXB Introductions Maven Dependency</p>
</div>
<p><br/><br />
Second, I created a JAXB Introductions mapping file.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot;?&gt;

&lt;jaxb-intros xmlns=&quot;http://www.jboss.org/xsd/jaxb/intros&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Class name=&quot;net.thoughtforge.model.Person&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlType/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlRootElement name=&quot;Person&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlAccessorType value=&quot;FIELD&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;dateOfBirth&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;dateOfBirth&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;firstName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;firstName&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;height&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;height&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;lastName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;lastName&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;weight&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;weight&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Class&gt;
&lt;/jaxb-intros&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 8 : marshaller-mapping.xml</p>
</div>
<p><br/><br />
Thirdly, I modified the Spring configuration to inject the JAXB Introductions annotation reader into the JAXB marshaller.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
&nbsp;&nbsp;xmlns:util=&quot;http://www.springframework.org/schema/util&quot;
&nbsp;&nbsp;xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

&nbsp;&nbsp;&lt;context:component-scan base-package=&quot;net.thoughtforge.marshaller&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;bean id=&quot;jaxb2Marshaller&quot; class=&quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;classesToBeBound&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;net.thoughtforge.model.Person&lt;/value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;jaxbContextProperties&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;map&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;entry&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;util:constant static-field=&quot;com.sun.xml.bind.api.JAXBRIContext.ANNOTATION_READER&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class=&quot;org.jboss.jaxb.intros.IntroductionsAnnotationReader&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg ref=&quot;jaxbIntroductions&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/entry&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/map&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;schema&quot; value=&quot;classpath:schema/person.xsd&quot;/&gt;
&nbsp;&nbsp;&lt;/bean&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;jaxbIntroductions&quot; class=&quot;org.jboss.jaxb.intros.IntroductionsConfigParser&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory-method=&quot;parseConfig&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg&gt;&lt;value&gt;classpath:marshaller-mapping.xml&lt;/value&gt;&lt;/constructor-arg&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&lt;/beans&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 9 : applicationContext-marshaller.xml</p>
</div>
<p><br/><br />
Finally, I removed the JAXB annotations from the model class (Person.java).</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;

public class Person implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = 8465162879793776395L;

&nbsp;&nbsp;private Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;private String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;private BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;private String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;private BigDecimal weight;

&nbsp;&nbsp;public Calendar getDateOfBirth() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDateOfBirth(Calendar dateOfBirth) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateOfBirth = dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;return firstName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setFirstName(String firstName) {
&nbsp;&nbsp;&nbsp;&nbsp;this.firstName = firstName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public BigDecimal getHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setHeight(BigDecimal height) {
&nbsp;&nbsp;&nbsp;&nbsp;this.height = height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;return lastName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setLastName(String lastName) {
&nbsp;&nbsp;&nbsp;&nbsp;this.lastName = lastName;
&nbsp;&nbsp;}

&nbsp;&nbsp;public BigDecimal getWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return weight;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setWeight(BigDecimal weight) {
&nbsp;&nbsp;&nbsp;&nbsp;this.weight = weight;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 10 : Person.java</p>
</div>
<p><br/><br />
Hopefully, this short example will prove useful for those starting out with JAXB and OXM.  For those already familiar with JAXB and OXM, perhaps it has shown you how you can use JAXB without annotations.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
