Home > JavaEE > My first Scala servlet (with Eclipse)

My first Scala servlet (with Eclipse)

In this article, I will show you how to tweak Eclipse so that you will be able to code “classical” webapps in Scala.

Note: I know about Lift, I just want to see how Scala can integrate in my existing infrastructure step-by-step.

Setting up your Eclipse project

Eclipse has a plugin(found at the Scala IDE site) that let you help develop with Scala. The plugin is by no mean perfect (autocompletion does not works in Ganymede), but it gets the job done, letting you create Scala projects that automatically compile Scala code with scalac.

The Web Tools Platform, another Eclipse plugin, let you create web application projects that can be deployed to application servers.

Most projects created with one or another Eclipse plugin are compatible with one another. For example, you can create a new Dynamic Web Project, then add a JPA extension and presto, you can now use the Java Persistence API in you project. Likewise, you can add a Vaadin extension to your Web Project and you can use Vaadin in it. These extensions are called “Facets” in Eclipse. Each project can have many facets: Java, JPA, Vaadin, etc. depending on the plugins you installed.

Unfortunately, the Scala plugin does not use the Facet mechanism. Thus, Dynamic Web Projects cannot be enhanced with the Scala facet. Creating a web project that compiles your Scala code requires a little tweaking. First, you should create a simple Dynamic Web Project. Then, open the .project file. If you do not see the file, go to Customize View in the view and uncheck .*resources in the Filter tab (the first one). It should look something like this:



    scala-servlet-example
    
    
    
    
        
            org.eclipse.wst.jsdt.core.javascriptValidator
            
            
        
        
            org.eclipse.jdt.core.javabuilder
            
            
        
        
            org.eclipse.wst.common.project.facet.core.builder
            
            
        
        
            org.eclipse.wst.validation.validationbuilder
            
            
        
    
    
        org.eclipse.jem.workbench.JavaEMFNature
        org.eclipse.wst.common.modulecore.ModuleCoreNature
        org.eclipse.wst.common.project.facet.core.nature
        org.eclipse.jdt.core.javanature
        org.eclipse.wst.jsdt.core.jsNature
    

Replace the org.eclipse.jdt.core.javabuilder with org.scala-ide.sdt.core.scalabuilder. Note: you can remove the Java builder with the IDE but you cannot add another one so hacking the configuration file is a necessary evil. Now add the Scala nature to your project: org.scala-ide.sdt.core.scalanature.

The .project file should now look like this:



    scala-servlet-example
    
    
    
    
        
            org.eclipse.wst.jsdt.core.javascriptValidator
            
            
        
        
            org.scala-ide.sdt.core.scalabuilder
            
            
        
        
            org.eclipse.wst.common.project.facet.core.builder
            
            
        
        
            org.eclipse.wst.validation.validationbuilder
            
            
        
    
    
        org.scala-ide.sdt.core.scalanature
        org.eclipse.jem.workbench.JavaEMFNature
        org.eclipse.wst.common.modulecore.ModuleCoreNature
        org.eclipse.wst.common.project.facet.core.nature
        org.eclipse.jdt.core.javanature
        org.eclipse.wst.jsdt.core.jsNature
    

If you made the right change, you should see a S instead of a J on your project’s icon (and it should keep the globe!).

The last thing to do should be to add the Scala library to your path. Depending on your application server configuration, either add the Scala library to your build path (Build Path -> Configure Build Path -> Add Library -> Scala Library) or manually add the needed library to your WEB-INF/lib folder. You’re all set to create your first Scala servlet!

Creating your servlet

In order to create your servlet “the easy way”, just do New -> Other -> Scala Class. Choose a package (it is a good practice to respect the Java guidelines regarding the class location according to its package name). Choose the HttpServlet as the superclass. Name it however you please and click OK.

It seems to compile but you and I know there will be some problem later since you don’t override the servlet’s doGet() method. Do it:

override def doGet(request:HttpServletRequest, response:HttpServletResponse) {

}

Don’t forget the imports. Let’s use the Scala way:

import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse}

Last but not least, let’s code some things for your servlet to do. Since I’m feeling very innovative, I will print the good old “Hello world!”:

