tag:blogger.com,1999:blog-33054199756760306482024-03-14T04:58:11.288+01:00CTP Java CompetenceCambridge Technology Partners SwitzerlandAnonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.comBlogger69125tag:blogger.com,1999:blog-3305419975676030648.post-42250486759378440552014-01-06T10:26:00.000+01:002014-01-06T10:26:16.414+01:00New Year, New Blog LocationDear Readers and Blog Followers<br />
<br />
First of all a Happy New Year to all of you! May 2014 bring us flying cars, light sabers and other geeky stuff (and, well, Java 8 maybe). While we wait for all this exciting stuff, we'll start with some less spectacular nevertheless important new things - a new blog location. Please redirect your RSS feeds to<br />
<br />
<a href="http://blog.ctp.com/category/java-competence/" target="_blank">the New and Official <b>CTP Java blog</b></a> (hurray!)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicbzxj_5ioQN9ZDn-Mi5KNWlprBU91CQZ8Er5VYbeJNZqJrdVYbm6ixGGGxvrh0zXeTlVb1lq-W1X-zZyvZ42NwBvu4iZPIiNDv5nTkxKRP_sFX5nqPFvncNqf3zbcx0c5Y9mq1xv7rds/s1600/yeah.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicbzxj_5ioQN9ZDn-Mi5KNWlprBU91CQZ8Er5VYbeJNZqJrdVYbm6ixGGGxvrh0zXeTlVb1lq-W1X-zZyvZ42NwBvu4iZPIiNDv5nTkxKRP_sFX5nqPFvncNqf3zbcx0c5Y9mq1xv7rds/s1600/yeah.gif" /></a></div>
<br />
<br />
where you will also find other articles about things we do at Cambridge - see <a href="http://blog.ctp.com/2013/11/21/git-recovering-from-mistakes/" target="_blank">Bartosz' article about recovering from mistakes in Git</a>. We will be working hard to make our new year resolution (blog more often) come true!<br />
<br />
We will leave all our old posts here as some other sites have referrals to it, but new posts will only appear on the new location.Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com1tag:blogger.com,1999:blog-3305419975676030648.post-66333705372765011142013-04-29T10:22:00.000+02:002013-04-29T12:51:49.807+02:00Efficient Structural Analysis of existing projects - part 1<span class="Apple-style-span" style="color: #333333; font-family: Arial, sans-serif; font-size: 14px; line-height: 19px;"></span><br />
<h2 id="EfficientStructuralAnalysisofexistingprojects-Introduction[post1]" style="border-bottom-color: rgb(145, 150, 153); border-bottom-style: solid; border-bottom-width: 1px; color: black; font-size: 1.6em; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 2em; padding-bottom: 2px;">
Introduction</h2>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
As a software engineer you already might have run in the following situation: A legacy application needs to be extended, and most of the initial developers have either left or work on new projects. Documentation is sparse and the code base is huge - but you need to quickly understand the structure of the project, or at least the parts you're about to change. How can you possibly achieve that?</div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
</div>
<h2 id="EfficientStructuralAnalysisofexistingprojects-Whatdoesstructuralanalysisinclude" style="border-bottom-color: rgb(145, 150, 153); border-bottom-style: solid; border-bottom-width: 1px; color: black; font-size: 1.6em; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 2em; padding-bottom: 2px;">
Structural analysis to the rescue</h2>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
Under structural analysis we understand the analysis of:</div>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<li><div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
project structure</div>
</li>
<li><div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
project elements</div>
</li>
<li><div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
elements structure</div>
</li>
<li><div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
elements relations</div>
</li>
</ul>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
We will have a general overview of those aspects below - the description refers mainly to two object oriented languages: Java and C#. The details we will present in a series of blog posts - so stay tuned for more!</div>
<h3 id="EfficientStructuralAnalysisofexistingprojects-Analysisofprojectstructure" style="color: black; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<span class="Apple-style-span" style="font-weight: normal;">Analysis of project structure</span></h3>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
A typical project is composed of:</div>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<li>modules<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>packages / namespaces<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>elements (classes)</li>
</ul>
</li>
</ul>
</li>
</ul>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
So first it is required to understand what modules are included in the project and what their roles are. Additionally one also has to understand how elements (classes) are organized within modules - what packages / namespaces are there and what elements do they contain.</div>
<h3 id="EfficientStructuralAnalysisofexistingprojects-Analysisofprojectelements" style="color: black; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<span class="Apple-style-span" style="font-weight: normal;">Analysis of project elements</span></h3>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
In Java and C# projects, elements of the following kinds/categories can be found:</div>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<li>class<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>interface<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li><span style="color: #333399;">annotation (Java)</span></li>
</ul>
</li>
<li><span style="color: purple;">attribute (C#)<span style="color: black;"> - equivalent to annotation in Java</span></span></li>
<li>enum</li>
<li>throwable / exception <span style="font-size: xx-small;">1)</span></li>
<li>array</li>
<li><span style="color: purple;">delegate (C#)</span></li>
</ul>
</li>
<li><span style="color: purple;">struct (C#)</span></li>
</ul>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<span style="font-size: xx-small;">1)</span> logical category</div>
<h3 id="EfficientStructuralAnalysisofexistingprojects-Analysisofelementsstructure" style="color: black; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<span class="Apple-style-span" style="font-weight: normal;">Analysis of elements structure</span></h3>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
Java and C# classes can contain the following members:</div>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<li>attribute<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>field</li>
<li>constant <span style="font-size: xx-small;">1)</span></li>
</ul>
</li>
<li>operation<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>method</li>
<li>constructor</li>
<li><s>finalizer / destructor</s> <span style="font-size: xx-small;">2)</span></li>
</ul>
</li>
<li>property <span style="font-size: xx-small;">1)</span><br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li><span style="color: purple;">indexer (C#)</span></li>
</ul>
</li>
<li><span style="color: purple;">operator (C#)</span></li>
<li><span style="color: purple;">event (C#)</span></li>
<li>nested element</li>
</ul>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<span style="font-size: xx-small;">1)</span> logical category in Java, language-level category in C#<br />
<span style="font-size: xx-small;">2)</span> logical category in both languages - should not be used anymore</div>
<h3 id="EfficientStructuralAnalysisofexistingprojects-Analysisofelementsrelations" style="color: black; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<span class="Apple-style-span" style="font-weight: normal;">Analysis of element relations</span></h3>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
An element can have any of the following relations:</div>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<li>outbound<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>generalization</li>
<li>abstractions</li>
<li>nestings</li>
<li>associations<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>uni-directional</li>
<li>bi-directional</li>
<li>aggregations<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>compositions</li>
</ul>
</li>
</ul>
</li>
<li>dependencies</li>
</ul>
</li>
<li>inbound</li>
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>specializations</li>
<li>realizations</li>
<li>nesting owner</li>
<li>association usages<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>aggregation usages<br /><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li>composition usages</li>
</ul>
</li>
</ul>
</li>
<li>dependency usages</li>
</ul>
</ul>
<div>
<h2 id="EfficientStructuralAnalysisofexistingprojects-StructuralanalysisofsampleJavaproject" style="border-bottom-color: rgb(145, 150, 153); border-bottom-style: solid; border-bottom-width: 1px; color: black; font-size: 1.6em; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 2em; padding-bottom: 2px;">
Structural analysis of a sample Java project</h2>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
Now imagine that you start working on an existing project: <a class="external-link" href="http://netbeans.org/kb/samples/scrum-toys.html" rel="nofollow" style="color: #326ca6; text-decoration: none;">ScrumToys</a>, an application to support conducting projects in SCRUM. Below you can see 2 screenshots from the application.<br />
<br /></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
</div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTIK_7z20jr4xm-HFTdCBn3KUQzOlc71ldxY-EJGSb553xjmG3F6ntF9TqbeejI-c8SX1cFW2jDX7goUnglCRpU58NzNUuWoJr4HXLlQ3O3im57z34lyV2TLysw5SBHfnPFmyf7j7AuC8/s1600/ScrumToys-dashboard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="446" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTIK_7z20jr4xm-HFTdCBn3KUQzOlc71ldxY-EJGSb553xjmG3F6ntF9TqbeejI-c8SX1cFW2jDX7goUnglCRpU58NzNUuWoJr4HXLlQ3O3im57z34lyV2TLysw5SBHfnPFmyf7j7AuC8/s640/ScrumToys-dashboard.png" width="640" /></a></div>
<b>Figure 1a. ScrumToys application - dashboard showing stories and tasks </b><b><b>of sample project sprint.</b></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="font-weight: normal;"></span></b></b></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSzC8WH0O-AGBUQS-0e98ZVcm3GRXZSL0YKDFjVfyv3Mh3BEVgIhk8PEXaSTszxNtfViiwjqyYAt_wXx3G6CV3U4DcKJVGU4ajL_2dohAXQw2cM1KmdADMRJLexxFS9psr3OvpbZCM824/s1600/ScrumToys-task.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="446" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSzC8WH0O-AGBUQS-0e98ZVcm3GRXZSL0YKDFjVfyv3Mh3BEVgIhk8PEXaSTszxNtfViiwjqyYAt_wXx3G6CV3U4DcKJVGU4ajL_2dohAXQw2cM1KmdADMRJLexxFS9psr3OvpbZCM824/s640/ScrumToys-task.png" width="640" /></a></div>
<b style="color: #333333;"><b><b>Figure 1b. ScrumToys application - editing of sample task.</b></b></b><br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
</div>
<br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
</div>
<b><b>
</b></b>
<br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="font-weight: normal;">Figure 1a shows stories and tasks. Tasks are grouped into 3 categories, according to their status: TODO, DOING, DONE. Figure 1b shows the task edit dialog.</span></b></b></div>
<b><b>
</b></b>
<br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="font-weight: normal;">Your role is to modify the application. You've received the following assignment:</span></b></b></div>
<b><b>
</b></b>
<br />
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"><b><b>
<li><span class="Apple-style-span" style="font-weight: normal;">add next task status-category: APPROVED</span></li>
<li><span class="Apple-style-span" style="font-weight: normal;">remove inconsistency in the name of task status: DOING (Figure 1a) and WORKING (Figure 1b) - it should be WORKING on all screens across the system (also on those not shown on screenshots)</span></li>
<li><span class="Apple-style-span" style="font-weight: normal;">make task status changeable - currently it cannot be changed (Figure 1b)</span></li>
</b></b></ul>
<b><b>
</b></b>
<br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="font-weight: normal;">In order to do your assignment correctly, you have to understand the structure of the application - at least of the parts related to the given tasks. Let's see a comparison on how popular software engineering tools can support you in your assignment.</span></b></b></div>
<b><b>
</b></b>
<br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"></span></span><br /></b></b>
<br />
<h3 id="EfficientStructuralAnalysisofexistingprojects-Usedtools" style="color: black; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">Tools</span></span></span></b></b></h3>
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
</span></span>
</b></b><br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">The following software engineering tools are chosen to help us with the structural analysis:</span></span></span></b></b></div>
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
</span></span>
</b></b><br />
<ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"><b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
<li><a class="external-link" href="http://www.class-visualizer.net/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">Class Visualizer</span></a><span class="Apple-style-span" style="font-weight: normal;"> 0.5.1 - free tool for structural analysis</span></li>
<li><span class="Apple-style-span" style="font-weight: normal;">Free Java IDEs:</span><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li><a class="external-link" href="http://www.eclipse.org/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">Eclipse</span></a><span class="Apple-style-span" style="font-weight: normal;"> 4.3 - most popular IDE, first choice of most software engineers</span></li>
<li><a class="external-link" href="http://netbeans.org/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">NetBeans</span></a><span class="Apple-style-span" style="font-weight: normal;"> 7.3 - second popular IDE</span></li>
<li><a class="external-link" href="http://www.jetbrains.com/idea/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">IntelliJ IDEA</span></a><span class="Apple-style-span" style="font-weight: normal;"> 12.0 Community Edition - third popular IDE</span></li>
</ul>
</li>
<li><span class="Apple-style-span" style="font-weight: normal;">Eclipse plugins (working with v4.3)</span><ul style="list-style-type: disc; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<li><a class="external-link" href="http://www.modelgoon.org/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">ModelGoon</span></a><span class="Apple-style-span" style="font-weight: normal;"> 4.4.1</span></li>
<li><a class="external-link" href="http://marketplace.eclipse.org/content/javadoc-uml-view" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">Javadoc As UML View</span></a><span class="Apple-style-span" style="font-weight: normal;"> 0.2.2 <span style="font-size: xx-small;">1)</span></span></li>
<li><a class="external-link" href="http://amateras.sourceforge.jp/cgi-bin/fswiki_en/wiki.cgi?page=AmaterasUML" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">AmaterasUML</span></a><span class="Apple-style-span" style="font-weight: normal;"> 1.3.4</span></li>
<li><a class="external-link" href="http://www.objectaid.com/" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">ObjectAid</span></a><span class="Apple-style-span" style="font-weight: normal;"> 1.1.0</span></li>
<li><a class="external-link" href="http://www.nwiresoftware.com/products/nwire-java" rel="nofollow" style="color: #326ca6; text-decoration: none;"><span class="Apple-style-span" style="font-weight: normal;">nWire for Java</span></a><span class="Apple-style-span" style="font-weight: normal;"> (commercial, 30 days free trial available) <span style="font-size: xx-small;">1)</span></span></li>
</ul>
</li>
</span></span></b></b></ul>
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
</span></span>
</b></b><br />
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;"><span style="font-size: xx-small;">1)</span> officially not supported on Eclipse 4</span></span></span></b></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div style="background-color: transparent; color: #333333; display: inline !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b>
</b>
<br />
<div style="background-color: transparent; color: #333333; display: inline !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<h3 id="EfficientStructuralAnalysisofexistingprojects-Theanalysis" style="color: black; display: inline !important; font-size: 1.4em; line-height: 1.5625; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 1.5em;">
<b>
<span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
<b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
<span class="Apple-style-span" style="font-weight: normal;">Analysis</span></span></span></b></b></span></span></b></h3>
</div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
</span></span></b></b></span></span></b></div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b><b>
</b></b><span class="Apple-style-span" style="font-family: Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 19px;"></span>
</span></span></b><br />
<h4 id="EfficientStructuralAnalysisofexistingprojects-Projectstructure" style="color: black; font-size: 1.2em; line-height: 20px; margin-bottom: 0.3em; margin-left: 0px; margin-right: 0px; margin-top: 1.2em;">
<b>
<span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
<span class="Apple-style-span" style="font-weight: normal;">Project structure</span></span></span></b></h4>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">First, we would like to have general overview of the project structure:</span></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-xk00m9F7ABKkimT_oApT3SbwUablunwwG2Gr0LffX2nhpZhAMqn5ze03NiRh4PbmjayajDr7szmTvrjLWeRQYcFEoZjlGYcyWH6JPYZVsNZIsLODsYW4wt_eto_yCLHXnlmoOw9RBU/s1600/proj-e43m4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-xk00m9F7ABKkimT_oApT3SbwUablunwwG2Gr0LffX2nhpZhAMqn5ze03NiRh4PbmjayajDr7szmTvrjLWeRQYcFEoZjlGYcyWH6JPYZVsNZIsLODsYW4wt_eto_yCLHXnlmoOw9RBU/s1600/proj-e43m4.png" /></a></div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b>Figure 2a. Project structure in Eclipse IDE.</b></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><br /></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8GBedGmDHZQcEV7H076oeLvyh-TOWUOGxbOtf6m9KtE9n5isKOIBJRHhWeIbgTowhr6VeBtUdL65f0MiTWJPct1InKA8HdKtUTLbVv1bEefx8QxqzyPTgthRqdFHhNhQvrqDN94aXOj0/s1600/proj-nb73b2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8GBedGmDHZQcEV7H076oeLvyh-TOWUOGxbOtf6m9KtE9n5isKOIBJRHhWeIbgTowhr6VeBtUdL65f0MiTWJPct1InKA8HdKtUTLbVv1bEefx8QxqzyPTgthRqdFHhNhQvrqDN94aXOj0/s1600/proj-nb73b2.png" /></a></div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b>Figure 2b. Project structure in NetBeans IDE.</b></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><br /></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjy04Lb1i1f1Qf-sd9MxNKPkktl6AMOaaRSxAHWQCehnibB_tIgbU2eivmjMz0R8D-LtgeHKIlYaWLC6AQFpZNA9hpwu-4uurQmEF6H97n2-numa47DJH49WQPwugUZiqAGjT4PZqLOpM/s1600/proj-idea12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjy04Lb1i1f1Qf-sd9MxNKPkktl6AMOaaRSxAHWQCehnibB_tIgbU2eivmjMz0R8D-LtgeHKIlYaWLC6AQFpZNA9hpwu-4uurQmEF6H97n2-numa47DJH49WQPwugUZiqAGjT4PZqLOpM/s1600/proj-idea12.png" /></a></div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b>Figure 2c. Project structure in IntelliJ IDEA.</b></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><br /></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRlcUjJt4lTBK_KytndVpSjhYTOxjOwSWnSkSmzHp99YKVorIgv-Z21I0T2FkOsWda8oDldHeOT_gxcdJSvRdGuBzcdlTTQPWKNOXAL5MCqhymbs5PJMBS-kzXLJDVPAuhuM05MEJvShI/s1600/proj-clsvis.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRlcUjJt4lTBK_KytndVpSjhYTOxjOwSWnSkSmzHp99YKVorIgv-Z21I0T2FkOsWda8oDldHeOT_gxcdJSvRdGuBzcdlTTQPWKNOXAL5MCqhymbs5PJMBS-kzXLJDVPAuhuM05MEJvShI/s640/proj-clsvis.png" width="640" /></a></div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><b>Figure 2d. Project structure in Class Visualizer.</b></span></span></b></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;"><br /></span></span></span></b>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">As shown in Figure 2, two out of four tools (IntelliJ IDEA and Class Visualizer) present graphical information about the kind of element (class, interface, enum, annotation) and one of them (Class Visualizer) presents the full list of project</span></span></span></b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;"> elements</span></span></span><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">. </span></span></span></b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">A</span></span></span><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">ll tools except Eclipse IDE show the structure of </span></span></span></b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">the </span></span></span><b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">element</span></span></span></b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;"> currently </span></span></span><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">selected </span></span></span> on the list.</span></span></span></div>
<div style="background-color: transparent; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px;">
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;"><span class="Apple-style-span" style="font-weight: normal;">The analysis of the element structure and its relations will be discussed in next parts of this series.</span></span></span></b></div>
</div>
<b><span class="Apple-style-span" style="color: black;"><span class="Apple-style-span" style="color: #333333;">
</span></span></b></div>
<b>
</b></div>
Jonatanhttp://www.blogger.com/profile/08127587300940801439noreply@blogger.com2Swissairstrasse, Zurich Airport (ZRH), 8302 Kloten, Switzerland47.4453178 8.569924899999932747.4453178 8.5699248999999327 47.4453178 8.5699248999999327tag:blogger.com,1999:blog-3305419975676030648.post-32323567723414793542012-05-22T07:18:00.000+02:002012-05-22T07:23:33.279+02:00CDI Query Alpha 4 ReleasedThere's been a while now since my last post on <a href="http://ctpconsulting.github.com/query/" target="_blank">CDI Query</a>, but that doesn't mean we haven't been busy working on it! Last week I've pushed another Alpha release to Maven Central, and I'm very curious about your feedback!<br />
<br />
Summarizing the feature highlights since the last post:<br />
<ul>
<li><b>Entities</b>: Support for entities defined in <span style="font-family: "Courier New",Courier,monospace;">orm.xml</span> descriptors, <span style="font-family: "Courier New",Courier,monospace;">@IdClass</span> and composite primary keys: this should close the gap for all kind of entities. </li>
</ul>
<ul>
<li><a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/methodexpressions.html" target="_blank"><b>Method expression</b></a> have gotten some more love: First of all validation. As those expressions are not very stable once it comes to refactorings, they are now validated at extension initialization. Also there's now support for ordering and nested properties.</li>
</ul>
<ul>
<li><a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/auditing.html" target="_blank"><b>Auditing</b></a>: Keeping track of entity creation and change dates is often a requirement in enterprise applications. This is supported by simpy annotating your entities temporal properties with <span style="font-family: "Courier New",Courier,monospace;">@CreatedOn</span> or <span style="font-family: "Courier New",Courier,monospace;">@ModifiedOn</span>. </li>
</ul>
<ul>
<li>Extensions in the <b>Criteria Support API</b>: Allows now <a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/criteria.html#criteria-selects" target="_blank">selections</a>. There's also been a major cleanup with regards to separation of API and implementation. </li>
</ul>
<ul>
<li><b>Bulk operations</b> - use <a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/annotations.html#annotations-bulk" target="_blank">modifying statements</a> in a <span style="font-family: "Courier New",Courier,monospace;">@Query</span> annotation.</li>
</ul>
<ul>
<li>Postprocessing of query methods with the <a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/annotations.html#annotations-queryoptions" target="_blank"><b><span style="font-family: "Courier New",Courier,monospace;">QueryResult</span></b></a> class. This will encapsulate the result of a method expression or a <span style="font-family: "Courier New",Courier,monospace;">@Query</span> annotation, and allows to add ordering, paging and other post processing dynamically. </li>
</ul>
<ul>
<li>The <a href="http://ctpconsulting.github.com/query/1.0.0.Alpha4/home.html" target="_blank"><b>EntityHome API</b></a>, inspired by the Seam 2 application framework, helps you to easily connect your entities to the UI and implementing CRUD pages with a few lines of code.</li>
</ul>
There have already jumped a few people on board, providing great feedback, bugfixes and new features! Special thanks to:<br />
<ul>
<li>Jason Porter (bug fixes, Solder upgrade, support for PK related features and feature requests)</li>
<li>Marek Smigielski (bug fixes, feature requests)</li>
<li>Aaron Walker (API extensions)</li>
<li>and various others, providing some food for thought - thanks guys!</li>
</ul>
<br />
<b>So what's next?</b> We're still in Alpha, and some features have been - frankly said - just been hacked in to try them out. So there is need for cleanups. Featurewise there is also a polish of the various APIs
required, but a larger part could be improved support for stored procedures, and a <a href="http://forge.github.com/" target="_blank">Forge</a> plugin (in case you don't know Forge - hurry up and install it!). Or whatever you feel is missing - looking forward to your Issues on GitHub!Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-54349800911651109552011-11-22T11:25:00.000+01:002011-11-22T11:25:00.673+01:00CDI Query Module First Alpha Released!<br />
It's been some months now since we started <a href="http://ctpjava.blogspot.com/2011/04/cdi-extension-for-query-generation.html">exploring CDI extensions</a> as a small <span class="Apple-style-span" style="border-collapse: collapse; font-family: Arial, Verdana, sans-serif; font-size: 14px;">exercise</span>. As it turned out, the exercise forged into something usable which we're pushing now in the open as a first Alpha shot.<br />
<br />
So I'm happy to announce the availability of the <a href="http://ctpconsulting.github.com/query">CDI Query Module</a> on <a href="http://search.maven.org/#search%7Cga%7C1%7Ccdi-query" target="_blank">Maven Central</a>! The module helps you creating JPA queries with much less boilerplate, and is of course leveraging the CDI extension API as well as <a href="http://seamframework.org/Seam3/Solder">Seam Solder</a>. Some of the feature highlights are:<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Query By Name</span></b><br />
<br />
Assuming you have a Person entity which looks probably similar to this:<br />
<br />
<pre class="java" name="code">@Entity
public class Person {
... // primary key etc. skipped
@Getter @Setter
private String firstName;
@Getter @Setter
private String lastName;
}
</pre>
<br />
You can simply create a DAO interface to query for Persons:<br />
<br />
<pre class="java" name="code">@Dao
public interface PersonDao extends EntityDao<Person, Long> {
Person findByFirstNameAndLastName(String firstName, String lastName);
}
</pre>
<br />
This interface does not need to be implemented. A client can just inject it, call the interface method and in the background, the JPA query is automatically created and executed. To create the query, the method name is analyzed and matching the name to entity properties.<br />
<br />
<pre class="java" name="code">public class PersonAction {
@Inject
private PersonDao personDao;
public void lookup() {
person = personDao.findByFirstNameAndLastName(firstName, lastName);
}
}
</pre>
<br />
Note that the base interface contains also a couple of other methods which you might also expect from an entity DAO. Ideally, you should not need to inject an EntityManager anymore.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Query by Query Strings and Named Queries</span></b><br />
<br />
Of course matching property names is not extremely safe to refactorings (some more validation support here is on the roadmap) - if you like to have more control over your JPA queries, you can also annotate the method with the query to execute:<br />
<br />
<pre class="java" name="code">@Dao
public interface PersonDao extends EntityDao<Person, Long> {
@Query("select p from Person p where p.ssn = ?1")
Person findBySSN(String ssn);
@Query(named=Person.BY_FULL_NAME)
Person findByFullName(String firstName, String lastName);
}
</pre>
<br />
<b><span class="Apple-style-span" style="font-size: large;">Criteria API Simplifications</span></b><br />
<br />
If you're not a big fan of query strings but rather prefer using the JPA 2 criteria API, we also allow to simplify this with a small utility API:<br />
<br />
<pre class="java" name="code">public abstract class PersonDao extends AbstractEntityDao<Person, Long> {
public List<Person> findAdultFamilyMembers(String name, Integer minAge) {
return criteria()
.like(Person_.name, "%" + name + "%")
.gtOrEq(Person_.age, minAge)
.eq(Person_.validated, Boolean.TRUE)
.orderDesc(Person_.age)
.createQuery()
.getResultList();
}
}
</pre>
<br />
All the code is <a href="http://ctpconsulting.github.com/query" target="_blank">hosted</a> and <a href="http://ctpconsulting.github.com/query" target="_blank">documented</a> on GitHub. Please:<br />
<br />
<ul>
<li>Give feedback! If you find this useful or actually not so, we're happy to hear what is still missing.</li>
<li>Participate! Forking and creating pull requests are really a breeze on GitHub :-)</li>
</ul>
<br />
<br />
Credits:<br />
<br />
<ul>
<li><a href="http://ctpjava.blogspot.com/2010/08/java-people-spotlight-bartek-majsak.html" target="_blank">Bartek Majsak</a> for improving the initial code, taking care about quality reports and soon finalizing the stuff on the validation branch ;-) (just kidding, check out Bartek's <a href="https://github.com/arquillian/arquillian-extension-persistence" target="_blank">cool work on the Arquillian Persistence Module</a>!)</li>
<li><a href="http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html" target="_blank">Grails GORM</a> for inspiring me for this Java implementation</li>
<li>The CDI folks for a really great specification</li>
<li>Last but not least the <a href="http://www.jboss.org/arquillian" target="_blank">Arquillian guys</a>, developing and testing this stuff is pure fun with Arquillian!</li>
</ul>
<br />Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com24Flughafen Zürich (ZRH), 8058 Zürich-Flughafen, Switzerland47.4504 8.561947.428925 8.522418 47.471875000000004 8.601382tag:blogger.com,1999:blog-3305419975676030648.post-65206530263745493032011-11-11T15:24:00.002+01:002011-11-11T16:31:13.354+01:00JBoss Forge JRebel Plugin - Video TutorialIt's actually out for quite a while now (and therefore already slighly out of date) but I have hardly found some time to blog about it: If you're using <a href="http://zeroturnaround.com/jrebel/" target="_blank">JRebel</a> and <a href="https://docs.jboss.org/author/display/FORGE/Home" target="_blank">JBoss Forge</a>, have a look at this <a href="http://www.youtube.com/watch?v=oxCIGjFGI7o&hd=1" target="_blank">Video tutorial</a> how to use both of them together. <br />
<br />
<iframe class="youtube-player" frameborder="0" height="385" src="http://www.youtube.com/embed/oxCIGjFGI7o" type="text/html" width="640">&lt;p&gt;&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;&lt;/p&gt;</iframe><br />
<br />
Make sure to watch it in HD and full screen mode. Thanks to <a href="http://ctpjava.blogspot.com/2008/09/java-people-spotlight-christoph-reimann.html">Chris "Kubrik" Reimann</a> for putting the tutorial together!<br />
<br />
As an addition, Forge now also supports checking out specific versions of a plugin, which is in our case version 1.0.0.Beta1 of the JRebel plugin. We've also added the plugin to the Forge plugin repository index so you can search for it.<br />
<br />
By the way, if you're only using one of the tools or (even worse) none of them, this is the perfect opportunity to get a quick hands-on.Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0Flughafen Zürich (ZRH), 8058 Zürich-Flughafen, Switzerland47.4504 8.561947.428925 8.522418 47.471875000000004 8.601382tag:blogger.com,1999:blog-3305419975676030648.post-59617127743687604422011-04-04T18:24:00.004+02:002011-04-04T18:54:32.995+02:00A CDI Extension for Query GenerationWhile the DAO pattern has come out of fashion with Java EE 6, it can still be a useful approach to centralize query related logic when you have to do more than just delegating to the entity manager. Often this approach leads then to small frameworks containing reusable code within a project, or also sometimes into a bigger framework spreading over complete IT departments within a company.<br /><br />Inspired by features of <a href="http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html" target="_blank">Grails</a> or the <a href="http://static.springsource.org/spring-data/data-jpa/docs/1.0.0.M1/reference/html/" target="blank">Spring Data JPA</a> project, my plan was to learn more about <a href="http://docs.jboss.org/weld/reference/latest/en-US/html/extend.html">CDI extensions</a> by implementing a proof of concept on such a DAO framework based on CDI. CDI is part of Java EE 6 and, already by itself a powerful addition to the platform programming model, provides SPIs to extend it even further. A prominent sample is the <a href="http://seamframework.org/Seam3" target="_blank">Seam framework</a>, which in its latest version contains a lot of those extensions. Just drop them in your classpath and they are ready for use. Impressive enough to learn more about the technology.<br /><br />While I was getting my hands dirty it seemed to me the result is useful enough to share it here - and also of course to demonstrate the power and easiness of creating CDI extensions. In this article I’ll give you a quick start on CDI extensions as well as (hopefully) an idea on how a portable framework might look like based on this technology. All code presented here is available on <a href="https://github.com/ctpconsulting/query" target="_blank">GitHub</a>.<br /><br /><b>The DAO Framework</b><br /><br />Some common ingredients of a DAO framework are captured in the code snippet below:<br /><pre name="code" class="java"><br />@Dao<br />public interface SimpleDao extends EntityDao<Simple, Long> {<br /> <br /> Simple findByNameAndEnabled(String name, Boolean enabled);<br /><br /> @Query(named=Simple.BY_NAME)<br /> List<Simple> findByNamedQuery(String name);<br /> <br /> @Query(named=Simple.BY_NAME)<br /> List<Simple> findByNamedQueryRestricted(String name, <br /> @MaxResults int max, @FirstResult int first);<br /> <br /> @Query(named=Simple.BY_ID)<br /> Simple findByNamedQueryNamedParams(<br /> @QueryParam("id") Long id, <br /> @QueryParam("enabled") Boolean enabled);<br /> <br /> @Query("select s from Simple s where s.name = ?1")<br /> Simple findByQueryString(String name);<br /><br />}<br /></pre><br />Typically a DAO framework has a common interface concrete DAOs can extend from. Using generics here allows to have a standard set of methods like saving or retrieving all entities of a specific type, and can also be used during query generation. Usually this is nothing that cannot be done easily with an entity manager. But once you have injected a DAO in your service class - do you really want to inject the entity manager as well? In order to keep code leaner, a DAO base interface should provide this kind of methods and of course implement them all automagically - nothing you would like to rewrite again and again.<br /><br />Some other features are shown in the method declarations above. Automatic query generation out of method names and parameters as GORM method expressions do, or creating queries based on annotation meta data and parameters will often allow just leaving those easy cases to the query generator and keep the code lean to focus on the complex ones.<br /><br /><b>The CDI Approach</b><br /><br />One way to implement such a framework is over a CDI extension. CDI allows extensions to listen to various lifecycle events:<br />- Before CDI starts discovering beans.<br />- While it processes annotated types, injection targets, producers, beans and observers.<br />- And when it finishes with both discovery and validation.<br /><br />As in our case we are dealing with plain interfaces, the easiest approach is to simply annotate the interface and then listen for annotation processing events. The sample above shows a Dao annotation on the interface, but this would be placed on the extended AbstractEntityDao interface so developers won’t have to worry about it.<br /><br />So on the extension we listen for annotated types, check if it is our Dao annotation and register a proxy bean which implements the annotated type. Registering the extension a matter of two things:<br />1. Implementing the extension class and listen for the Dao annotation.<br /><pre name="code" class="java"><br />public class QueryExtension implements Extension {<br /><br /> <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> event, BeanManager beanManager) {<br /> // all the required information on the type is found in the event<br /> // the bean manager is used to register the proxy<br /> }<br /><br />}<br /></pre><br />2. Register the extension class as a service provider in the appropriate file (META-INF/services/javax.enterprise.inject.spi.Extension).<br /><br />Registering the proxy with the bean manager is slightly more work, but luckily someone has already done that. If you work with CDI extensions, make sure to include <a href="http://docs.jboss.org/seam/3/solder/latest/reference/en-US/html/" target="_blank">Seam Solder</a> - the Swiss army knife for CDI developers. Solder has built-in support for so called <a href="http://docs.jboss.org/seam/3/solder/latest/reference/en-US/html/servicehandler.html" target="_blank">service handlers</a>, where you annotate an abstract type with a reference to the handler class. The documentation use case looks probably kind of familiar ;-) All our extension will have to do is to override the handler lookup - and we’re done with registering the proxy! The reason we don't use the ServiceHandlerExtension directly is to separate the handler reference from the annotation, and that we can have a chance to e.g. validate and process further meta data in the extension class.<br /><pre name="code" class="java"><br />public class QueryExtension extends ServiceHandlerExtension {<br /><br /> @Override<br /> protected <X> Class<?> getHandlerClass(ProcessAnnotatedType<X> event) {<br /> if (event.getAnnotatedType().isAnnotationPresent(Dao.class)) {<br /> return QueryHandler.class;<br /> }<br /> return null;<br /> }<br /><br />}<br /><br />public class QueryHandler {<br /><br /> @Inject<br /> private Instance<EntityManager> entityManager;<br /> <br /> @AroundInvoke<br /> public Object handle(InvocationContext ctx) throws Exception {<br /> ...<br /> }<br /><br />}<br /><br /></pre><br />The handler class simply has to provide a public method annotated with @AroundInvoke, where you get all the required information to build up your query dynamically. Note that in the handler class you will also be able to use CDI services like injection.<br />As a framework user, all you will have to do is to drop the JAR in the classpath and annotate the interface. Look mom, no XML! Well almost, you still need an (empty) beans.xml somewhere to activate all the CDI magic.<br /><br /><b>Testing the Extension</b><br /><br /><a href="http://docs.jboss.org/arquillian/reference/latest/en-US/html_single/" target="_blank">Arquillian</a> is a relatively new testing framework which allows you to create dynamic deployment units and run them in a container. A great feature for an extension as you can easily test it live in a unit test without leaving the IDE! This looks like the following:<br /><pre name="code" class="java"><br />@RunWith(Arquillian.class)<br />public class QueryHandlerTest {<br /> <br /> @Deployment<br /> public static Archive<?> deployment() {<br /> return ShrinkWrap.create(WebArchive.class, "test.war")<br /> .addClasses(QueryExtension.class)<br /> .addAsWebInfResource("test-persistence.xml", ArchivePaths.create("classes/META-INF/persistence.xml"))<br /> .addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))<br /> .addAsWebInfResource("glassfish-resources.xml")<br /> .addClasses(SimpleDao.class)<br /> .addPackage(Simple.class.getPackage());<br /> }<br /> <br /> @Inject<br /> private SimpleDao dao;<br /> <br /> @Produces<br /> @PersistenceContext<br /> private EntityManager entityManager;<br /> <br /> @Test<br /> public void shouldCreateQueryByMethodName() {<br /> // given<br /> final String name = "testCreateQueryByMethodName";<br /> createSimple(name);<br /> <br /> // when<br /> Simple result = dao.findByNameAndEnabled(name, Boolean.TRUE);<br /> <br /> // then<br /> Assert.assertNotNull(result);<br /> Assert.assertEquals(name, result.getName());<br /> }<br /><br />}<br /></pre><br />This creates a stripped down web archive deployment, in this sample for an embedded GlassFish. The test class itself is registered as a bean in the test and can therefore use injections (CDI or container injections, see the @PersistenceContext). Resources like persistence units can be added on demand as we see in the deployment method (persistence.xml for the persistence unit, glassfish-resources.xml contains a data source definition).<br /><br />The container gets started and we can see our injected proxy in action. In the sample above we then create some test data and see if our generated query fetches the right data back.<br /><br /><b>Conclusion</b><br /><br />Of course this article is a very simplified version of the whole setup - especially the Arquillian setup required some trial and error as the framework is still in Alpha (if anybody finds out how to create the data source without deploying the glassfish-resources.xml into a web archive - let me know). <br /><br />Check out the project source on <a href="https://github.com/ctpconsulting/query" target="_blank">GitHub</a> to get started. The module structure might look a little complicate but it follows common Seam module structure separating API (in our case the client annotations) from implementation (the extension code). Documentation is still "basic" but looking at the unit tests might give an indication on the usage.<br /><br />Once the project setup is done, things get extremely productive though. Seam Solder provides a rich tool set you can use to create an extension, Arquillian lets you immediately test your code inside a container. The result is an easy to reuse and easy to distribute framework you will probably get back to in many of your following Java EE 6 projects.Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com4tag:blogger.com,1999:blog-3305419975676030648.post-21253945077989610922011-03-18T14:35:00.001+01:002011-03-21T17:03:19.996+01:00Introduction to OSGi<span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;" id="internal-source-marker_0.6541155833928415">As my first blog entry here I want to introduce you to the OSGi framework. It allows you to build Java applications with high modularity and I believe that this technology will become more and more important in the future. The goal of this introduction is that the reader has a quick overview about the OSGi framework and that he understands the benefits of it. Further, this should be an introduction to my planned series of Eclipse plug-in development.</span><br /> <h2 style="margin:20px 0 20px 0;" style="margin:20px 0 20px 0;"><span style="font-size: 18pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">1 What is OSGi?</span></h2> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The </span><a href="http://www.osgi.org/"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline;">OSGi Alliance</span></a><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> (formerly known as Open Services Gateway initiative, now an obsolete name), founded in March 1999, originally specified and maintains the </span><a href="http://www.osgi.org/Release4/HomePage"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline;">OSGi specification</span></a><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">. This specification allows you to write so called bundles, self contained modules that can provide functionality to other bundles. There are several implementations of this specification, the most common ones are:</span> <ul><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Eclipse Equinox</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Apache Felix</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Knoplerfish</span></li></ul> <br /> <h3 style="margin:15px 0 15px 10px;"><span style="font-size: 14pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">1.1 Why OSGi?</span></h3> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">As mentioned before, the OSGi specification aims to create Java applications with extremely high modularity. Of course, this is what every developer aims at, but OSGi encourages and supports you in doing so. Also a great feature is that you can install or uninstall such bundles during runtime of the application without restarting it. It also supports lazy loading. This means that you can configure a bundle to be loaded when it’s called the first time. This truly increases the performance of an application. The OSGi specification also defines some useful services, that have to be provided by an OSGi implementation.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">What does that mean to CTP? As high modularity is becoming more and more important, clients will have the need to extend their application. As seen in the sM-Client project, for example, the client wants to make small extensions like custom forms without packaging a whole new release. Which is quite understandable. Now a plug-in style mechanism is evaluated, but there may be problems, especially with classloading, which are well solved in OSGi.</span><br /> <h2 style="margin:20px 0 20px 0;"><span style="font-size: 18pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">2 Architecture</span><span style="font-size: 14pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></h2> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The OSGi framework is based on several Layers:</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Security layer:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> The OSGi Security Layer is an optional layer that underlies the OSGi Service</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Platform. The layer is based on the Java 2 security architecture. It provides</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">the infrastructure to deploy and manage applications that must run in finegrained</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">controlled environments.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Module layer:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> The Module Layer is responsible for the packaging of the modules (“bundles”), those are simple JAR files which follow some requirements. I will explain more about bundles in section 2.1.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Life cycle layer:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> This layer gives you the possibility to install, uninstall, start and stop bundles inside an application framework without restarting the whole framework, (e.g. if you contribute a bug fix inside a bundle). This also increases the availability of your application framework.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Service Layer: </span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The Service Layer enables you to provide OSGi services to other bundles. An OSGi service is nothing but a POJO, that is registered in the </span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Service Registry</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> and can be referenced from everywhere outside the declaring bundle. The service has to implement an agreed interface.</span><span style="font-size: 14pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /><br /><img src="https://lh5.googleusercontent.com/BcerVUV-fxSlfE6BKo-fVT0ecvt4aA8I48biV0r-ussrJlfO7dRIZUAknAUDRLou_71lOX3LPXZ6KFSaoTuEgM3vjeLNRiK_QFiwwJhnL1_Zb509AQ" width="300px;" height="240px;" /><br /> <h3 style="margin:15px 0 15px 10px;"><span style="font-size: 14pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">2.1 Bundles</span></h3> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">As the description of the Module Layer says, a bundle is a plain old JAR file. But it has some special characteristics. There has to be a MANIFEST.MF file in the META-INF directory, which is located at the root of the JAR file (see the </span><a href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline;">JAR specification</span></a><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">). This file provides several meta information about the bundle like dependencies, exported and imported packages etc. Note, that in difference to a normal JAR file, all packages are hidden by default to other bundles. So you have to define which packages are exported and therefore are accessible from other bundles. Additionally, you have to specify which packages you want to import from other bundles. Also you can define required bundles, which will import all exported packages of the required bundles. Let’s have a look at an example MANIFEST.MF file:</span><br /> <pre name="code" class="plain"><br />Bundle-Name: Hello World<br />Bundle-SymbolicName: com.ctp.helloworld<br />Bundle-Description: A Hello World bundle<br />Bundle-ManifestVersion: 2<br />Bundle-Version: 1.0.0<br />Bundle-Activator: com.ctp.Activator<br />Export-Package: com.ctp.helloworld;version="1.0.0"<br />Import-Package: org.osgi.framework;version="1.3.0"<br />Require-Bundle: com.ctp.other;bundle-version="2.5.0"<br />Bundle-RequiredExecutionEnvironment: JavaSE-1.6</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">These configuration elements are explained as follows:</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span> <ul><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-Name:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Defines a human-readable name for this bundle, Simply assigns a short name to the bundle.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-SymbolicName:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> The only required header, this entry specifies a unique identifier for a bundle, based on the reverse domain name convention (also used by the java packages).</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-Description:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> A description of the bundle's functionality.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-ManifestVersion:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> This little known header indicates the OSGi specification to use for reading this bundle.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-Version:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Designates a version number to the bundle.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-Activator:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Indicates the class name to be invoked once a bundle is activated.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Export-Package:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Expresses what Java packages contained in a bundle will be made available to the outside world.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Import-Package:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Indicates what Java packages will be required from the outside world, in order to fulfill the dependencies needed in a bundle.</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Require-Bundle:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Indicates what OSGi bundles will be required from the application framework. This will import all exported packages from the specified bundle(s).</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle-RequiredExecutionEnvironment:</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Specifies the minimum execution environment(s) required to run this bundle.</span></li></ul> <br /> <h4 style="margin:10px 0 10px 10px;"><span style="font-size: 12pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">2.1.1 Bundle life cycles</span></h4> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">A bundle’s life cycle could have the following states (managed by OSGi’s Life Cycle Layer):</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span> <table style="border: medium none; border-collapse: collapse;"> <tbody><tr style="height: 28px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; background-color: rgb(204, 204, 204); padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle State</span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; background-color: rgb(204, 204, 204); padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Description</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">INSTALLED</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle has been successfully installed.</span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">RESOLVED</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">All Java classes that the bundle needs are available. This state indicates that the bundle is either ready to be started or has stopped.</span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">STARTING</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle is being started, the </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">BundleActivator.start</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> method will be called, and this method has not yet returned. When the bundle has an activation policy, the bundle will remain in the </span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">STARTING</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> state until the bundle is activated according to its activation policy.</span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">ACTIVE</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle has been successfully activated and is running; its Bundle Activator start method has been called and returned.</span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">STOPPING</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle is being stopped. The </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">BundleActivator.stop</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> method has been called but the stop method has not yet returned.</span></td></tr><tr style="height: 0px;"><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">UNINSTALLED</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span></td><td style="border: 1px dotted rgb(170, 170, 170); vertical-align: top; padding: 7px;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle has been uninstalled. It cannot move into another state.</span></td></tr></tbody> </table> <br /> <h3 style="margin:15px 0 15px 10px;"><span style="font-size: 14pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">2.2 OSGi Services</span></h3> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">OSGi Services are Java objects, that implement agreed interfaces. This means that the Service itself is defined by a Java interface and the bundles which use the service don’t have to know where the specific implementation actually is. The following is a simple OSGi Service:</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The service interface:</span><pre name="code" class="java">public interface HelloWorld {<br /> public String getMessage();<br />}</pre><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The service implementation:</span><pre name="code" class="java">package com.ctp.helloworld.service.impl;<br /><br />import com.ctp.helloworld.service.HelloWorld;<br /><br />class HelloWorldImpl implements HelloWorld {<br /> @Override<br /> public String getMessage() {<br /> return “Hello World”;<br /> }<br />}</pre><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Now, without any tools like Spring Dynamic Modules, iPOJO or Declarative Services, we have to register our service manually so that it can be accessed by other bundles. I will explain this in the following section.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Please note that the -Impl naming convention does not really make sense in OSGi, since it’s possible to have multiple implementations of one service, it was just the easiest for this example.</span><br /> <h2 style="margin:20px 0 20px 0;"><span style="font-size: 18pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">3 Example</span></h2> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Let’s write a simple bundle that contains the HelloWorld service we created above. First, download an OSGi framework (I’m using </span><a href="http://download.eclipse.org/equinox/drops/R-3.6-201006080911/index.php"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline;">Equinox 3.6</span></a><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">, but this example should work on all implementations since it’s very basic). This example is made as you could get going without any special IDE. The source code can be downloaded <a href="http://code.google.com/p/ctpjava/downloads/detail?name=com.ctp.helloworld.zip&can=2&q=">here</a>.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Copy the downloaded jar file to a location where you would like to start your application (further called </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$APP_HOME</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">).</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Now create a work folder, where your source files are (further called </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">).</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Create the following folders and files:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/service/HelloWorld.java</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/service/impl/HelloWorldImpl.java</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/Activator.java</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/META-INF/MANIFEST.MF</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The MANIFEST.MF file is very basic and should have the following contents:</span><br /> <pre name="code" class="plain"><br />Manifest-Version: 1.0<br />Bundle-ManifestVersion: 2<br />Bundle-Name: Hello World<br />Bundle-SymbolicName: com.ctp.helloworld<br />Bundle-Version: 1.0.0<br />Bundle-Activator: com.ctp.helloworld.Activator<br />Bundle-Vendor: CTP<br />Bundle-RequiredExecutionEnvironment: JavaSE-1.6<br />Import-Package: org.osgi.framework;version="1.3.0"<br />Bundle-ActivationPolicy: lazy<br /></pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Make sure you have a carriage return and/or newline character at the end of the last line as this is required (see manifest specification in the </span><a href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline;">JAR specification</span></a><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">).</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Let’s create the OSGi Service as the example in section 2.2:</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/service/HelloWorld.java:</span><br /> <pre name="code" class="java"><br />package com.ctp.helloworld.service;<br /><br />public interface HelloWorld {<br /> public String getMessage();<br />}<br /></pre><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/service/impl/HelloWorldImpl.java:</span><br /><pre name="code" class="java">package com.ctp.helloworld.service.impl;<br /><br />import com.ctp.helloworld.service.HelloWorld;<br /><br />public class HelloWorldImpl implements HelloWorld {<br /><br /> @Override<br /> public String getMessage() {<br /> return "Hello World";<br /> }<br />}</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The defined activator (</span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$SRC_HOME/com/ctp/helloworld/Activator.java)</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> should have the following contents so that it is able to run:</span><br /><pre name="code" class="java">package com.ctp.helloworld;<br /><br />import org.osgi.framework.BundleActivator;<br />import org.osgi.framework.BundleContext;<br /><br />public class Activator implements BundleActivator {<br /><br /> private static BundleContext context;<br /><br /> static BundleContext getContext() {<br /> return context;<br /> }<br /><br /> public void start(BundleContext bundleContext) throws Exception {<br /> Activator.context = bundleContext;<br /> }<br /><br /> public void stop(BundleContext bundleContext) throws Exception {<br /> Activator.context = null;<br /> }<br /><br />}</pre> <br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">At this state, the OSGi bundle should be ready to compile and deploy it. But first, we want to register our service. We do this in the method </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.helloworld.Activator#start:</span><br /><pre name="code" class="java">import org.osgi.framework.ServiceReference;<br />import com.ctp.helloworld.service.HelloWorld;<br />import com.ctp.helloworld.service.impl.HelloWorldImpl;<br />...<br />public void start(BundleContext bundleContext) throws Exception {<br /> System.out.println("Registering HelloWordld service...");<br /><br /> // this will register the service in the Service Registry<br /> bundleContext.registerService(HelloWorld.class.getName(), new HelloWorldImpl(), null);<br /><br /> // Test the availability of the service<br /> ServiceReference ref = bundleContext.getServiceReference(HelloWorld.class.getName());<br /><br /> if(ref == null) {<br /> System.out.println("Service is not registered...");<br /> } else {<br /> // it’s also possible to get an array of services...<br /> HelloWorld service = (HelloWorld)bundleContext.getService(ref);<br /> System.out.println("HelloWorld#getMessage(): " + service.getMessage());<br /> }<br /> Activator.context = bundleContext;<br />}<br />...</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Now we can compile the code and create a JAR file:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">cd $SRC_HOME;</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">javac -cp $APP_HOME/org.eclipse.osgi_3.6.0.v20100517.jar com/ctp/helloworld/service/HelloWorld.java com/ctp/helloworld/service/impl/HelloWorldImpl.java com/ctp/helloworld/Activator.java;</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">jar cvfm example.jar META-INF/MANIFEST.MF com;</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">cp example.jar $APP_HOME/example.jar;</span><span style="font-size: 8pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 8pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">If your bundle was built correctly you could start your test application:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">cd $APP_HOME;</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">java -jar org.eclipse.osgi_3.6.0.v20100517.jar -console;</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Now you can administrate the OSGi platform with the console. Test the bundle like the following:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">osgi>install file:///$APP_HOME/example.jar</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Bundle id is 4</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">osgi>start 4</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Registering HelloWorld service...</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">HelloWorldService#getMessage(): Hello World</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">osgi></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">NOTE: If you want to use the service inside another bundle, you have to add the package </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.helloworld.service</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> to the </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Export-Package</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> directive in the MANIFEST.MF file.</span><br /> <h2 style="margin:20px 0 20px 0;"><span style="font-size: 18pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">4 Multiple Implementations</span></h2> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">This example shows you how to use multiple implementations of a service. It’s a solution which I think, personally, is quite elegant. I won’t go through all steps that we already did in the previous example. A source code can be downloaded <a href="http://code.google.com/p/ctpjava/downloads/detail?name=com.ctp.playground.multiple.zip&can=2&q=">here</a>. Let’s create a bundle with the symbolic name </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> and the following classes:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.Activator</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.math.OperationService</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.math.OperationServiceFactory</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.math.internal.Addition</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.math.internal.Substraction</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Also create the following Enum:</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.math.Operation</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The bundle activator should have the following contents (don’t forget the imports):</span><br /> <pre name="code" class="java">public class Activator implements BundleActivator {<br /><br /> private static BundleContext context;<br /><br /> public static BundleContext getContext() {<br /> return context;<br /> }<br /><br /> public void start(BundleContext bundleContext) throws Exception {<br /> Activator.context = bundleContext;<br /> }<br /><br /> public void stop(BundleContext bundleContext) throws Exception {<br /> Activator.context = null;<br /> }<br /><br />}</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The interface </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.OperationService</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> has one method:</span><br /> <pre name="code" class="java">public Double doOperation(Double a, Double b);</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The classes </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Addition </span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">and </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Substraction </span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">implement this interface and are our actual services:</span><br /> <pre name="code" class="java">@Override<br />public Double doOperation(Double a, Double b) {<br /> return a + b;<br />}</pre><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">and:</span><pre name="code" class="java">@Override<br />public Double doOperation(Double a, Double b) {<br /> return a - b;<br />}</pre><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The Enum </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Operation</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> looks like the following (don’t forget the imports):</span><br /> <pre name="code" class="java">public enum Operation {<br /> ADDITION {<br /> @Override<br /> public Class<?> getServiceClass() {<br /> return Addition.class;<br /> }<br /> }, SUBSTRACTION {<br /> @Override<br /> public Class<?> getServiceClass() {<br /> return Substraction.class;<br /> }<br /> };<br /> public abstract Class<?> getServiceClass();<br />}</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">And now comes the part where we get our service implementations and decide which one to take. For that we created the Class </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">OperationServiceFactory</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">. Now extend it with the following method:</span><br /> <pre name="code" class="java">public static OperationService getService(Operation o) {<br /> BundleContext bundleContext = Activator.getContext();<br /> ServiceReference[] refs = null;<br /> try {<br /> // get the service references<br /> refs = bundleContext.getServiceReferences(OperationService.class.getName(),null);<br /> <br /> } catch (InvalidSyntaxException e) {<br /> // this should never happen, because the second argument<br /> // of bundleContext.getServiceReferences() is null.<br /> // You have the possibility to give filter criterias with<br /> // this parameter<br /> }<br /> OperationService service = null;<br /> if(refs != null) {<br /> for(int i = 0;i<refs.length;i++) {<br /> service = (OperationService) bundleContext.getService(refs[i]);<br /> // check, if the service is the wanted one<br /> if(service.getClass().equals(o.getServiceClass())) {<br /> return service;<br /> }<br /> }<br /> }<br /> return null;<br />}</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">All we have to do now is to register the services in the Activator class and test them. Extend the </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">com.ctp.playground.multiple.Activator</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">:</span><br /> <pre name="code" class="java">...<br />public void start(BundleContext bundleContext) throws Exception {<br /><br /> Activator.context = bundleContext;<br /> // register services<br /> bundleContext.registerService(OperationService.class.getName(), new Addition(), null);<br /> bundleContext.registerService(OperationService.class.getName(), new Substraction(), null);<br /> <br /> // test the services<br /> OperationService operation = OperationServiceFactory.getService(Operation.ADDITION);<br /> Double result = operation.doOperation(10.0, 20.0);<br /> System.out.println(result);<br /> operation = OperationServiceFactory.getService(Operation.SUBSTRACTION);<br /> result = operation.doOperation(10.0, 20.0);<br /> System.out.println(result);<br />}<br />...</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The MANIFEST.MF file should have the following contents:</span><br /> <pre name="code" class="plain">Manifest-Version: 1.0<br />Bundle-ManifestVersion: 2<br />Bundle-Name: Multiple Service implementations Example<br />Bundle-SymbolicName: com.ctp.playground.multiple<br />Bundle-Version: 1.0.0<br />Bundle-Activator: com.ctp.playground.multiple.Activator<br />Bundle-Vendor: CTP<br />Bundle-RequiredExecutionEnvironment: JavaSE-1.6<br />Import-Package: org.osgi.framework;version="1.3.0"<br />Bundle-ActivationPolicy: lazy<br />Export-Package: com.ctp.playground.multiple.math</pre><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Now build the bundle (compile and make jar file), put it in the </span><span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">$APP_HOME</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> directory, run the platform and install / start it like we did in the previous example.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">You should have the following output after starting the bundle:</span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">osgi> 30.0</span><br /> <span style="font-size: 11pt; font-family: Courier New; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">-10.0</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <h2 style="margin:20px 0 20px 0;"><span style="font-size: 18pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">5 Conclusion</span></h2> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Let’s summarize and see if you reached your targets:</span> <ul><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">OSGi is a framework specification for creating highly modular Java applications</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">A bundle is a simple jar file, defined through manifest headers</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">An OSGi Service is a simple POJO that needs to be registered in the OSGi Service Registry</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">You can create a simple bundle</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">You are able to create a simple OSGi Service</span></li><li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">You can manage multiple service implementations</span></li></ul> <br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"></span><br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">As I mentioned at the top of this blog, this is the first part of my series about OSGi and Eclipse plug-in development. I will publish the blogs like the following (there may be changes):</span> <ol><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Introduction to OSGi</span></li><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">OSGi in a declarative way<br /></span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">How to use additional frameworks like Spring DM or Declarative Services</span></li><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">OSGi and Eclipse<br /></span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">The way how Eclipse uses OSGi and introduction to Eclipse plug-in development</span></li><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Eclipse UI<br /></span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">How the Eclipse UI works and how to use it</span></li><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Eclipse SDK 4.0 - Model driven development<br /></span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">All about the new Eclipse SDK and its model driven approach</span></li><li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Eclipse SDK 4.0 - New features</span><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><br />New features of the SDK like XWT and usage of dependency injection</span></li></ol> <br /> <span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">I hope you enjoyed this little introduction to OSGi and I’m looking forward to read your comments, so I could improve my further planned blogs.</span>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-3305419975676030648.post-12154375103163242932010-10-15T08:10:00.004+02:002010-10-15T13:38:35.846+02:00Starting Scala<br /><br />I'm starting to learn <a href="http://www.scala-lang.org/">Scala</a>. I try to learn a new programming language every year (a tip from the <a href="http://www.pragprog.com/titles/tpp/the-pragmatic-programmer">Pragmatic programmer</a>) because it's a good way to keep your head young. Last year I learned JavaFx Script, too bad that <a href="http://java.dzone.com/articles/oracle-discontinue-javafx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+javalobby%2Ffrontpage+%28Javalobby+%2F+Java+Zone%29">Oracle announced</a> that they are not going forward with this. I really liked the whole notion of binding.<br /><br />Anyway Scala is a <a href="http://en.wikipedia.org/wiki/Functional_programming">functional language</a>, so that will be a challenge, because I've never written any code in a functional language before. I'm still learning so I thought let's take something form my day to day job.<br /><br />This was the problem, we have a web service that we can only call with 100 ids at a time. So we need to split our list with ids in batches of a 100. Fist I thought there must be some library that can do this. We did some google-ing, but we could not find it, so this is what we came up with:<br /><br /><pre name="code" class="java"><br /> static <E> List<List<E>> subDivide(List<E> list, int size) {<br /> List<List<E>> resultList = new ArrayList<List<E>>();<br /> <br /> int subdivideCount = list.size() / size;<br /> if (list.size() % size != 0) {<br /> subdivideCount++;<br /> }<br /> <br /> for (int i = 0; i < subdivideCount; i++) {<br /> int maxLength = Math.min(i * size + size, list.size());<br /> resultList.add(list.subList(i * size, maxLength));<br /> }<br /> <br /> return resultList;<br /> }<br /></pre><br /><br />Very standard way to solve something like this in Java. So I thought let's solve this in Scala. List are very cool in Scala and you can do pattern matching on them. Let's try that:<br /><br /><pre name="code" class="java"><br /> def subDivide(list: List[Int], batchSize:Int):List[List[Int]] = list match {<br /> case Nil => Nil<br /> case l if l.length > batchSize => List(list.splitAt(batchSize)._1) ::: subDivide(list.splitAt(batchSize)._2, batchSize)<br /> case l => List(list)<br /> }<br /></pre><br /><br />As you can see this code is much nicer. It checks the size of the list taking the batchSize off and then sub dividing the rest and adding this to the result. If the size is smaller than the batchSize we can return it without splitting. If anyone knows a better way of doing this in Scala, please leave me a comment.<br /><br />This is a much nicer solution, because there is way less int calculation involved. And the recursion also makes it a lot nicer, because there is no need of a for loop. So maybe this is what people are talking about, Scala does make you solve things differently.<br /><br />But of course we could do this in Java as well. In Java we don't have a nice pattern matching, so we'll have to do with if-s.<br /><br /><pre name="code" class="java"><br /> static <E> void subDivide(List<E> list, int size, List<List<E>> result) {<br /> if (list.isEmpty()) {<br /> return;<br /> } <br /> if (list.size() > size) {<br /> result.add(list.subList(0, size));<br /> subDivide(list.subList(size, list.size()), size, result);<br /> } else {<br /> result.add(list);<br /> }<br /> }<br /></pre><br /><br />As you can see a lot better. So at least Scala improved my Java code a bit today.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-15563357072258302502010-09-28T09:32:00.004+02:002010-09-28T09:48:01.658+02:00Swiss ICT Awards 2010Ok, this is not really a Java article as we usually post here on the blog - just a small company advertisement where you might help out. CTP has been nominated by the Swiss ICT Awards 2010 in the category "Champion". This award category gets selected by a jury. For the PUBLIC category, you can actually place a vote!<br /><br />Please click on the below link and vote for Cambridge Technology Partners now and we may become the winners of the PUBLIC category:<br /> <br /><a href="http://www.swissitmagazine.ch/index.cfm?pid=7786&cid=2103">http://www.swissitmagazine.ch/index.cfm?pid=7786&cid=2103</a><br /><br />Thanks!Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-10427606465608833172010-09-23T06:13:00.051+02:002010-09-24T07:11:04.589+02:00JavaOne 2010Time is running quickly, and shocked we have realized that this year's JavaOne is already over - high time to share some conference highlights with you! It's the first time that Oracle drove the conference after acquiring Sun, so we were curious whether the spirit we valued so much during the last years is still around. To give you the conclusion already now - it's a yes, but there are some drawbacks.<br /><br />It's clear that JavaOne is just the "side conference" this year - it had to leave its home in the Moscone center, which is mainly hosting Oracle OpenWorld. With the move, things got slightly smaller - session rooms (which is probably the most annoying aspect), the chill-out zones and exhibition space, ... . But of course it's not the size that matters; it's the content that compensates for it! The quality of the talks, we've seen, has been very good so far, and as usual it's a lot of great ideas, visions and news floating around. Below we give you a quick summary of the latest Java news and session highlights:<br /><br /><h3>Keynotes</h3>On Sunday evening Larry Ellison hosted the opening session of the Oracle OpenWorld. First of all most of the JavaOne attendees were rather surprised, they were not allowed to join in for this keynote. Nevertheless a quick update on this keynote is provided here before moving on with the real Java stuff.<br /><br />The first presentation was the Oracle Exalogic Elastic Cloud, which is very briefly summarized “The Cloud in a Box”. The Exalogic box provides both hardware and software. Oracle further announced benefits to the customer due to the homogeneous hardware and software, which is also reflected in Oracle's new tag line "Hardware and Software Engineered to Work Together". Exalogic combines up to 30 servers, including storage (hard disk drive and SSD) and a high-speed internal network between the servers in a rack. The Exalogic solution is designed and optimized to run Enterprise Java applications, i.e. the Oracle Fusion Middleware stack, similar to the Oracle Exadata center which runs Oracle DB servers. Oracle Exalogic can be scaled from 1/4 up to 8 racks, whereas according to Larry Ellison two full racks were enough to host all of Facebook.com.<br /><br />Afterwards the Unbreakable Enterprise Kernel was presented, which will be 100% RedHat compatible. It is Oracle’s answer to the slowly moving RedHat distribution; according to Larry Ellison RedHat is 4 years behind the mainline.<br /><br />Finally Oracle Fusion Application was unveiled. It is a CRM/ERP/HRMS system which offers the features of products earlier acquired by Oracle such as PeopleSoft and Siebel. The entire code basis has been re-written based on Oracle Fusion Middleware, which had to be enhanced to support all the middleware functionality needed. It took Oracle five years to develop Oracle Fusion Applications and is one of the biggest projects Oracle ever faced.<br /><br />On Monday and Tuesday the JavaOne Opening Keynote and the General Technical Session were about the Future of Java, which is the right thing to do after the Sun/Oracle merger last year. After finalizing the Java EE 6 Specification in December 2009, this year the focus is moved to the next version of the Java Standard Edition (Java SE). The last update on the Standard Edition was Java SE 6 in 2006. After a five years break we will get two new versions within roughly 18 months, OpenJDK 7 in mid 2011 and OpenJDK 8 in late 2012.<br /><br /><a href="http://farm5.static.flickr.com/4089/5016218388_6cc76bff51.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px; height: 332px;" title="Thomas Kurian, Executive Vice President, Product Development at Oracle at JavaOne 2010 Opening Keynote" src="http://farm5.static.flickr.com/4089/5016218388_6cc76bff51.jpg" border="0" alt="Thomas Kurian, Executive Vice President, Product Development at Oracle at JavaOne 2010 Opening Keynote" /></a><br /><br /><span style="font-weight: bold;">Java SE version 7</span> contains a bunch of smaller language changes and enhancements. Project Coin contributes most of the new language features, such as Diamond Operator for declaration and instantiation of generics, Try-with-Resource block for proper closing of resources implementing the new <code>AutoCloseable</code> interface in the <code>java.lang</code> package, Mutli-Catch and Re-Throw of Exceptions, Switch statements with Strings and String literals using “_” (int a = 0b100_1010_0011;). Additionally JSR 292 is implemented in this release, which supports mainly other languages setting up on top of the JVM, such as Scala and Groovy. The Fork/Join Framework provides better support for modern multi core processors. There are some other updates shipped with this release such as JDBC 4.1, which supports resource management, and more.<br /><br /><span style="font-weight: bold;">Java SE version 8</span> will bring a new modularization concept, finally no more hassle with the JAR files and the classpath! Project Jigsaw is defining these new features. A module (<code>*.jmod</code>) contains all its classfiles and a declaration of modules it depends on. This declaration is placed in the module-info.java file, which contains the name and the version of the dependencies. Modules need to be installed on the target system before they can be executed. A second set of major improvements will come out of the Project Lambda. These improvements include closures, value classes - no need to write getters and setters, extension methods and eventually reification.<br /><br />On the tooling side two new versions of Netbeans IDE will be released during 2011 (<a href="http://netbeans.org/community/releases/roadmap.html">check the feature list</a>). Project Glassfish also committed to publish two new releases during calendar year 2011 (<a href="https://glassfish.dev.java.net/roadmap/">check the feature list</a>).<br /><br />JavaFX script will not be further developed by Oracle and is replaced by a set of APIs, which is supposed to make the technology more accessible to all Java developers without the need to learn a new language. Additionally 3D support is added to JavaFX! According to Thomas Kurian there will be direct 3D hardware rendering support using Microsoft DirectX or OpenGL and a HTML5/JavaScript output for web-based clients.<br /><br />Not surprisingly, hot topics like the lawsuit with Google or the future of the JCP were not discussed.<br /><br /><h3>Session Highlights</h3><br /><br />In <span style="font-weight: bold;">Hyperproductive JSF 2.0</span>, JSF co-spec lead Ed Burns showed a couple of reasons why your project development might run with hand brake pulled. With several demos he showed probably underused new features in JSF 2 like Groovy support for all JSF artifacts that get hot deployed, or the new facelets >ui:debug< tag that gives you information on the component trees or scope variables. He also emphasised the importance of standards or conventions for a team, which is indeed an often overlooked aspect when a new project needs to get out quickly. This was supplemented by another talk on the new <span style="font-weight: bold;">JSF 2 composite components</span>, which make it very easy to create reusable components for e.g. your corporate layout and build up a highly productive framework like that.<br /><br />While Maven founder Jason van Zyl's talk on <span style="font-weight: bold;">Maven 3</span> was not intended to show new Maven features, he gave an overview of how he envisions future enterprise development. This includes tight integration from IDE over SCM to CI, up to a new tool called Proviso which is targeted to standardize enterprise deployment processes. Another interesting aspect was how Sonatype standardized their component model around Maven and Hudson plugins as well as their repository manager to achieve better reuse, which is now all built around JSR-330.<br /><br />As a company mainly dealing with enterprise development we were of course giving a main focus on all the Java EE 6 talks. Spec lead Roberto Chinnici gave one of them <span style="font-weight: bold;">explaining the Java EE programming model</span>. Even though we have been working with the technology for a while now, this gave a nice summary and showed again that you still get that extra little information from JavaOne that makes the conference very useful when you hear things from the mind behind it. Roberto provided a quick overview on managed beans, CDI and several "must knows" when changing to the new programming model.<br /><br />On the same track was Dan Allen with presenting in depth on <span style="font-weight: bold;">CDI and Seam 3</span>. The talk went from all the CDI concepts from typesafe injection with qualifiers over loose coupling with events to the SPI in CDI leading to Seam 3. This is now split in several independent modules where your application can take what it needs. Spinning this thought further - why not break up all the EJB services and make them a portable extension? We might see something like this in Java EE 7. By the way, Dan is not only an excellent author (when are we going to see Seam in Action 2nd edition?), but also a great speaker - make sure to visit one of his talks when you got a chance.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm5.static.flickr.com/4149/5019730840_d0d323b9ac.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand; height: 332px;" src="http://farm5.static.flickr.com/4149/5019730840_d0d323b9ac.jpg" border="0" alt="" /></a> To close the sessions on Java EE, we were deeply impressed by the session on <span style="font-weight: bold;">Arquillian</span>. The framework evolved out of working on the RI for CDI (Weld) and takes the idea of the new EE component model to your unit tests. By eliminating the build to create archives for integration tests, the team around Arquillian has managed to decrease complexity and improve speed of the integration test massively - something critical if you want your team to actually use them. The outcome was a generic component testing framework, which we're convinced will significantly improve quality on EE applications. You can programmatically create an archive on the components you want to test, and run the test either in container or as client in a running application server. This is the time when you feel that enterprise engineering is still a young discipline - why has this not been around for longer?<br /><br />Last but not least, if you have been following our people spotlights you probably know we're big fans of the <span style="font-weight: bold;">Java Posse</span>! As in the last 4 years the posse was present also at this year's JavaOne holding a BoF in the Mason street tent, celebrating the 5th anniversary of the Java Posse. While it was less interactive than the last years BoFs, we got a great show with special guest "Loose" Bruce Kerr giving a live performance of the Posse song, funky costumes and interesting insights on the future of Java - well kind of. Go and download the recordings - although this time I guess it's too bad this is not a video podcast!<br /><br />As usual we enjoyed being here - CU again next year!Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-25183879445986148542010-09-21T14:02:00.020+02:002010-09-29T17:07:11.652+02:00Installing Oracle on UbuntuMost of the applications we write here at <a href="http://www.ctp-consulting.com">CTP</a> depend on an Oracle database.<br />After putting some effort on configuring our development environment for a new project and figuring out the process wasn't as straightforward as I expected, I decided to share my finding in this walkthrough.<br />It describes the steps required to install Oracle on a Ubuntu Server.<br /><br /><h2>Prerequisites</h2><br />The instructions apply to Oracle 11g (version 11.2.0.1.0) on an Ubuntu 10.04.1 Server Edition 64-bit.<br />Download Ubuntu's installation ISO from <a href="http://www.ubuntu.com/server/get-ubuntu/download">http://www.ubuntu.com/server/get-ubuntu/download</a> and Oracle's ZIPs from <a href="http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html">http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html</a>.<br />A Windows environment is used as client. You will need the following tools:<br /><ul><li>PuTTY, an SSH client - <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">http://www.chiark.greenend.org.uk/~sgtatham/putty/</a></li><li>Cygwin X, a POSIX environment, but here we're interested only on its X-Server capabilities - <a href="http://www.cygwin.com">http://www.cygwin.com</a><ul><li>You will need the following packages (within group "X11")<ul><li>xorg-server</li><li>xinit</li><li>xorg-docs (optional, man)</li><li>X-start-menu-icons</li></ul></li><li>From other packages<ul><li>openssh<br /></li><li>inetutils</li></ul></li></ul></li></ul><br /><br /><h2>Server configuration</h2><br /><br /><h3>Installation</h3><br />Install Ubuntu in your server. In this example a virtual machine with 32 Gb of disk and 2Gb of RAM is used. <br />During the installation process, select the "SSH server" to be installed. To do it after installation, run:<br /><pre name="code" class="html"><br /> sudo apt-get install openssh-server openssh-client<br /></pre><br /><h3>X Forwarding</h3><br />You should configure PuTTY to forward the graphical applications from the Ubuntu server (the 'server') to your Windows workstation (the 'client'), <br />as the Oracle 11g installation depends on it.<br />Open PuTTY and enter the IP address of your server, give a name to the session and save it. Configure the following options:<br /> <ul><br /> <li>In "Connection > SSH > X11", check "Enable X11 forwarding" and for "X display location" enter "localhost:0"<br /> </li><br /> <li>Go to the "Session" menu and save your session again, to persist the configuration changes.<br /> </li><br /> </ul><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid2JEpr-_Cti35gXwJSAo2BlI-vDXLKzakKR14uJsdf2IPtt3HtcedsGZK9sMUZWVSiyIMxP49vqpjfYdNklKZk9cv8-371vx7NyX2RS7wat3iAes1IVZJiWulEm8_TB7IOwHV3l9d1inr/s1600/xforwarding.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 385px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid2JEpr-_Cti35gXwJSAo2BlI-vDXLKzakKR14uJsdf2IPtt3HtcedsGZK9sMUZWVSiyIMxP49vqpjfYdNklKZk9cv8-371vx7NyX2RS7wat3iAes1IVZJiWulEm8_TB7IOwHV3l9d1inr/s400/xforwarding.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5522339640120302802" /></a><br />Start the X server in your client computer <b>before</b> connecting to the server through PuTTY. In the programs menu, open "Cygwin-X" and run "XWin Server". <br />It may start a graphical terminal (XTerm) but you should close it, to avoid confusion. All you need is to keep the server running, indicated by the fancy X icon in the system tray.<br />Now you can establish the SSH connection. To test if the X Forwarding is properly configured, run <code>xeyes</code> in the server (if not found, run <code>sudo apt-get install x11-apps</code>) and you should see the eyes in your desktop.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCdhMiuloPjctdr_-NObvXjv3DzclQLLLYr5ZsOLeiNdDkdT5TaBQAPvA-4JAquCOaOUYTuaLTTKVTymyC7M1uyU43CyUeYFGLQIHK9ptZbZGtI25dXeI7TTpzVdFV8V6646I0jRhQFsPL/s1600/xeyes.png"><img style="cursor:pointer; cursor:hand;width: 166px; height: 138px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCdhMiuloPjctdr_-NObvXjv3DzclQLLLYr5ZsOLeiNdDkdT5TaBQAPvA-4JAquCOaOUYTuaLTTKVTymyC7M1uyU43CyUeYFGLQIHK9ptZbZGtI25dXeI7TTpzVdFV8V6646I0jRhQFsPL/s400/xeyes.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5522339967292798898" /></a><br /><h3>Swap configuration</h3><br />The amount of swap space required by the Oracle DB depends on the available RAM:<br /><table><tr><th>Available RAM</th><th>Swap required</th></tr><tr><td>Between 1 and 2 Gb</td><td>1.5 x RAM</td></tr><tr><td>Between 2 and 16 Gb</td><td>1 x RAM</td></tr><br /><tr><td>More than 16 Gb</td><td>16 Gb</td></tr></table><br />To check the existing configured space, run<br /><pre name="code" class="html"><br /> $ free<br /> total used free shared buffers cached<br /> Mem: 2057836 181680 1876156 0 12268 91092<br /> -/+ buffers/cache: 78320 1979516<br /> Swap: 1417208 0 1417208<br /></pre><br />In this walkthrough I'm going to add 2Gb to the existing swap space. <br /><pre name="code" class="html"><br /> # Creates a swap file, may take a while to execute<br /> $ sudo dd if=/dev/zero of=/mnt/2Gb.swap bs=1M count=2048<br /> # Activating the swap file<br /> sudo mkswap /mnt/2Gb.swap<br /> sudo swapon /mnt/2Gb.swap<br /></pre><br />To have the swap file mounted automatically after a reboot, add the following line to the <code>/etc/fstab</code> file:<br /><pre name="code" class="html"><br /> /mnt/2Gb.swap none swap sw 0 0<br /></pre><br /><h3>Updating and installing dependencies</h3><br /><pre name="code" class="html"><br /> $ sudo apt-get update<br /> $ sudo apt-get upgrade<br /> $ sudo apt-get install build-essential libaio1 libaio-dev libmotif3 libtool expat alien ksh pdksh unixODBC unixODBC-dev sysstat elfutils libelf-dev binutils lesstif2 lsb-cxx rpm lsb-rpm gawk unzip x11-utils ia32-libs<br /></pre><br /><h3>Installing libstdc++ 5</h3><br />Ubuntu comes with libstdc++ version 6, but Oracle requires version 5. To fix it:<br /><pre name="code" class="html"><br /> $ wget http://mirrors.kernel.org/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_amd64.deb<br /> $ dpkg-deb -x libstdc++5_3.3.6-17ubuntu1_amd64.deb ia64-libs<br /> $ sudo cp ia64-libs/usr/lib/libstdc++.so.5.0.7 /usr/lib64<br /> $ cd /usr/lib64<br /> $ sudo ln -s libstdc++.so.5.0.7 libstdc++.so.5<br /> $ ls -al libstdc++.*<br /> lrwxrwxrwx 1 root root 18 2010-09-17 14:19 libstdc++.so.5 -> libstdc++.so.5.0.7<br /> -rw-r--r-- 1 root root 829424 2010-09-17 14:18 libstdc++.so.5.0.7<br /> lrwxrwxrwx 1 root root 19 2010-09-14 12:05 libstdc++.so.6 -> libstdc++.so.6.0.13<br /> -rw-r--r-- 1 root root 1044112 2010-03-27 01:16 libstdc++.so.6.0.13<br /></pre><br /><h3>Links update</h3><br />Update the symbolic link <code>/bin/sh</code> from <code>/bin/dash</code> to <code>/bin/bash</code>.<br /><pre name="code" class="html"><br /> $ ls -l /bin/sh<br /> lrwxrwxrwx 1 root root 4 2010-09-14 12:05 sh -> dash<br /> $ cd /bin<br /> $ sudo ln -sf bash /bin/sh<br /> $ ls -l sh<br /> lrwxrwxrwx 1 root root 4 2010-09-14 14:19 sh -> bash<br /></pre><br />Some links need to be created as well:<br /><pre name="code" class="html"><br /> ln -s /usr/bin/awk /bin/awk<br /> ln -s /usr/bin/rpm /bin/rpm<br /> ln -s /usr/bin/basename /bin/basename<br /></pre><br /><h3>System users & groups</h3><br />Change to root and create the following users and groups<br /><pre name="code" class="html"><br /> ctp@oracle11g:~$ sudo -s<br /> root@oracle11g:~# addgroup oinstall<br /> Adding group `oinstall' (GID 1001) ...<br /> Done.<br /> root@oracle11g:~# addgroup dba<br /> Adding group `dba' (GID 1002) ...<br /> Done.<br /> root@oracle11g:~# addgroup nobody<br /> Adding group `nobody' (GID 1003) ...<br /> Done.<br /> root@oracle11g:~# usermod -g nobody nobody<br /> root@oracle11g:~# useradd -g oinstall -G dba -p password -d /home/oracle -s /bin/bash oracle<br /> root@oracle11g:~# passwd -l oracle<br /> passwd: password expiry information changed.<br /> root@oracle11g:~# mkdir /home/oracle<br /> root@oracle11g:~# chown -R oracle:dba /home/oracle<br /></pre><br /><h3>Creating ORACLE_HOME</h3><br /><pre name="code" class="html"><br /> root@oracle11g:~# mkdir -p /u01/app/oracle<br /> root@oracle11g:~# chown -R oracle:dba /u01<br /></pre><br /><h3>System parameters</h3><br />Some Linux kernel parameters need to be modified, as specified in Oracle's installation guide. To do that, add the parameters below to the file <code>/etc/sysctl.conf</code>:<br /><pre name="code" class="html"><br /> fs.file-max = 65535 <br /> kernel.shmall = 2097152 <br /> kernel.shmmax = 2147483648 <br /> kernel.shmmni = 4096 <br /> kernel.sem = 250 32000 100 128 <br /> net.ipv4.ip_local_port_range = 1024 65535 <br /> net.core.rmem_default = 1048576 <br /> net.core.rmem_max = 1048576 <br /> net.core.wmem_default = 262144 <br /> net.core.wmem_max = 262144<br /></pre><br />The <code>oracle</code> user needs to have some shell limits increased by adding the parameters below to the file <code>/etc/security/limits.conf</code>:<br /><pre name="code" class="html"><br /> oracle soft nproc 2047 <br /> oracle hard nproc 16383 <br /> oracle soft nofile 1023 <br /> oracle hard nofile 65535 <br /></pre><br />Add the parameters below to the file <code>/etc/pam.d/login</code>:<br /><pre name="code" class="html"><br /> session required /lib/security/pam_limits.so <br /> session required pam_limits.so<br /></pre><br />Reboot the system to reload the configuration.<br /><br /><h2>Oracle installation</h2><br />From the directory you extracted the Oracle zip files, run <code>database/runInstaller</code> as the user <code>oracle</code> created above (see <a href="#unixTips">Unix Tips</a> if you need help). You can ignore the DISPLAY warning, if any. If you receive an error regarding the X forwarding permission, use this <a href="#remoteX">remote X forwarding</a> trick.<br /><h3>Installation options</h3><br />The suggested installation options:<br /><ul><br /><li>Create and configure a database<br /></li><br /><li>Server class<br /></li><br /><li>Single instance database installation<br /></li><br /><li>Advanced install<br /></li><br /><li>Enterprise Edition<br /></li><br /><li>General purpose/Transaction processing<br /></li><br /><li>Memory, Character sets, Security and Sample Schemas - as default<br /></li><br /></ul><br />Run the fixup script following the instructions and then ignore the package dependencies.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM6cWPqCR_lmRQywcWNrIvNHR9W9BWmU1ju-BWJx0SYr1K3u7MHIIF4hkHvLYVzqLb43jOtJE7y6UwsHuNp6AuzvV5Ck08ErI1ZmCo10kbjoKH6-G4-ihIE78sYwM2AVNdxPhYrhDM0TFH/s1600/dependencies.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 313px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM6cWPqCR_lmRQywcWNrIvNHR9W9BWmU1ju-BWJx0SYr1K3u7MHIIF4hkHvLYVzqLb43jOtJE7y6UwsHuNp6AuzvV5Ck08ErI1ZmCo10kbjoKH6-G4-ihIE78sYwM2AVNdxPhYrhDM0TFH/s400/dependencies.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5522340123733501090" /></a><br />To check if everything is ok, open the following address in your browser:<br /><pre name="code" class="html"><br /> https://<server>:1158/em<br /></pre><br /><br /><h2>Startup script</h2><br />First, edit the file <code>/etc/oratab</code> or create one if you don't have it already. Make sure that the last parameter is "Y", meaning you want the database to be started during boot.<br /><pre name="code" class="html"><br /> oracle:/u01/app/oracle/product/11.2.0/dbhome_1:Y<br /></pre><br />Now create the startup script <code>/etc/init.d/oracledb</code>.<br /><pre name="code" class="html"><br /> cd /etc/init.d<br /> sudo touch oracledb<br /> sudo chmod a+x oracledb<br /></pre><br />Add the following content to the startup script<br /><pre name="code" class="html"><br /> #!/bin/bash<br /> #<br /> # /etc/init.d/oracledb<br /> #<br /> # Run-level Startup script for the Oracle Enterprise Manager<br /> <br /> export ORACLE_BASE=/u01/app/oracle<br /> export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1<br /> export ORACLE_OWNR=oracle<br /> export ORACLE_SID=oracle<br /> export PATH=$PATH:$ORACLE_HOME/bin<br /> <br /> if [ ! -f $ORACLE_HOME/bin/emctl -o ! -d $ORACLE_HOME ]<br /> then<br /> echo "Oracle startup: cannot start"<br /> exit 1<br /> fi<br /> <br /> case "$1" in<br /> start)<br /> # Oracle listener and instance startup<br /> echo -n "Starting Oracle: "<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/lsnrctl start<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/dbstart $ORACLE_HOME<br /> sudo -u $ORACLE_OWNR -E touch /var/lock/oracle<br /> # Oracle enterprise manager startup<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/emctl start dbconsole<br /> echo "OK"<br /> ;;<br /> stop)<br /> <br /> echo -n "Shutdown Oracle: "<br /> # Oracle enterprise manager shutdown<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/emctl stop dbconsole<br /> # Oracle listener and instance shutdown<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/lsnrctl stop<br /> sudo -u $ORACLE_OWNR -E $ORACLE_HOME/bin/dbshut $ORACLE_HOME<br /> sudo -u $ORACLE_OWNR -E rm -f /var/lock/oracle<br /> echo "OK"<br /> ;;<br /> reload|restart)<br /> $0 stop<br /> $0 start<br /> ;;<br /> *)<br /> echo "Usage: `basename $0` start|stop|restart|reload"<br /> exit 1<br /> esac<br /> <br /> exit 0<br /> <br /></pre><br />To execute the script automatically during server startup:<br /><pre name="code" class="html"><br /> sudo update-rc.d oracledb defaults 99<br /></pre><br /><br /><h2>General tips n' tricks</h2><br /><a id="unixTips" name="unixTips"></a><br /><h3>Unix tips</h3><br />Open a shell as anoter user:<br /><pre name="code" class="html"><br /> sudo -u <username> -s<br /></pre><br /><a id="remoteX" name="remoteX"></a><br /><h3>Remote X session config</h3><br /><pre name="code" class="html"><br /> $ xauth list<br /> oracle/unix:10 MIT-MAGIC-COOKIE-1 a18621a7bf2c102fc2b27758007b56a0<br /> # Copy the line returned above <br /> sudo -u oracle -s<br /> export HOME=/home/oracle<br /> # Paste the copied line after xauth add<br /> xauth add oracle/unix:10 MIT-MAGIC-COOKIE-1 a18621a7bf2c102fc2b27758007b56a0<br /></pre><br /><br /><h2>References</h2><br /><ul><br /><li><a href="http://download.oracle.com/docs/cd/B28359_01/install.111/b32285/toc.htm">http://download.oracle.com/docs/cd/B28359_01/install.111/b32285/toc.htm</a><br /></li><br /><li><a href="http://en.kioskea.net/faq/4405-linux-installing-oracle-11g-on-ubuntu">http://en.kioskea.net/faq/4405-linux-installing-oracle-11g-on-ubuntu</a><br /></li><br /><li><a href="http://www.pythian.com/news/2329/installing-oracle-11gr1-on-ubuntu-904-jaunty-jackalope/">http://www.pythian.com/news/2329/installing-oracle-11gr1-on-ubuntu-904-jaunty-jackalope/</a><br /></li><br /><li><a href="http://forums.oracle.com/forums/thread.jspa?threadID=1077139">http://forums.oracle.com/forums/thread.jspa?threadID=1077139</a><br /></li><br /></ul>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-91837868886945702502010-08-13T14:22:00.001+02:002010-08-13T14:44:20.130+02:00Java People Spotlight: Bartek Majsak<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0aZVMSvNea1iMsheXgyNAr_3mbgVRz5pFYDwyG9lDetEyAvHUVB184iM7cMGeZQ-B0OgQSK2o625eSdHzip5bv4HjObAQukRx94LNuOdEo4wXShYfm5XimSZyDAQRThnl30UPCuqhEEqM/s1600/bartek.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0aZVMSvNea1iMsheXgyNAr_3mbgVRz5pFYDwyG9lDetEyAvHUVB184iM7cMGeZQ-B0OgQSK2o625eSdHzip5bv4HjObAQukRx94LNuOdEo4wXShYfm5XimSZyDAQRThnl30UPCuqhEEqM/s320/bartek.jpg" /></a></div><span class="Apple-style-span" style="font-style: italic;">I'm glad to write another people spotlight, this time about a "newbee" (from a timely perspective), or from a technical perspective about a spicy addition to the Java Geeks at our Zurich Office: Bartosz Majsak... well actually Bartek, but that's another story. He joined CTP in March 2010.</span><br />
<span style="font-style: italic;">So let's see how geeky his answers are then!</span><br />
<br />
<b>Java Competence Role</b>:<br />
Senior Developer<b> </b>[aka Mr. T due to his extreme passion on Testing]<b> <br />
My Master Kung-Fu Skills</b>:<br />
I can mock you out even if you are static ;)<br />
<b>I'd be excited to get my hands dirty on</b>:<br />
Scala and/on Android<br />
<hr /><span style="font-weight: bold;">Q&A</span> <br />
<span style="font-weight: bold;">Q: </span>Hi Bartek, how would your message look like if you would have to tell it via Twitter what you are currently doing?<br />
<span style="font-weight: bold;">A: </span>Thinking how to design my own #arquillian TestEnricher and how to complete "The Challenge of Hades" in GoW at the same time.<br />
<span class="Apple-style-span" style="font-weight: bold;">Q:</span> ... and having some drops of <a href="http://hot-saucen.ch/blairs-sudden-death-p-49.html">Sudden Death</a> on top of it? ;-)<br />
<br />
<span style="font-weight: bold;">Q: </span>What was the greatest piece of code you have ever written so far?<br />
<span style="font-weight: bold;">A: </span>Please come back to me with this question when I will retire :) After a few days, the code which I thought was the most brilliant I've ever written... I refactor, so... I don't have a good answer for this question yet :D<br />
<br />
<span style="font-weight: bold;">Q: </span>What is the best quote you have ever heard about programming?<br />
<span style="font-weight: bold;">A: </span>"If debugging is the process of removing bugs, then programming must be the process of putting them in." (E.W. Dijkstra)<br />
<br />
<span style="font-weight: bold;">Q: </span>What is the best quote you have heard from our managers?<br />
<span style="font-weight: bold;">A: </span>"There is nothing as permanent as a temporary solution".<br />
<br />
<span style="font-weight: bold;">Q: </span>What is the most cutting-edge technology or framework you actually used on projects?<br />
<span style="font-weight: bold;">A: </span>CDI (JSR-299) and <a href="http://ctpjava.blogspot.com/search/label/arquillian" target="_blank">Arquillian</a>.<br />
<br />
<span style="font-weight: bold;">Q: </span>What is your favorite podcast?<br />
<span style="font-weight: bold;">A: </span>I used to listen podcast while I was commuting but nowadays I'm a little bit out of the loop - living too close to the office ;) Of course I like Java Posse (who doesn't?!) and <a href="http://www.se-radio.net/" target="_blank">Software Engineering Radio</a>. I'm also addicted to <a href="http://parleys.com/" target="_blank">Parleys</a>, <a href="http://dzone.com/" target="_blank">DZone</a> and <a href="http://infoq.com/">InfoQ</a>.<br />
<br />
<span style="font-weight: bold;">Q: </span>Which Java book can you recommend and for what reason?<br />
<span style="font-weight: bold;">A: </span>I really enjoyed reading <a href="http://www.amazon.com/Implementation-Patterns-Kent-Beck/dp/0321413091" target="_blank">"Implementation Patterns"</a> by <a href="http://twitter.com/kentbeck" target="_blank">Kent Beck</a> and <a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052" target="_blank">"Working Effectively with Legacy Code"</a> by <a href="http://twitter.com/mfeathers" target="_blank">Michael Feathers</a>. The first one gives you interesting hints for how to express yourself through code by keeping it clean and easy to understand for others. The second one will help you to stay sane while digging into the code of a person who definitely never read the first book. If you are serious about testing you should read <a href="http://www.growing-object-oriented-software.com/" target="_blank">Growing Object-Oriented Software Guided by Tests</a> by <a href="http://twitter.com/sf105" target="_blank">Steve Freeman</a> & <a href="http://twitter.com/natpryce" target="_blank">Nat Pryce</a> as well as <a href="http://xunitpatterns.com/" target="_blank">xUnit Test Patterns</a> by <a href="http://twitter.com/gerardmes" target="_blank">Gerard Meszaros</a>. Of course all books <a href="http://ctpjava.blogspot.com/search/label/people">recommended already</a> by my colleagues are also just great but I didn't want to repeat them here.<br />
<b>Q: </b>DRY pattern... :-) .... Well thanks for your answers and enjoy your mock-ito this evening at the CTP Summer Event!!<br />
<br />
<br />
<i>You can further follow Bartek's web presence in these directions:</i><br />
<i>- linked in: <a href="http://ch.linkedin.com/in/bartoszmajsak">http://ch.linkedin.com/in/bartoszmajsak</a><br />
- lastfm: <a href="http://www.last.fm/user/majson">http://www.last.fm/user/majson</a><br />
- twitter: <a href="http://twitter.com/majson">http://twitter.com/majson</a></i>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-84159580766850579132010-08-13T11:02:00.005+02:002010-08-13T14:36:42.642+02:00Test drive with Arquillian and CDI (Part 2)<p>The <a href="http://ctpjava.blogspot.com/2010/07/test-drive-with-arquillian-and-cdi-part.html" target="_blank">first part</a> of the <a href="http://jboss.org/arquillian" target="_blank">Arquillian</a> series was mainly focused on working with an in-memory database, <b>DI</b> (dependency injection) and events from the <b><a href="http://jcp.org/en/jsr/detail?id=299" target="_blank">CDI</a></b> spec. Now we will take a closer look on how to deal with testing <b>C</b>ontextual components. For this purpose we will extend our <a href="http://ctpjava.googlecode.com/svn/trunk/arquillian-demo-01" target="_blank">sample project</a> from the first part by adding a <code>PortfolioController</code> class, a <a href="http://docs.jboss.org/cdi/api/1.0-SP1/javax/enterprise/context/ConversationScoped.html" target="_blank">conversation scoped</a> bean for handling processing of user's portfolio management.</p><pre name="code" class="java">@ConversationScoped @Named("portfolioController")<br />public class PortfolioController implements Serializable {<br /> <br /> // ...<br /><br /> Map<Share, Integer> sharesToBuy = new HashMap<Share, Integer>();<br /><br /> @Inject @LoggedIn<br /> User user;<br /><br /> @Inject<br /> private TradeService tradeService;<br /> <br /> @Inject<br /> private Conversation conversation;<br /> <br /> public void buy(Share share, Integer amount) {<br /> if (conversation.isTransient()) {<br /> conversation.begin();<br /> }<br /> Integer currentAmount = sharesToBuy.get(share);<br /> if (null == currentAmount) {<br /> currentAmount = Integer.valueOf(0);<br /> }<br /> <br /> sharesToBuy.put(share, currentAmount + amount); <br /> }<br /> <br /> public void confirm() {<br /> for (Map.Entry<Share, Integer> sharesAmount : sharesToBuy.entrySet()) {<br /> tradeService.buy(user, sharesAmount.getKey(), sharesAmount.getValue());<br /> }<br /> conversation.end();<br /> }<br /> <br /> public void cancel() {<br /> sharesToBuy.clear();<br /> conversation.end();<br /> }<br /><br /> // ...<br /><br />}</pre><p>So, let's try out Arquillian! As we already know from the first part we need to create a deployment package, which then will be deployed by Arquillian on the target container (in our case Glassfish 3.0.1 Embedded).</p><pre name="code" class="java"><br />@Deployment<br />public static Archive<?> createDeploymentPackage() {<br /> return ShrinkWrap.create("test.jar", JavaArchive.class)<br /> .addPackages(false, Share.class.getPackage(), <br /> ShareEvent.class.getPackage())<br /> .addClasses(TradeTransactionDao.class, <br /> ShareDao.class, <br /> PortfolioController.class)<br /> .addManifestResource(new ByteArrayAsset("<beans />".getBytes()), ArchivePaths.create("beans.xml"))<br /> .addManifestResource("inmemory-test-persistence.xml", ArchivePaths.create("persistence.xml"));<br />}<br /></pre><p>Next we can start develop a simple test scenario:<br /><ul><br /><li><b><i>given</i></b> user choose CTP share,</li><br /><li><b><i>when</i></b> he confirms the order,</li><br /><li><b><i>then</i></b> his portfolio should be updated.</li></ul><br />Which in JUnit realms could be written as follows:</p><pre name="code" class="java"><br />@RunWith(Arquillian.class)<br />public class PortfolioControllerTest {<br /><br /> // deployment method<br /> <br /> @Inject <br /> ShareDao shareDao;<br /> <br /> @Inject<br /> PortfolioController portfolioController;<br /> <br /> @Test <br /> public void shouldAddCtpShareToUserPortfolio() {<br /> // given<br /> User user = portfolioController.getUser();<br /> Share ctpShare = shareDao.getByKey("CTP");<br /> <br /> // when<br /> portfolioController.buy(ctpShare, 1);<br /> portfolioController.confirm();<br /> <br /> // then<br /> assertThat(user.getSharesAmount(ctpShare)).isEqualTo(3);<br /> }<br /> <br />}<br /></pre><p>Looks really simple, doesn't it? Well, it's almost that simple but there are some small details which you need to be aware of.</p><p><b><span class="Apple-style-span" style="font-size: x-large;">Producers</span></b></p><p>CDI provides a feature similar to <a href="http://docs.jboss.com/seam/2.1.0.GA/api/org/jboss/seam/annotations/Factory.html" target="_blank">Seam factories</a> or <a href="http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Provider.html" target="_blank">Guice providers</a>. It's called producer and it allows you to create injectable dependency. This could be especially useful when creation of such an instance requires additional logic, i.e. it needs to be obtained from an external source. A logged in user in a web application is a good example here. Thanks to the CDI <a href="http://docs.jboss.org/cdi/api/1.0/javax/enterprise/inject/Produces.html" target="_blank"><code>@Produces</code></a> construct we can still have very clean code which just works! All we need to do in order to inject the currently logged in user to our bean is as simple as that:</p><p>1. Create a <code>@LoggedIn</code> qualifier which will be used to define that a particular injection is expecting this concrete <code>User</code> bean.</p><pre name="code" class="java"><br />@Qualifier<br />@Retention(RetentionPolicy.RUNTIME)<br />@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})<br />public @interface LoggedIn {<br />}<br /></pre><p>2. Implement the producer method which will instantiate the logged in user in the session scope just after he successfully accesses the application, so it will provide an instance of the <code>User</code> class which is of <code>@LoggedIn</code> "type".</p><pre name="code" class="java"><br />@Produces @SessionScoped @LoggedIn User loggedInUser() {<br /> // code for retrieving current user from session<br />}<br /></pre><p>3. Decorate all injection points in other beans where we need this instance.</p><pre name="code" class="java"><br />@Inject @LoggedIn<br />User user;<br /></pre><p>However this construct could be problematic when writing tests and an attentive reader would probably already be concerned about it. But with Arquillian we will run our test code in the CDI container and there is no need to simulate login procedure, using mock http sessions or any other constructs. We can take full advantage of this fact and create producer method which will replace our original one and provide the user directly from entity manager for example.</p><pre name="code" class="java"><br />@Produces @LoggedIn User loggedInUser() {<br /> return entityManager.find(User.class, 1L);<br />}<br /></pre><p><b>Note: </b>I removed <code>@SessionScoped</code> annotation from <code>loggedInUser()</code> producer method intentionally. Otherwise you could have troubles with Weld proxies and EclipseLink while trying to persist the entity class. For tests it actually does not make any difference.</p><p><b><span class="Apple-style-span" style="font-size: x-large;">Context handling</span></b></p><p>One small problem arrived when I tried to test logic based on the conversation context. I had to figure out a way to programmatically create the appropriate context which then will be used by the SUT (or CUT if you prefer this abbreviation), because I was getting <code>org.jboss.weld.context.ContextNotActiveException</code>. Unfortunately I wasn't able to find anything related to it on the Arquillian forum or wiki, so I desperately jumped to the <a href="http://anonsvn.jboss.org/repos/seam/examples/" target="_blank">Seam 3 examples</a>. I read somewhere that they are also using this library to test their modules and sample projects. Bingo! I found what I was looking for. To make the test code more elegant I built my solution the same way as for handling the database in the first part - by using annotations and JUnit rules. Using a <code>@RequiredScope</code> annotation on the test method will instruct JUnit rule to handle proper context initialization and cleanup after finishing the test. To make the code even cleaner we can implement such logic in a dedicated class and treat the enum as a factory:</p><pre name="code" class="java"><br />public enum ScopeType {<br /><br /> CONVERSATION {<br /> @Override<br /> public ScopeHandler getHandler() {<br /> return new ConversationScopeHandler();<br /> }<br /> }<br /> <br /> // ... other scopes<br /> <br /> public abstract ScopeHandler getHandler();<br /> <br />}<br /></pre><pre name="code" class="java"><br />public class ConversationScopeHandler implements ScopeHandler {<br /><br /> @Override<br /> public void initializeContext() {<br /> ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();<br /> conversationContext.setBeanStore(new HashMapBeanStore());<br /> conversationContext.setActive(true);<br /> }<br /><br /> @Override<br /> public void cleanupContext() {<br /> ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();<br /> if (conversationContext.isActive()) {<br /> conversationContext.setActive(false);<br /> conversationContext.cleanup();<br /> }<br /> }<br />}<br /></pre><p>The JUnit rule will only extract the annotation's value of the test method and delegate context handling to the proper implementation:</p><pre name="code" class="java"><br />public class ScopeHandlingRule extends TestWatchman {<br /><br /> private ScopeHandler handler;<br /> <br /> @Override<br /> public void starting(FrameworkMethod method) {<br /> RequiredScope rc = method.getAnnotation(RequiredScope.class);<br /> if (null == rc) {<br /> return;<br /> } <br /> ScopeType scopeType = rc.value();<br /> handler = scopeType.getHandler();<br /> handler.initializeContext();<br /> }<br /> <br /> @Override<br /> public void finished(FrameworkMethod method) {<br /> if (null != handler) {<br /> handler.cleanupContext();<br /> }<br /> }<br />}<br /></pre><p>Finally here's fully working test class with two additional test scenarios. I also used <a href="http://www.dbunit.org/" target="_blank">DBUnit</a> add-on from first post for convenience.</p><pre name="code" class="java"><br />@RunWith(Arquillian.class)<br />public class PortfolioControllerTest {<br /><br /> @Rule<br /> public DataHandlingRule dataHandlingRule = new DataHandlingRule();<br /> <br /> @Rule<br /> public ScopeHandlingRule scopeHandlingRule = new ScopeHandlingRule();<br /> <br /> @Deployment<br /> public static Archive<?> createDeploymentPackage() {<br /> return ShrinkWrap.create("test.jar", JavaArchive.class)<br /> .addPackages(false, Share.class.getPackage(), <br /> ShareEvent.class.getPackage())<br /> .addClasses(TradeTransactionDao.class, <br /> ShareDao.class, <br /> TradeService.class,<br /> PortfolioController.class)<br /> .addManifestResource(new ByteArrayAsset("<beans />".getBytes()), ArchivePaths.create("beans.xml"))<br /> .addManifestResource("inmemory-test-persistence.xml", ArchivePaths.create("persistence.xml"));<br /> }<br /> <br /> @PersistenceContext<br /> EntityManager entityManager;<br /> <br /> @Inject <br /> ShareDao shareDao;<br /> <br /> @Inject<br /> TradeTransactionDao tradeTransactionDao;<br /> <br /> @Inject<br /> PortfolioController portfolioController;<br /> <br /> @Test<br /> @PrepareData("datasets/shares.xml")<br /> @RequiredScope(ScopeType.CONVERSATION)<br /> public void shouldAddCtpShareToUserPortfolio() {<br /> // given<br /> User user = portfolioController.getUser();<br /> Share ctpShare = shareDao.getByKey("CTP");<br /> <br /> // when<br /> portfolioController.buy(ctpShare, 1);<br /> portfolioController.confirm();<br /> <br /> // then<br /> assertThat(user.getSharesAmount(ctpShare)).isEqualTo(3);<br /> }<br /> <br /> @Test<br /> @PrepareData("datasets/shares.xml")<br /> @RequiredScope(ScopeType.CONVERSATION)<br /> public void shouldNotModifyUserPortfolioWhenCancelProcess() {<br /> // given<br /> User user = portfolioController.getUser();<br /> Share ctpShare = shareDao.getByKey("CTP");<br /> <br /> // when<br /> portfolioController.buy(ctpShare, 1);<br /> portfolioController.cancel();<br /> <br /> // then<br /> assertThat(user.getSharesAmount(ctpShare)).isEqualTo(2);<br /> }<br /> <br /> @Test<br /> @RequiredScope(ScopeType.CONVERSATION)<br /> @PrepareData("datasets/shares.xml")<br /> public void shouldRecordTransactionWhenUserBuysAShare() {<br /> // given<br /> User user = portfolioController.getUser();<br /> Share ctpShare = shareDao.getByKey("CTP");<br /> <br /> // when<br /> portfolioController.buy(ctpShare, 1);<br /> portfolioController.confirm();<br /><br /> // then<br /> List<TradeTransaction> transactions = tradeTransactionDao.getTransactions(user);<br /> assertThat(transactions).hasSize(1);<br /> }<br /> <br /> @Produces @LoggedIn User loggedInUser() {<br /> return entityManager.find(User.class, 1L);<br /> }<br /> <br />}<br /></pre><p>For the full source code you can jump directly to our <a href="http://ctpjava.googlecode.com/svn/trunk/arquillian-demo-02/" target="_blank">google code repository</a>.</p><p><b><span class="Apple-style-span" style="font-size: x-large;">Conclusion</span></b></p><p>As you can see playing with Arquillian is pure fun for me. Latest 1.0.0.Alpha3 release brought a lot of <a href="http://community.jboss.org/en/arquillian/blog/2010/07/30/arquillian-100-alpha3--released" target="_blank">new goodies</a> to the table. I hope that the examples in this blog post convinced you that working with different scopes is quite straightforward and requires just a little bit of additional code. However it's still not the ideal solution because it's using <a href="http://seamframework.org/Weld" target="_blank">Weld</a>'s internal API to create and manage scopes. So if you are using a different CDI container you need to figure out how to achieve it, but it's just a matter of adjusting <code>ScopeHandler</code> implementation to your needs.<br /><br />There is much more to write about Arquillian so keep an eye on our blog and share your thoughts and suggestions through comments.</p>Bartosz Majsakhttp://www.blogger.com/profile/17042462575032728792noreply@blogger.com3tag:blogger.com,1999:blog-3305419975676030648.post-47778061198789882142010-07-30T13:20:00.008+02:002010-07-30T13:53:46.286+02:00Using Seam 2 with JPA 2It’s a difficult time to architect new Java web applications. <a href="http://www.seamframework.org/">Seam 2</a> is a proven and well working application stack, but we will hardly see many new versions on the Seam 2 train. Java EE 6 is in general an excellent option, but if your customer’s choice of application server does not yet support it, it is not reasonable. Also there is still some time left for <a href="http://www.seamframework.org/Seam3">Seam 3</a> prime time, which builds on top of Java EE 6.<br /><br />Facing this kind of choice recently, I looked into possible migration paths between the two variants. One thing I have seen often on Seam 2 applications is that people really like the Hibernate criteria API and therefore use Hibernate directly. While Hibernate is an excellent ORM framework, it’s preferrable to use the JPA API when moving to Java EE 6. So - why not use Seam 2 with JPA 2, which finally features an even better (typesafe) <a href="http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/querycriteria.html">criteria API</a>?<br /><br />It turns out to be a quite easy setup (once you get classloading right), with some small extra modifications. I’ve been using Maven, Seam 2.2 and Hibernate 3.5.4 on JBoss 4.2.3. Lets start with preparing the server. You need to remove the old Hibernate and JPA classes and add the new persistence provider with some dependencies (of course this will be different on other servers):<br /><br />To be removed from server/lib:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBB41zXOJqI2A88oiHUozJfSF48tHTHijquiveANJJGt9px1juaPhLzFtuxjprUgPtykz6cUl0VOrxyQEOSA2VmrFThSTyRfEZbC-dWfh7vOrXTMvHnaEB72dlJ-8QZMd3czPLRH3vOGs/s1600/remove.png"><img style="cursor:pointer; cursor:hand;width: 187px; height: 183px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBB41zXOJqI2A88oiHUozJfSF48tHTHijquiveANJJGt9px1juaPhLzFtuxjprUgPtykz6cUl0VOrxyQEOSA2VmrFThSTyRfEZbC-dWfh7vOrXTMvHnaEB72dlJ-8QZMd3czPLRH3vOGs/s400/remove.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5499662488332587762" /></a><br /><br />Add to server/lib:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxAUXymhGLQQgvFXMtrVMPCjxJ2NoSpnhGpw4rWf5gKFV9GDcKNIUjCUrY8QFxxfrYSerXpWKnPOtrykGN1bj-x3Bsxk_POujmCeby0CSrJK-RIZPtLWc5lgl_IU1rEsaqEpRXZ_4I2E/s1600/add.png"><img style="cursor:pointer; cursor:hand;width: 283px; height: 273px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxAUXymhGLQQgvFXMtrVMPCjxJ2NoSpnhGpw4rWf5gKFV9GDcKNIUjCUrY8QFxxfrYSerXpWKnPOtrykGN1bj-x3Bsxk_POujmCeby0CSrJK-RIZPtLWc5lgl_IU1rEsaqEpRXZ_4I2E/s400/add.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5499663451747856802" /></a><br /><br />Next lets create a sample Seam project. I’m using the <a href="http://ctpjava.blogspot.com/2010/04/jboss-seam-maven-archetype-video.html">CTP Maven archetype for Seam</a>. In the POM file, remove the references to the Hibernate and old JPA libraries and add the new JPA 2 libraries:<br /><pre name="code" class="xml"><br /><!-- Remove all embedded dependencies<br /><dependency><br /> <groupId>org.jboss.seam.embedded</groupId><br /> <artifactId>...</artifactId><br /></dependency --> <br /><br /> <dependency> <br /> <groupId>org.hibernate.javax.persistence</groupId><br /> <artifactId>hibernate-jpa-2.0-api</artifactId><br /> <version>1.0.0.Final</version><br /> <scope>provided</scope><br /> </dependency><br /><dependency><br /> <groupId>org.hibernate</groupId><br /> <artifactId>hibernate-core</artifactId><br /> <version>3.5.4-Final</version><br /> <scope>provided</scope><br /></dependency><br /><dependency><br /> <groupId>org.hibernate</groupId><br /> <artifactId>hibernate-jpamodelgen</artifactId><br /> <version>1.0.0.Final</version><br /> <scope>provided</scope><br /></dependency><br /></pre><br />Note: If you’ve been using embedded JBoss for your integration tests, this will probably not work without exchanging the JARS there too. I’ve been moving away from this approach as it turned out to be a common reason for headache on our nightly builds as well as running tests in Eclipse. I’m very excited to see <a href="http://ctpjava.blogspot.com/2010/07/test-drive-with-arquillian-and-cdi-part.html">Arquillian evolving</a> on this topic!<br /><br />JPA 2 integrates with JSR 303 bean validation, which is the successor of <a href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html/">Hibernate Validator</a>. Unfortunately Seam 2 has references to Hibernate Validator 3, where JPA needs version 4. Adding the validator legacy JAR fixes this problem. As bean validation is now part of Java EE 6, we can add it to the server classpath as shown above, as well as to our POM:<br /><pre name="code" class="xml"><br /><dependency><br /> <artifactId>validation-api</artifactId><br /> <groupId>javax.validation</groupId><br /> <version>1.0.0.GA</version><br /> <scope>provided</scope><br /></dependency><br /></pre><br />Now it’s time to move to some code. You can jump straight in your persistence config files and bring the schema up to version 2:<br /><pre name="code" class="xml"><br /><persistence xmlns="http://java.sun.com/xml/ns/persistence" <br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" <br /> version="2.0"> ...<br /><br /><entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"<br /> version="2.0"> ...<br /></pre><br />Seam proxies entity managers to implement features like EL replacements in JPQL queries. This proxy does not implement methods new in JPA 2 and will therefore fail. You can write your own proxy very easy:<br /><pre name="code" class="java"><br />public class Jpa2EntityManagerProxy implements EntityManager {<br /> <br /> private EntityManager delegate;<br /><br /> public Jpa2EntityManagerProxy(EntityManager entityManager) {<br /> this.delegate = entityManager;<br /> }<br /> <br /> @Override<br /> public Object getDelegate() {<br /> return PersistenceProvider.instance()<br /> .proxyDelegate(delegate.getDelegate());<br /> }<br /><br /> @Override<br /> public void persist(Object entity) {<br /> delegate.persist(entity);<br /> }<br /> ...<br />}<br /></pre><br />Add the special Seam functionality as needed. In order to use the proxy with Seam, you’ll have to overwrite the HibernatePersistenceProvider Seam component:<br /><pre name="code" class="java"><br />@Name("org.jboss.seam.persistence.persistenceProvider")<br />@Scope(ScopeType.STATELESS)<br />@BypassInterceptors<br />// The original component is precedence FRAMEWORK<br />@Install(precedence = Install.APPLICATION, <br /> classDependencies={"org.hibernate.Session",<br /> "javax.persistence.EntityManager"})<br />public class HibernateJpa2PersistenceProvider extends HibernatePersistenceProvider {<br /><br /> @Override<br /> public EntityManager proxyEntityManager(EntityManager entityManager) {<br /> return new Jpa2EntityManagerProxy(entityManager);<br /> }<br /><br />}<br /></pre><br />If you use Hibernate Search, have a look at the superclass implementation - you might want to instantiate a FullTextEntityManager directly (as you have it in your classpath - but note that this has not been tested here).<br /><br />Both implementations are on our <a href="http://ctpjava.googlecode.com/svn/trunk/repository">Google Code repository</a>, and you can integrate them directly over the following Maven dependency:<br /><pre name="code" class="xml"><br /><dependency><br /> <groupId>com.ctp.seam</groupId><br /> <artifactId>seam-jpa2</artifactId><br /> <version>1.0.0</version><br /></dependency><br /></pre><br /><br />You’re now ready to code JPA 2 queries! We’ve already included the meta model generator utility, so let’s activate it for the build:<br /><pre name="code" class="xml"><br /><plugin><br /> <groupId>org.codehaus.mojo</groupId><br /> <artifactId>build-helper-maven-plugin</artifactId><br /> <executions><br /> <execution><br /> <id>add-source</id><br /> <phase>validate</phase><br /> <goals><br /> <goal>add-source</goal><br /> </goals><br /> <configuration><br /> <sources><br /> <source>${basedir}/src/main/hot</source><br /> <source>${basedir}/target/metamodel</source><br /> </sources><br /> </configuration><br /> </execution><br /> </executions><br /></plugin><br /><plugin><br /> <groupId>org.bsc.maven</groupId><br /> <artifactId>maven-processor-plugin</artifactId><br /> <version>1.3.1</version><br /> <executions><br /> <execution><br /> <id>process</id><br /> <goals><br /> <goal>process</goal><br /> </goals><br /> <phase>generate-sources</phase><br /> <configuration><br /> <outputDirectory>${basedir}/target/metamodel</outputDirectory><br /> <processors><br /> <processor><br /> org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor<br /> </processor><br /> </processors><br /> </configuration><br /> </execution><br /> </executions><br /></plugin><br /></pre><br /><br />In order to use the processor plugin, you also need the following Maven repositories in your POM:<br /><pre name="code" class="xml"><br /><pluginRepository><br /> <id>annotation-processing-repository</id><br /> <name>Annotation Processing Repository</name><br /> <url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo</url><br /></pluginRepository><br /><pluginRepository><br /> <id>jfrog-repository</id><br /> <name>JFrog Releases Repository</name><br /> <url>http://repo.jfrog.org/artifactory/plugins-releases</url><br /></pluginRepository><br /></pre><br />Run the build, update the project config to include the new source folder - and finally we’re ready for some sample code:<br /><pre name="code" class="java"><br />@Name("userDao")<br />@AutoCreate<br />public class UserDao {<br /><br /> @In<br /> private EntityManager entityManager;<br /> <br /> private ParameterExpression<String> param;<br /> private CriteriaQuery<User> query;<br /> <br /> @Create<br /> public void init() {<br /> CriteriaBuilder cb = entityManager.getCriteriaBuilder();<br /> query = cb.createQuery(User.class);<br /> param = cb.parameter(String.class);<br /> Root<User> user = query.from(User.class);<br /> query.select(user)<br /> .where(cb.equal(user.get(User_.username), param));<br /> }<br /><br /> public User lookupUser(String username) {<br /> return entityManager.createQuery(query)<br /> .setParameter(param, username)<br /> .getSingleResult();<br /> }<br />}<br /></pre><br />This is now quite close to Java EE 6 code - all we will have to do is exchange some annotations:<br /><pre name="code" class="java"><br />@Stateful<br />public class UserDao {<br /><br /> @PersistenceContext<br /> private EntityManager entityManager; ...<br /><br /> @Inject<br /> public void init() { ...<br />}<br /></pre><br />Enjoy!Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-62030363771713976462010-07-13T14:19:00.000+02:002010-07-14T09:30:06.842+02:00Test drive with Arquillian and CDI (Part 1)<p>Here at Cambridge Technology Partners we are as serious about testing as we are about cutting-edge technologies like <a href="http://jcp.org/en/jsr/detail?id=299" target="_blank">CDI</a>. Last time we wrote about <a href="http://ctpjava.blogspot.com/2009/10/unit-testing-ejbs-and-jpa-with.html" target="_blank">testing EJBs on embedded Glassfish</a> and now we are back with something even more powerful, so keep on reading!</p><p><b><span class="Apple-style-span" style="font-size: x-large;">Background</span></b></p><p>Recently I was involved in a project based on JBoss Seam where we used <a href="http://www.unitils.org/" target="_blank">Unitils</a> for testing business logic and JPA. I really like this library, mainly because of the following aspects:<br /><ul><li>Provides easy configuration and seamless integration of JPA (also a little bit of DI).</li><li>Greatly simplifies management of the test data. All you need to do in order to seed your database with prepared data is providing a xml dataset (in a DBUnit flat xml format) and then add <code>@DataSet</code> annotation on the test class or method. </li></ul>Unitils library is definitely an interesting topic for another blog entry, but since we are going to dive into the Java EE 6 testing those of you who are not patient enough for next blog entry can jump directly to the <a href="http://www.unitils.org/tutorial.html" target="_blank">tutorial site</a>. I'm sure you will like it.</p><p>The only thing in Unitils which I'm not really comfortable with, is the fact that this library is not really designed for integration testing. The example which is clearly demonstrating it is an observer for Seam events. In this particular case we might need to leave unit testing world (mocks, spies and other test doubles) and develop real integration tests. The <a href="http://docs.jboss.org/seam/2.0.1.GA/reference/en/html/testing.html" target="_blank">SeamTest</a> module together with <a href="http://community.jboss.org/docs/DOC-13843">JBoss Embedded</a> could help but it's really a tough task to make it running with Maven. On the other hand JBoss AS wasn't the target environment for us. Thankfully there is a new kid on the block from JBoss called <a href="http://www.jboss.org/arquillian/" target="_blank">Arquillian</a>. In the next part of this post I will try to summarize my hands-on experience with this very promissing integration testing library. But first things first, let's look briefly at CDI events.</p><p><b><span class="Apple-style-span" style="font-size: x-large;">CDI Events</span></b></p><p>We are going to have JEE6 workshops for our customers and I was extremely happy when my colleagues asked me to play around with Arquillian and prepare some integration tests. I picked up a piece of logic responsible for logging market transactions based on CDI events. In brief it is a design technique which provides components interaction without any compilation-time dependencies. It's similar to the observer pattern but in case of CDI events, producers and observers are entirely decoupled from each other. If following example won't give you a clear explanation of the concept please refer to this <a href="http://www.andygibson.net/blog/index.php/2010/01/11/getting-started-with-jsf-2-0-and-cdi-part-3/" target="_blank">well written blog post</a>. Let's take a look at quite simplified code example.</p><pre name="code" class="java">import javax.ejb.Stateless;<br />import javax.enterprise.event.Event;<br />import javax.inject.Inject;<br /><br />@Stateless<br />public class TradeService {<br /><br /> @Inject @Buy<br /> private Event<ShareEvent> buyEvent;<br /><br /> public void buy(User user, Share share, Integer amount) {<br /> user.addShares(share, amount);<br /> ShareEvent shareEvent = new ShareEvent(share, user, amount);<br /> buyEvent.fire(shareEvent);<br /> }<br /><br /> ...<br /><br />}</pre><pre name="code" class="java"><br />import javax.enterprise.event.Observes;<br />import javax.inject.Inject;<br />import javax.inject.Singleton;<br /><br />@Singleton<br />public class TradeTransactionObserver implements Serializable {<br /><br /> ...<br /><br /> @Inject<br /> TradeTransactionDao tradeTransactionDao;<br /><br /> public void shareBought(@Observes @Buy ShareEvent event) {<br /> TradeTransaction tradeTransaction = new TradeTransaction(event.getUser(), event.getShare(), event.getAmount(), TransactionType.BUY);<br /> tradeTransactionDao.save(tradeTransaction);<br /> }<br /><br /> ...<br /><br />}<br /></pre><p>To preserve the clear picture I'm not going to include <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/Share.java" target="_blank">Share</a></code>, <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/TradeTransaction.java" target="_blank">TradeTransaction</a></code>, <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/User.java" target="_blank">User</a></code> and <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/event/ShareEvent.java" target="_blank">ShareEvent</a></code> classes. What is worth to mention however is that the instance of <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/event/ShareEvent.java" target="_blank">ShareEvent</a></code> contains user, a share which he bought and amount. In the <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/User.java" target="_blank">User</a></code> entity we store a map of shares together with amount using new <code>@ElementCollection</code> annotation introduced in JPA 2.0. It allows to use entity classes as keys in the map.</p><pre name="code" class="java">@ElementCollection<br />@CollectionTable(name="USER_SHARES")<br />@Column(name="AMOUNT")<br />@MapKeyJoinColumn(name="SHARE_ID")<br />private Map<Share, Integer> shares = new HashMap<Share, Integer>();<br /></pre><p>Then in the <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/TradeTransaction.java" target="_blank">TradeTransaction</a></code> entity we simply store this information and additionally date and <code><a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/main/java/com/ctp/arquilliandemo/ex1/domain/TransactionType.java" target="_blank">TransactionType</a></code>. Complete code example could be downloaded from our google code page - see <a href="http://www.blogger.com/post-edit.g?blogID=3305419975676030648&postID=6203036377171397646#resources">Resources</a> section at the bottom of the post.</p><p><b><span class="Apple-style-span" style="font-size: x-large;">The very first test</span></b></p><p>We will use a following scenario for our test example (written in the <a href="http://blog.dannorth.net/introducing-bdd/" target="_blank">BDD</a> manner):<br /><ul><li><i><b>given</b> user choose a CTP share,</i></li><li><i><b>when </b>he buys it,</i></li><li><i><b>then</b> market transaction should be logged.</i></li></ul>So the test method could look as follows:</p><pre name="code" class="java">@Test<br />public void shouldLogTradeTransactionAfterBuyingShare() {<br /> // given<br /> User user = em.find(User.class, 1L);<br /> Share share = shareDao.getByKey("CTP");<br /> int amount = 1;<br /><br /> // when<br /> tradeService.buy(user, share, amount);<br /><br /> // then<br /> List<TradeTransaction> transactions = tradeTransactionDao.getTransactions(user);<br /> assertThat(transactions).hasSize(1);<br />}<br /></pre><p>In the ideal world we could simply run this test in our favourite IDE or a build tool without writing a lot of plumbing code or dirty hacks to set up the environment like Glassfish, JBoss AS or Tomcat. And here's when <a href="http://www.jboss.org/arquillian/" target="_blank">Arquillian</a> comes to play. The main goal of this project is to provide a convenient way for developers to run tests either in embedded or remote containers. It's still in alpha version but amount of already supported containers is really impressive. It opens the door to world of easy and pleasant to write integration tests. There are only two things required in order to make our tests <i>"arquillian infected"</i>:<br /><ol><li>Set <code>@RunWith(Arquillian.class)</code> annotation for you test class (or extend <code>Arquillian</code> base class if you are a TestNG guy).</li><li>Prepare a deployment package using <a href="http://www.jboss.org/shrinkwrap/">ShrinkWrap API</a> in a method marked by the <code>@Deployment</code> annotation.</li></ol></p><pre name="code" class="java">@Deployment<br />public static Archive<?> createDeploymentPackage() {<br /> return ShrinkWrap.create("test.jar", JavaArchive.class)<br /> .addPackages(false, Share.class.getPackage(),<br /> ShareEvent.class.getPackage(),<br /> TradeTransactionDao.class.getPackage())<br /> .addClass(TradeService.class)<br /> .addManifestResource(new ByteArrayAsset("<beans/>".getBytes()), ArchivePaths.create("beans.xml"))<br /> .addManifestResource("inmemory-test-persistence.xml", ArchivePaths.create("persistence.xml"));<br />}<br /></pre><p><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:x-large;">Odds and ends</span></span></p><p>Until now I guess everything was rather easy to grasp. Unfortunately while playing with tests I encountered a few shortcomings but found the solutions which I hope make this post valuable for readers. Otherwise you could simply jump to the user guide and code examples, don't you?</p><p><b><span class="Apple-style-span" style="font-size: large;">JAR hell</span></b></p><p>The most time consuming issue were the dependencies conflicts better known as <b>JAR hell</b>. The target environment for the workshop application is Glassfish v3 so I used the embedded version for my integration tests. I decided to have my tests as integral part of the project and here problems began.</p><p>The main problem is that you cannot use <code>javaee-api </code>because you will get exceptions while bootstrapping the container more or less similar to : <span class="Apple-style-span" style=" white-space: pre;font-family:monospace;color:#5b5b5b;">java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/validation/constraints/Pattern$Flag</span> (<a href="http://community.jboss.org/message/531881" target="_blank">related thread</a> on JBoss forum). I also recommend not to download separated jars for each project which you are using because you will get even more exceptions :)</p><p><b>Important remark here:</b> if you are using JPA 2.0 with Criteria API and a <code>hibernate-jpamodelgen </code>module for generating metamodel classes then you should also exclude <code>org.hibernate.javax.persistence:hibernate-jpa-2.0-api</code> dependency to avoid yet another class conflict.</p><p>You have basically two options:</p><ol><li>Use <code>glassfish-embedded-all </code>jar since it already contains all needed APIs.</li><li>Create a separated project for integration testing and forget about everything what I mentioned in this section.</li></ol><p><b><span class="Apple-style-span" style="font-size: large;">Preparing a database for testing</span></b></p><p>Next step is to create a data source for the Glassfish instance. But first we need to tell Arquillian to not delete the Glassfish server folder after each deployment / test execution (which is the default behaviour). All you need to do is to create a <code>arquillian.xml</code> file and add following configuration:</p><pre name="code" class="xml"><arquillian xmlns="http://jboss.com/arquillian"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xmlns:glassfish="urn:arq:org.jboss.arquillian.glassfish.embedded30"><br /> <glassfish:container><br /> <glassfish:bindPort>9090</glassfish:bindPort><br /> <glassfish:instanceRoot>src/test/glassfish-embedded30</glassfish:instanceRoot><br /> <glassfish:autoDelete>false</glassfish:autoDelete><br /> </glassfish:container><br /></arquillian><br /></pre><p>Then we need to take a <code>domain.xml </code> file from our normal Glassfish instance (i.e. from <code>${glassfish_home}/glassfish/domains/domain1/config</code>), remove all <code><applications> </code> and <code><system-applications></code> nodes, add new data source and copy it to the <code>src/test/glassfish-embedded-30/config</code> folder. We will use HSQL 1.8.0.7 version in our tests (2.0 version is causing some problems with DBUnit). </p><pre name="code" class="xml"><domain log-root="${com.sun.aas.instanceRoot}/logs" application-root="${com.sun.aas.instanceRoot}/applications" version="22"><br /> <system-applications /><br /> <applications /><br /> <resources><br /> ...<br /> <jdbc-connection-pool res-type="java.sql.Driver" description="In memory HSQLDB instance" name="arquilliandemo" driver-classname="org.hsqldb.jdbcDriver"><br /> <property name="URL" value="jdbc:hsqldb:mem:arquilliandemomem" /><br /> <property name="user" value="sa" /><br /> <property name="password" value="" /><br /> </jdbc-connection-pool><br /> <jdbc-resource pool-name="arquilliandemo" jndi-name="arquilliandemo-ds" /><br /> </resources><br /> <servers><br /> <server name="server" config-ref="server-config"><br /> ...<br /> <resource-ref ref="arquilliandemo-ds" /><br /> </server><br /> </servers><br /> <configs><br /> ...<br /> </configs><br /></domain><br /></pre><p>The last file which you need to take from <code>${glassfish_home}/glassfish/domains/domain1/config </code>folder is <code>server.policy</code>. And that's it! You have running Glassfish with HSQL database ready for some serious testing.</p><p><b><span class="Apple-style-span" style="font-size:large;">Data preparation</span></b></p><p>As I mentioned in the introductory section I really like Unitils and the way how you can seed the database with the test data. The only thing to do is to provide an XML file in flat dbunit format like this one:</p><pre name="code" class="xml"><dataset><br /> <user id="1" firstname="John" lastname="Smith" username="username" password="password" /><br /> <share id="1" key="CTP" price="18.00" /><br /></dataset></pre><p>and then put the <code>@DataSet("test-data.xml") </code>annotation either on the test method or a class.</p><p>I was really missing this feature so I decided to implement it myself. Very cool way of adding such behaviour is by using a JUnit rule. This mechanism, similar to interceptors, has been available since 4.7 release. I choose to extend the <a href="http://kentbeck.github.com/junit/javadoc/latest/org/junit/rules/TestWatchman.html" target="_blank"><code>TestWatchman</code></a> class since it provides methods to hook around test invocation. You can see the <a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/test/java/com/ctp/test/db/DataHandlingRule.java" target="_blank">rule's logic</a> based on the <a href="http://code.google.com/p/ctpjava/source/browse/trunk/arquillian-demo-01/src/test/java/com/ctp/test/db/XmlDatasetSeeder.java" target="_blank">DBUnit flat xml data for seeding database</a> in the <a href="http://www.blogger.com/post-edit.g?blogID=3305419975676030648&postID=6203036377171397646#resources">example project</a>. All you need to do is to create a public field in your test class and decorate it with <code>@Rule</code> annotation. Here's the complete test class.<br /></p><pre name="code" class="java">@RunWith(Arquillian.class)<br />public class TradeServiceTest {<br /><br /> @Deployment<br /> public static Archive<?> createDeploymentPackage() {<br /> return ShrinkWrap.create("test.jar", JavaArchive.class)<br /> .addPackages(false, Share.class.getPackage(),<br /> ShareEvent.class.getPackage(),<br /> TradeTransactionDao.class.getPackage())<br /> .addClass(TradeService.class)<br /> .addManifestResource(new ByteArrayAsset("<beans />".getBytes()), ArchivePaths.create("beans.xml"))<br /> .addManifestResource("inmemory-test-persistence.xml", ArchivePaths.create("persistence.xml"));<br /> }<br /><br /> @Rule<br /> public DataHandlingRule dataHandlingRule = new DataHandlingRule();<br /><br /> @PersistenceContext<br /> EntityManager em;<br /><br /> @Inject<br /> ShareDao shareDao;<br /><br /> @Inject<br /> TradeTransactionDao tradeTransactionDao;<br /><br /> @Inject<br /> TradeService tradeService;<br /><br /> @Test<br /> @PrepareData("datasets/shares.xml")<br /> public void shouldLogTradeTransactionAfterBuyingShare() {<br /> // given<br /> User user = em.find(User.class, 1L);<br /> Share share = shareDao.getByKey("CTP");<br /> int amount = 1;<br /><br /> // when<br /> tradeService.buy(user, share, amount);<br /><br /> // then<br /> List<TradeTransaction> transactions = tradeTransactionDao.getTransactions(user);<br /> assertThat(transactions).hasSize(1);<br /> }<br /><br />}<br /></pre><p>I must admit that it's a JUnit specific solution, but you can always implement your own <code>@BeforeTest</code> and <code>@AfterTest </code>methods to achieve the same result in TestNG.</p><p><b><span class="Apple-style-span" style="font-size:large;">DBUnit gotchas</span></b></p><p>Using DBUnit's <code>CLEAN_INSERT</code> strategy (or deleting table content after test execution by using <code>DELETE_ALL</code>) could raise constraint violation exceptions. HSQL provides special <a href="http://www.hsqldb.org/doc/guide/ch09.html#set_refint-section" target="_blank">SQL statement</a> for this purpose and the sample project is invoking this statement just before DBUnit.</p><p><b><span class="Apple-style-span" style="font-size:x-large;">Final thoughts</span></b></p><p>All in all Arquillian is a really great integration testing tool with full of potential. It's just great that the JBoss guys are aiming to provide support for almost all widely used application servers and web containers. As you could see from the examples above it's not that hard to have tests for more sophisticated scenarios than you can find in the user guide. Keep your eyes on Arquillian - <a href="https://jira.jboss.org/browse/ARQ#selectedTab=com.atlassian.jira.plugin.system.project%3Aroadmap-panel" target="_blan">the roadmap</a> is really promising.<br />In the upcoming second part I will dive into CDI contexts and demonstrate how to use Arquillian for testing contextual components.<br />If you are writing an application for the Java EE 6 stack while not using Arquillian is a serious mistake!</p></p><p><span class="Apple-style-span" style=" font-weight: bold; "><span class="Apple-style-span" style="font-size:x-large;">Resources<a id="resources"> </a></span></span></p><p><ul><li>Full code example with all aspects mentioned in the article (<a href="https://ctpjava.googlecode.com/svn/trunk/arquillian-demo-01">svn</a> or <a href="https://ctpjava.googlecode.com/svn/trunk/arquillian-demo-01/arquillian-demo-01.zip">zip</a>)</li><li><a href="http://easytesting.org/assert/wiki/pmwiki.php">Fest-Assert</a> - offers convenient assertions following fluent interface pattern<i> (</i><code><i>assertThat()</i></code><i>).</i></li><li><a href="http://www.infoq.com/news/2009/07/junit-4.7-rules">JUnit Rules on InfoQ</a></li><li><a href="http://unitils.org/">Unitils</a></li></ul></p>Bartosz Majsakhttp://www.blogger.com/profile/17042462575032728792noreply@blogger.com8tag:blogger.com,1999:blog-3305419975676030648.post-26733383615634357402010-06-24T14:42:00.018+02:002010-06-28T13:04:46.735+02:00JSF composite componentOn my latest project we used <a href="http://www.jboss.org/richfaces">RichFaces</a> as a component library. Our client didn't like to fill out the time with the RichFaces calendar. They wanted two combo boxes to fill out the time. I don't think this is the most user friendly way to solve picking a time (I like this <a href="http://haineault.com/media/examples/jquery-utils/demo/ui-timepickr.html">timepicker</a>) but our customer is king.<br /><br />I thought that there would be someone on the internet who already created a component like that, but I could not find any so I made my own. JSF 2 will introduce a new <a href="http://www.ibm.com/developerworks/java/library/j-jsf2fu2/index.html">component creation</a> method. It will be simpler to create components and you do not have to write java code to make them work. But until we have JSF 2 available on all major application servers we will have to program some java for our components to work.<br /><br />The plan I had for creating it was simple enough just take two HtmlSelectOneMenu components and fill them with default options.<br /><br />So I ended with something like this:<br /><br /><pre name="code" class="java"><br />private void createChildComponents(FacesContext context) {<br /> Application application = context.getApplication();<br /> hourInput = (HtmlSelectOneMenu) application.createComponent(HtmlSelectOneMenu.COMPONENT_TYPE);<br /> minuteInput = (HtmlSelectOneMenu) application.createComponent(HtmlSelectOneMenu.COMPONENT_TYPE);<br /> List<UIComponent> children = getChildren();<br /> children.add(hourInput);<br /> HtmlOutputText sparator = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);<br /> sparator.setValue(":");<br /> children.add(sparator);<br /> children.add(minuteInput);<br /><br /> UISelectItems hourItems = createSelectItems(application, 24, 1);<br /> hourInput.getChildren().add(hourItems);<br /><br /> UISelectItems minuteItems = createSelectItems(application, 60, 5);<br /> minuteInput.getChildren().add(minuteItems);<br /> delegateProperties();<br />}<br /><br />private UISelectItems createSelectItems(Application application, int number, int step) throws FacesException {<br /> UISelectItems selectItems = (UISelectItems) application.createComponent(UISelectItems.COMPONENT_TYPE);<br /> List<SelectItem> items = new ArrayList<SelectItem>();<br /> for (int i = 0; i < number; i += step) {<br /> items.add(new SelectItem(StringUtils.leftPad(String.valueOf(i), 2, "0")));<br /> }<br /> selectItems.setValue(items);<br /> return selectItems;<br />}<br /></pre><br /><br />Rendering this was not hard but to extract the selected value and store the submitted value back into the value binding, that was not so easy. First I tried to override the validate method but that didn't "sound" right, doing it in the updateModel was much better.<br /><br />The only weird thing I was still facing was that, sometimes the value from the hour and minute components were converted to Integer but sometimes they where not. So I ended up with this construction to ensure that they were always Integer.<br /><br /><pre name="code" class="java"><br /> @Override<br /> public void updateModel(FacesContext context) {<br /> super.updateModel(context);<br /><br /> hourInput.validate(context);<br /> minuteInput.validate(context);<br /><br /> ValueExpression valueExpression = getValueExpression("value");<br /> Date value = (Date) valueExpression.getValue(context.getELContext());<br /> if (value != null && hourInput.getValue() != null <br /> && minuteInput.getValue() != null) {<br /> Calendar calendar = Calendar.getInstance();<br /> calendar.setTime(value);<br /> Integer hour = Integer.valueOf(hourInput.getValue().toString());<br /> calendar.set(Calendar.HOUR_OF_DAY, hour);<br /> Integer minute = Integer.valueOf((minuteInput.getValue().toString()));<br /> calendar.set(Calendar.MINUTE, minute);<br /><br /> valueExpression.setValue(context.getELContext(), calendar.getTime());<br /> }<br /> }<br /></pre><br /><br />Here I'm using the Java Date API. That of course is extremely sadistic so we could change it to use <a href="http://joda-time.sourceforge.net/">joda-time</a>.<br /><br />Now to use it we first register it as a component in components.taglib.xml<br /><pre name="code" class="xml"><br /><facelet-taglib><br /><namespace>http://ctp-consulting.com/components</namespace><br /><!--<br /> usage: <ctp:timepicker value="date"/><br /> --><br /><tag><br /> <tag-name>timepicker</tag-name><br /> <component><br /> <component-type>com.ctp.web.components.Timepicker</component-type><br /> </component><br /></tag><br /></pre><br /><br />Then make sure you have the components.taglib.xml registered in you're web.xml<br /><pre name="code" class="xml"><br /><context-param><br /> <param-name>facelets.LIBRARIES</param-name><br /> <param-value>/WEB-INF/tags/components.taglib.xml;</param-value><br /></context-param><br /></pre><br />And here an example of use, fist add the namespace on the top of you're page:<br /><pre name="code" class="xml"><br /> xmlns:ctp="http://ctp-consulting.com/components"<br /></pre><br />Then in our page you can do something like:<br /><pre name="code" class="xml"><br /> <ctp:timepicker value="#{catering.deliveryTime}"/><br /></pre><br />Maybe this is not the best solution, if you have comments or tips, feel free drop them directly on this post. I'm interested in what you have to say!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-7021693210636704272010-06-05T10:49:00.000+02:002010-06-05T10:49:44.258+02:00Jazoon 2010<div><div><div><div>As a Java developer you'll need to stay on-top of what is new and noteworthy. A great way to do this is to go to a conference, because this is an interactive way to learn about new stuff. Together with <a href="http://ctpjava.blogspot.com/2008/10/java-people-spotlight-douglas-rodrigues.html">Douglas</a>, I was attending <a href="http://jazoon.com/">Jazoon</a>, an international conference held in Zurich, it is my first time here. Like <a href="http://www.devoxx.com/display/Devoxx2K10/Home">Devoxx</a> it's also held in a movie theater. Although Jazoon is also an international conference there are of course a lot of Swiss here and it's a little smaller. But that just means I have more change to win an iPad :D (didn't happen, too bad).</div><div><br />
</div><div>After the keynote the first presentation I attend is about REST. <a href="http://www.innoq.com/blog/st/about/">Stefan Tilkov</a> is the presenter and he does a nice job bashing web frameworks like <a href="http://java.sun.com/javaee/javaserverfaces/">JSF</a> that do not do <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> at all. He has a point, the web is about <a href="http://en.wikipedia.org/wiki/Uniform_Resource_Identifier">URI</a> (Unified Resource Indicator) and a document should be identified with that. That has always been the way of the web. And "modern" web application frameworks have a tendency not to change the URI for every resource and use only one HTTP method (e.g. POST) instead of all 7 of them. Stefan calls this abusing the web, or even desktop applications in disguise. I must agree to what he has to say about a lot of things. Search engines like Google work because of this and even if we are writing applications that are used inside intranets they are still web applications and they should be able to work accordingly. I'll need to investigate what people developing JSF thoughts are about this.</div><div><br />
</div><div>Next up <a href="http://www.ibm.com/developerworks/opensource/library/os-osgiblueprint/index.html">Blueprint</a> by <a href="https://www.springsource.com/people/cleau">Costin Leau</a>, he works for <a href="http://www.springsource.com/">SpringSource</a>. I personally have not used Spring since they were hesitant to adopt annotations and was rather using JBoss Seam ever since. But as we have customers interested in doing something with <a href="http://www.osgi.org/Main/HomePage">OSGi</a> it will be interesting to see how they eased the way to develop something for OSGi. When I heard about Spring the first time, I was amazed and wondered why I didn't think of that. Now I have the same feeling with OSGi, it can be a lot simpler when you use IoC in combination with it. Blueprint is only a spec and there are 2 implementations. I really need to take a look at it because it looks really helpful.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitPVzJbMsyG4YsQZmSviqTVT6QCiXrjSsRkUq6-xu8Pxb32aANUAg3dtPi59-Yt_POpwDLuBCC1EltuCgycBIzGFor0AmYjw0OLDHXmdSUD9WEZFz5sNidkXqvF4UAUhaiFYIUisLYYbJ6/s1600/photo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitPVzJbMsyG4YsQZmSviqTVT6QCiXrjSsRkUq6-xu8Pxb32aANUAg3dtPi59-Yt_POpwDLuBCC1EltuCgycBIzGFor0AmYjw0OLDHXmdSUD9WEZFz5sNidkXqvF4UAUhaiFYIUisLYYbJ6/s320/photo.jpg" /></a><br />
<span class="Apple-style-span" style="font-size: small;"><i>On Thursday we had a nice Java roundtable to discuss all the news.<br />
Erik was all excited! :D</i></span></div><br />
</div><div><br />
</div><div><b>On day 2</b> the keynote is from <a href="http://www.scrumalliance.org/profiles/7">Ken Schwaber</a> he is one of the founders of <a href="http://www.scrum.org/">SCRUM</a>. In his presentation he made the point that a lot of people who think they are doing scrum are actually not: Because they don't finish their user stories. This is due to the fact that we don't include enough when we say it's done. When is a user story <a href="http://www.scrumalliance.org/articles/105-what-is-definition-of-done-dod">done</a>? When user acceptance testing has taken place? Load test integration test and refactoring? When things like these are kept to the very end of the project a lot of work still remains to be done when the project should have been finished. According to Ken this work will be exponentially more then when you do it after each sprint. All in all it was quite a mood breaker because Ken tried to emphasize that a lot of software projects still fail and that we should be professional and fix that by changing what we call done.</div><div><br />
</div><div><a href="http://tech.kaazing.com/training/index.html">Peter Lubers</a> (he must be Dutch :D ) had a talk about <a href="http://www.kaazing.org/confluence/display/KAAZING/What+is+an+HTML+5+WebSocket">HTML 5 Websockets</a>. I've heard about a couple of things that are going to be in the HTML 5 spec but I did not know about this! And this is very exiting: there are a lot of projects that have tried to solve the problem how to push data to a web browser client. All of the implementations are not ideal. There are a couple of polling solutions, but the overhead that you get when making a request, on average, is about 800k. That does not look like much but if you want to scale your applications it is a lot. The way Websockets work is to "upgrade" your standard HTTP connection to a socket where you can then send and receive data over. He showed a working example of this with Google Chrome the only browser that supports this right now- At the end of the presentation he said he talked to one of the technical guys from Microsoft and he has a strong feeling it will not be in <a href="http://ie.microsoft.com/testdrive/">IE9</a>, how nice is that (the <a href="http://mashable.com/2010/01/29/google-ie6/">IE6</a> story all over).</div><div><br />
</div><div>The two talks I went to after lunch were both about <b>alternative languages on the JVM</b> namely Groovy and Scala. And they we're both about <a href="http://en.wikipedia.org/wiki/Distributed_Computing">Distributed Computing</a>. I thought it was really exciting, all we need now is a customer with a large set of data and a need to compute something with. That is the only problem with distributed computing and with cloud computing even more so, it needs lot of data to work with. Otherwise there is no need to use it. This is even more true when you already use web applications. They scale very easy because they use the request response model. Every request could be handled by a separate thread or instance in a cluster. So interesting things are happening here and a lot of development is going into solutions based on distributed computing and cloud computing.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHkn2ucKVJYuwv2Nkay4J7eU5UmOE1T1iMnzT3NDzgjOqGc9SeKeUvfdWZ6JftSMVq54XykIbzIOBeOSmkGYcwCGmHybMX9R-a7oE_0zn9NCja2yxK0vd1lvI1t9bSvz7_DkJE22hyRSIt/s1600/photo+(1).jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHkn2ucKVJYuwv2Nkay4J7eU5UmOE1T1iMnzT3NDzgjOqGc9SeKeUvfdWZ6JftSMVq54XykIbzIOBeOSmkGYcwCGmHybMX9R-a7oE_0zn9NCja2yxK0vd1lvI1t9bSvz7_DkJE22hyRSIt/s320/photo+(1).jpg" /></a><br />
<span class="Apple-style-span" style="font-size: small;"><i>Douglas and Daniel trying to get more infos about Web Sockets...<br />
Well...isn't that a game on that iPad?</i></span></div><br />
</div><div><br />
</div><div><b>Last Day</b><br />
<br />
On the last day of the conference the keynote was about Gaia the satellite that is going to map a lot of stars in our milky way. It was interesting to see that they use Java to analyse the huge amount of data. And that there are still debates about Java being fast enough. Come on people it's 2010 Java is blazing fast!!</div><div><br />
</div><div>The whole last day was more or less about testing. There were a lot of talks in this area and only one that I would like to mention here. There was a way to short talk about <a href="http://www.jboss.org/arquillian/">Arquillian</a>. I don't think that the presenters wanted to have a small slot but I guess they we're forced to use a small one. Arquillian is a cool way to test EJBs inside the container. The project is brand new and they still need to add support for a couple of containers. But it's looking really promising. I got a cool shirt at their presentation so I'll definitely keep an eye on this project :-). </div><div><br />
<b>Thoughts</b><br />
<br />
</div><div>All in all Jazoon was great to see and to be at. But if I would have to choose between Jazoon or Devoxx I'd rather go for Devoxx. The idea I get is that Jazoon is younger than Devoxx and still has to proof itself as important and unique besides Devoxx. Of course Jazoon is better organized, everybody knows that people from Belgium are chaotic ( :D sorry guys), but that is not enough of course. At Jazoon I don't get yet the atmosphere you get from a Devoxx, this hold true for the size and quality of speakers too.<br />
<br />
But I do have a lot of new things I have to look at! So all in all it was a positive experience. I hope Jazoon gets more popularity so it will attract more people from around the world.</div></div></div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-69863339829885964362010-05-20T21:22:00.002+02:002010-05-20T21:24:50.753+02:00JavaOne 2010 and Oracle OpenWorld 2010... or "Oracle acquired the city of San Francisco":<br />
This year is the first year of JavaOne under the umbrella of Oracle and it takes place in the same city and the same week as Oracle OpenWorld: September 19th - 23rd in San Francisco.<br />
<br />
You may ask how Oracle can host two conferences of that size at the same time in the same city: Moscone Center (for me the home of JavaOne) is now the home of <a href="http://www.oracle.com/us/openworld/index.html">Oracle OpenWorld</a> whereas <a href="http://www.oracle.com/us/javaonedevelop/index.html">JavaOne</a> has been relocated to the so called "The Zone" consisting of three large hotels, all near Union Square (see red markers in the following map):<br />
<br />
<iframe frameborder="0" height="350" marginheight="0" marginwidth="0" scrolling="no" src="http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=113798857262975569717.0004870b2d3929d94520a&ll=37.784801,-122.404651&spn=0.002699,0.009319&t=h&output=embed" width="425"></iframe><br />
<small>View <a href="http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=113798857262975569717.0004870b2d3929d94520a&ll=37.784801,-122.404651&spn=0.002699,0.009319&t=h&source=embed" style="color: blue; text-align: left;">JavaOne 2010</a> in a larger map</small><br />
<br />
Registration is open for both conferences and both do offer a discount at this moment when registering within the next few weeks.<br />
<br />
If you go to JavaOne for the first time you might want to compare it with last year's conference where it was hosted by Sun Microsystems for the last time:<br />
<br />
<ul><li><a href="http://ctpjava.blogspot.com/2009/06/java-one-2009-summary-monday.html">Monday</a></li>
<li><a href="http://ctpjava.blogspot.com/2009/06/java-one-2009-summary-tuesday-day-1.html">Tuesday</a></li>
<li><a href="http://ctpjava.blogspot.com/2009/06/javaone-2009-summary-wednesday-day-2.html">Wednesday</a></li>
<li><a href="http://ctpjava.blogspot.com/2009/06/javaone-2009-summary-thursday-day-3.html">Thursday</a></li>
<li><a href="http://ctpjava.blogspot.com/2009/06/javaone-2009-summary-friday-day-4.html">Friday</a></li>
</ul><div>We (the CTP Java Competence Group) are very curious how both conferences will present themselves in this new Java era led by Oracle.</div><div><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZRV9ikPmlpzV2ETighE-7jwFw7HHQAiGYQ9yz7120BWULDxDlZ75ZScJryzNQP3XwjCGfTm08Yk-26n4U7kPViul_gjsXSzvTptXwq7ss6cZKoIVJeGotgfpHCOcEVZr-B9OpvnfOtSQk/s1600/java.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZRV9ikPmlpzV2ETighE-7jwFw7HHQAiGYQ9yz7120BWULDxDlZ75ZScJryzNQP3XwjCGfTm08Yk-26n4U7kPViul_gjsXSzvTptXwq7ss6cZKoIVJeGotgfpHCOcEVZr-B9OpvnfOtSQk/s320/java.jpg" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQvu_DdP_HVKbwitGNj4kxbAeXbG6N24dSckSm-zPjBAz_XvZHu1fiwyYORgFxm7R5Q1B2MI6YO7pFUtIKVXRkiJZoLbM2dj9nSEdeJNtWwSFlwl-BUVzzqRcaEzwmmydGG-tOkbYKWVXf/s1600/oracle.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQvu_DdP_HVKbwitGNj4kxbAeXbG6N24dSckSm-zPjBAz_XvZHu1fiwyYORgFxm7R5Q1B2MI6YO7pFUtIKVXRkiJZoLbM2dj9nSEdeJNtWwSFlwl-BUVzzqRcaEzwmmydGG-tOkbYKWVXf/s320/oracle.jpg" /></a></div><br />
</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-73377014583986608672010-04-29T09:00:00.054+02:002010-04-29T10:10:50.603+02:00Java People Spotlight: Erik Jan de Wit<div class="separator" style="clear: both; text-align: center;"><a href="http://farm4.static.flickr.com/3119/4560060299_9913486feb_o.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://farm4.static.flickr.com/3119/4560060299_9913486feb_o.jpg" /></a></div><span style="font-style: italic;">After a rather long break, we are back with interesting articles in the pipeline, one of them released <a href="http://ctpjava.blogspot.com/2010/04/jboss-seam-maven-archetype-video.html">yesterday</a> containing a nice video tutorial!<br />
</span><br />
<span style="font-style: italic;">So today we want to present a rather new member in the CTP Java gang: Erik Jan de Wit, dutch Java power at its best!<br />
Erik has joined <a href="http://ctp.com/">Cambridge Technology Partners</a> in February 2009. His technical excellence and social skills are true assets for our projects as well as for our Java oriented internal activities. Not without reasons, "@EJD" became an alias among CTP Java dudes to shortcut the fact that Erik will get "injected" and involved on projects, tasks...:-)<br />
So let's check out the answers by Erik then!</span><br />
<br />
<b>Java Competence Role</b>:<br />
Senior Developer<b> </b>[aka Singing Scrum Master]<b> <br />
My Master Kung-Fu Skills</b>:<br />
Intergate new technology into existing projects fast<br />
<b>I'd be excited to get my hands dirty on</b>:<br />
Scala, ESB, JavaFX, Cloud-Computing and the new EJD... sorry EJB Criteria... well it's anyway JPA Criteria API :-)<br />
<hr /><span style="font-weight: bold;">Q&A</span> <br />
<span style="font-weight: bold;">Q: </span>Hi Erik, how would your message look like if you would have to tell it via Twitter what you are currently doing?<br />
<span style="font-weight: bold;">A: </span>Be a great <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29">Scrum</a> master on this time challenged project<br />
<br />
<span style="font-weight: bold;">Q: </span>What was the greatest piece of code you have ever written so far?<br />
<span style="font-weight: bold;">A: </span>A screen scraper that enabled to integrate an external site into another site while changing all links back to our site including form actions.<br />
<span style="font-weight: bold;">Q: </span>Really? I'm sure dutch scrum masters did something more fancy on projects than this....:-)<br />
<span style="font-weight: bold;">A: </span>Well yeah, you're right: So on my <a href="http://kenai.com/people/21530-Erik-Jan">kenai.com</a> account I published an open-source framework which is basically a reverse regular expression generator that is used in the testdata project to generate test data that adheres to a specific regular expression. The testdata framework inspects your domain model and creates data for your domain. So if you use hibernate validator or bean validation annotations in your domain it will use the regular expression on the field to generate data that is valid. So that's what I used later on projects.<br />
<span style="font-weight: bold;">Q: </span>Awesome!<span style="font-weight: bold;"><br />
A: </span>And!! ... there is also a <a href="http://www.scala-lang.org/">Scala</a> version of it, based on the <a href="http://www.scala-lang.org/docu/files/api/scala/util/parsing/combinator/syntactical/StandardTokenParsers.html">StandardTokenParsers</a><br />
<span style="font-weight: bold;">Q: </span>Now we're talking :-)<br />
<br />
<span style="font-weight: bold;">Q: </span>What is the best quote you have ever heard about programming?<br />
<span style="font-weight: bold;">A: </span>All my peers are trying to talk dutch... very nice!<br />
<br />
<span style="font-weight: bold;">Q: </span>What is the best quote you have heard from our managers?<br />
<span style="font-weight: bold;">A: </span>I had to review Java code written in Turkish and my manager said: <span style="font-style: italic;">"It is still Java, it is not Rocket Science!"</span><br />
<br />
<span style="font-weight: bold;">Q: </span>What is the most cutting-edge technology or framework you actually used on projects?<br />
<span style="font-weight: bold;">A: </span>jBPM, Seam, JSF and Java EE6<br />
<br />
<span style="font-weight: bold;">Q: </span>What is your favorite podcast?<br />
<span style="font-weight: bold;">A: </span>I really love the <a href="http://www.javaposse.com/">Java Posse</a>, I listen to it all the time... another that I like which is actually non-Java related is <a href="http://www.bestofyoutube.com/">Best of Youtube VideoCast</a>.<br />
<br />
<span style="font-weight: bold;">Q: </span>Which Java book can you recommend and for what reason?<br />
<span style="font-weight: bold;">A: </span>It seems that always the latest book I've read is the best one, in this case it's "<a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code</a>" from "<a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew">Uncle Bob</a>"<br />
<br />
<i>You can further visit Erik at his <a href="http://www.google.com/profiles/erikjan.dewit">Google Profile</a> or on <a href="http://ch.linkedin.com/pub/erik-jan-de-wit/0/255/aba">linkedin</a>.</i>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-38232166027062997852010-04-28T16:19:00.008+02:002010-04-29T09:09:18.309+02:00JBoss Seam Maven Archetype Video TutorialWhile the release of <a href="http://in.relation.to/Bloggers/TheTimelineForSeam3" target="_blank">Seam 3 is getting closer</a>, you might still want to do quick prototyping based on a Seam 2 project. Of course this is easiest done with either <code>seam-gen</code>, or if you're like me a <a href="http://maven.apache.org/" target="_blank">Maven</a> user, with an Archetype.<br /><br /><a href="http://ctpjava.blogspot.com/2008/09/java-people-spotlight-christoph-reimann.html">Chris</a> has prepared a video tutorial on how to get started with our <a href="http://code.google.com/p/ctpjava/wiki/JBossSeamMavenArchetype">Maven WAR archetype</a> (featuring hot deploy, <a href="http://testng.org/" target="_blank">TestNG</a> with embedded JBoss and either <a href="http://www.jboss.org/richfaces" target="_blank">RichFaces</a> or <a href="http://www.icefaces.org/" target="_blank">ICEFaces</a> inclusion) based on one of my <a href="http://ctpjava.blogspot.com/2009/07/jboss-seam-archetype-now-with-icefaces.html">previous articles</a>. Check it out here (best seen in HD [UPDATE: sorry, missed the HD embed]):<br /><br /><object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/Zpn-teo1l3E&ap=%2526fmt%3D18"></param><param name="wmode" value="window"></param><embed src="http://www.youtube.com/v/Zpn-teo1l3E&ap=%2526fmt%3D18" type="application/x-shockwave-flash" wmode="window" width="480" height="295"></embed></object><br /><br />Enjoy!Anonymoushttp://www.blogger.com/profile/03406453074932551739noreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-85266544416189601052009-11-20T13:33:00.002+01:002009-11-20T13:58:05.625+01:00Java People Spotlight: Sylvain Berthouzoz<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOZpdxe8s8tg0TliO_t249DHViLMakSiKTt5wZ9p1wzo22872FeLdU-QAsphDjBUDeWCRzZT3srYr2mOAg9c7eEejpRPAQcQUaCiVcFR-Acw5IyVV8efoSGs8JCxo9KXZ1spMEcPWjCRvh/s1600/sylvain.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOZpdxe8s8tg0TliO_t249DHViLMakSiKTt5wZ9p1wzo22872FeLdU-QAsphDjBUDeWCRzZT3srYr2mOAg9c7eEejpRPAQcQUaCiVcFR-Acw5IyVV8efoSGs8JCxo9KXZ1spMEcPWjCRvh/s200/sylvain.JPG" /></a><span style="font-style: italic;">The "People Spotlight" series is catching up after a rather long break... <br />
Sylvain has joined Cambridge Technology Partners in January 2006 and is an important know-how carrier in the Java Competence Group since then.<br />
So let's check out the answers by Sylvain then!</span><br />
<br />
<b>Java Competence Role</b>:<br />
Developer<b> </b>[aka Java Debugger or Mr. jBPM]<b> <br />
My Master Kung-Fu Skills</b>:<br />
I can hit everyone with a single process in jBPM<br />
<b>I'd be excited to get my hands dirty on</b>:<br />
JPA2: see how they included the Criteria query...<br />
...and to see what <a href="http://assassinscreed.uk.ubi.com/assassins-creed-2/">Ezio Audirore da Firenze</a> will do.<br />
<hr /><span style="font-weight: bold;">Q&A</span> <br />
<span style="font-weight: bold;">Q: </span>Hi Sylvain, how would your message look like if you would have to tell it via Twitter what you are currently doing?<br />
<span style="font-weight: bold;">A: </span>Sitting in the train in hoping that the locomotive don’t break this time. <br />
<br />
<span style="font-weight: bold;">Q: </span>What was the greatest piece of code you have ever written so far?<br />
<span style="font-weight: bold;">A: </span>Testing if all the elements in a list are different from each other:<br />
<pre class="java" name="code">List< Long > list = Arrays.asList(longs);
Set< Long > set = new HashSet< Long >(list);
return (longs.length == set.size());
</pre><span style="font-weight: bold;">Q: </span>What is the best quote you have ever heard about programming?<br />
<span style="font-weight: bold;">A: </span><span style="font-style: italic;">“koffienodig”</span> <br />
<br />
<span style="font-weight: bold;">Q: </span>What is the best quote you have heard from our managers?<br />
<span style="font-weight: bold;">A: </span><span style="font-style: italic;">"There is not enough boxes here."</span><br />
<br />
<span style="font-weight: bold;">Q: </span>What is the most cutting-edge technology or framework you actually used on projects?<br />
<span style="font-weight: bold;">A: </span>JBoss Seam<br />
<br />
<span style="font-weight: bold;">Q: </span>What is your favorite podcast?<br />
<span style="font-weight: bold;">A: </span>The <a href="http://www.gameblog.fr/podcasts.php" target="_blank">gameblog podcast</a> every week. And the Java Posse from time to time.<br />
<br />
<span style="font-weight: bold;">Q: </span>Which Java book can you recommend and for what reason?<br />
<span style="font-weight: bold;">A: </span><a href="http://www.manning.com/dallen/" target="_blank">Seam in Action</a>, because it is a great book to start with seam and you’ll also learn how to play golf.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-3305419975676030648.post-80208256335394806662009-11-20T10:43:00.003+01:002009-11-30T20:03:32.418+01:00Devoxx day 4/5Day 4 was really great we had some very good keynote sessions. <a href="http://devoxx.com/display/DV09/Ivar+Jacobson">Ivar Jacobson</a> is the father of components and UML. In his presentation he told us about the work he is doing to standardise the methodologies. Now a lot of companies make their own flavour of a methodology or create an entirely new one but "steal" from others. He want to create reuse so that people don't have to relearn the entire thing but just have to learn the new parts. It's food for thought, that is for sure and if it works out we'll have to wait and see.<br /><br />After that, another great keynote from <a href="http://devoxx.com/display/DV09/Robert+C.+Martin">Robert Martin</a> a.k.a Uncle Bob he is the founder of <a href="http://www.fitnesse.org/">fitnesse</a> and very focused on TDD (Test driven development). His talk was about "Filling The Professionalism Gap" by being Craftsmen. What it comes down to, is to make more IT projects succeed, developers must see themselves more as craftsmen. That means that developers should have a more "ethic" approach in delivering things and only create software that is clean tested and that really works. This is what we already do at <a href="http://www.ctp.com/">CTP</a> but I think a lot of developers can learn from this.<br /><br />There were also some big announcements made at this Devoxx:<br /><ol><li>Closures are in JDK7</li><li>More new components in JavaFx 1.3</li></ol>Big stuff and cool to hear that closures are going to make it in JDK7, that is a huge thing.<br /><br />Also I had some fun of this day at devoxx, I went to the presentation of the JavaPosse. And when you hear the recording you can probably hear me shout: "Switzerland" :-). Of course they had their beer sponsor <a href="http://www.atlassian.com/">Atlassian</a> so we had some nice Belgium beer (<a href="http://www.duvel.be/">Duvel</a>). A cool side effect of conferences is the fact that they are normally hosted inside a movie theatre: So at Devoxx they showed the new movie '2012', a very nice movie with lots of effects.<br /><br />And then it is already the last day and I didn't notice this before, but it's only half a day. So I had some good sessions today one from <a href="http://www.devoxx.com/display/DV09/Andy+Wilkinson" title="Andy Wilkinson">Andy Wilkinson</a> about Modular Web Applications with OSGi. He uses Spring DM (that's an application server, but not a <a href="http://java.sun.com/javaee/overview/compatibility.jsp">Java EE certified</a> one) to be able to split his web application vertically and/or horizontally in different OSGi bundles. That could be really good to manage big applications. Also he had some news, they are working on a version that does not require Spring DM, so that is definitely something we must keep an eye on.<br /><br />That is it from Antwerp, Devoxx 2009!<br />So let's see what will happen with all the announcements made here in the next year...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-18708385472700583302009-11-18T10:36:00.014+01:002009-11-20T09:37:13.099+01:00Devoxx Day 3The network at devoxx is letting me down a bit, so this post is a little bit late. This day is the first conference day, the university days are over. That means that there are a lot more people here than yesterday. Oracle (<a href="http://devoxx.com/display/DV09/Steven+Harris">Steven Harris</a>) had a long keynote talk in which interesting upcoming details have been presented with what is coming with future WebLogic releases. What they demo-ed was kinda cool. A modular WebLogic based on OSGi (often referred as mSA aka Micro Service Architecture) that you can assemble using a GUI tool. That you can also run in a virtual machine without adding an OS.<br /><br />Next keynote was presented by <a href="http://devoxx.com/display/DV09/Roberto+Chinnici">Roberto Chinnici</a> from SUN, he is the spec lead for JavaEE6 and gave a quick overview what is new in EE6. As I already had a 2 hours talk about that topic during the university days there was nothing new to me but all in all it well covered all aspects for people hearing about it for the first time. One of the cool things in Java EE 6 I like most is the modularity of the web.xml being part of the Servlet 3.0 spec. Using 3rd party frameworks only requires to add a library, instead of also adding a servlet or servlet filter in your web.xml.<br /><br />Also announced in the keynote is that everything presented at Devoxx is going to be released on parleys.com (currently upgraded to version 3!! ). That is great as all the presentations I've visited can be watched again including comments by other visitors etc.<br /><br />During the break I ran into a lot of people I know from previous companies I worked for. It is always nice to hear what they are doing now and what other sessions they have seen and to tell them if they ever want to work for a nice company in Switzerland, I would know a good one :D<br /><br />Now an update on where JDK7 is right now by <a href="http://devoxx.com/display/DV09/Mark+Reinhold" title="Mark Reinhold">Mark Reinhold</a>. Great talk about what is important and where the focus for making Java move forward is going to lay. Talking about Project Jigsaw this is the first time ever I have seen some implementation how this could/would work. The shame is that there is no JSR for Java SE 7 so all development will not progress as long as this is the case. What was very surprising is that Mark wants Closures in, but in a very simple form, but that is great news for a lot of things Closures will make my code look nice.<br /><br />In the keynote Apple gets a lot of criticism about being slow accepting apps in the store and the kind of feedback Apple provides when apps are disallowed.<br /><br />Lunch break: Bumping into a lot of people again that I know; Talking to someone from JBoss about their community, now I have a nice CD to give away.<br /><br /><a href="http://www.devoxx.com/display/DV09/James+Gosling" title="James Gosling">James Gosling</a> is talking about the <a href="http://java.com/en/store/">Java Store</a> and I hope he is going to tell us that we here in Europe can use it now. So he is talking that we should provide him with feedback on the stuff they made, but as of now the Java Store is still not accessible for us. That makes his whole talk a bit pointless. Yes, I would love to have a platform I can sell my hobby projects with, but no need to tell me about how great it is when I still can't use it. There are a couple of countries being added in the near future, but Switzerland is not one of them.<br /><br /><a href="http://www.devoxx.com/display/DV09/Cameron+Purdy" title="Cameron Purdy">Cameron Purdy</a> tells us how we should change our programming paradigms if we want to use multi core, multi node programs. So the answer to all our problems is to use partitioning? I'm a bit puzzled how I could use this. I think this presentation could have been a bit more concrete. He presents all theoretical ways to do parallel distributed computing. At the very end I know why everything was so vague, if you want an implementation of all of what he talked about than you'll need to buy Coherence a bit of an anticlimax.<br /><br /><a href="http://www.devoxx.com/display/DV09/Doug+Tidwell" title="Doug Tidwell">Doug Tidwell</a> will now tell us a little about how to extract a way from implementations of cloud computing. He is from IBM an I hope this is not another product plug and it turns out that it's not, he is funny and a good speaker. What he is trying to tell us is that we need a standard for doing cloud computing, an API to talk to different clouds. The problem is that the services that clouds provide now are so diverse that one API to rule them all makes no sense. That is a bit what I miss, nobody is talking about how using a cloud will impact my design.<br /><br />Then one of the creators of the Android platform <a href="http://www.devoxx.com/display/DV09/Romain+Guy" title="Romain Guy">Romain Guy</a> will talk about animation. <a href="http://www.devoxx.com/display/DV09/Romain+Guy" title="Romain Guy">Romain Guy</a> is really famous in the Java world so his presentation will be good. It's about animating GUI using the cartoon rules. There are some basic cartoon rules for doing animation he shows us how they apply to GUI animation.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3305419975676030648.post-85698182652313317912009-11-17T11:28:00.017+01:002009-11-18T10:40:27.341+01:00Devoxx day 2Today it is day two at Devoxx. What I didn't put in <a href="http://ctpjava.blogspot.com/2009/11/devoxx-day-1.html">my last post</a> is the BOF I went to last night. BOFs here are great - there are only a couple of people in the room, it is really different than at <a href="http://java.sun.com/javaone/">JavaOne</a> where there are a lot more people. So yesterday I had a BOF with the JSF spec leads (well the 3 key persons: Dan Allen, Peter Muir and Andy Schwartz) and we could in a very relaxed setting ask them some questions about the JSF 2 spec. So we could find out how and why they made some decisions. The question I asked them: "Why is JSF 2 not more focused on components so that I can mix and match components of 3rd party providers?". The answer was that they are looking into that and that a lot of problems one has with that right now is how resources are loaded: all 3rd parties made something on their own. So now all the AJAX stuff needs to be gathered and then they will look into that. Good answer, I'm glad that they are aware of what lives in the community.<br /><br />My first session of today is a session about JEE6. They are talking about and demo-ing everything that is new in the spec. <a href="http://www.antoniogoncalves.org/xwiki/bin/view/Main/WebHome" rel="nofollow">Antonio Goncalves</a> a French Java Rockstar has a lot of humor and a nice presenting style. JSF 2.0 is kind of confusing, because it could run on servlet 2.5 but also on 3.0 but then less needs to be configured. Yesterday the expert group also talked about this that they communicate better what is now the "preferred" way of doing things. This is difficult when you make a spec. You can't remove things, because it needs to be backwards compatible. This is also the case for EJB3 - there is now a EJB3.1 lite edition where all old stuff is removed. According to them there are some containers being built that only support this spec.<br /><br />JavaFX is what my next talk is about. This is hyped a lot by Sun and now with the takeover by Oracle also Oracle will continue with JavaFX. The last changes around JavaFX involved a lot of tooling at this year's JavaOne. <a href="http://blogs.sun.com/tor" target="_blank">Tor Norbye</a> presented a tool for designers that they can layout an application for mobile and desktop. <a href="http://devoxx.com/display/DV09/Stephen+Chin">Stephen Chin</a><span id="breadcrumb-display" class="breadcrumbs"> also a Java Champion starts with a nice little JavaFX Puzzle. For his demo he is using twitter but that was a bit of a poor choice, because with the Devoxx network, reaching twitter proves a bit of a challenge. So most of the time we are waiting for some internet resource to load. So I'm changing again, I already know the basics about JavaFX and I was hoping this would be a little bit more deep dive. </span><a href="http://devoxx.com/display/DV09/Emmanuel+Bernard" title="Emmanuel Bernard">Emmanuel Bernard</a> is also a guru of the Hibernate team and here at Devoxx he is talking about integrating <a href="http://lucene.apache.org/">Lucene</a> into Hibernate as an alternative query API. So the bridge they have built for Hibernate is really cool. In the past we did this on ourselves, have a Lucene index to search on and then load entities when needed. But with the Hibernate search query API we can do it "automatically".<br /><br />During the lunch I talked to <a href="http://ceki.blogspot.com/">Ceki Gülcü</a> who is also from Switzerland and giving a talk about logback, the continuation of the dead log4j project, tomorrow. He would make a nice speaker on the <a href="http://www.jugs.ch/">JUGS</a>.<br /><br />Now it's time for tools in action again, first up is <a href="http://www.gradle.org/">Gradle</a>. Hans Dockter is the project lead and he gives an introduction about Gradle. Gradle is a build tool that uses CoC and has a DSL to configure your build. Yet another build tool, but this time is using groovy DSL to make a build file. I also <a href="http://ctpjava.blogspot.com/2009/09/maven-3-early-access.html">blogged</a> that Maven3 is also going to provide this. I don't know what Hans is trying to explain to me or how this is better than Maven3, but he is a bit chaotic. After a while there is a new speaker that is even worse. I think there are some good options in Gradle, but these are not the guys to explain it to me. One thing I did get from the presentation that you could fork your test over more threads, which is cool.<br /><br />Next up is <a href="http://devoxx.com/display/DV09/Scala+Actors" title="Scala Actors">Scala Actors</a> that will be a good one. You all know of course that <a href="http://www.scala-lang.org/">Scala</a><span id="breadcrumb-display" class="breadcrumbs"> is a language on top of the JVM and developed in Switzerland. Because computers are getting more and more processors, functional languages like Scala could be very useful for this, because they are stateless and you don't need to think about how to distribute the work. After a little history lesson, </span><a href="http://devoxx.com/display/DV09/Scala+Actors" title="Scala Actors">Frank Sommers</a> gave us a concrete example of how Actors can be used in Scala. It's great, a lot of stuff you get for free. Of course the concept of Actors is not bound to Scala, but there are things that Scala offers that make Scala a good language to use with Actors. For instance types in Scala are immutable by default. Great talk and when I'm going to type synchronized in code again I must remember this talk.<br /><br />That is it for day number 2, it was a fun packed day and I look forward to tomorrow. One more thing I noticed today if you want to present on Devoxx you'll need a Mac and <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-3305419975676030648.post-23146889438574530252009-11-16T12:38:00.018+01:002009-11-17T09:35:03.946+01:00Devoxx day 1<a href="http://www.devoxxx.com/">Devoxx</a> is probably the largest European Java Conference. As it always takes place at the end of the year and approximately half a year later than big brother JavaOne, it's a good time to get the stuff again that has been announced at JavaOne and to see how the news and forecasts have been adopted in the meanwhile.<br /><br />When I think of Belgium I think of beer, bars, chocolate, hospitality and cosiness. But when I arrived and saw my hotel all these feelings went away. The location of my hotel and the conference is in an industrial part of Antwerp. There is nothing here but harbours and sea containers. So there is absolutely nothing distracting me from attending the sessions :D<br /><br />So my first session of the day was about <a href="http://jbpm.org/">jBpm 4</a> and that was very impressive, I've used jBpm in the past together with <a href="http://www.seamframework.org/">Seam</a>. I wish that I could use it with my last project. They changed a lot the API making deployment and testing easier. The console is now rewritten in GWT, and there is a web app that business people can use to create and modify processes. Also creating screens for tasks now works!<br /><div><br /></div><div>So with the new version they really focused on working together and fixing the issues with regards to configuration. So I'm definitely trying that out. </div><div><br /></div><div>Strange thing about this fist day that I haven't seen any companies yet. Maybe they will only setup their stuff when The conference days are starting. <font style="font-style: italic;">OK update on this: they are building up their stuff now.</font><br /></div><div><br /></div><div>Another important note... I already have my 2 t-shirts and one of them is a limited edition!</div><div><br /></div><div>Next up is <a href="http://devoxx.com/display/DV09/Architecting+Robust+Applications+for+Amazon+EC2" title="Architecting Robust Applications for Amazon EC2">Architecting Robust Applications for Amazon EC2</a> , let's see what they have there.<br /><br />This one was not interesting at all, if I want to know how the <a href="http://aws.amazon.com/ec2/">webservices of amazon</a> work I'll look it up myself. So I switched to a talk from a SUN guy who is clicking stuff together in Netbeans. What he is talking about is interesting. But his demos don't go further than the wizard screens of Netbeans and he is looking all the time to his <a href="http://www.javapassion.com/">webpage</a>.<br /><br />So after the break it was "Tools in Action" time, these sessions are shorter and focused on tools, hence the name. The first one I saw was about <a href="http://devoxx.com/display/DV09/Introducing+Scimpi" title="Introducing Scimpi">Introducing Scimpi</a> a framework rather than an actual tool, build on <a href="http://www.nakedobjects.org/">Naked Objects</a>, but the concept is a bit old and Scimpi is sort of redefining it. I've used <a href="http://metawidget.sourceforge.net/">metawidget</a> for similar things but I think this gives me more control over the output than Scimpi and also has more powerful components that I can use.<br /><div><br /></div>So now the last one of day one <a href="http://devoxx.com/display/DV09/NoSQL+with+Cassandra+and+Hadoop" title="NoSQL with Cassandra and Hadoop">NoSQL with Cassandra and Hadoop</a>. That was a nice introduction and they presented a nice usecase when to throw out the relational database. But I want to know more about it. Let's see if I can find some more talks.<br /><br />All in all it was a very interesting day and let's see what tomorrow brings. </div>Unknownnoreply@blogger.com0