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

<channel>
	<title>Javatech &#187; Open Source</title>
	<atom:link href="http://javatech.org/category/open-source/feed/" rel="self" type="application/rss+xml" />
	<link>http://javatech.org</link>
	<description>The Bleeding Edge of Java Technology</description>
	<lastBuildDate>Wed, 24 Jun 2009 22:30:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Conventionally Annotated Configuration &#8211; Spring, Hibernate, Eclipse</title>
		<link>http://javatech.org/2009/02/a-conventionally-annotated-configuration-spring-hibernate-eclipse/</link>
		<comments>http://javatech.org/2009/02/a-conventionally-annotated-configuration-spring-hibernate-eclipse/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 07:31:29 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://javatech.org/2009/02/18/a-conventionally-annotated-configuration-spring-hibernate-eclipse/</guid>
		<description><![CDATA[I&#8217;m starting on a personal project and decided I was going to take the time to do things right.  This means different things to different folks, but to me it basically entails:

Using the latest and greatest versions of everything.  Eclipse 3.4.  Hibernate 3.3.1.  Spring 2.5.6.  Tomcat 6.  Maven 2.0.9.  Java 6 ( 7? ), DWR [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m starting on a personal project and decided I was going to take the time to do things right.  This means different things to different folks, but to me it basically entails:</p>
<ol>
<li>Using the latest and greatest versions of everything.  Eclipse 3.4.  Hibernate 3.3.1.  Spring 2.5.6.  Tomcat 6.  Maven 2.0.9.  Java 6 ( 7? ), DWR 3.0.</li>
<li>Using Eclipse plugins to do as much as possible without causing headaches</li>
<li>Using as little XML configuration as possible &#8211; conventions, conventions, conventions!!!</li>
<li>Using JPA annotations for ORM classes.</li>
<li>Using Annotations for IOC dependencies.</li>
<li>Using Annotations for Transactional demarcation.</li>
<li>Using Annotations for MVC mappings.</li>
<li>Using very basic JSTL-based JSP&#8217;s for views.</li>
<li>Using Sitemesh to present a uniform look and feel across all pages.</li>
<li>For icing on the cake I&#8217;d like to also include GWT components.</li>
</ol>
<p><strong>Using the latest and greatest versions of everything</strong><br />
If you install Eclipse 3.4 first, and then install the Maven Integration plugin, it will greatly simplify things.  Just add Maven Integration to your project and then use &#8220;Add Dependency&#8221; option to quickly scour the entire repository and find the exact groupIds, artifactIds, and versions you want.  It also has a great view of the dependency hierarchy!  Getting all of these bleeding-edge versions to play nice together has its fair share of challenges.</p>
<p><strong> Using as little XML configuration as possible</strong></p>
<p><strong>Using Eclipse plugins to do as much as possible without causing headaches</strong></p>
<p>I already mentioned Maven Integration above to help with getting the LAGV of all the technologies being used.  Also of great value and import are SysDeo and  Subclipse.  Sysdeo is great for deploying and debugging your webapp in Tomcat.  Subclipse is great for seamless integration with an SVN repostiory.  Yes &#8211; use SCM on personal projects, you never know when you&#8217;ll need to revert or bring the code down onto a new machine.</p>
<p>But where do we draw the line here?  When do we have so much annotation cruft that an externalized xml configuration will seem like the ideal solution ( from whence we currently come in search of clarity! ).</p>
<p><strong>Using very basic JSTL-based JSP&#8217;s for views</strong><br />
OK &#8211; well, tonight I was getting ready to put together the first couple of jsp&#8217;s now that the @Controller mappings are working and the pages are being served correctly.  I&#8217;ve got the method mapped correctly with @RequestMapping and I&#8217;ve got the model being put into pagescope with @ModelAttribute.  I&#8217;m ready to loop through a List using JSTL forEach.  But wait, can this possibly be true?  Tomcat6 has no implementation of JSTL.  JSTL 1.2 is the LAGV and the JSTL 1.1 is abandoned.  Only *Glassfish* ships with the reference implementation of JSTL 1.2?!?  Oh brother.  Thanks to <a title="Tomcat6 depends on Glassfish?!?" href="http://www.mularien.com/blog/2008/02/19/tutorial-how-to-set-up-tomcat-6-to-work-with-jstl-12/">Peter Mularien for writing a nice post</a> informing me of this.</p>
<p>As if needing to download and install glassfish in order to get the JSTL 1.2 implementation jars for Tomcat6 wasn&#8217;t bad enough, well I hit a couple more snags after that.  First of all, I want to know who decided on the namespaces for JSTL 1.1 vs 1.2.  Here they are:</p>
<p>1.0  == &lt;%@taglib prefix=&#8221;c&#8221; uri=&#8221;http://java.sun.com/jsp/core&#8221; %&gt;</p>
<p>1.1 &amp; 1.2 ==&lt;%@taglib prefix=&#8221;c&#8221; uri=&#8221;http://java.sun.com/jsp/jstl/core&#8221; %&gt;</p>
<p>I mean all they did was add the &#8220;jstl&#8221; into the path?!?  I&#8217;m supposed to remember this?  OK &#8211; I&#8217;ll try harder to remember for next time.</p>
<p>Then, I learned that Maven2 doesn&#8217;t copy &#8220;system&#8221; provided jars into WEB-INF/lib by default and they need to be placed there manually as part of the project.  So, the appserv-jstl.jar I copied from glassfish wasn&#8217;t being included because I linked Maven to it as a system ( vs provided, or compile, or test, etc&#8230; ) dependency.</p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2009/02/a-conventionally-annotated-configuration-spring-hibernate-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connection Pool Showdown</title>
		<link>http://javatech.org/2008/02/connection-pool-showdown/</link>
		<comments>http://javatech.org/2008/02/connection-pool-showdown/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 15:00:54 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=29</guid>
		<description><![CDATA[I put C3P0, DBCP, and Proxool to the test and confirmed that DBCP is the fastest pool in the West, so long as there isn&#8217;t any complicated synchronization being done by the code using DBCP!  C3P0, safe even with complicated synchronization and very, very configurable and robutst, came in a pretty close second.  [...]]]></description>
			<content:encoded><![CDATA[<p>I put C3P0, DBCP, and Proxool to the test and confirmed that DBCP is the fastest pool in the West, so long as there isn&#8217;t any complicated synchronization being done by the code using DBCP!  C3P0, safe even with complicated synchronization and very, very configurable and robutst, came in a pretty close second.  Proxool, the loser in this test, was surprisingly unable to deal with more threads requesting Connections than it&#8217;s maxSize.  It wouldn&#8217;t block, it would instantly throw an Exception.  SO, I made sure that the pool sizes for all 3 were larger than the number of threads which would be concurrently accessing the pools.</p>
<h2><a href="http://javatech.org/wp-content/uploads/2008/03/connection_pool_showdown_2008_03_12__07_36_am.png" title="C3P0, DBCP, and Proxool battle it out"><img src="http://javatech.org/wp-content/uploads/2008/03/connection_pool_showdown_2008_03_12__07_36_am.png" alt="C3P0, DBCP, and Proxool battle it out" /></a></h2>
<h3>Connection Pool Showdown</h3>
<div style='font-size:smaller;font-weight:bolder;'>JVM Version 1.6.0_05-ea<br />
Windows XP[x86] &#8211; 2 processors<br />
31.55MB/254.06MB Memory
</div>
<table border=1>
<tr>
<th>Benchmark</th>
<th>Threads</th>
<th>Avg Nanos</th>
<th>Slow Factor</th>
</tr>
<tr>
<td>DBCP</td>
<td>40</td>
<td>74092.28</td>
<td>1.00x</td>
</tr>
<tr>
<td>DBCP</td>
<td>30</td>
<td>75085.88</td>
<td>1.01x</td>
</tr>
<tr>
<td>DBCP</td>
<td>20</td>
<td>75230.27</td>
<td>1.02x</td>
</tr>
<tr>
<td>DBCP</td>
<td>10</td>
<td>76437.40</td>
<td>1.03x</td>
</tr>
<tr>
<td>C3P0</td>
<td>10</td>
<td>93405.98</td>
<td>1.26x</td>
</tr>
<tr>
<td>C3P0</td>
<td>30</td>
<td>94054.79</td>
<td>1.27x</td>
</tr>
<tr>
<td>C3P0</td>
<td>20</td>
<td>94087.60</td>
<td>1.27x</td>
</tr>
<tr>
<td>C3P0</td>
<td>40</td>
<td>94865.61</td>
<td>1.28x</td>
</tr>
<tr>
<td>DBCP</td>
<td>1</td>
<td>104907.12</td>
<td>1.42x</td>
</tr>
<tr>
<td>C3P0</td>
<td>1</td>
<td>116039.45</td>
<td>1.57x</td>
</tr>
<tr>
<td>Proxool</td>
<td>10</td>
<td>142769.39</td>
<td>1.93x</td>
</tr>
<tr>
<td>Proxool</td>
<td>20</td>
<td>143932.09</td>
<td>1.94x</td>
</tr>
<tr>
<td>Proxool</td>
<td>30</td>
<td>146066.93</td>
<td>1.97x</td>
</tr>
<tr>
<td>Proxool</td>
<td>40</td>
<td>148903.46</td>
<td>2.01x</td>
</tr>
<tr>
<td>Proxool</td>
<td>1</td>
<td>183513.91</td>
<td>2.48x</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2008/02/connection-pool-showdown/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Log4J Conversion Pattern Performance</title>
		<link>http://javatech.org/2008/02/log4j-conversion-pattern-performance/</link>
		<comments>http://javatech.org/2008/02/log4j-conversion-pattern-performance/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 14:59:31 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=27</guid>
		<description><![CDATA[I&#8217;ve seen the warnings before in log4j&#8217;s documentation about the format directives %C, %F, %L, %l and %M, which give really useful information, but at a cost.  Well, what is the cost of using some of these settings?  What if I use them all, or none?  I just had to find out, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve seen the warnings before in log4j&#8217;s documentation about the format directives %C, %F, %L, %l and %M, which give really useful information, but at a cost.  Well, what is the cost of using some of these settings?  What if I use them all, or none?  I just had to find out, here are the results:</p>
<p><a href="http://javatech.org/wp-content/uploads/2008/03/log4j_conversion_patterns_2008_03_12__02_35_am.png" title="log4j_conversion_patterns_2008_03_12__02_35_am.png"><img src="http://javatech.org/wp-content/uploads/2008/03/log4j_conversion_patterns_2008_03_12__02_35_am.png" alt="log4j_conversion_patterns_2008_03_12__02_35_am.png" /></a></p>
<p>These results completely reinforce the fact that the expensive settings %F, %L and %C should not be used in your production environment.  In the unfortunate case that you use all of them, then you&#8217;re looking at ( already expensive ) logging calls taking 9 times longer, verging on millisecond timings.</p>
<h3>Log4J Conversion Patterns</h3>
<p style="font-size: smaller; font-weight: bolder">JVM Version 1.6.0_05-ea<br />
Windows XP[x86] &#8211; 2 processors<br />
5.46MB/63.56MB Memory</p>
<table border="1">
<tr>
<th>Benchmark</th>
<th>Threads</th>
<th>Avg Nanos</th>
<th>Slow Factor</th>
</tr>
<tr>
<td>Fast</td>
<td>1</td>
<td>28825.21</td>
<td>1.00x</td>
</tr>
<tr>
<td>Fast</td>
<td>15</td>
<td>31416.34</td>
<td>1.09x</td>
</tr>
<tr>
<td>Fast</td>
<td>20</td>
<td>32638.25</td>
<td>1.13x</td>
</tr>
<tr>
<td>Fast</td>
<td>5</td>
<td>33509.15</td>
<td>1.16x</td>
</tr>
<tr>
<td>Fast</td>
<td>10</td>
<td>33564.08</td>
<td>1.16x</td>
</tr>
<tr>
<td>Fast</td>
<td>35</td>
<td>34246.23</td>
<td>1.19x</td>
</tr>
<tr>
<td>Fast</td>
<td>50</td>
<td>36421.31</td>
<td>1.26x</td>
</tr>
<tr>
<td>Fast</td>
<td>40</td>
<td>39088.55</td>
<td>1.36x</td>
</tr>
<tr>
<td>Fast</td>
<td>30</td>
<td>39572.70</td>
<td>1.37x</td>
</tr>
<tr>
<td>Fast</td>
<td>45</td>
<td>42566.97</td>
<td>1.48x</td>
</tr>
<tr>
<td>Fast</td>
<td>25</td>
<td>44669.52</td>
<td>1.55x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>1</td>
<td>99596.84</td>
<td>3.46x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>1</td>
<td>109776.19</td>
<td>3.81x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>15</td>
<td>120370.05</td>
<td>4.18x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>20</td>
<td>121903.60</td>
<td>4.23x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>5</td>
<td>122038.00</td>
<td>4.23x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>25</td>
<td>125623.38</td>
<td>4.36x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>35</td>
<td>126799.53</td>
<td>4.40x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>10</td>
<td>127100.32</td>
<td>4.41x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>30</td>
<td>128148.09</td>
<td>4.45x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>40</td>
<td>128208.69</td>
<td>4.45x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>20</td>
<td>131857.94</td>
<td>4.57x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>50</td>
<td>133799.33</td>
<td>4.64x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>10</td>
<td>133837.24</td>
<td>4.64x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>25</td>
<td>134114.84</td>
<td>4.65x</td>
</tr>
<tr>
<td>%F:%L</td>
<td>45</td>
<td>134969.59</td>
<td>4.68x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>35</td>
<td>135091.85</td>
<td>4.69x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>15</td>
<td>138423.94</td>
<td>4.80x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>30</td>
<td>139919.54</td>
<td>4.85x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>5</td>
<td>142347.28</td>
<td>4.94x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>45</td>
<td>144215.52</td>
<td>5.00x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>40</td>
<td>144652.90</td>
<td>5.02x</td>
</tr>
<tr>
<td>%C:%F:%L</td>
<td>50</td>
<td>155159.06</td>
<td>5.38x</td>
</tr>
<tr>
<td>ALL</td>
<td>45</td>
<td>260584.64</td>
<td>9.04x</td>
</tr>
<tr>
<td>ALL</td>
<td>15</td>
<td>260779.51</td>
<td>9.05x</td>
</tr>
<tr>
<td>ALL</td>
<td>40</td>
<td>263862.17</td>
<td>9.15x</td>
</tr>
<tr>
<td>ALL</td>
<td>1</td>
<td>264690.88</td>
<td>9.18x</td>
</tr>
<tr>
<td>ALL</td>
<td>25</td>
<td>266042.80</td>
<td>9.23x</td>
</tr>
<tr>
<td>ALL</td>
<td>35</td>
<td>267562.76</td>
<td>9.28x</td>
</tr>
<tr>
<td>ALL</td>
<td>5</td>
<td>270316.00</td>
<td>9.38x</td>
</tr>
<tr>
<td>ALL</td>
<td>50</td>
<td>272006.58</td>
<td>9.44x</td>
</tr>
<tr>
<td>ALL</td>
<td>10</td>
<td>276599.74</td>
<td>9.60x</td>
</tr>
<tr>
<td>ALL</td>
<td>30</td>
<td>277064.42</td>
<td>9.61x</td>
</tr>
<tr>
<td>ALL</td>
<td>20</td>
<td>286092.27</td>
<td>9.93x</td>
</tr>
</table>
<p>But, then, how long does the individual usage of the perpetrators cost?  I ran that one, too.  Here are the results:<br />
<a href='http://javatech.org/wp-content/uploads/2008/03/log4j_conversion_patterns_2008_03_15__12_25_pm.png' title='log4j_conversion_patterns_2008_03_15__12_25_pm.png'><img src='http://javatech.org/wp-content/uploads/2008/03/log4j_conversion_patterns_2008_03_15__12_25_pm.png' alt='log4j_conversion_patterns_2008_03_15__12_25_pm.png' /></a></p>
<p>%l is the most expensive conversion pattern.  On average it takes an extra 140,000 nanoseconds.<br />
%C is the next most expensive, taking about 110,000 nanoseconds longer.<br />
The rest ( %M, %F, %L ) each take about 100,000 nanoseconds longer.</p>
<p>Now you know.</p>
<h3>Log4J Conversion Patterns</h3>
<div style='font-size:smaller;font-weight:bolder;'>JVM Version 1.6.0_05-ea<br />
Windows XP[x86] &#8211; 2 processors<br />
4.94MB/63.56MB Memory
</div>
<table border=1>
<tr>
<th>Benchmark</th>
<th>Threads</th>
<th>Avg Nanos</th>
<th>Slow Factor</th>
</tr>
<tr>
<td>Fast</td>
<td>30</td>
<td>33106.79</td>
<td>1.00x</td>
</tr>
<tr>
<td>Fast</td>
<td>35</td>
<td>36082.72</td>
<td>1.09x</td>
</tr>
<tr>
<td>Fast</td>
<td>20</td>
<td>37435.39</td>
<td>1.13x</td>
</tr>
<tr>
<td>Fast</td>
<td>40</td>
<td>37615.85</td>
<td>1.14x</td>
</tr>
<tr>
<td>Fast</td>
<td>10</td>
<td>40022.65</td>
<td>1.21x</td>
</tr>
<tr>
<td>Fast</td>
<td>1</td>
<td>40961.19</td>
<td>1.24x</td>
</tr>
<tr>
<td>Fast</td>
<td>25</td>
<td>41009.21</td>
<td>1.24x</td>
</tr>
<tr>
<td>Fast</td>
<td>45</td>
<td>41631.96</td>
<td>1.26x</td>
</tr>
<tr>
<td>Fast</td>
<td>50</td>
<td>42989.00</td>
<td>1.30x</td>
</tr>
<tr>
<td>Fast</td>
<td>15</td>
<td>46050.36</td>
<td>1.39x</td>
</tr>
<tr>
<td>Fast</td>
<td>5</td>
<td>50155.79</td>
<td>1.51x</td>
</tr>
<tr>
<td>%M </td>
<td>5</td>
<td>126486.35</td>
<td>3.82x</td>
</tr>
<tr>
<td>%L</td>
<td>15</td>
<td>132137.75</td>
<td>3.99x</td>
</tr>
<tr>
<td>%L</td>
<td>35</td>
<td>134056.48</td>
<td>4.05x</td>
</tr>
<tr>
<td>%L</td>
<td>40</td>
<td>134538.77</td>
<td>4.06x</td>
</tr>
<tr>
<td>%M </td>
<td>15</td>
<td>135388.24</td>
<td>4.09x</td>
</tr>
<tr>
<td>%F</td>
<td>10</td>
<td>137914.76</td>
<td>4.17x</td>
</tr>
<tr>
<td>%L</td>
<td>5</td>
<td>138189.31</td>
<td>4.17x</td>
</tr>
<tr>
<td>%L</td>
<td>25</td>
<td>138781.50</td>
<td>4.19x</td>
</tr>
<tr>
<td>%F</td>
<td>15</td>
<td>139051.26</td>
<td>4.20x</td>
</tr>
<tr>
<td>%L</td>
<td>10</td>
<td>139648.04</td>
<td>4.22x</td>
</tr>
<tr>
<td>%F</td>
<td>25</td>
<td>139736.45</td>
<td>4.22x</td>
</tr>
<tr>
<td>%L</td>
<td>20</td>
<td>140881.53</td>
<td>4.26x</td>
</tr>
<tr>
<td>%M </td>
<td>10</td>
<td>140943.95</td>
<td>4.26x</td>
</tr>
<tr>
<td>%F</td>
<td>20</td>
<td>142361.85</td>
<td>4.30x</td>
</tr>
<tr>
<td>%M </td>
<td>20</td>
<td>142539.18</td>
<td>4.31x</td>
</tr>
<tr>
<td>%M </td>
<td>25</td>
<td>142656.80</td>
<td>4.31x</td>
</tr>
<tr>
<td>%C </td>
<td>20</td>
<td>143221.29</td>
<td>4.33x</td>
</tr>
<tr>
<td>%M </td>
<td>30</td>
<td>143781.90</td>
<td>4.34x</td>
</tr>
<tr>
<td>%F</td>
<td>5</td>
<td>143855.32</td>
<td>4.35x</td>
</tr>
<tr>
<td>%L</td>
<td>30</td>
<td>144129.23</td>
<td>4.35x</td>
</tr>
<tr>
<td>%M </td>
<td>40</td>
<td>144481.16</td>
<td>4.36x</td>
</tr>
<tr>
<td>%F</td>
<td>35</td>
<td>145803.89</td>
<td>4.40x</td>
</tr>
<tr>
<td>%F</td>
<td>30</td>
<td>145891.32</td>
<td>4.41x</td>
</tr>
<tr>
<td>%C </td>
<td>10</td>
<td>147103.22</td>
<td>4.44x</td>
</tr>
<tr>
<td>%F</td>
<td>45</td>
<td>148460.17</td>
<td>4.48x</td>
</tr>
<tr>
<td>%L</td>
<td>45</td>
<td>148951.05</td>
<td>4.50x</td>
</tr>
<tr>
<td>%C </td>
<td>25</td>
<td>149877.80</td>
<td>4.53x</td>
</tr>
<tr>
<td>%F</td>
<td>50</td>
<td>150231.08</td>
<td>4.54x</td>
</tr>
<tr>
<td>%C </td>
<td>30</td>
<td>150495.98</td>
<td>4.55x</td>
</tr>
<tr>
<td>%L</td>
<td>50</td>
<td>151044.66</td>
<td>4.56x</td>
</tr>
<tr>
<td>%C </td>
<td>5</td>
<td>151478.15</td>
<td>4.58x</td>
</tr>
<tr>
<td>%C </td>
<td>35</td>
<td>151516.71</td>
<td>4.58x</td>
</tr>
<tr>
<td>%M </td>
<td>45</td>
<td>152534.57</td>
<td>4.61x</td>
</tr>
<tr>
<td>%C </td>
<td>15</td>
<td>152969.01</td>
<td>4.62x</td>
</tr>
<tr>
<td>%M </td>
<td>50</td>
<td>152989.03</td>
<td>4.62x</td>
</tr>
<tr>
<td>%C </td>
<td>50</td>
<td>154476.76</td>
<td>4.67x</td>
</tr>
<tr>
<td>%F</td>
<td>40</td>
<td>155057.98</td>
<td>4.68x</td>
</tr>
<tr>
<td>%C </td>
<td>45</td>
<td>155471.11</td>
<td>4.70x</td>
</tr>
<tr>
<td>%M </td>
<td>35</td>
<td>155759.06</td>
<td>4.70x</td>
</tr>
<tr>
<td>%C </td>
<td>40</td>
<td>165737.16</td>
<td>5.01x</td>
</tr>
<tr>
<td>%l </td>
<td>10</td>
<td>170275.18</td>
<td>5.14x</td>
</tr>
<tr>
<td>%l </td>
<td>5</td>
<td>172227.11</td>
<td>5.20x</td>
</tr>
<tr>
<td>%l </td>
<td>20</td>
<td>172265.43</td>
<td>5.20x</td>
</tr>
<tr>
<td>%l </td>
<td>35</td>
<td>174530.94</td>
<td>5.27x</td>
</tr>
<tr>
<td>%l </td>
<td>50</td>
<td>175687.72</td>
<td>5.31x</td>
</tr>
<tr>
<td>%l </td>
<td>45</td>
<td>177227.30</td>
<td>5.35x</td>
</tr>
<tr>
<td>%l </td>
<td>15</td>
<td>177944.97</td>
<td>5.37x</td>
</tr>
<tr>
<td>%l </td>
<td>30</td>
<td>177987.91</td>
<td>5.38x</td>
</tr>
<tr>
<td>%l </td>
<td>25</td>
<td>181043.73</td>
<td>5.47x</td>
</tr>
<tr>
<td>%l </td>
<td>40</td>
<td>186023.07</td>
<td>5.62x</td>
</tr>
<tr>
<td>%F</td>
<td>1</td>
<td>203322.88</td>
<td>6.14x</td>
</tr>
<tr>
<td>%L</td>
<td>1</td>
<td>209034.65</td>
<td>6.31x</td>
</tr>
<tr>
<td>%C </td>
<td>1</td>
<td>218245.92</td>
<td>6.59x</td>
</tr>
<tr>
<td>%M </td>
<td>1</td>
<td>222148.81</td>
<td>6.71x</td>
</tr>
<tr>
<td>%l </td>
<td>1</td>
<td>223007.37</td>
<td>6.74x</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2008/02/log4j-conversion-pattern-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freemarker vs Raw Java</title>
		<link>http://javatech.org/2008/02/freemarker-vs-raw-java/</link>
		<comments>http://javatech.org/2008/02/freemarker-vs-raw-java/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 07:27:31 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=24</guid>
		<description><![CDATA[I&#8217;ve recently been pitting Freemarker against Raw Java of late because I was under the impression that Freemarker would blow up under load in a multi-threaded environment.  Well, it turns out that things aren&#8217;t nearly as bad as I&#8217;d thought, but it&#8217;s still significantly slower than what I&#8217;ve been calling &#8220;Raw Java&#8221;.   [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been pitting Freemarker against Raw Java of late because I was under the impression that Freemarker would blow up under load in a multi-threaded environment.  Well, it turns out that things aren&#8217;t nearly as bad as I&#8217;d thought, but it&#8217;s still significantly slower than what I&#8217;ve been calling &#8220;Raw Java&#8221;.   Here&#8217;s the final results with a pretty graph and everything.<br />
<a href="http://javatech.org/wp-content/uploads/2008/03/freemarker_vs_raw_java_2008_03_12__02_02_am.png" title="freemarker_vs_raw_java_2008_03_12__02_02_am.png"><img src="http://javatech.org/wp-content/uploads/2008/03/freemarker_vs_raw_java_2008_03_12__02_02_am.png" alt="freemarker_vs_raw_java_2008_03_12__02_02_am.png" /></a><a href="http://javatech.org/wp-content/uploads/2008/02/freemarker_vs_raw_java_2008_02_26__12_21_am.png" title="Freemarker vs Raw Java"><br />
</a><br />
Previous test results had shown Freemarker going into the 200 times slower category, but it does actually stay in the 20 times slower category.  So, I&#8217;m not nearly as freaked out by this as I was a few weeks ago.  I still think that the example I&#8217;m using, where the FTL is more of a program than a template, that the Raw Java method is nearly as appropriate and positively 20 times faster!</p>
<h4>Freemarker vs Raw Java</h4>
<p style="font-size: smaller; font-weight: bolder">JVM Version 1.6.0_05-ea<br />
Windows XP[x86] &#8211; 2 processors<br />
4.99MB/63.56MB Memory</p>
<table border="1">
<tr>
<th>Benchmark</th>
<th>Threads</th>
<th>Avg Nanos</th>
<th>Slow Factor</th>
</tr>
<tr>
<td>Raw Java</td>
<td>50</td>
<td>1585.19</td>
<td>1.00x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>30</td>
<td>1796.52</td>
<td>1.13x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>20</td>
<td>1862.14</td>
<td>1.17x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>10</td>
<td>1890.36</td>
<td>1.19x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>60</td>
<td>1891.35</td>
<td>1.19x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>40</td>
<td>1891.70</td>
<td>1.19x</td>
</tr>
<tr>
<td>Raw Java</td>
<td>1</td>
<td>2494.68</td>
<td>1.57x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>10</td>
<td>26320.65</td>
<td>16.60x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>20</td>
<td>27597.29</td>
<td>17.41x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>30</td>
<td>28638.00</td>
<td>18.07x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>40</td>
<td>29562.36</td>
<td>18.65x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>50</td>
<td>30019.56</td>
<td>18.94x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>60</td>
<td>31576.83</td>
<td>19.92x</td>
</tr>
<tr>
<td>Freemarker</td>
<td>1</td>
<td>34447.90</td>
<td>21.73x</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2008/02/freemarker-vs-raw-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MultiThreaded Freemarker Benchmarks</title>
		<link>http://javatech.org/2008/02/multithreaded-freemarker-benchmarks/</link>
		<comments>http://javatech.org/2008/02/multithreaded-freemarker-benchmarks/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 05:47:07 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=23</guid>
		<description><![CDATA[I recently blogged about Freemarker performing 10-20x slower than pure Java analogues.  I got to thinking about our webapp and the fact that I wasn&#8217;t quite testing the correct scenario.  In a web environment there might be numerous threads all running Freemarker templates simultaneously.  So, I had to put the pure Java [...]]]></description>
			<content:encoded><![CDATA[<p>I recently <a href="http://javatech.org/?p=21" title="Freemarker vs Pure Java">blogged about Freemarker performing 10-20x slower</a> than pure Java analogues.  I got to thinking about our webapp and the fact that I wasn&#8217;t quite testing the correct scenario.  In a web environment there might be numerous threads all running Freemarker templates simultaneously.  So, I had to put the pure Java analogues up against the simple Freemarker template in a multithreaded test.  I ran tests for each with 10,20,40,60 and 80 threads.  The results are more impetus towards moving away from Freemarker for the most used and most basic cases ( input tags, labels, script includes ).</p>
<p>So how bad is it&#8230;drum roll&#8230;</p>
<p>Class[10] indicates the pure Java method running a 10 Thread test.  FTL[20] indicates the Freemarker test running a 20 Thread test.  And so on&#8230; Results are listed from best to worst with the avg and max results in nanoseconds.</p>
<p style="border: 1px solid ; background: #cccccc none repeat scroll 0% 50%; color: red; padding-left: 5px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"> Class[10]:    1000100 trials,    18046 avg, 67973245 max    1.0x<br />
Class[80]:    1000800 trials,    28960 avg, 104784259 max  1.6x<br />
Class[20]:    1000200 trials,    30387 avg, 106770756 max  1.7x<br />
Class[60]:    1000200 trials,    35917 avg, 96320112 max    2.0x<br />
Class[40]:    1000400 trials,    37220 avg, 162898182 max   2.1x<br />
FTL[10]:    1000100 trials,   293093 avg, 104114975 max  16.2x<br />
FTL[20]:    1000200 trials,   587117 avg,      158432568 max  32.5x<br />
FTL[40]:    1000400 trials,  1204641 avg,      190966244 max  66.8x<br />
FTL[60]:    1000200 trials,  1843190 avg,      284686324 max  102.1x<br />
FTL[80]:    1000800 trials,  2498693 avg,      358187778 max  138.5x</p>
<p>The last piece of info on each line is how much slower that particular test was ( on average ) than the fastest.  Notice how the pure Java tests don&#8217;t jump right into the crapper when under load.  But the FTL tests get progressively worse as the thread counts are increased.  Under an 80 thread load, not only is the pure Java way 138 times faster on average, but the FTL way has max time of 358 milliseconds vs a 104 millisecond max for pure Java.  This is a perceptible 250 millisecond difference when rendering a single button tag!</p>
<p>The case for easing up on the Freemarker templates is solidifying <img src='http://javatech.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2008/02/multithreaded-freemarker-benchmarks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freemarker Benchmarks</title>
		<link>http://javatech.org/2008/02/freemarker-benchmarks/</link>
		<comments>http://javatech.org/2008/02/freemarker-benchmarks/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 06:11:46 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=21</guid>
		<description><![CDATA[All of us at iCentris have currently embarked upon a torrid love affair with Freemarker templates.  I admit that I, too, have been very excited about having them around.    A freemarker template has quickly become the knee-jerk, defacto response to generating output &#8211; which is great for readability and maintainability.  [...]]]></description>
			<content:encoded><![CDATA[<p>All of us at iCentris have currently embarked upon a torrid love affair with <a href="http://freemarker.org" title="Freemarker Template Engine" target="_blank">Freemarker </a>templates.  I admit that I, too, have been very excited about having them around.    A freemarker template has quickly become the knee-jerk, defacto response to generating output &#8211; which is great for readability and maintainability.  But lately, after repeated profiling sessions with all the top offenders coming from freemarker packages, I&#8217;ve come to realize that we&#8217;re using them way too much.   And here&#8217;s why&#8230;</p>
<p>When should a template engine be used?  There seem to be two answers to this question which both carry equal weight with developers.  They are:</p>
<ol>
<li>You want to have an easily editable version of your dynamic view.  This will allow easy customization.</li>
<li>You want the representation to be easily readable to future developers.  This will keep it understandable and maintainable.</li>
</ol>
<p>Now, this might seem like a minor point to pick at.   But bear with me&#8230;</p>
<p>So, how much faster is pure java than freemarker templates?  Well, this is going to depend largely on the complexity of the template.   As an example, I&#8217;m going to pick a template of medium complexity that renders an HTML button tag in a consistent fashion.  The output will be very simple and we&#8217;ll have a lot of HTML attributes that can be set within the template.  Here&#8217;s the ftl file:</p>
<p>button.ftl</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
[source:xml]<br />
&lt;@compress single_line=true&gt;<br />
&lt;button 			&lt;#if id?exists&gt;<br />
id=&#8221;${id}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if name?exists&gt;<br />
name=&#8221;${name}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if value?exists&gt;<br />
value=&#8221;${value}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if accesskey?exists&gt;<br />
accesskey=&#8221;${accesskey}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if classname?exists&gt;<br />
class=&#8221;${classname}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if style?exists&gt;<br />
style=&#8221;${style}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if title?exists&gt;<br />
title=&#8221;${title}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if href?exists || onclick?exists &gt;<br />
onclick=&#8221;<br />
&lt;#if href?exists&gt;document.location.href=&#8217;${href}&#8217;;&lt;/#if&gt;<br />
&lt;#if onclick?exists&gt;${onclick}&lt;/#if&gt;<br />
&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if ondblclick?exists&gt;<br />
ondblclick=&#8221;${ondblclick}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if onmouseout?exists&gt;<br />
onmouseout=&#8221;${onmouseout}&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if type?exists&gt;<br />
type=&#8221;${type}&#8221;<br />
&lt;#else&gt;<br />
type=&#8221;button&#8221;<br />
&lt;/#if&gt;</p>
<p>&lt;#if disabled?exists &amp;&amp; disabled == &#8216;true&#8217; &gt;<br />
disabled=&#8221;disabled&#8221;<br />
&lt;/#if&gt;<br />
&gt;<br />
&lt;div&gt;<br />
&lt;div&gt;<br />
&lt;#if icon?exists&gt;${icon}&lt;/#if&gt;</p>
<p>&lt;span&gt;<br />
${content}<br />
&lt;/span&gt;<br />
&lt;/div&gt;<br />
&lt;/div&gt;</p>
<p>&lt;/button&gt;<br />
&lt;/@compress&gt;<br />
[/source]<br />
It outputs something along the lines of :<br />
[source:xml]<br />
&lt;button id=&#8221;buttonId&#8221; style=&#8221;buttonStyle&#8221; onclick=&#8221; alert(&#8217;hi&#8217;); &#8221; type=&#8221;button&#8221; &gt; &lt;div&gt; &lt;div&gt; &lt;img src=&#8217;pretty.jpg&#8217;&gt; &lt;span&gt; This is required &lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/button&gt;<br />
[/source]</p>
<p>Now, is this a good place to use a template like the above?  The answer is Yes.  But, as with most things, only in moderation.  Or perhaps the answer is actually a definite maybe?</p>
<p>So, what can the downside be?</p>
<p>Speed.</p>
<p>Having just benchmarked this I have an unfair advantage, but the raw Java implementation that spits out the same exact templating logic presented above in button.ftl runs over 15 times faster.</p>
<p>Running 1000 trials of button.ftl (FTL) vs ButtonTemplate.java (Class) gives me the following results ( in microsecond timing ):</p>
<p>FTL 419033 micros<br />
Class 31828 micros<br />
Class is 13 times faster!</p>
<p>With only 100 trials:</p>
<p>FTL 15888 micros<br />
Class 834 micros<br />
Class is 19 times faster!</p>
<p>So, back to the moderation.  Nobody is going to notice if a couple of buttons are rendered in 1 microSecond instead of 15 microSeconds, that&#8217;s for sure.  But, if your entire page, overtime, has been rewritten to do absolutely everything using FTL, and the page ends up taking a second to load.  Well, then, a 15x speed increase would get that page out in less than a tenth of a second.</p>
<p>I ran these tests with Freemarker 2.3.10 and then again with 2.3.12 and got the same results, so the optimization they added in <a href="http://www.freemarker.org/docs/versions_2_3_11.html">2.3.11</a> doesn&#8217;t seem to affect this type of simple usage ( using maps ).</p>
<p>Here is a screenshot showing the intense framework supporting the Freemarker template engine.  Notice how the pure java class ( highlighted in blue ) just goes about its business directly.<a href="http://javatech.org/wp-content/uploads/2008/02/javavsfreemarker10.png" title="Freemarker Benchmark - 2.3.10 - Using FTL vs raw Java"><img src="http://javatech.org/wp-content/uploads/2008/02/javavsfreemarker10.png" alt="Freemarker Benchmark - 2.3.10 - Using FTL vs raw Java" /></a></p>
<p>So, back to the two reasons to use an FTL template.</p>
<ol>
<li>You want to have an easily editable version of your dynamic view.</li>
<li>You want the representation to be easily readable to future developers.</li>
</ol>
<p>Well, in regards to #1, I don&#8217;t think we really need to have an easily editable version of our &lt;button&gt; tag.  I mean, really, a button&#8217;s a button&#8217;s a button.  It might keep growing for a while, gathering more attributes and complexity over time, but I don&#8217;t think we&#8217;ll ever need to plug in a custom version for a different client.</p>
<p>As for #2, I don&#8217;t think the java code is really that much more difficult to read, and since we won&#8217;t be needing to change this (because it&#8217;s a button, for christ&#8217;s sake!) template that often, why take the speed hit here?</p>
<p>Here, btw, is the code for ButtonTemplate.java ( w/o Javabean boilerplate )<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
[source:Java]<br />
public void render( Writer out ) throws IOException {<br />
out.write( &#8220;&lt;button&#8221; );<br />
if ( id != null )        writeAttribute( out, &#8220;id&#8221;, id );<br />
if ( name != null )      writeAttribute( out, &#8220;name&#8221;, name );<br />
if ( value != null )     writeAttribute( out, &#8220;value&#8221;, value );<br />
if ( accessKey != null ) writeAttribute( out, &#8220;accesskey&#8221;, accessKey );<br />
if ( className != null ) writeAttribute( out, &#8220;class&#8221;, className );<br />
if ( style != null )     writeAttribute( out, &#8220;style&#8221;, style );<br />
if ( title != null )     writeAttribute( out, &#8220;title&#8221;, title );</p>
<p>if ( href != null || onClick != null ) {<br />
out.write( &#8221; onclick=\&#8221;" );<br />
if ( href != null ) {<br />
out.write( &#8220;document.location.href=&#8217;&#8221; );<br />
out.write(href);<br />
out.write(&#8221;&#8216;;&#8221;);<br />
}<br />
if ( onClick != null ) {<br />
out.write( onClick );<br />
}<br />
out.write( &#8220;\&#8221;" );<br />
}</p>
<p>if ( onDblClick != null )     writeAttribute( out, &#8220;ondblclick&#8221;, onDblClick );<br />
if ( onMouseOut != null )     writeAttribute( out, &#8220;onmouseout&#8221;, onMouseOut );<br />
if ( type != null )	{<br />
writeAttribute( out, &#8220;type&#8221;, type );<br />
} else {<br />
writeAttribute( out, &#8220;type&#8221;, &#8220;button&#8221; );<br />
}<br />
if ( disabled ) {<br />
writeAttribute( out, &#8220;disabled&#8221;, &#8220;disabled&#8221; );<br />
}</p>
<p>out.write( &#8221; &gt; &lt;div&gt; &lt;div&gt; &#8221; );</p>
<p>if ( icon != null ) {<br />
out.write( icon );<br />
out.write( &#8221; &#8221; );<br />
}<br />
out.write( &#8220;&lt;span&gt; &#8221; );<br />
out.write( content );<br />
out.write( &#8221; &lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/button&gt;&#8221; );<br />
}</p>
<p>[/source]<br />
Now, I mentioned the torrid love affair we&#8217;re in at work.  Well, we are using  a whole lot more FTL to simply render HTML elements : inputs, labels, selects, buttons, checkboxes, creditCards, datePickers, dropDowns, addresses ( which use the previous elements ) and even style and javascript includes.   So, in conclusion, since Freemarker is the artsy smartsy way to do things and it will be used wherever and whenever possible once it takes root &#8211; I implore you to only use it where/when it is <strong>truly </strong>needed.   That is, for large views that are truly complex and for views that will be frequently customized.  For the simple cases, it&#8217;s just not worth the hit.</p>
<p>Time to go refactoring&#8230;perhaps&#8230;</p>
<p>Afterthough:::  If only the freemarker templates would compile into java bytecode, then this would probably be a nonfactor.  JSP&#8217;s can do it.  Is anyone up  to the task?</p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2008/02/freemarker-benchmarks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C3P0 vs DBCP &#8211; The Straight Dope</title>
		<link>http://javatech.org/2007/11/c3p0-vs-dbcp-the-straight-dope/</link>
		<comments>http://javatech.org/2007/11/c3p0-vs-dbcp-the-straight-dope/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 04:18:57 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=17</guid>
		<description><![CDATA[I&#8217;ve found it very difficult to find any accurate comparisons of C3P0 and DBCP.  Why should I choose C3P0 over DBCP?  When might DBCP be better?
Well, here&#8217;s a fairly in-depth overview of both with pros and cons and similarities and differences included.
The first thing to note is that if you&#8217;re not in a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found it very difficult to find any accurate comparisons of C3P0 and DBCP.  Why should I choose C3P0 over DBCP?  When might DBCP be better?</p>
<p>Well, here&#8217;s a fairly in-depth overview of both with pros and cons and similarities and differences included.</p>
<p>The first thing to note is that if you&#8217;re not in a multi-threaded environment, then DBCP is going to be faster than C3P0 and will also use significantly fewer connections than C3P0.  For example, using the default settings for each and sizing the pool to contain 50 connections at most, will yield results like the following single-threaded test.</p>
<p><strong>Single-threaded Benchmark &#8211; 50,000 calls to getConnection()</strong></p>
<table border="1">
<tr>
<th></th>
<th>Trials</th>
<th>MaxPoolSize</th>
<th>Connections Used</th>
<th>Seconds</th>
<th>Settings</th>
</tr>
<tr>
<th>DBCP</th>
<td>50,000</td>
<td>50</td>
<td>1</td>
<td>5.18</td>
<td>&#8212;</td>
</tr>
<tr>
<th>C3P0</th>
<td>50,000</td>
<td>50</td>
<td>50</td>
<td>6.72</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>50,000</td>
<td>50</td>
<td>39</td>
<td>6.6</td>
<td>numHelperThreads=4</td>
</tr>
<tr>
<th>C3P0</th>
<td>50,000</td>
<td>50</td>
<td>27</td>
<td>6.45</td>
<td>numHelperThreads=5</td>
</tr>
<tr>
<th>C3P0</th>
<td>50,000</td>
<td>50</td>
<td>30</td>
<td>6.63</td>
<td>numHelperThreads=6</td>
</tr>
</table>
<p>Suffice it to say that DBCP is obviously better suited to Single-threaded applications with high load.  Needing 50 connections in the pool to do the work where only 1 is needed is certainly not desired.  This is the case with C3P0&#8217;s default setting of &#8220;numHelperThreads=3&#8243;.  Regardless of the environment you have ( single-threaded, multi-threaded ) I would always change this setting if you forsee high load on the program.  I would always use at least &#8220;numHelperThreads=5&#8243;.  As a bit of background/explanation, C3P0 doesn&#8217;t actually make a connection available in the pool when it is checked-in.  Instead the HelperThreads will detect these and do the work to get them back in the pool.  This is great in high-load, multi-threaded environments as it avoids blocking issues.  But it inherently requires a much larger number of connections to provide the same functionality ( especially if you keep &#8220;numHelperThreads=3&#8243; ).  Also, notice that DBCP is 20% faster regardless of how we tweak numHelperThreads.</p>
<p>Score 2 points for DBCP.  2-0.</p>
<p>Next what if we run the same test with a smaller connection pool size &#8211; say of only 5 connections, and numHelperThreads=3 for C3P0?</p>
<p>The results are a bit counterintuitive ( to me at least ).  DBCP does at least manage to stay the same &#8211; very fast and reasonable ( needing just 1 connection in its pool ).  But C3P0, which I expected to take longer because it previously needed all 50 connections, but actually runs faster with a smaller pool : 6.25 seconds down from 6.7 seconds.  The lesson here is that C3P0 is slowing itself down with the HelperThreads having to manage all the extra connections to get them back in the pool.</p>
<table border="1">
<tr>
<th></th>
<th>Trials</th>
<th>MaxPoolSize</th>
<th>Connections Used</th>
<th>Seconds</th>
<th>Settings</th>
</tr>
<tr>
<th>DBCP</th>
<td>50,000</td>
<td>5</td>
<td>1</td>
<td>5.18</td>
<td>&#8212;</td>
</tr>
<tr>
<th>C3P0</th>
<td>50,000</td>
<td>5</td>
<td>5</td>
<td>6.18</td>
<td>*numHelperThreads=3</td>
</tr>
</table>
<p>Score 1 point each.  DBCP for making sense and C3P0 for speeding up.</p>
<p>3-1, DBCP in the lead.</p>
<p>Now for the good stuff &#8211; the multi-threaded tests.  I&#8217;ll be varying the number of Threads which will be running.<br />
<strong>Multi-threaded tests</strong></p>
<table border="1">
<tr>
<th></th>
<th>Threads</th>
<th>MaxPoolSize</th>
<th>Connections Used</th>
<th>Seconds</th>
<th>Settings</th>
</tr>
<tr>
<th>DBCP</th>
<td>25</td>
<td>5</td>
<td>5</td>
<td>90</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>25</td>
<td>10</td>
<td>10</td>
<td>107</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>25</td>
<td>25</td>
<td>25</td>
<td>167</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>50</td>
<td>50</td>
<td>50</td>
<td>198</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>50</td>
<td>100</td>
<td>50</td>
<td>207</td>
<td>&#8212;</td>
</tr>
<tr>
<th>C3P0</th>
<td>25</td>
<td>5</td>
<td>5</td>
<td>156</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>25</td>
<td>10</td>
<td>10</td>
<td>142</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>25</td>
<td>25</td>
<td>25</td>
<td>137</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>50</td>
<td>50</td>
<td>50</td>
<td>252</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>50</td>
<td>100</td>
<td>100</td>
<td>252</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>50</td>
<td>100</td>
<td>100</td>
<td>269</td>
<td>numHelperThreads=6</td>
</tr>
</table>
<p>Score yet another to DBCP.   Faster across the board on all accounts.  So, what is it about C3P0 that has everybody ( myself included ) using it and singing its praises?  Multiple threads yield multiple points again for DBCP &#8211; 2 points awarded.</p>
<p>5-1, C3P0 will need a miracle comeback at this point.</p>
<p>I know, usually Connections aren&#8217;t just checked out and run with a small SQL statement and immediately returned like the Benchmarks I&#8217;ve been running.  Maybe I need to put some delay in there to more closely mimic real world performance.  I&#8217;m going to throw a new setting in here which is a delay in milliseconds that each call to getConnection() will endure before finishing with the connection.  I&#8217;ll give it a shot with an extra 100ms of sleep time after each SQL statement is run.</p>
<p><strong>Multi-threaded &#8211; 100ms of sleep time added</strong></p>
<table border="1">
<tr>
<th></th>
<th>Threads</th>
<th>MaxPoolSize</th>
<th>Connections Used</th>
<th>Seconds</th>
<th>Settings</th>
</tr>
<tr>
<th>DBCP</th>
<td>50</td>
<td>25</td>
<td>25</td>
<td>9338</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>50</td>
<td>10</td>
<td>10</td>
<td>20918</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>100</td>
<td>50</td>
<td>50</td>
<td>9248</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>0</td>
<td>50</td>
<td>50</td>
<td>0</td>
<td>&#8212;</td>
</tr>
<tr>
<th>DBCP</th>
<td>0</td>
<td>100</td>
<td>50</td>
<td>0</td>
<td>&#8212;</td>
</tr>
<tr>
<th>C3P0</th>
<td>50</td>
<td>25</td>
<td>25</td>
<td>9295</td>
<td>numHelperThreads=6</td>
</tr>
<tr>
<th>C3P0</th>
<td>50</td>
<td>10</td>
<td>10</td>
<td>20088</td>
<td>numHelperThreads=6</td>
</tr>
<tr>
<th>C3P0</th>
<td>100</td>
<td>50</td>
<td>50</td>
<td>9412</td>
<td>numHelperThreads=6</td>
</tr>
<tr>
<th>C3P0</th>
<td>0</td>
<td>50</td>
<td>50</td>
<td>0</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>0</td>
<td>100</td>
<td>100</td>
<td>0</td>
<td>*numHelperThreads=3</td>
</tr>
<tr>
<th>C3P0</th>
<td>0</td>
<td>100</td>
<td>100</td>
<td>0</td>
<td>numHelperThreads=6</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2007/11/c3p0-vs-dbcp-the-straight-dope/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>C3P0 ConnectionPool Configuration Rules of Thumb</title>
		<link>http://javatech.org/2007/11/c3p0-connectionpool-configuration-rules-of-thumb/</link>
		<comments>http://javatech.org/2007/11/c3p0-connectionpool-configuration-rules-of-thumb/#comments</comments>
		<pubDate>Sun, 04 Nov 2007 05:14:23 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=14</guid>
		<description><![CDATA[C3P0 is a fantastic open source ConnectionPool that is feature rich, stable, and positively production ready.  I personally like it more than DBCP because there is too much blocking encountered when checking in/out connections with DBCP.    C3P0 dodges that problem with an asynchronous return to the pool, but you might end [...]]]></description>
			<content:encoded><![CDATA[<p>C3P0 is a fantastic open source ConnectionPool that is feature rich, stable, and positively production ready.  I personally like it more than DBCP because there is too much blocking encountered when checking in/out connections with DBCP.    C3P0 dodges that problem with an asynchronous return to the pool, but you might end up using a lot more connections than you need to if you&#8217;re not careful.  Here&#8217;s a list of the most important C3P0 settings and good production settings to use &#8211; along with some words of wisdom as to why the change from default is a good thing.</p>
<p><strong>acquireIncrement=5</strong> <em>default(3)</em> Batching the retrieval of Connections is wise because the process of opening a Connection is expensive.  Why do it 5 times instead of once?  The downside to this is that you may only need the one connection.  Read on to maxIdleTime settings to make sure idle connections make their way back into the pool.</p>
<p><strong>maxIdleTime=3600</strong> <em>default(0)</em> Setting the maxIdleTime to a non-zero value permits C3P0 to remove Connections from the pool and freeing up database resources.  This will never happen when maxIdleTime is set to 0.  Setting to a small value might have Connections being retrieved and returned on too frequent a basis to be practical, so I&#8217;ve picked 3600 seconds ( 1 hour ) as a nice happy medium.  Once the peak traffic is over, then the connections can be returned.</p>
<p><strong>maxIdleTimeExcessConnections=300</strong> <em>default(0)</em> You need to set this in addition to maxIdleTime to have the Connections removed from the pool and returned to the DB.</p>
<p><strong>maxPoolSize=100</strong> <em>default(15)</em> You&#8217;ll have to fine tune this setting base on your own individual situation, but it&#8217;s important to keep this on the largish side for the simple reason that C3P0 doesn&#8217;t synchronously return connections to the pool.  The implication of this is that the pool should actually be sized slightly larger than what you think the maximum number of Connections needed at peak time would be.  For more on this, see numHelperThreads.</p>
<p><strong>minPoolSize=20</strong> <em>default(3)</em> This one too can be fine tuned based on your individual needs, but let&#8217;s just say that you don&#8217;t always want to be returning all your Connections and having to reacquire new ones.  20 is a good size to allow for handling of new bursts of sporadic traffic w/o having to reacquire them.</p>
<p><strong>numHelperThreads=6</strong> <em>default(3)</em> This is a very important property if you&#8217;re going to have large bursts of traffic on your site.  C3P0 ( as was alluded to previously ) doesn&#8217;t return connections to the pool synchronously and as a result doesn&#8217;t have the same issues with blocking that DBCP has.  However, as a result, Connections are not made available until some arbitrary time after they are returned to the pool.  C3P0 has helperThreads which are responsible for doing the actual return work and making them available.  Under large load I&#8217;ve experienced times where these spikes could require 400 Connections using the default setting of 3.  Using 6 HelperThreads will keep this spike under 100 connections.  If you can afford the connections or won&#8217;t have huge loads on the system, then the default of 3 will probably be fine for you.</p>
<p><strong>unreturnedConnectionTimeout=3600</strong> <em>default(0)</em> I&#8217;ve set this to 1 hour.  If a Connection is used for longer than an hour, then C3P0 will assume it&#8217;s been orphaned and will reclaim the Connection to the pool &#8211; closing it in the process.</p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2007/11/c3p0-connectionpool-configuration-rules-of-thumb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Checking Email with Java</title>
		<link>http://javatech.org/2007/11/checking-email-with-java/</link>
		<comments>http://javatech.org/2007/11/checking-email-with-java/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 21:07:54 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=13</guid>
		<description><![CDATA[I&#8217;ve probably used Java to send email somewhere in the neighborhood of 30 times and have never really had much trouble with it.  But how in blazes do I connect to a (Pop3) account and pull down email?  Well, after much cursing at the javamail API the solution crystallized to something containing the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve probably used Java to send email somewhere in the neighborhood of 30 times and have never really had much trouble with it.  But how in blazes do I connect to a (Pop3) account and pull down email?  Well, after much cursing at the javamail API the solution crystallized to something containing the following:<br />
<code><br />
Properties props = new Properties();<br />
Session session = Session.getDefaultInstance(props, null);<br />
store = session.getStore("pop3");<br />
store.connect( "mail.isp.com", "myUserName", "myPassword" );<br />
inbox = store.getFolder("INBOX");<br />
inbox.open(Folder.READ_ONLY);<br />
Message[] msgs = inbox.getMessages();<br />
// Do something with the messages here<br />
inbox.close(false);<br />
store.close();<br />
</code></p>
<p>It should be noted that the elusive activation.jar and mail.jar from J2EE 1.4 were used to get the above to compile and run.  When I tried using the JEE5 libraries, I didn&#8217;t have a POP3 implementation and got &#8220;JavaMail &#8211; NoSuchProviderException: No provider for pop3&#8243; exceptions.</p>
<p>Here&#8217;s a code snippet that will show you all of the providers you have available to you:</p>
<p><code><br />
        Properties props = new Properties();<br />
        Session session = Session.getDefaultInstance(props, null);<br />
        Provider[] p = session.getProviders();<br />
        for (int i=0;i
<p.length;i++) {<br />
        	System.out.println(p[i].getProtocol());<br />
        }<br />
</code>
<p>I get back the results: imap, pop3, smtp.</p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2007/11/checking-email-with-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Wicket Component Model Explained</title>
		<link>http://javatech.org/2007/10/the-wicket-component-model-explained/</link>
		<comments>http://javatech.org/2007/10/the-wicket-component-model-explained/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 05:25:37 +0000</pubDate>
		<dc:creator>deevis</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web Frameworks]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://javatech.org/?p=12</guid>
		<description><![CDATA[Wicket is a Java/HTML approach to building the guts of a J2EE web application, and I must admit that when I first heard of it I was both eagerly excited (to try it) and more than mildly pessimistic (that an application written in Wicket would be maintainable beyond a certain trivial size ).  The [...]]]></description>
			<content:encoded><![CDATA[<p>Wicket is a Java/HTML approach to building the guts of a J2EE web application, and I must admit that when I first heard of it I was both eagerly excited (to try it) and more than mildly pessimistic (that an application written in Wicket would be maintainable beyond a certain trivial size ).  The past few months I&#8217;ve heard only good things about Wicket, and haven&#8217;t heard anything in the negative.  I&#8217;m eager to benchmark it and check it out for performance on the Application Servers, but figure first things first &#8211; let&#8217;s tear it apart, see what makes it tick, and find out what really matters in Wicket.</p>
<p>So, basically everything ( apart from the <strong>WebApplication </strong>itself ) in Wicket is a <strong>Component</strong>.  Now the Wicket Component is no slouch; it&#8217;s a 3,000+ line abstract class with loads of functionality built right in.  I&#8217;ll dig into this base class later, but for now, let&#8217;s focus on the two immediate subclasses of Component: <strong>MarkupContainer </strong>and <strong>WebComponent</strong>.</p>
<p><strong>MarkupContainer</strong>s include things like: <strong>WebPage</strong>, <strong>RedirectPage</strong>, <strong>Form</strong>, <strong>FormComponent</strong>, <strong>FormComponentLabel</strong>, <strong>Button</strong>, <strong>CheckBox</strong>, <strong>TextArea</strong>, and <strong>TextField</strong>.</p>
<p><strong>WebComponent</strong>s include things like: <strong>Image</strong>, <strong>Include</strong>, <strong>Label</strong>.</p>
<p>I&#8217;m surprised, initially, to find controls such as <strong>Button</strong>, <strong>CheckBox</strong>, <strong>TextArea </strong>and <strong>TextField </strong>as <strong>MarkupContainers </strong>and not as <strong>WebComponents</strong>.</p>
<p>Also of interest is that subclassing is used to achieve behavior that might seem best placed in attributes of some of the classes.  For example, to create a hidden input field, I might expect to create a <strong>TextField </strong>instance and set its visible property false.   Instead, <strong>TextField </strong>is subclassed as <strong>HiddenField</strong>.  This is also true for adding password characteristics (<strong>PasswordTextField</strong>) or making the input required (<strong>RequiredTextField</strong>).  This same pattern of subclassing is used most thoroughly for <strong>Links </strong>( <strong>AjaxFallbackLink</strong>, <strong>BookmarkablePageLink</strong>, <strong>DownloadLink</strong>, <strong>PageLink</strong>, <strong>PopupCloseLink</strong>, and <strong>ResourceLink </strong>).</p>
<p>So, there&#8217;s a very rich Component-Model existing within Wicket for creating all the elements you&#8217;ll need on a web page, but where does the web page come from?  For this we look to another subclass of <strong>MarkupContainer</strong>. The class <strong>WebPage </strong>is the primary analog to a conventional webpage.  So much so, that the Wicket convention is actually to sit an HTML file of the same (prefix) name as the (simpleName) of the Java class extending <strong>WebPage</strong>.  That is, if you were to write a new class called FunPage like this:<br />
<code><br />
package org.javatech.wicket.examples;<br />
class FunPage extends WebPage {}<br />
</code></p>
<p>Then you would have an HTML file named FunPage.html located in org/javatech/wicket/examples which would contain the HTML used in rendering the webpage.</p>
<p>Cool.</p>
<p>But this is still a bit too abstract &#8211; should we really bother writing (yet another) Hello World application for Wicket?  No &#8211; there are plenty of them out there.  Instead, let&#8217;s discuss how the Components get added to the WebPage and then how the HTML is able to provide the layout used to create the desired web page.   And since every website since the beginning of time has forms on it, let&#8217;s show how to add a form.</p>
<p><strong>Adding a form using Wicket Components and a Wicket WebPage</strong>:</p>
<p>When I think of an html form, my mind drifts towards thoughts of Maps where the form element&#8217;s names are the keys and the values entered by the user are the corresponding values.  Then there are just a few other lingering details like the form&#8217;s name, whether to use POST or GET, and to what URL the form data should be sent.  Having isolated the Component <strong>Form</strong> as the candidate for the job, I&#8217;m immediately stunned by the Constructor which takes an id and/or an <strong>IModel</strong>.  The id makes sense.  I mean, really, every html element should have one.  But what on god&#8217;s green earth is an <strong>IModel</strong>?  I know one thing, it&#8217;s an interface &#8211; score one for the I-school of thought!  Upon inspection, it turns out that an <strong>IModel </strong>is simply a wrapper for a model object used by a component.  It provides methods to get/set the actual model object and to drill down into a nested model object.  This being learned, I see that it isn&#8217;t required for such humble beginnings as just getting a form to work and shall be forgotten for at least two days now.</p>
<p>So, our first form will be called DemoForm and starts out on the Java side as:<br />
<code><br />
package org.javatech.wicket.pages;</code></p>
<p>import wicket.markup.html.WebPage;<br />
import wicket.markup.html.basic.Label;<br />
import wicket.markup.html.form.Button;<br />
import wicket.markup.html.form.Form;<br />
import wicket.markup.html.form.TextField;</p>
<p>public class DemoForm extends WebPage {</p>
<p>public DemoForm() {<br />
Form f = new Form( &#8220;myForm&#8221; );<br />
f.add( new TextField( &#8220;myTextField&#8221; ));<br />
Button button = new Button(&#8221;mySubmitButton&#8221;);<br />
f.add( button );<br />
f.setDefaultButton( button );<br />
add( f );<br />
}<br />
}<br />
Which should look something like:</p>
<form>
<input type="text" />
<input onclick="alert('Javatech sample');return false;" type="submit" /> </form>
<p>When I start Wicket and hit the URL, I get an exception, because I haven&#8217;t created the appropriate HTML file.<br />
<strong>WicketMessage: Markup of type &#8216;html&#8217; for component &#8216;org.javatech.wicket.pages.LandingPage&#8217; not found</strong></p>
<p>So, it turns out that you need to have EVERY component added in the Java represented in the corresponding HTML.  In this case, the HTML would need to contain:<br />
<code><br />
&lt;form wicket:id="myForm"&gt;<br />
&lt;input wicket:id="myTextField" /&gt;<br />
&lt;input type="submit" wicket:id="mySubmitButton"&gt;&lt;/button&gt;<br />
&lt;/form&gt;<br />
</code></p>
<p>So I gotta admit that my Spidey-sense is tingling at this point.  This has the potential to grow quite ugly &#8211; having to manage the same essential layout in both Java code and in the HTML.  More on that later &#8211; so, now my form comes up and works.<br />
I can type into the textbox and click on the button.  When I do click on the button, however, I&#8217;m taken to a urHell:<br />
<strong>http://localhost:8080/hello_wicket/?wicket:interface=:24:myForm::IFormSubmitListener</strong> &#8211; SAY WHAT?</p>
<p>So, enough suspense.  Here are the remaining hoops that Wicket requires you to jump through:<br />
1) You must have a backing model object for your form.<br />
2) You must explicitly implement onSubmit() on the Form object being used.<br />
3) The onSubmit() method will ( in Java code! ) specify the response page for the form.<br />
4) You must (manually) pass the model object to the Confirmation Page.</p>
<p>We&#8217;ll have a new class called DemoFormModel defined as:</p>
<p><code><br />
package org.javatech.wicket.pages;</code></p>
<p>import java.io.Serializable;</p>
<p>public class DemoFormModel implements Serializable {</p>
<p>private String myTextField;</p>
<p>public String getMyTextField() {<br />
return myTextField;<br />
}</p>
<p>public void setMyTextField(String myTextField) {<br />
this.myTextField = myTextField;<br />
}<br />
}<br />
An instance of DemoFormModel will be instantiated in the constructor of DemoForm and will then be passed ( in the new onSubmit() method ) to the DemoFormConfirmation WebPage.  DemoForm now looks like:</p>
<p><code><br />
package org.javatech.wicket.pages;</code></p>
<p>import wicket.markup.html.WebPage;<br />
import wicket.markup.html.form.Button;<br />
import wicket.markup.html.form.Form;<br />
import wicket.markup.html.form.TextField;<br />
import wicket.model.CompoundPropertyModel;</p>
<p>public class DemoForm extends WebPage {</p>
<p>public DemoForm() {<br />
Form f = new Form( &#8220;myForm&#8221; ) {<br />
@Override<br />
protected void onSubmit() {<br />
DemoFormModel o = (DemoFormModel)getModelObject();<br />
DemoFormConfirmation landingPageSubmission = new DemoFormConfirmation( o );<br />
setResponsePage( landingPageSubmission );<br />
}</p>
<p>};<br />
f.setModel( new CompoundPropertyModel( new DemoFormModel() ));<br />
f.add( new TextField( &#8220;myTextField&#8221; ));<br />
Button button = new Button(&#8221;mySubmitButton&#8221;);<br />
f.add( button );<br />
f.setDefaultButton( button );<br />
add( f );<br />
}<br />
}<br />
The Java and HTML for DemoFormConfirmation look like:</p>
<p>DemoFormConfirmation.java<br />
<code><br />
package org.javatech.wicket.pages;</code></p>
<p>import wicket.markup.html.WebPage;<br />
import wicket.markup.html.basic.Label;</p>
<p>public class DemoFormConfirmation extends WebPage {</p>
<p>public DemoFormConfirmation(DemoFormModel o) {<br />
this.add( new Label( &#8220;myTextField&#8221;, o.getMyTextField() ));<br />
}<br />
}<br />
DemoFormConfirmation.html<br />
<code><br />
You entered:&lt;span wicket:id="myTextField"&gt;&lt;/span&gt;<br />
</code></p>
<p>So, in a mighty big nutshell, we needed to create 5 files to pull off a simple form submission and confirmation:</p>
<p>DemoForm.java, DemoForm.html, DemoFormModel.java, DemoFormConfirmation.java, and DemoFormConfirmation.html.</p>
<p>DemoForm specifies the form, the components on the form, the model object the components will bind to, and the form&#8217;s onSubmit() method.  The onSubmit() method is responsible for retrieving the model object, instantiating the DemoFormConfirmation instance with that object, and finally redirecting to that instance.</p>
<p>Then, DemoForm.html needs to reference the components added in DemoForm.java by the same String id&#8217;s and DemoFormModel.java needs to have properties which match these names.  DemoFormConfirmation.java and DemoFormConfirmation.html have the same sort of coupling but on a smaller scale ( 1 field only ).</p>
<p>The big lesson here is that naming conventions are super important and having a reliable, predictable mechanism for coming up with wicket id&#8217;s is going to be essential.  Fortunately, there are numerous ways to do this with the simplest being a ModelObject first driven development cycle.  Once your ModelObject is created, then it&#8217;s fieldNames should be used verbatim in both the Components added on the Java side and the wicket:id&#8217;s in the HTML.</p>
<p>I&#8217;m not particularly excited about hardcoding site navigation inside of onSubmit() methods in Java code.  I&#8217;ve been completely brainwashed that this should be configurable behavior, but I&#8217;ve seen configurable behavior become a royal pain in the butt and am willing to entertain this backward seeming restriction.  Besides, there are way to dynamically wire this stuff together if one is determined to do so ( custom code at this point in time ).</p>
]]></content:encoded>
			<wfw:commentRss>http://javatech.org/2007/10/the-wicket-component-model-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