override def doGet(request: HttpServletRequest, response: HttpServletResponse) {

  response setContentType ("text/html")

  val out = response getWriter

  out println """
  
      Scala Servlet
  <body>
      <p>Hello world!"""
  }
}</pre>
<p>Don’t forget to add the servlet to your web.xml and presto, you should see some familiar example, in a familiar IDE, but with some unorthodox language.</p>
<h3>Conclusion</h3>
<p>Once Eclipse correctly set up, it’s pretty straightforward to develop your webapp in Scala. I do hope the next version of the Scala IDE plugin will definitely improve Scala’s integration into Eclipse and WTP further.</p>
<p>Here are the <a href="/wp-content/resources/my-first-scala-servlet/scala-servlet-example.zip" target="_self">sources</a> of the example, in Eclipse format.</p>
<p>To go further:</p>
<ul>
<li>The <a href="http://www.scala-lang.org/" rel="nofollow"  target="_blank" onclick="_gaq.push(['_trackEvent', 'outbound-article', 'http://www.scala-lang.org/', 'Scala Programming Language']);"  target="_blank">Scala Programming Language</a></li>
<li>The <a href="http://www.scala-ide.org/" rel="nofollow"  target="_blank" onclick="_gaq.push(['_trackEvent', 'outbound-article', 'http://www.scala-ide.org/', 'Scala IDE']);"  target="_blank">Scala IDE</a> site</li>
<li><a href="http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees" rel="nofollow"  target="_blank" onclick="_gaq.push(['_trackEvent', 'outbound-article', 'http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees', 'Scala for Java refugees']);"  target="_blank">Scala for Java refugees</a></li>
</ul>
<a id="dd_end"></a><div class='dd_outer'><div class='dd_inner'><div id='dd_ajax_float'><div class='dd_button_v'><div class='dd-google1-ajax-load dd-google1-1345'></div><g:plusone size='tall' href='http://blog.frankel.ch/my-first-scala-servlet'></g:plusone></div><div style='clear:left'></div><div class='dd_button_v'><div class='dd-linkedin-ajax-load dd-linkedin-1345'></div><script type='IN/share' data-url='http://blog.frankel.ch/my-first-scala-servlet' data-counter='top'></script></div><div style='clear:left'></div><div class='dd_button_v'><div class='dd-twitter-ajax-load dd-twitter-1345'></div><a href="http://twitter.com/share" rel="nofollow"  target="_blank" onclick="_gaq.push(['_trackEvent', 'outbound-article', 'http://twitter.com/share', '']);"  class="twitter-share-button" data-url="http://blog.frankel.ch/my-first-scala-servlet" data-count="vertical" data-text="My first Scala servlet (with Eclipse)" data-via="nicolas_frankel"></a></div><div style='clear:left'></div><div class='dd_button_v'><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:like href="http://blog.frankel.ch/my-first-scala-servlet" send="true" show_faces="false"  layout="box_count" width="50"  ></fb:like></div><div style='clear:left'></div><div class='dd_button_extra_v'><script type="text/javascript">jQuery(document).load(function(){ stLight.options({publisher:''}); });</script><div class="st_email_custom"><span id='dd_email_text'>email</span></div></div><div style='clear:left'></div><div id='dd_name'><a href="http://bufferapp.com/diggdigg" rel="nofollow"  target="_blank" onclick="_gaq.push(['_trackEvent', 'outbound-article', 'http://bufferapp.com/diggdigg', 'Digg Digg']);"  target='_blank'>Digg Digg</a></div></div></div></div><script type="text/javascript">var dd_offset_from_content = 45;var dd_top_offset_from_content = 0;var dd_override_start_anchor_id = "";var dd_override_top_offset = "";</script><script type="text/javascript" src="http://blog.frankel.ch/wp-content/plugins/digg-digg//js/diggdigg-floating-bar.js?ver=5.3.6"></script><script type="text/javascript"> jQuery(document).ready(function($) { window.setTimeout('loadGoogle1_1345()',1000);window.setTimeout('loadLinkedin_1345()',1000);window.setTimeout('loadTwitter_1345()',1000); }); </script><script type="text/javascript"> function loadGoogle1_1345(){ jQuery(document).ready(function($) { $('.dd-google1-1345').remove();$.getScript('https://apis.google.com/js/plusone.js'); }); } function loadLinkedin_1345(){ jQuery(document).ready(function($) { $('.dd-linkedin-1345').remove();$.getScript('http://platform.linkedin.com/in.js'); }); } function loadTwitter_1345(){ jQuery(document).ready(function($) { $('.dd-twitter-1345').remove();$.getScript('http://platform.twitter.com/widgets.js'); }); }</script><div class='kindleWidget kindleLight' style='font-family: arial;'><img src="http://blog.frankel.ch/wp-content/plugins/send-to-kindle/media/white-15.png" /><span>Send to Kindle</span></div>			<div class="fixed"></div>
		</div>
		<div class="under">
			<span class="categories">Categories: </span><span><a href="http://blog.frankel.ch/category/tech/dev/java/javaee" rel="category tag">JavaEE</a></span>			<span class="tags">Tags: </span><span><a href="http://blog.frankel.ch/tag/eclipse" rel="tag">eclipse</a>, <a href="http://blog.frankel.ch/tag/scala" rel="tag">scala</a></span>		</div>
	</div>

	<!-- related posts START -->
		<!-- related posts END -->

	<script type="text/javascript" src="http://blog.frankel.ch/wp-content/themes/inove/js/comment.js"></script>



<div id="comments">

<div id="cmtswitcher">
			<a id="commenttab" class="curtab" href="javascript:void(0);" onclick="MGJS.switchTab('thecomments,commentnavi', 'thetrackbacks', 'commenttab', 'curtab', 'trackbacktab', 'tab');">Comments (2)</a>
		<a id="trackbacktab" class="tab" href="javascript:void(0);" onclick="MGJS.switchTab('thetrackbacks', 'thecomments,commentnavi', 'trackbacktab', 'curtab', 'commenttab', 'tab');">Trackbacks (0)</a>
				<span class="addcomment"><a href="#respond">Leave a comment</a></span>
				<span class="addtrackback"><a href="http://blog.frankel.ch/my-first-scala-servlet/trackback">Trackback</a></span>
		<div class="fixed"></div>
</div>

<div id="commentlist">
	<!-- comments START -->
	<ol id="thecomments">
		<li class="comment regularcomment" id="comment-3564">
		<div class="author">
			<div class="pic">
				<img alt='' src='http://0.gravatar.com/avatar/c66fb39909abcb18afadb1a5ff1b6f4f?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' />			</div>
			<div class="name">
									<span id="commentauthor-3564">
				
				Mohammed
									</span>
							</div>
		</div>

		<div class="info">
			<div class="date">
				March 27th, 2013 at 17:16					 | <a href="#comment-3564">#1</a>
			</div>
			<div class="act">
				<a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-3564', 'comment-3564', 'comment');">Reply</a> | 
				<a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-3564', 'comment-3564', 'commentbody-3564', 'comment');">Quote</a>
							</div>
			<div class="fixed"></div>
			<div class="content">
				
				<div id="commentbody-3564">
					<p>Hi,<br />
Thank’s for the tuto !<br />
But I have a problem, when I run this web application on a server, I get a blanck page on my navigator?!</p>
<p>Med</p>
				</div>
			</div>
		</div>
		<div class="fixed"></div>

</li><!-- #comment-## -->
	<li class="comment regularcomment" id="comment-3714">
		<div class="author">
			<div class="pic">
				<img alt='' src='http://1.gravatar.com/avatar/d6af45aedf026842b744247eeda71083?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' />			</div>
			<div class="name">
									<span id="commentauthor-3714">
				
				raw thinktank
									</span>
							</div>
		</div>

		<div class="info">
			<div class="date">
				March 31st, 2013 at 14:14					 | <a href="#comment-3714">#2</a>
			</div>
			<div class="act">
				<a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-3714', 'comment-3714', 'comment');">Reply</a> | 
				<a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-3714', 'comment-3714', 'commentbody-3714', 'comment');">Quote</a>
							</div>
			<div class="fixed"></div>
			<div class="content">
				
				<div id="commentbody-3714">
					<p>it all a HUGE SCAM</p>
<p>or else there would had been a servlet Plugin for Eclipse, where we could just say, File -> new- Scala Servlet Project.</p>
<p>and guess what, Scala IE cant debug it.</p>
				</div>
			</div>
		</div>
		<div class="fixed"></div>

</li><!-- #comment-## -->
	</ol>
	<!-- comments END -->


	<!-- trackbacks START -->
			<ol id="thetrackbacks">
							<li class="messagebox">
					No trackbacks yet.				</li>

					</ol>
		<div class="fixed"></div>
	<!-- trackbacks END -->
</div>

</div>

	<form action="http://blog.frankel.ch/wp-comments-post.php" method="post" id="commentform">
	<div id="respond">

					
			<div id="author_info">
				<div class="row">
					<input type="text" name="author" id="author" class="textfield" value="" size="24" tabindex="1" />
					<label for="author" class="small">Name (required)</label>
				</div>
				<div class="row">
					<input type="text" name="email" id="email" class="textfield" value="" size="24" tabindex="2" />
					<label for="email" class="small">E-Mail (will not be published) (required)</label>
				</div>
				<div class="row">
					<input type="text" name="url" id="url" class="textfield" value="" size="24" tabindex="3" />
					<label for="url" class="small">Website</label>
				</div>
			</div>

			
		
		<!-- comment input -->
		<div class="row">
			<textarea name="comment" id="comment" tabindex="4" rows="8" cols="50"></textarea>
		</div>

		<!-- comment submit and rss -->
		<div id="submitbox">
			<a class="feed" href="http://blog.frankel.ch/comments/feed">Subscribe to comments feed</a>
			<div class="submitbutton">
				<input name="submit" type="submit" id="submit" class="button" tabindex="5" value="Submit Comment" />
			</div>
						<input type="hidden" name="comment_post_ID" value="1345" />
			<div class="fixed"></div>
		</div>

	</div>
		<script type='text/javascript'>
	<!--
	refJS = escape( document[ 'referrer' ] );
	document.write("<input type='hidden' name='refJS' value='"+refJS+"'>");
	// -->
	</script>
	<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="85235de1bf" /></p><noscript><p><strong>Currently you have JavaScript disabled. In order to post comments, please make sure JavaScript and Cookies are enabled, and reload the page.</strong> <a href="http://www.google.com/support/bin/answer.py?answer=23852" rel="nofollow external" >Click here for instructions</a> on how to enable JavaScript in your browser.</p></noscript>
<p style="display: none;"><input type="hidden" id="ak_js" name="ak_js" value="227"/></p>	</form>

	

	<div id="postnavi">
		<span class="prev"><a href="http://blog.frankel.ch/softshake-2010" rel="next">SoftShake 2010</a></span>
		<span class="next"><a href="http://blog.frankel.ch/hibernate-hard-facts-part-6" rel="prev">Hibernate hard facts – Part 6</a></span>
		<div class="fixed"></div>
	</div>


	</div>
	<!-- main END -->

	
<!-- sidebar START -->
<div id="sidebar">

<!-- sidebar north START -->
<div id="northsidebar" class="sidebar">

	<!-- feeds -->
	<div class="widget widget_feeds">
		<div class="content">
			<div id="subscribe">
				<a rel="external nofollow" id="feedrss" title="Subscribe to this blog..." href="http://blog.frankel.ch/feed"><abbr title="Really Simple Syndication">RSS</abbr></a>
							</div>
						<div class="fixed"></div>
		</div>
	</div>

	<!-- showcase -->
	
<div id="text-3" class="widget widget_text"><h3>Integration Testing from the Trenches</h3>			<div class="textwidget"><a href="https://leanpub.com/integrationtest/" onclick="_gaq.push(['_trackEvent', 'outbound-widget', 'https://leanpub.com/integrationtest/', '']);" ><img class="alignleft" src="/wp-content/resources/first-release-of-integration-testing-from-the-trenches/cover.png" /></a>Software is becoming more complex day-by-day and without a test harness, maintenance will be near impossible. Although unit testing and TDD have become mainstream, neither is enough to guarantee bug-free software. That's where integration tests enter the scene.</div>
		</div><div id="text-2" class="widget widget_text"><h3>Learning Vaadin 7</h3>			<div class="textwidget"><p><a href="http://www.packtpub.com/learning-vaadin-7-second-edition/book" onclick="_gaq.push(['_trackEvent', 'outbound-widget', 'http://www.packtpub.com/learning-vaadin-7-second-edition/book', '']);" ><img class="alignleft" src="/wp-content/resources/learning-vaadin-7-is-out/9772OS.jpg" /></a>Learning Vaadin is a practical step-by-step tutorial to understanding, using, and mastering the art of RIA development with Vaadin. You will learn about the fundamental concepts that are the cornerstones of the framework, at the same time making progress on building your own web application. The book will also show you how to integrate Vaadin with other popular frameworks and how to run it on top of internal as well as externalized infrastructures.</p>
</div>
		</div><div id="advman-3" class="widget Advman_Widget"><h3></h3><script type="text/javascript"><!--
google_ad_client = "pub-1912713618652264";
/* 160x600, date de création 13/09/10 */
google_ad_slot = "1401534104";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>		<div id="recent-posts-2" class="widget widget_recent_entries">		<h3>Recent Posts</h3>		<ul>
					<li>
				<a href="http://blog.frankel.ch/avoid-conditional-logic-in-configuration">Avoid conditional logic in @Configuration</a>
						</li>
					<li>
				<a href="http://blog.frankel.ch/from-vaadin-to-docker-a-novices-journey">From Vaadin to Docker, a novice’s journey</a>
						</li>
					<li>
				<a href="http://blog.frankel.ch/metrics-metrics-everywhere">Metrics, metrics everywhere</a>
						</li>
					<li>
				<a href="http://blog.frankel.ch/dear-recruiters">Dear recruiters</a>
						</li>
					<li>
				<a href="http://blog.frankel.ch/integration-testing-around-europe">Integration Testing around Europe</a>
						</li>
				</ul>
		</div>	        <div id="wp-cumulus" class="widget wp_cumulus_widget">						<!-- SWFObject embed by Geoff Stearns geoff@deconcept.com http://blog.deconcept.com/swfobject/ --><script type="text/javascript" src="http://blog.frankel.ch/wp-content/plugins/wp-cumulus/swfobject.js"></script><div id="wpcumuluswidgetcontent1559500"><p><a href='http://blog.frankel.ch/tag/angularjs' class='tag-link-334' title='3 topics' style='font-size: 9.4867256637168pt;'>angularjs</a>
<a href='http://blog.frankel.ch/tag/architecture' class='tag-link-129' title='4 topics' style='font-size: 10.725663716814pt;'>Architecture</a>
<a href='http://blog.frankel.ch/tag/book' class='tag-link-155' title='4 topics' style='font-size: 10.725663716814pt;'>book</a>
<a href='http://blog.frankel.ch/tag/cdi' class='tag-link-263' title='9 topics' style='font-size: 14.442477876106pt;'>CDI</a>
<a href='http://blog.frankel.ch/tag/configuration' class='tag-link-119' title='3 topics' style='font-size: 9.4867256637168pt;'>configuration</a>
<a href='http://blog.frankel.ch/tag/custom' class='tag-link-142' title='3 topics' style='font-size: 9.4867256637168pt;'>custom</a>
<a href='http://blog.frankel.ch/tag/design' class='tag-link-133' title='3 topics' style='font-size: 9.4867256637168pt;'>design</a>
<a href='http://blog.frankel.ch/tag/design-pattern' class='tag-link-152' title='3 topics' style='font-size: 9.4867256637168pt;'>design pattern</a>
<a href='http://blog.frankel.ch/tag/devoxx' class='tag-link-304' title='10 topics' style='font-size: 14.938053097345pt;'>devoxx</a>
<a href='http://blog.frankel.ch/tag/dry' class='tag-link-261' title='3 topics' style='font-size: 9.4867256637168pt;'>dry</a>
<a href='http://blog.frankel.ch/tag/eclipse' class='tag-link-151' title='4 topics' style='font-size: 10.725663716814pt;'>eclipse</a>
<a href='http://blog.frankel.ch/tag/hibernate' class='tag-link-62' title='14 topics' style='font-size: 16.672566371681pt;'>hibernate</a>
<a href='http://blog.frankel.ch/tag/integration-testing' class='tag-link-311' title='5 topics' style='font-size: 11.716814159292pt;'>integration testing</a>
<a href='http://blog.frankel.ch/tag/java' class='tag-link-5' title='5 topics' style='font-size: 11.716814159292pt;'>Java</a>
<a href='http://blog.frankel.ch/tag/javaconfig' class='tag-link-333' title='4 topics' style='font-size: 10.725663716814pt;'>javaconfig</a>
<a href='http://blog.frankel.ch/tag/javascript' class='tag-link-337' title='3 topics' style='font-size: 9.4867256637168pt;'>javascript</a>
<a href='http://blog.frankel.ch/tag/jboss' class='tag-link-172' title='4 topics' style='font-size: 10.725663716814pt;'>jboss</a>
<a href='http://blog.frankel.ch/tag/jpa' class='tag-link-60' title='3 topics' style='font-size: 9.4867256637168pt;'>jpa</a>
<a href='http://blog.frankel.ch/tag/logging' class='tag-link-122' title='3 topics' style='font-size: 9.4867256637168pt;'>logging</a>
<a href='http://blog.frankel.ch/tag/m2eclipse' class='tag-link-166' title='3 topics' style='font-size: 9.4867256637168pt;'>m2eclipse</a>
<a href='http://blog.frankel.ch/tag/maven' class='tag-link-167' title='20 topics' style='font-size: 18.407079646018pt;'>maven</a>
<a href='http://blog.frankel.ch/tag/method-injection' class='tag-link-316' title='3 topics' style='font-size: 9.4867256637168pt;'>method injection</a>
<a href='http://blog.frankel.ch/tag/open-source' class='tag-link-47' title='3 topics' style='font-size: 9.4867256637168pt;'>open source</a>
<a href='http://blog.frankel.ch/tag/opensource' class='tag-link-46' title='3 topics' style='font-size: 9.4867256637168pt;'>opensource</a>
<a href='http://blog.frankel.ch/tag/persistence' class='tag-link-61' title='6 topics' style='font-size: 12.58407079646pt;'>persistence</a>
<a href='http://blog.frankel.ch/tag/proxy' class='tag-link-93' title='3 topics' style='font-size: 9.4867256637168pt;'>proxy</a>
<a href='http://blog.frankel.ch/tag/quality' class='tag-link-48' title='4 topics' style='font-size: 10.725663716814pt;'>quality</a>
<a href='http://blog.frankel.ch/tag/scala' class='tag-link-273' title='12 topics' style='font-size: 15.805309734513pt;'>scala</a>
<a href='http://blog.frankel.ch/tag/security' class='tag-link-83' title='8 topics' style='font-size: 13.823008849558pt;'>security</a>
<a href='http://blog.frankel.ch/tag/sonar' class='tag-link-45' title='3 topics' style='font-size: 9.4867256637168pt;'>sonar</a>
<a href='http://blog.frankel.ch/tag/spring' class='tag-link-49' title='40 topics' style='font-size: 22pt;'>spring</a>
<a href='http://blog.frankel.ch/tag/spring-data' class='tag-link-315' title='3 topics' style='font-size: 9.4867256637168pt;'>spring data</a>
<a href='http://blog.frankel.ch/tag/spring-mvc' class='tag-link-347' title='4 topics' style='font-size: 10.725663716814pt;'>Spring MVC</a>
<a href='http://blog.frankel.ch/tag/sun' class='tag-link-7' title='2 topics' style='font-size: 8pt;'>sun</a>
<a href='http://blog.frankel.ch/tag/swing' class='tag-link-265' title='3 topics' style='font-size: 9.4867256637168pt;'>Swing</a>
<a href='http://blog.frankel.ch/tag/taglib' class='tag-link-12' title='3 topics' style='font-size: 9.4867256637168pt;'>taglib</a>
<a href='http://blog.frankel.ch/tag/test' class='tag-link-90' title='9 topics' style='font-size: 14.442477876106pt;'>test</a>
<a href='http://blog.frankel.ch/tag/testng' class='tag-link-30' title='6 topics' style='font-size: 12.58407079646pt;'>testng</a>
<a href='http://blog.frankel.ch/tag/tomcat' class='tag-link-79' title='5 topics' style='font-size: 11.716814159292pt;'>tomcat</a>
<a href='http://blog.frankel.ch/tag/unit-testing' class='tag-link-96' title='5 topics' style='font-size: 11.716814159292pt;'>unit testing</a>
<a href='http://blog.frankel.ch/tag/vaadin' class='tag-link-257' title='16 topics' style='font-size: 17.29203539823pt;'>vaadin</a>
<a href='http://blog.frankel.ch/tag/validation' class='tag-link-224' title='3 topics' style='font-size: 9.4867256637168pt;'>validation</a>
<a href='http://blog.frankel.ch/tag/web' class='tag-link-25' title='5 topics' style='font-size: 11.716814159292pt;'>web</a>
<a href='http://blog.frankel.ch/tag/webapp' class='tag-link-240' title='3 topics' style='font-size: 9.4867256637168pt;'>webapp</a>
<a href='http://blog.frankel.ch/tag/xml' class='tag-link-137' title='4 topics' style='font-size: 10.725663716814pt;'>xml</a></p><p>WP Cumulus Flash tag cloud by <a href="http://www.roytanck.com">Roy Tanck</a> and <a href="http://lukemorton.co.uk/">Luke Morton</a> requires <a href="http://www.macromedia.com/go/getflashplayer">Flash Player</a> 9 or better.</p></div><script type="text/javascript">var widget_so7322084 = new SWFObject("http://blog.frankel.ch/wp-content/plugins/wp-cumulus/tagcloud.swf?r=1081283", "tagcloudflash", "260", "260", "9", "#ffffff");widget_so7322084.addParam("wmode", "transparent");widget_so7322084.addParam("allowScriptAccess", "always");widget_so7322084.addVariable("tcolor", "0x2970a6");widget_so7322084.addVariable("tcolor2", "0x2970a6");widget_so7322084.addVariable("hicolor", "0xFF0000");widget_so7322084.addVariable("tspeed", "100");widget_so7322084.addVariable("distr", "true");widget_so7322084.addVariable("mode", "tags");widget_so7322084.addVariable("tagcloud", "%3Ctags%3E%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fangularjs%27+class%3D%27tag-link-334%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Eangularjs%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Farchitecture%27+class%3D%27tag-link-129%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3EArchitecture%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fbook%27+class%3D%27tag-link-155%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Ebook%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fcdi%27+class%3D%27tag-link-263%27+title%3D%279+topics%27+style%3D%27font-size%3A+14.442477876106pt%3B%27%3ECDI%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fconfiguration%27+class%3D%27tag-link-119%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Econfiguration%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fcustom%27+class%3D%27tag-link-142%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Ecustom%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fdesign%27+class%3D%27tag-link-133%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Edesign%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fdesign-pattern%27+class%3D%27tag-link-152%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Edesign+pattern%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fdevoxx%27+class%3D%27tag-link-304%27+title%3D%2710+topics%27+style%3D%27font-size%3A+14.938053097345pt%3B%27%3Edevoxx%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fdry%27+class%3D%27tag-link-261%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Edry%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Feclipse%27+class%3D%27tag-link-151%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Eeclipse%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fhibernate%27+class%3D%27tag-link-62%27+title%3D%2714+topics%27+style%3D%27font-size%3A+16.672566371681pt%3B%27%3Ehibernate%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fintegration-testing%27+class%3D%27tag-link-311%27+title%3D%275+topics%27+style%3D%27font-size%3A+11.716814159292pt%3B%27%3Eintegration+testing%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fjava%27+class%3D%27tag-link-5%27+title%3D%275+topics%27+style%3D%27font-size%3A+11.716814159292pt%3B%27%3EJava%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fjavaconfig%27+class%3D%27tag-link-333%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Ejavaconfig%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fjavascript%27+class%3D%27tag-link-337%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Ejavascript%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fjboss%27+class%3D%27tag-link-172%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Ejboss%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fjpa%27+class%3D%27tag-link-60%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Ejpa%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Flogging%27+class%3D%27tag-link-122%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Elogging%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fm2eclipse%27+class%3D%27tag-link-166%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Em2eclipse%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fmaven%27+class%3D%27tag-link-167%27+title%3D%2720+topics%27+style%3D%27font-size%3A+18.407079646018pt%3B%27%3Emaven%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fmethod-injection%27+class%3D%27tag-link-316%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Emethod+injection%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fopen-source%27+class%3D%27tag-link-47%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Eopen+source%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fopensource%27+class%3D%27tag-link-46%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Eopensource%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fpersistence%27+class%3D%27tag-link-61%27+title%3D%276+topics%27+style%3D%27font-size%3A+12.58407079646pt%3B%27%3Epersistence%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fproxy%27+class%3D%27tag-link-93%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Eproxy%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fquality%27+class%3D%27tag-link-48%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Equality%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fscala%27+class%3D%27tag-link-273%27+title%3D%2712+topics%27+style%3D%27font-size%3A+15.805309734513pt%3B%27%3Escala%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fsecurity%27+class%3D%27tag-link-83%27+title%3D%278+topics%27+style%3D%27font-size%3A+13.823008849558pt%3B%27%3Esecurity%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fsonar%27+class%3D%27tag-link-45%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Esonar%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fspring%27+class%3D%27tag-link-49%27+title%3D%2740+topics%27+style%3D%27font-size%3A+22pt%3B%27%3Espring%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fspring-data%27+class%3D%27tag-link-315%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Espring+data%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fspring-mvc%27+class%3D%27tag-link-347%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3ESpring+MVC%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fsun%27+class%3D%27tag-link-7%27+title%3D%272+topics%27+style%3D%27font-size%3A+8pt%3B%27%3Esun%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fswing%27+class%3D%27tag-link-265%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3ESwing%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Ftaglib%27+class%3D%27tag-link-12%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Etaglib%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Ftest%27+class%3D%27tag-link-90%27+title%3D%279+topics%27+style%3D%27font-size%3A+14.442477876106pt%3B%27%3Etest%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Ftestng%27+class%3D%27tag-link-30%27+title%3D%276+topics%27+style%3D%27font-size%3A+12.58407079646pt%3B%27%3Etestng%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Ftomcat%27+class%3D%27tag-link-79%27+title%3D%275+topics%27+style%3D%27font-size%3A+11.716814159292pt%3B%27%3Etomcat%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Funit-testing%27+class%3D%27tag-link-96%27+title%3D%275+topics%27+style%3D%27font-size%3A+11.716814159292pt%3B%27%3Eunit+testing%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fvaadin%27+class%3D%27tag-link-257%27+title%3D%2716+topics%27+style%3D%27font-size%3A+17.29203539823pt%3B%27%3Evaadin%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fvalidation%27+class%3D%27tag-link-224%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Evalidation%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fweb%27+class%3D%27tag-link-25%27+title%3D%275+topics%27+style%3D%27font-size%3A+11.716814159292pt%3B%27%3Eweb%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fwebapp%27+class%3D%27tag-link-240%27+title%3D%273+topics%27+style%3D%27font-size%3A+9.4867256637168pt%3B%27%3Ewebapp%3C%2Fa%3E%0A%3Ca+href%3D%27http%3A%2F%2Fblog.frankel.ch%2Ftag%2Fxml%27+class%3D%27tag-link-137%27+title%3D%274+topics%27+style%3D%27font-size%3A+10.725663716814pt%3B%27%3Exml%3C%2Fa%3E%3C%2Ftags%3E");widget_so7322084.write("wpcumuluswidgetcontent1559500");</script>	        </div>		<div id="recent-comments-2" class="widget widget_recent_comments"><h3>Recent Comments</h3><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href='http://www.flowstopper.org/' rel='external nofollow' class='url'>Fabian Kessler</a></span> on <a href="http://blog.frankel.ch/throwing-a-nullpointerexception-or-not/comment-page-1#comment-28404">Throwing a NullPointerException… or not</a></li><li class="recentcomments"><span class="comment-author-link"><a href='http://frankel.ch' rel='external nofollow' class='url'>Nicolas Frankel</a></span> on <a href="http://blog.frankel.ch/your-code-coverage-metric-is-not-meaningful/comment-page-1#comment-28322">Your code coverage metric is not meaningful</a></li><li class="recentcomments"><span class="comment-author-link">Marcus K.</span> on <a href="http://blog.frankel.ch/your-code-coverage-metric-is-not-meaningful/comment-page-1#comment-28319">Your code coverage metric is not meaningful</a></li><li class="recentcomments"><span class="comment-author-link"><a href='http://frankel.ch' rel='external nofollow' class='url'>Nicolas Frankel</a></span> on <a href="http://blog.frankel.ch/avoid-conditional-logic-in-configuration/comment-page-1#comment-27398">Avoid conditional logic in @Configuration</a></li><li class="recentcomments"><span class="comment-author-link"><a href='http://olivergierke.de' rel='external nofollow' class='url'>Oliver Gierke</a></span> on <a href="http://blog.frankel.ch/avoid-conditional-logic-in-configuration/comment-page-1#comment-27326">Avoid conditional logic in @Configuration</a></li></ul></div></div>
<!-- sidebar north END -->

<div id="centersidebar">

	<!-- sidebar east START -->
	<div id="eastsidebar" class="sidebar">
	

		</div>
	<!-- sidebar east END -->

	<!-- sidebar west START -->
	<div id="westsidebar" class="sidebar">
	

		</div>
	<!-- sidebar west END -->
	<div class="fixed"></div>
</div>

<!-- sidebar south START -->
<div id="southsidebar" class="sidebar">


</div>
<!-- sidebar south END -->

</div>
<!-- sidebar END -->
	<div class="fixed"></div>
</div>
<!-- content END -->

<!-- footer START -->
<div id="footer">
	<a id="gotop" href="#" onclick="MGJS.goTop();return false;">Top</a>
	<a id="powered" href="http://wordpress.org/">WordPress</a>
	<div id="copyright">
		Copyright © 2008-2014 A Java geek	</div>
	<div id="themeinfo">
		Theme by <a href="http://www.neoease.com/">NeoEase</a>. Valid <a href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS 3</a>.	</div>
</div>
<!-- footer END -->

</div>
<!-- container END -->
</div>
<!-- wrap END -->

		<!-- Advertising Manager v3.5.1 (0.329 seconds.) -->
<!-- Powered by WPtouch: 3.6.3 --><script type='text/javascript' src='http://blog.frankel.ch/wp-content/plugins/akismet/_inc/form.js?ver=3.0.4'></script>
<script type='text/javascript' src='http://blog.frankel.ch/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shCore.js?ver=3.0.9'></script>
<script type='text/javascript' src='http://blog.frankel.ch/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushXml.js?ver=3.0.9'></script>
<script type='text/javascript' src='http://blog.frankel.ch/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushScala.js?ver=3.0.9'></script>
<script type='text/javascript'>
	(function(){
		var corecss = document.createElement('link');
		var themecss = document.createElement('link');
		var corecssurl = "http://blog.frankel.ch/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shCore.css?ver=3.0.9";
		if ( corecss.setAttribute ) {
				corecss.setAttribute( "rel", "stylesheet" );
				corecss.setAttribute( "type", "text/css" );
				corecss.setAttribute( "href", corecssurl );
		} else {
				corecss.rel = "stylesheet";
				corecss.href = corecssurl;
		}
		document.getElementsByTagName("head")[0].insertBefore( corecss, document.getElementById("syntaxhighlighteranchor") );
		var themecssurl = "http://blog.frankel.ch/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shThemeEclipse.css?ver=3.0.9";
		if ( themecss.setAttribute ) {
				themecss.setAttribute( "rel", "stylesheet" );
				themecss.setAttribute( "type", "text/css" );
				themecss.setAttribute( "href", themecssurl );
		} else {
				themecss.rel = "stylesheet";
				themecss.href = themecssurl;
		}
		//document.getElementById("syntaxhighlighteranchor").appendChild(themecss);
		document.getElementsByTagName("head")[0].insertBefore( themecss, document.getElementById("syntaxhighlighteranchor") );
	})();
	SyntaxHighlighter.config.strings.expandSource = '+ expand source';
	SyntaxHighlighter.config.strings.help = '?';
	SyntaxHighlighter.config.strings.alert = 'SyntaxHighlighter\n\n';
	SyntaxHighlighter.config.strings.noBrush = 'Can\'t find brush for: ';
	SyntaxHighlighter.config.strings.brushNotHtmlScript = 'Brush wasn\'t configured for html-script option: ';
	SyntaxHighlighter.defaults['pad-line-numbers'] = true;
	SyntaxHighlighter.defaults['tab-size'] = 2;
	SyntaxHighlighter.all();
</script>
<script type='text/javascript' src='http://w.sharethis.com/button/buttons.js?ver=4.1'></script>
<script type='text/javascript'>
/* <![CDATA[ */
(function k(){window.$SendToKindle&&window.$SendToKindle.Widget?$SendToKindle.Widget.init({"title":".entry-title","published":".entry-date","content":".post","exclude":".sharedaddy"}):setTimeout(k,500);})();
/* ]]> */
</script>
<script type='text/javascript' src='http://d1xnn692s7u6t6.cloudfront.net/widget.js'></script>

</body>
</html>