<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3155249211158577195</id><updated>2012-01-19T23:18:39.137-08:00</updated><category term='Business'/><category term='Data'/><category term='View'/><category term='J2EE Core'/><category term='Database'/><category term='Deployment'/><category term='Tools'/><category term='Money'/><category term='Build'/><category term='Spring'/><category term='Security'/><category term='Opinions'/><category term='Application'/><category term='Testing'/><title type='text'>The Java Web 2.0 Application Stack</title><subtitle type='html'>Tips from the Bottom to the Top of the Stack.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-2214095512422143940</id><published>2011-12-06T18:00:00.001-08:00</published><updated>2011-12-13T13:34:23.334-08:00</updated><title type='text'>Win 7 Security 2012 Virus Infection</title><content type='html'>Recently a customer of mine had a virus on his computer called Win 7 Security 2012.  This Win 7 Security 2012 is a rogue anti-spyware application, which is often downloaded and installed by a Trojan, through browser security holes or via other unconventional unethical mechanisms.  Once installed, Win 7 Security 2012 will display notifications of imaginary security and privacy risks in its attempts to get the user to purchase the full version and may generate system slowdown and instability.  This program is extremely difficult to manually remove.  I noticed that this customer also had McAfee Security Center running and updated.  I ran the scan and McAfee did not pick up this malware.  Two thumbs down.  I was able to find a free anti-virus to remove this virus available online.  If you are struggling with fixing this virus, let me know of your problems by commenting below and I'll be sure to get back to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-2214095512422143940?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/2214095512422143940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/12/win-7-security-2012-virus-infection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2214095512422143940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2214095512422143940'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/12/win-7-security-2012-virus-infection.html' title='Win 7 Security 2012 Virus Infection'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-3059601161124683893</id><published>2011-12-05T14:20:00.000-08:00</published><updated>2011-12-05T14:25:37.155-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>Changing the Session Identifier (JSESSIONID) on Authentication.  Protecting against Session Fixation attacks in Java Web Environments</title><content type='html'>It is a standard security practice to change the session identifier (JSESSIONID) after a successful login or authentication. &lt;br /&gt;&lt;br /&gt;The attack scenario with this vulnerability is that a user can open a browser on a shared terminal and record the session identifier set by the application. Later when any other user of the system logs into the application without closing instances of that browser the same cookie will be used to track the victim's session. &lt;br /&gt;&lt;br /&gt;Alternatively, if the application is susceptible to cross-site scripting on a publicly accessible page (most damagingly the home page), an attacker can use this vulnerability to learn the value of the session identifier, because the cookie does not change since it was first set.  The attacker now knows the value of the session token can hijack the victim's session.  This is a limited session fixation attack where the attacker does not have control over the value of the session identifier, but is able to know its value through various means before and after a user authenticates.&lt;br /&gt;&lt;br /&gt;Most times, invalidating the session and creating a new one may suffice.  However, if you are storing variables or objects, you may need to carry these variables or objects from the old session into the new session.  &lt;br /&gt;&lt;br /&gt;Below is a javax.servlet.Filter.  This filter protects against the Session Fixation attacks described above.  The filter looks for a specific session attribute, the (NEW_SESSION_INDICATOR) attribute.  If one is found, the filter copies out relevant session data to a map, invalidates the session, creates a new session and loads the new session with the old session data.&lt;br /&gt;&lt;br /&gt;The filter is simply mapped in your web.xml.  Any place you successfully authenticate, an attribute is added to the session (NEW_SESSION_INDICATOR).  &lt;br /&gt;&lt;br /&gt;The code below follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import java.io.IOException;&lt;br /&gt;import java.util.Enumeration;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import javax.servlet.Filter;&lt;br /&gt;import javax.servlet.FilterChain;&lt;br /&gt;import javax.servlet.FilterConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.ServletRequest;&lt;br /&gt;import javax.servlet.ServletResponse;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpSession;&lt;br /&gt;&lt;br /&gt;public class NewSessionFilter implements Filter {&lt;br /&gt;  &lt;br /&gt;  private static Logger logger = Logger.getLogger(NewSessionFilter.class.getName());&lt;br /&gt; &lt;br /&gt;  public static final String NEW_SESSION_INDICATOR = "filter.NewSessionFilter";&lt;br /&gt;  &lt;br /&gt;  public void destroy() {}&lt;br /&gt;  &lt;br /&gt;  @SuppressWarnings("unchecked")&lt;br /&gt;  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)&lt;br /&gt;        throws IOException, ServletException {&lt;br /&gt;    if (request instanceof HttpServletRequest){&lt;br /&gt;      HttpServletRequest httpRequest = (HttpServletRequest) request;&lt;br /&gt;      if (httpRequest.getSession(false) != null &amp;&amp; &lt;br /&gt;          httpRequest.getSession(false).getAttribute(NEW_SESSION_INDICATOR) != null&lt;br /&gt;      ){&lt;br /&gt;        //copy session attributes from new session to a map. &lt;br /&gt;        HttpSession session = httpRequest.getSession();&lt;br /&gt;        HashMap&lt;String, Object&gt; old = new HashMap&lt;String, Object&gt;();&lt;br /&gt;        Enumeration&lt;string&gt; keys = (Enumeration&lt;string&gt;) session.getAttributeNames();&lt;br /&gt;        while (keys.hasMoreElements()) {&lt;br /&gt;          String key = keys.nextElement();&lt;br /&gt;          if (!NEW_SESSION_INDICATOR.equals(key)) {&lt;br /&gt;            old.put(key, session.getAttribute(key));&lt;br /&gt;            session.removeAttribute(key);&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;        logger.info("session invalidated on " + httpRequest.getRequestURI());&lt;br /&gt;  &lt;br /&gt;        //invalidation session and create new session.&lt;br /&gt;        session.invalidate();&lt;br /&gt;        session = httpRequest.getSession(true);&lt;br /&gt; &lt;br /&gt;        //copy key value pairs from map to new session.&lt;br /&gt;        for (Map.Entry&lt;String, Object&gt; entry : old.entrySet()) {&lt;br /&gt;          session.setAttribute(entry.getKey(), entry.getValue());&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        logger.info((new StringBuffer()).append("new Session for URI '")&lt;br /&gt;             .append(httpRequest.getRequestURI()).append("':")&lt;br /&gt;             .append( session.getId()).toString());&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    chain.doFilter(request, response);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void init(FilterConfig filterconfig) {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Any questions about this posting or filter, comment below and I'll be sure to answer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-3059601161124683893?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/3059601161124683893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/12/changing-session-identifier-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3059601161124683893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3059601161124683893'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/12/changing-session-identifier-on.html' title='Changing the Session Identifier (JSESSIONID) on Authentication.  Protecting against Session Fixation attacks in Java Web Environments'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7840469872099355488</id><published>2011-11-30T10:54:00.000-08:00</published><updated>2011-12-13T13:48:05.397-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>Steps to a CAPTCHA Implementation using JAVA/JSP</title><content type='html'>CAPTCHA can quickly and easily protect your web application against brute force and bot attacks or abuse.  There are just a few simple steps to a CAPTCHA implementation in Java/JSP.  The solution is simple and the documentation is quite clear, so I only provide the steps and quick links to those resources.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 1: Signup for a CAPTCHA account and generate keys for your website domains.&lt;/b&gt;&lt;br /&gt;Navigate to &lt;a href="http://www.google.com/recaptcha"&gt;http://www.google.com/recaptcha&lt;/a&gt; and signup for an account.  After obtaining a login, generate keys for your domain.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 2: Find the developers guide for CAPTCHA &lt;/b&gt;&lt;br /&gt;Navigate to &lt;a href="http://code.google.com/apis/recaptcha/intro.html"&gt;http://code.google.com/apis/recaptcha/intro.html&lt;/a&gt;.  From here, you'll find all the information you need.  Notice in the left hand menu, there's a Java/JSP Plugin link available.  Click into that.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 3: Download the Java/JSP Plugin and Implement&lt;/b&gt;&lt;br /&gt;Navigate to &lt;a href="http://code.google.com/apis/recaptcha/docs/java.html"&gt;http://code.google.com/apis/recaptcha/docs/java.html&lt;/a&gt; where you will find a link to download the plugin, which is a set of Java classes.  Extract the source files into your web applications java source tree.  The directions on the page are extremely straight forward.&lt;br /&gt;&lt;br /&gt;The form page looks like:&lt;pre&gt; &lt;br /&gt;&lt;%@ page import="net.tanesha.recaptcha.ReCaptcha" %&gt;&lt;br /&gt;&lt;%@ page import="net.tanesha.recaptcha.ReCaptchaFactory" %&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;form action="" method="post"&amp;gt;&lt;br /&gt;   &lt;%&lt;br /&gt;      ReCaptcha c = ReCaptchaFactory.newReCaptcha("your_public_key", "your_private_key", false);&lt;br /&gt;      out.print(c.createRecaptchaHtml(null, null));&lt;br /&gt;   %&gt;&lt;br /&gt;   &amp;lt;input type="submit" value="submit" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;You also may be using reCaptcha over https.  In that case, follow the instructions from this page: &lt;a href="http://code.google.com/apis/recaptcha/docs/tips.html"&gt;http://code.google.com/apis/recaptcha/docs/tips.html&lt;/a&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&lt;br /&gt;   src="https://www.google.com/recaptcha/api/challenge?k=your_public_key"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;noscript&amp;gt;&lt;br /&gt;   &amp;lt;iframe src="https://www.google.com/recaptcha/api/noscript?k=your_public_key"&lt;br /&gt;       height="300" width="500" frameborder="0"&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;   &amp;lt;textarea name="recaptcha_challenge_field" rows="3" cols="40"&amp;gt;&lt;br /&gt;   &amp;lt;/textarea&amp;gt;&lt;br /&gt;   &amp;lt;input type="hidden" name="recaptcha_response_field"&lt;br /&gt;       value="manual_challenge"&amp;gt;&lt;br /&gt;&amp;lt;/noscript&amp;gt;&lt;br /&gt;&lt;/pre&gt;When the form is submitted, the reCaptcha entries can be verified easily.&lt;pre&gt;&lt;br /&gt;&amp;lt;%@ page import="net.tanesha.recaptcha.ReCaptchaImpl" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page import="net.tanesha.recaptcha.ReCaptchaResponse" %&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;html&amp;gt;&lt;br /&gt;       &amp;lt;body&amp;gt;&lt;br /&gt;       &amp;lt;%&lt;br /&gt;        String remoteAddr = request.getRemoteAddr();&lt;br /&gt;        ReCaptchaImpl reCaptcha = new ReCaptchaImpl();&lt;br /&gt;        reCaptcha.setPrivateKey("your_private_key");&lt;br /&gt;&lt;br /&gt;        String challenge = request.getParameter("recaptcha_challenge_field");&lt;br /&gt;        String uresponse = request.getParameter("recaptcha_response_field");&lt;br /&gt;        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);&lt;br /&gt;&lt;br /&gt;        if (reCaptchaResponse.isValid()) {&lt;br /&gt;          out.print("Answer was entered correctly!");&lt;br /&gt;        } else {&lt;br /&gt;          out.print("Answer is wrong");&lt;br /&gt;        }&lt;br /&gt;      %&gt;&lt;br /&gt;      &amp;lt;/body&amp;gt;&lt;br /&gt;    &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Step 4: Give the JVM a time interval to refresh its DNS cache&lt;/b&gt;&lt;br /&gt;By default the Java Virtual Machine (JVM) caches all DNS lookups forever instead of using the time-to-live (TTL) value which is specified in the DNS record of each host.  To fix this issue for good, you can pass -Dsun.net.inetaddr.ttl=30 to your app-server (this tells Java to only cache DNS for 30 seconds).&lt;br /&gt;&lt;br /&gt;There is a great article on the JVM and DNS caching.  A must read at &lt;a href="http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/1887"&gt;http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/1887&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The steps above are quick and easy to implement, post back and let me know if you have any issues with the implementation and I will try and assist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7840469872099355488?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7840469872099355488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/steps-to-captcha-implementation-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7840469872099355488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7840469872099355488'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/steps-to-captcha-implementation-using.html' title='Steps to a CAPTCHA Implementation using JAVA/JSP'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5018790696219202828</id><published>2011-11-17T11:51:00.000-08:00</published><updated>2011-12-01T11:07:22.045-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>Disabling certain HTTP Methods in Tomcat</title><content type='html'>HTTP protocol defines eight methods that can be performed on a resource on the HTTP server.  GET, POST and HEAD are the most common methods that are used to access information provided by a web server. The other methods such as OPTIONS, PUT, DELETE, CONNECT and TRACE are not normally used in the general operation of a web server can potentially pose a security risk for any web application. So it is good practice to restrict the response to specific HTTP Methods.  &lt;br /&gt;&lt;br /&gt;First, determine which HTTP Methods your installation is responding too.  I use browser plug-ins that enable me to submit HTTP requests, specifying the URL and HTTP method. There are various plugins available for Chrome and Firefox and I do not make any recommendations here.&lt;br /&gt;&lt;br /&gt;Second, according to your test results, configure your Tomcat installtion to not respond for certain HTTP Methods.  This can be configured at the instance level by inserting a &amp;lt;security-constraint&amp;gt; element directly under the &amp;lt;web-app&amp;gt; element, in the installations web.xml file located at.  &lt;br /&gt;[tomcatinstallation]/conf/web.xml&lt;br /&gt;&lt;br /&gt;Below is the added configuration.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;security-constraint&amp;gt;&lt;br /&gt;&amp;lt;web-resource-collection&amp;gt;&lt;br /&gt;&amp;lt;web-resource-name&amp;gt;restricted methods&amp;lt;/web-resource-name&amp;gt;&lt;br /&gt;&amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;lt;http-method&amp;gt;TRACE&amp;lt;/http-method&amp;gt;&lt;br /&gt;&amp;lt;http-method&amp;gt;PUT&amp;lt;/http-method&amp;gt;&lt;br /&gt;&amp;lt;http-method&amp;gt;OPTIONS&amp;lt;/http-method&amp;gt;&lt;br /&gt;&amp;lt;http-method&amp;gt;DELETE&amp;lt;/http-method&amp;gt;&lt;br /&gt;&amp;lt;/web-resource-collection&amp;gt;&lt;br /&gt;&amp;lt;auth-constraint /&amp;gt;&lt;br /&gt;&amp;lt;/security-constraint&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The configuration above will disable the HTTP Methods TRACE, PUT, OPTIONS or DELETE.  &lt;br /&gt;&lt;br /&gt;Any questions, comment and I'll be sure to answer them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5018790696219202828?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5018790696219202828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/disabling-certain-http-methods-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5018790696219202828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5018790696219202828'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/disabling-certain-http-methods-in.html' title='Disabling certain HTTP Methods in Tomcat'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7518749623436115430</id><published>2011-11-03T07:50:00.000-07:00</published><updated>2011-12-01T11:08:44.467-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE Core'/><title type='text'>javax.net.ssl.SSLException: Received fatal alert: unexpected_message</title><content type='html'>If you are attempting to establish an SSL Connection as a client to a server and getting this error at the very end of the SSL Handshake, then check the server settings for client authentication.  &lt;br /&gt;&lt;br /&gt;Client Authentication is the ability of a webserver to verify the client, whether it be a browser or other application. &lt;br /&gt;&lt;br /&gt;Setting client authentication does reduce the level of security enabled, so this decision should be made based on your needs and threat model.  &lt;br /&gt;&lt;br /&gt;If you do require client authentication, there are two great articles below:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sandbox.rulemaker.net/ngps/m2/howto.ca.html"&gt;HOWTO: Creating your own CA with OpenSSL&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.freebsddiary.org/openssl-client-authentication.php"&gt;Client Authentication with SSL&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If you have any JSSE/OpenSSL questions, feel free to comment and I'll try and get back to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7518749623436115430?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7518749623436115430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/javaxnetsslsslexception-received-fatal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7518749623436115430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7518749623436115430'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/javaxnetsslsslexception-received-fatal.html' title='javax.net.ssl.SSLException: Received fatal alert: unexpected_message'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-6677736600093271959</id><published>2011-11-03T07:31:00.000-07:00</published><updated>2011-12-01T11:09:02.531-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE Core'/><title type='text'>SSL Connections over a proxy using JSSE</title><content type='html'>The Java Secure Socket Extension (JSSE) enables secure Internet communications. It provides a framework and an implementation for a Java version of the SSL and TLS protocols and includes functionality for data encryption, server authentication, message integrity, and optional client authentication. Using JSSE, developers can provide for the secure passage of data between a client and a server running any application protocol, such as Hypertext Transfer Protocol (HTTP), Telnet, or FTP, over TCP/IP.&lt;br /&gt;&lt;br /&gt;The https protocol is similar to http, but https first establishes a secure channel via SSL/TLS sockets and then verifies the identity of the peer before requesting/receiving data. javax.net.ssl.HttpsURLConnection extends the java.net.HttpsURLConnection class, and adds support for https-specific features. Upon obtaining a HttpsURLConnection, you can configure a number of http/https parameters before actually initiating the network connection via the method URLConnection.connect.&lt;br /&gt;&lt;br /&gt;In some situations, it is desirable to specify the SSLSocketFactory that an HttpsURLConnection instance uses. For example, you may wish to tunnel through a proxy type which is NOT supported by the default implementation.  The new SSLSocketFactory could return sockets that have already performed all necessary tunneling, thus allowing HttpsURLConnection to use additional proxies.&lt;br /&gt;&lt;br /&gt;Post your issue below, and I'll try and answer your JSSE questions.   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html"&gt;JSSE Reference Guide for Java SE6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#HostnameVerifier"&gt;JSSE Reference Guide for Java SE6 - Hostname Verifier&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/1,5.0/docs/api/javax/net/ssl/SSLSocketFactory.html"&gt;javadoc: javax.net.ssl.SSLSocketFactory&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/1,5.0/docs/api/javax/net/ssl/HttpsURLConnection.html"&gt;javadoc: javax.net.ssl.HttpsURLConnection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/1,5.0/docs/api/java/net/URLConnection.html"&gt;javadoc: java.net.URLConnection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/1,5.0/docs/api/java/net/URL.html#openConnection%28%29"&gt;javadoc: java.net.URL.openConnection()&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-6677736600093271959?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/6677736600093271959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/ssl-connections-over-proxy-using-jsse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6677736600093271959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6677736600093271959'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/11/ssl-connections-over-proxy-using-jsse.html' title='SSL Connections over a proxy using JSSE'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5940661681380513445</id><published>2011-08-27T18:24:00.001-07:00</published><updated>2011-12-01T11:09:18.777-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Opinions'/><title type='text'>Photo Card</title><content type='html'>&lt;div class="sflyProductPreviewWidget" style="width:425px; height:494px;"&gt;&lt;div class="sflyProductPreviewWidgetTop" style="height:6px; background-image:url(http://cdn.staticsfly.com/img_/share/preview/msc/widget/top.gif);"&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewWidgetCenter" style="height:482px; padding: 0 6px 0 6px; background-image:url(http://cdn.staticsfly.com/img_/share/preview/msc/widget/bg.gif); background-repeat:repeat-y;"&gt;&lt;div class="sflyProductPreviewLogo" style="width: 105px; height: 34px; padding: 14px 0 0 14px;"&gt;&lt;img src="http://cdn.staticsfly.com/img_/share/preview/msc/widget/logo.gif" style="padding: 0; background: #ffffff; border: none; box-shadow: none;"&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewContainer" style="height:350px; text-align:center; padding: 0;"&gt;&lt;a href="http://share.shutterfly.com/action/welcome?sid=0CcOWLFs0cM3Kw&amp;amp;cid=SFLYOCWIDGET&amp;amp;eid=115"&gt;&lt;img src="http://images-community.shutterfly.com/prs/v1/0CcOWLFs0cM-/0CcOWLFs0cM-cW/p/67b0de21b3127d902548/JPEG/1314494682000/0/" style="padding: 0; background: #ffffff; border: none;  box-shadow: none;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewMessageContainer" style="height:55px; background-color:#f4f4e9; text-align:center; padding: 15px 0 15px 0; line-height: 19px;"&gt;&lt;div class="sflyProductPreviewTitle" style="font-family: arial, sans-seris; font-size: 15px; color: #333333; font-weight: bold;"&gt;&lt;span&gt;Jungle Favor Birthday&lt;/span&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewSEOText" style="font-family: arial, sans-seris; font-size: 13px; color: #333333;"&gt;&lt;span&gt;Shop &lt;a href="http://www.shutterfly.com/cards-stationery/birthday-invitations" style="color: #6666cc;"&gt;birthday cards and invitations&lt;/a&gt; at Shutterfly.com.&lt;/span&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewViewCollection" style="font-family: arial, sans-seris; font-size: 13px; color: #333333;"&gt;&lt;span&gt;View the entire &lt;a href="http://www.shutterfly.com/cards-stationery" style="color: #6666cc;"&gt;collection&lt;/a&gt; of cards.&lt;/span&gt;&lt;/div&gt;&lt;img width="1" height="1" border="0" style="padding: 0; background: #ffffff; border: none; box-shadow: none;" src="https://os.shutterfly.com/b/ss/sflyshareprod/1/H.15/111?pageName=sharekey&amp;c1=msc&amp;c2=blogger" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="sflyProductPreviewWidgetBottom" style="height:6px; background-image:url(http://cdn.staticsfly.com/img_/share/preview/msc/widget/bottom.gif);"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5940661681380513445?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5940661681380513445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/08/photo-card.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5940661681380513445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5940661681380513445'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2011/08/photo-card.html' title='Photo Card'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-9092937434704075385</id><published>2010-11-20T08:49:00.000-08:00</published><updated>2011-12-01T11:09:41.447-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Build'/><title type='text'>Upgrading your Eclipse workspace to a new version</title><content type='html'>Upgrading my eclipse workspace to a new version.  This &lt;a href="http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-2.htm"&gt;article&lt;/a&gt; did the trick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-9092937434704075385?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-2.htm' title='Upgrading your Eclipse workspace to a new version'/><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/9092937434704075385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/upgrading-your-eclipse-workspace-to-new.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/9092937434704075385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/9092937434704075385'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/upgrading-your-eclipse-workspace-to-new.html' title='Upgrading your Eclipse workspace to a new version'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5808582261867827075</id><published>2010-11-20T07:48:00.000-08:00</published><updated>2010-11-20T07:52:12.586-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Opinions'/><title type='text'>Download the Girl Talk - All Day album</title><content type='html'>Obviously a lot of work went into this sampling mixing mish mosh.  What makes it cooler is a free download.  Click &lt;a href="http://illegal-art.net/allday/"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5808582261867827075?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://illegal-art.net/allday/' title='Download the Girl Talk - All Day album'/><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5808582261867827075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/download-girl-talk-all-day-album.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5808582261867827075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5808582261867827075'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/download-girl-talk-all-day-album.html' title='Download the Girl Talk - All Day album'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-1182449689449100367</id><published>2010-11-06T16:49:00.000-07:00</published><updated>2010-11-20T07:51:32.073-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>JAX-RS @Path Precedence Rules</title><content type='html'>The other day I needed to figure out how the JAX-RS provider resolves ambiguous path expressions passed in the @javax.ws.rs.Path annotation.  I learned about the provider's precedence rules and wanted to document them here with a short example.  &lt;br /&gt;&lt;br /&gt;For example, say we have the following @javax.ws.rs.Path expressions in the following class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Path("/users") &lt;br /&gt;public class UserResource {&lt;br /&gt;&lt;br /&gt;  @GET&lt;br /&gt;  @Path("{id : .+}")&lt;br /&gt;  public String getUser(@PathParam("id") String id){&lt;br /&gt;    ....&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  @GET&lt;br /&gt;  @Path("{id : .+}/address")&lt;br /&gt;  public String getAddress(@PathParam("id") String id){&lt;br /&gt;    ....&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that .+ will match any stream of characters after "/users".&lt;br /&gt;Now, suppose the following GET request was submitted.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;GET /users/32/address&lt;/pre&gt;&lt;br /&gt;The request actually matches both expressions, but the request would be routed to the getAddress(@PathParam("id") String id) method.  The JAX-RS provider determines which method to call based on a set of precedence rules.  On deployment, the JAX-RS provider gathers and sorts all URI expressions contained within all known @Path annotations based on the following logic:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The number of literal characters contained within the expression, sorted in descending order.  In the example above, the getAddress(@PathParam("id") String id) method gets precedence over the getUser(@PathParam("id") String id) method.  The getUser(@PathParam("id") String id) method contains 7 literal characters (/users/). The getAddress @PathParam("id") String id) method contains 14 literal characters (/users/ + address).&lt;/li&gt;&lt;li&gt;The number of template expressions within the expression, sorted in descending order.  For example, an expression containing {id}/{name} would get precedence over {id}.&lt;/li&gt;&lt;li&gt;Finally, the number of regular expressions contained within the expression.  For example, {id : .+} would get precedence over {id}.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;In closing, the following URI expressions are sorted by the order of precedence above.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;/users/{id}/{name}/address&lt;/li&gt;&lt;li&gt;/users/{id : .+}/address&lt;/li&gt;&lt;li&gt;/users/{id}/address&lt;/li&gt;&lt;li&gt;/users/{id : .+}&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Any questions, leave a comment and I'll be sure to answer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-1182449689449100367?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/1182449689449100367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/jax-rs-path-precedence-rules.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1182449689449100367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1182449689449100367'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/11/jax-rs-path-precedence-rules.html' title='JAX-RS @Path Precedence Rules'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5328355177753390620</id><published>2010-01-11T18:14:00.000-08:00</published><updated>2010-01-11T18:30:28.270-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Spring JDBC Tutorial with Transaction Management</title><content type='html'>I recently wrote a post on &lt;a href="http://j2eewebprogrammer.blogspot.com/2008/12/spring-and-jdbc-tutorial.html"&gt;Spring JDBC&lt;/a&gt; with some good and positive feedback from the user community.&lt;br /&gt;&lt;br /&gt;In this posting, I will present a more in-depth tutorial and a data access strategy that I use for projects accessing a single data source or database.  This tutorial makes use of &lt;a href="http://www.springsource.com/products/enterprise"&gt;Spring 2.5.6&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;In this tutorial, I use &lt;a href="http://dev.mysql.com/downloads/"&gt;MySQL&lt;/a&gt; as the data source.&lt;br /&gt;Follow the installation instructions and make note of your username and password. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;REQUIRED LIBRARIES&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, download all the necessary libraries needed to execute this tutorial:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dev.mysql.com/downloads/connector/j/5.1.html"&gt;JDBC driver for MySQL, MySQL Connector/J.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springsource.org/download"&gt;Spring Framework 2.5.6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://commons.apache.org/"&gt;Commons Project&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;commons-beanutils-1.8.2&lt;/li&gt;&lt;li&gt;commons-collections-3.2.1&lt;/li&gt;&lt;li&gt;commons-configuration-1.6&lt;/li&gt;&lt;li&gt;commons-dbcp-1.2.2&lt;/li&gt;&lt;li&gt;commons-digester-2.0&lt;/li&gt;&lt;li&gt;commons-lang-2.4&lt;/li&gt;&lt;li&gt;commons-logging-1.1.1&lt;/li&gt;&lt;li&gt;commons-pool-1.5.4&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;PACKAGE STRUCTURE&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we'll define our package structure for the data project and we provide a description for each package.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;com.edwardwebnerd.persistence&lt;br /&gt;&lt;ul&gt;&lt;li&gt;adapter - single SQL operations and implementations.&lt;/li&gt;&lt;li&gt;dbcp - database connection pool and configurations.&lt;/li&gt;&lt;li&gt;domain - domain models&lt;/li&gt;&lt;li&gt;exception - exception classes&lt;/li&gt;&lt;li&gt;transmanager - business level services &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;These are very rudimentary package definitions but they do provide us with some structure and conventions in our development.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;CREATE THE DATABASE TABLE&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;First, we'll create a user table in our database.  The table is very simple and only meant for illustrative purposes.  &lt;br /&gt;&lt;pre&gt;CREATE TABLE user (&lt;br /&gt; id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),&lt;br /&gt; username VARCHAR(30),&lt;br /&gt; email VARCHAR(30),&lt;br /&gt; password VARCHAR(50)&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We'll provide Spring JDBC access the user table on a single access level, within the adapter package.  After that, we'll introduce Spring JDBC transaction management facilities within the transmanager package to provide data services which may be comprised of one or more calls to the adapter package.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;CREATE YOUR DOMAIN MODEL&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, generate the domain model of the user table you just created. &lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.domain;&lt;br /&gt;&lt;br /&gt;/** User Domain Model */&lt;br /&gt;public class User {&lt;br /&gt;&lt;br /&gt; private Integer id;&lt;br /&gt; public Integer getId() { return id; }&lt;br /&gt; public void setId(Integer id) { this.id = id; }&lt;br /&gt; &lt;br /&gt; private String username;&lt;br /&gt; public String getUsername() { return username; }&lt;br /&gt; public void setUsername(String username) { this.username = username; }&lt;br /&gt; &lt;br /&gt; private String password;&lt;br /&gt; public String getPassword() { return password; }&lt;br /&gt; public void setPassword(String password) { this.password = password; }&lt;br /&gt; &lt;br /&gt; private String email;&lt;br /&gt; public String getEmail() { return email; }&lt;br /&gt; public void setEmail(String email) { this.email = email; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;CREATE YOUR DAO INTERFACE&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we create our DAO interface, providing definitions of our single access calls and services to the user table.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.adapter;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.domain.User;&lt;br /&gt;&lt;br /&gt;public interface UserServiceAdapter {&lt;br /&gt;&lt;br /&gt; public User getByUsername(String username);&lt;br /&gt; &lt;br /&gt; public User getByEmail(String username);&lt;br /&gt; &lt;br /&gt; public User getById(Integer id);&lt;br /&gt; &lt;br /&gt; public void createUser(User user);&lt;br /&gt; &lt;br /&gt; public void updateUser(User user);&lt;br /&gt; &lt;br /&gt; public void deleteUser(String username);&lt;br /&gt; &lt;br /&gt; public List&amp;lt;User&amp;gt; getUsers(Integer pageNumber, Integer pageLength, String sortCriterion, String sortOrder);&lt;br /&gt; &lt;br /&gt; public Integer getNumberOfUsers();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;IMPLEMENT YOUR DAO&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we implement our DAO interface using Spring JDBC in a subpackage called springjdbc off of the adapter package.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.adapter.springjdbc;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import org.springframework.dao.EmptyResultDataAccessException;&lt;br /&gt;import org.springframework.jdbc.core.support.JdbcDaoSupport;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.adapter.UserServiceAdapter;&lt;br /&gt;import com.edwardwebnerd.persistence.adapter.springjdbc.mapper.UserMapper;&lt;br /&gt;import com.edwardwebnerd.persistence.domain.User;&lt;br /&gt;&lt;br /&gt;public class UserServiceAdapterImpl extends JdbcDaoSupport implements UserServiceAdapter {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public User getByUsername(String username) {&lt;br /&gt;  try{&lt;br /&gt;   return (User) getJdbcTemplate().queryForObject(&lt;br /&gt;     "SELECT * FROM user WHERE username = ?", &lt;br /&gt;     new Object [] {username}, &lt;br /&gt;     new UserMapper());&lt;br /&gt;  }catch(EmptyResultDataAccessException erdae){&lt;br /&gt;   return null;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public User getByEmail(String email) {&lt;br /&gt;  try{&lt;br /&gt;   return (User) getJdbcTemplate().queryForObject(&lt;br /&gt;     "SELECT * FROM user WHERE email = ?", &lt;br /&gt;     new Object [] {email}, &lt;br /&gt;     new UserMapper());&lt;br /&gt;  }catch(EmptyResultDataAccessException erdae){&lt;br /&gt;   return null;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public User getById(Integer id) {&lt;br /&gt;  try{&lt;br /&gt;   return (User) getJdbcTemplate().queryForObject(&lt;br /&gt;     "SELECT * FROM user WHERE id = ?", &lt;br /&gt;     new Object [] {id}, &lt;br /&gt;     new UserMapper());&lt;br /&gt;  }catch(EmptyResultDataAccessException erdae){&lt;br /&gt;   return null;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public void createUser(User user) {&lt;br /&gt;  getJdbcTemplate().update(&lt;br /&gt;    "INSERT INTO user (username, email, password) VALUES (?, ?, ?)",&lt;br /&gt;    new Object[] {user.getUsername(), user.getEmail(), user.getPassword()});&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public void deleteUser(String username) {&lt;br /&gt;  getJdbcTemplate().update(&lt;br /&gt;    "DELETE FROM user WHERE username = ?",&lt;br /&gt;    new Object[] {username});&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void updateUser(User user) {&lt;br /&gt;  getJdbcTemplate().update(&lt;br /&gt;    "UPDATE user SET username = ?, email = ?, password = ? WHERE id = ?",&lt;br /&gt;    new Object[] {user.getUsername(), user.getEmail(), user.getPassword(), user.getId()});&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; @SuppressWarnings("unchecked")&lt;br /&gt; @Override&lt;br /&gt; public List&amp;lt;User&amp;gt; getUsers(Integer pageNumber, Integer pageLength, String sortCriterion, String sortOrder) {&lt;br /&gt;  StringBuffer query = new StringBuffer("SELECT * FROM user");&lt;br /&gt;  if(sortCriterion != null &amp;&amp; sortOrder != null)&lt;br /&gt;   query.append(" ORDER BY ").append(sortCriterion).append(" ").append(sortOrder);&lt;br /&gt;  &lt;br /&gt;  query.append(" LIMIT ").append(pageLength).append(" OFFSET ").append((pageNumber-1) * pageLength);&lt;br /&gt;  return getJdbcTemplate().query(query.toString(), new UserMapper());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Integer getNumberOfUsers() {&lt;br /&gt;  return getJdbcTemplate().queryForInt("SELECT COUNT(*) FROM user");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are a few things to note about the Spring JDBC implementation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The class extends &lt;a href="http://www.jarvana.com/jarvana/view/org/springframework/spring/1.2.9/spring-1.2.9-javadoc.jar!/org/springframework/jdbc/core/support/JdbcDaoSupport.html"&gt;org.springframework.jdbc.core.support.JdbcDaoSupport&lt;/a&gt; - a convenient superclass for JDBC data access objects, which requires a DataSource to be set, which we will set in our config files.&lt;/li&gt;&lt;li&gt;Most of the methods in this implementation use a &lt;a href="http://static.springsource.org/spring/docs/2.5.6/api/org/springframework/jdbc/core/RowMapper.html"&gt;RowMapper&lt;/a&gt; implementation, to help transfer data from the ResultSet to the Domain Model.  We will provide the RowMapper implementation below.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Below, we provide an implementation of the RowMapper interface for our User table and domain model.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.adapter.springjdbc.mapper;&lt;br /&gt;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;&lt;br /&gt;import org.springframework.jdbc.core.RowMapper;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.domain.User;&lt;br /&gt;&lt;br /&gt;public class UserMapper implements RowMapper{&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Object mapRow(ResultSet resultSet, int rowNum) throws SQLException {&lt;br /&gt;  User user = new User();&lt;br /&gt;  user.setEmail(resultSet.getString("email"));&lt;br /&gt;  user.setUsername(resultSet.getString("username"));&lt;br /&gt;  user.setPassword(resultSet.getString("password"));&lt;br /&gt;  user.setId(resultSet.getInt("id"));&lt;br /&gt;  return user;&lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;DEFINE THE USER MANAGER INTERFACE&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We use the term 'Manager' to dictate which portion of the package applications should access.&lt;br /&gt;Next, define the User Manager Interface.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.transmanager;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import org.springframework.transaction.annotation.Transactional;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.domain.User;&lt;br /&gt;import com.edwardwebnerd.persistence.exception.UserEmailAlreadyExistsException;&lt;br /&gt;import com.edwardwebnerd.persistence.exception.UsernameAlreadyExistsException;&lt;br /&gt;&lt;br /&gt;@Transactional&lt;br /&gt;public interface UserManager {&lt;br /&gt; &lt;br /&gt; public User getUserByUsername(String username);&lt;br /&gt; &lt;br /&gt; public User getUserByEmail(String email);&lt;br /&gt; &lt;br /&gt; public User getUserById(Integer id);&lt;br /&gt; &lt;br /&gt; public void createUser(User user) &lt;br /&gt;  throws UsernameAlreadyExistsException, UserEmailAlreadyExistsException;&lt;br /&gt; &lt;br /&gt; public void updateUser(User user);&lt;br /&gt; &lt;br /&gt; public List&amp;lt;User&amp;gt; getUsers(Integer pageNumber, Integer pageLength, String sortCriterion, String sortOrder);&lt;br /&gt; &lt;br /&gt; public Integer getNumberOfUsers();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are a few things to note about interface:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We use the &lt;a href="http://static.springsource.org/spring/docs/2.5.6/api/org/springframework/transaction/annotation/Transactional.html"&gt;@Transactional&lt;/a&gt; annotation to denote that all methods and implementation should be demarcated at the method level.  This annotation also needs to be coupled with a spring configuration which will be provided below.&lt;/li&gt;&lt;li&gt;We defined a couple of exception classes that our implementations should throw up to the application tier on certain cases.  We'll provide the implementations below.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Below we provide the implementation of both exception classes utilized in our UserManager interface.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.exception;&lt;br /&gt;&lt;br /&gt;public class UserEmailAlreadyExistsException extends DataAccessException{&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public UserEmailAlreadyExistsException(String email){&lt;br /&gt;  super("A user with the email " + email + " already exists");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.exception;&lt;br /&gt;&lt;br /&gt;public class UsernameAlreadyExistsException extends DataAccessException{&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public UsernameAlreadyExistsException(String username){&lt;br /&gt;  super("A user with the username " + username + " already exists");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Both of these exceptions extend our base DataAccessException class.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.exception;&lt;br /&gt;&lt;br /&gt;import java.io.PrintStream;&lt;br /&gt;import java.io.PrintWriter;&lt;br /&gt;&lt;br /&gt;public class DataAccessException extends Exception {&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; /** A wrapped Throwable */&lt;br /&gt; protected Throwable cause;&lt;br /&gt;&lt;br /&gt; public DataAccessException() { super("A data exception occurred"); }&lt;br /&gt;&lt;br /&gt; public DataAccessException(String message) { super(message); }&lt;br /&gt;&lt;br /&gt; public DataAccessException(String message, Throwable cause) {&lt;br /&gt;  super(message);&lt;br /&gt;  this.cause = cause;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; public Throwable getCause()  { return cause; }&lt;br /&gt; &lt;br /&gt; public Throwable initCause(Throwable cause) {&lt;br /&gt;  this.cause = cause;&lt;br /&gt;  return cause;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; /** Builds the message off of its own message + all nested exception messages */&lt;br /&gt; public String getMessage() {&lt;br /&gt;  // Get the message for this exception&lt;br /&gt;  String msg = super.getMessage();&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  // Get the message for each nested exception&lt;br /&gt;  Throwable parent = this;&lt;br /&gt;  Throwable child;&lt;br /&gt;  while((child = parent.getCause()) != null) {&lt;br /&gt;   String msg2 = child.getMessage();&lt;br /&gt;&lt;br /&gt;   if (msg2 != null) {&lt;br /&gt;    if (msg != null) { msg += ": " + msg2; } &lt;br /&gt;    else { msg = msg2; }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if (child instanceof DataAccessException) { break; }&lt;br /&gt;   &lt;br /&gt;   parent = child;&lt;br /&gt;  }&lt;br /&gt;  return msg;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; /** Prints the stack trace + all nested stack traces */&lt;br /&gt; public void printStackTrace() {&lt;br /&gt;  // Print the stack trace for this exception.&lt;br /&gt;  super.printStackTrace();&lt;br /&gt;  &lt;br /&gt;  // Print the stack trace for each nested exception.&lt;br /&gt;  Throwable parent = this;&lt;br /&gt;  Throwable child;&lt;br /&gt;  while((child = parent.getCause()) != null) {&lt;br /&gt;   if (child != null) {&lt;br /&gt;    System.err.print("Caused by: ");&lt;br /&gt;    child.printStackTrace();&lt;br /&gt;&lt;br /&gt;    if (child instanceof DataAccessException) { break; }&lt;br /&gt;                   &lt;br /&gt;    parent = child;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; /** Prints the stack trace + all nested stack traces */&lt;br /&gt; public void printStackTrace(PrintStream s) {&lt;br /&gt;  // Print the stack trace for this exception.&lt;br /&gt;  super.printStackTrace(s);&lt;br /&gt;  &lt;br /&gt;  Throwable parent = this;&lt;br /&gt;  Throwable child;&lt;br /&gt;&lt;br /&gt;  // Print the stack trace for each nested exception.&lt;br /&gt;  while((child = parent.getCause()) != null) {&lt;br /&gt;   if (child != null) {&lt;br /&gt;    s.print("Caused by: ");&lt;br /&gt;    child.printStackTrace(s);&lt;br /&gt;&lt;br /&gt;    if (child instanceof DataAccessException) { break; }&lt;br /&gt;    &lt;br /&gt;    parent = child;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; /** Prints the stack trace + all nested stack traces */&lt;br /&gt; public void printStackTrace(PrintWriter w) {&lt;br /&gt;  // Print the stack trace for this exception.&lt;br /&gt;  super.printStackTrace(w);&lt;br /&gt;&lt;br /&gt;  Throwable parent = this;&lt;br /&gt;  Throwable child;&lt;br /&gt;&lt;br /&gt;  // Print the stack trace for each nested exception.&lt;br /&gt;  while((child = parent.getCause()) != null) {&lt;br /&gt;   if (child != null) {&lt;br /&gt;    w.print("Caused by: ");&lt;br /&gt;    child.printStackTrace(w);&lt;br /&gt;&lt;br /&gt;    if (child instanceof DataAccessException) {&lt;br /&gt;     break;&lt;br /&gt;    }&lt;br /&gt;    parent = child;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;IMPLEMENT YOUR MANAGER&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we implement the User Manager interface using Spring JDBC, in a subpackage called springjdbc off of the transmanager package.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.transmanager.springjdbc;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.adapter.UserServiceAdapter;&lt;br /&gt;import com.edwardwebnerd.persistence.domain.User;&lt;br /&gt;import com.edwardwebnerd.persistence.exception.UserEmailAlreadyExistsException;&lt;br /&gt;import com.edwardwebnerd.persistence.exception.UsernameAlreadyExistsException;&lt;br /&gt;import com.edwardwebnerd.persistence.transmanager.UserManager;&lt;br /&gt;&lt;br /&gt;public class UserManagerImpl implements UserManager {&lt;br /&gt;&lt;br /&gt; private UserServiceAdapter userServiceAdapter = null;&lt;br /&gt; public void setUserServiceAdapter(UserServiceAdapter userServiceAdapter){&lt;br /&gt;  this.userServiceAdapter = userServiceAdapter;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public void createUser(User user) &lt;br /&gt;  throws UsernameAlreadyExistsException, UserEmailAlreadyExistsException&lt;br /&gt; {&lt;br /&gt;  User usernameTest = userServiceAdapter.getByUsername(user.getUsername());&lt;br /&gt;  if(usernameTest != null){&lt;br /&gt;   throw new UsernameAlreadyExistsException(user.getUsername());&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  User userEmailTest = userServiceAdapter.getByEmail(user.getEmail());&lt;br /&gt;  if(userEmailTest != null){&lt;br /&gt;   throw new UserEmailAlreadyExistsException(user.getEmail());&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  userServiceAdapter.createUser(user);&lt;br /&gt;  userServiceAdapter.createUser(null);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public List&lt;user&gt; getUsers(Integer pageNumber, Integer pageLength, String sortCriterion, String sortOrder) {&lt;br /&gt;  return userServiceAdapter.getUsers(pageNumber, pageLength, sortCriterion, sortOrder);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public User getUserByUsername(String username) {&lt;br /&gt;  return userServiceAdapter.getByUsername(username);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public User getUserByEmail(String email) {&lt;br /&gt;  return userServiceAdapter.getByEmail(email);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public User getUserById(Integer id) {&lt;br /&gt;  return userServiceAdapter.getById(id);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void updateUser(User user) {&lt;br /&gt;  userServiceAdapter.updateUser(user);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Integer getNumberOfUsers() {&lt;br /&gt;  return userServiceAdapter.getNumberOfUsers();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Most of the methods in the manager are just single access operations.  As a result many of the implementations are straight mappings to UserServiceAdapter.&lt;br /&gt;&lt;br /&gt;Note the last two line in the implementation of the createUser implementation.&lt;br /&gt;&lt;pre&gt;userServiceAdapter.createUser(user);&lt;br /&gt;userServiceAdapter.createUser(null);&lt;br /&gt;&lt;/pre&gt;The very last call will throw a NullPointerException.  Any call to this method will always rollback the user created in the second to last call.  We'll leave it up to you to test and verify this.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;SPRING CONFIGURATIONS&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We are now ready to wire our services together using spring.&lt;br /&gt;&lt;br /&gt;In almost every environment, there is always a need to support test and production modes.  We handle this using a property we set at runtime.  Based on the environment property variable 'env' we will load a set of properties file, which will point us to our test or production resources, based on the value set.  The property is easily passed during execution through the -D argument.  For the property env we accept qa and production as valid values.&lt;br /&gt;&lt;br /&gt;Below we provide our spring configuration file, which is stored in our com.edwardwebnerd.persistence.dbcp package.&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xmlns:tx="http://www.springframework.org/schema/tx"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt;  http://www.springframework.org/schema/tx&lt;br /&gt;  http://www.springframework.org/schema/tx/spring-tx.xsd&lt;br /&gt;"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!--&lt;br /&gt;  You must use a -D JVM level option.&lt;br /&gt;  There are two configurations supported.&lt;br /&gt;    -Denv=qa&lt;br /&gt;    -Denv=production&lt;br /&gt;  based on the configuration loaded the appropriate data source will be loaded. &lt;br /&gt; --&amp;gt;&lt;br /&gt; &amp;lt;bean id="DataAccessProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&amp;gt;&lt;br /&gt;  &amp;lt;property name="location" value="classpath:com/edwardwebnerd/persistence/dbcp/${env}.properties"/&amp;gt;&lt;br /&gt;     &amp;lt;/bean&amp;gt;&lt;br /&gt;     &lt;br /&gt; &amp;lt;bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"&amp;gt;&lt;br /&gt;  &amp;lt;!-- &amp;lt;property name="driverClassName" value="com.ibm.as400.access.AS400JDBCDriver"/&amp;gt; --&amp;gt;&lt;br /&gt;  &amp;lt;property name="driverClassName" value="${jdbc.driver}"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="url" value="${jdbc.url}"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="username" value="${jdbc.username}"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="password" value="${jdbc.password}"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="maxActive" value="30"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="maxIdle" value="2"/&amp;gt;&lt;br /&gt;  &amp;lt;property name="maxWait" value="5000"/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&amp;gt;&lt;br /&gt;  &amp;lt;property name="dataSource" ref="dataSource"/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false"/&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;bean id="userManager" class="com.edwardwebnerd.persistence.transmanager.springjdbc.UserManagerImpl"&amp;gt;&lt;br /&gt;  &amp;lt;property name="userServiceAdapter" ref="userServiceAdapter"/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;bean id="userServiceAdapter" class="com.edwardwebnerd.persistence.adapter.springjdbc.UserServiceAdapterImpl"&amp;gt;&lt;br /&gt;  &amp;lt;property name="dataSource" ref="dataSource"/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here we see that we wire together our data sources with our service adapter and manager.  There are also some configurations that are required to support the @Transactional annotation used in the UserManager interface.  Below, we'll provide an example of one of our properties file located in the com.edwardwebnerd.persistence.dbcp pacakage.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jdbc.driver=com.mysql.jdbc.Driver&lt;br /&gt;jdbc.url=jdbc:mysql://localhost:3306/test?autoReconnect=true&lt;br /&gt;jdbc.username=root&lt;br /&gt;jdbc.password=admin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We'll leave it up to you, to test the project above.  In our next tutorial, we will expose these services on our web tier, strictly for illustrative purposes.&lt;br /&gt;&lt;br /&gt;Please feel free to leave any comments or suggestions on how the code above can be improved.  I'll be sure to answer them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5328355177753390620?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5328355177753390620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/01/spring-jdbc-tutorial-with-transaction.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5328355177753390620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5328355177753390620'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/01/spring-jdbc-tutorial-with-transaction.html' title='Spring JDBC Tutorial with Transaction Management'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-6821252127516485099</id><published>2010-01-01T18:00:00.000-08:00</published><updated>2010-01-01T18:00:31.129-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Sub Queries vs. Outer Joins :  (SELECT of a SELECT) vs. (LEFT OUTER JOINS)</title><content type='html'>One performance bottleneck that as Java developers we may encounter may be our poor use of SQL.  &lt;br /&gt;&lt;br /&gt;I often see a Nested SELECT like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SELECT name FROM bbc&lt;br /&gt;WHERE population &gt;&lt;br /&gt;(SELECT population FROM bbc&lt;br /&gt;WHERE name='Russia')&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Implemented as a LEFT OUTER JOIN&lt;br /&gt;SELECT name FROM BBC LEFT OUTER JOIN ON BBC&lt;br /&gt;&lt;br /&gt;Dependant on the query, the Nested SELECT technique may force the subquery to be evaluated for every row in the left-hand table.  &lt;br /&gt;A LEFT OUTER join, by contrast, can often use a much more efficient query plan. &lt;br /&gt;&lt;br /&gt;This is not always the case as they are mathematically equivalent and a good query optimizer may generate the same query plan, but this is not always the case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-6821252127516485099?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/6821252127516485099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/01/sub-queries-vs-outer-joins-select-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6821252127516485099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6821252127516485099'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2010/01/sub-queries-vs-outer-joins-select-of.html' title='Sub Queries vs. Outer Joins :  (SELECT of a SELECT) vs. (LEFT OUTER JOINS)'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5429595994229095092</id><published>2009-12-09T19:30:00.000-08:00</published><updated>2010-01-01T18:05:21.196-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Why you should look into ORM, if you haven't already?</title><content type='html'>In my last posting, I got clobbered by the blogosphere concerning my posting "&lt;a href="http://j2eewebprogrammer.blogspot.com/2009/12/data-access-plain-jdbc-vs-orm.html"&gt;Data Access: Plain JDBC vs. ORM&lt;/a&gt;".    &lt;br /&gt;&lt;br /&gt;I feel that the title was misleading, however, I do think that I do make some valid points about the shortcomings of authoring a data tier without the assistance of some type of ORM.&lt;br /&gt;&lt;br /&gt;It is my opinion that, yes, there are many applications out there that still use raw JDBC as the primary method of accessing a data source in their data tier.  &lt;br /&gt;&lt;br /&gt;With that being said, I was targeting this article to those programmers that still write data tiers using raw JDBC, and was thinking of following up with some simple posts and tutorials on ORM's like Spring JDBC and  Hibernate.&lt;br /&gt;&lt;br /&gt;Without further ado, I am going to repost my thoughts and concerns.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Why you should look into ORM, if you haven't already?&lt;/h3&gt;&lt;br /&gt;A developer's goal when writing data access code is to properly contain the responsibilities of all data access operations. Leaking data access operations into the application is referred to as leakage of data-access details and has some adverse affects when the application has to adapt to changes on the data side.&lt;br /&gt;&lt;br /&gt;Let's take a look at a method that uses raw JDBC:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class UserRegistrationJDBC {&lt;br /&gt;&lt;br /&gt;   private javax.sql.DataSource dataSource;&lt;br /&gt;&lt;br /&gt;   public int getUserRegistrationCount() throws MyDataAccessException {&lt;br /&gt;&lt;br /&gt;      java.sql.Connection connection = null;&lt;br /&gt;      java.sql.Statement statement = null;&lt;br /&gt;      java.sql.ResultSet resultSet = null;&lt;br /&gt;      try{&lt;br /&gt;         connection = dataSource.getConnection();&lt;br /&gt;         statement = connection.createStatement();&lt;br /&gt;         resultSet = statement.executeQuery(&lt;br /&gt;            "SELECT COUNT(*) FROM USER_REGISTRATION");&lt;br /&gt;&lt;br /&gt;         rs.next();&lt;br /&gt;         return rs.getInt(1);&lt;br /&gt;      }catch(java.sql.SQLException sqle){&lt;br /&gt;         throw new MyDataAccessException(e);&lt;br /&gt;      }finally{&lt;br /&gt;         if(resultSet != null){ &lt;br /&gt;            try{ resultSet.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;         if(statement != null){ &lt;br /&gt;            try{ statement.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;         if(connection != null){ &lt;br /&gt;            try{ connection.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Let's look at some technical details contained within the code above:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The call to getConnection() on the javax.sql.DataSource object can be problematic because it obtains its own database connection.  For example, suppose we wrote all our data access methods like the one above, even for inserts and updates.  Imagine attempting to persist multiple records, perhaps on the completion of an order, something with an invoice, shipping details and billing details.  If one of those transactions fail for some unexpected reason, how would you rollback the transactions?  Obtaining a connection from the pool will only rollback the last transaction, leaving you to hand implement the rollback.  It becomes even worse if the set of transactions spans multiple data sources.&lt;/li&gt;&lt;li&gt;The call to createStatement() is problematic as well. All sql should be rendered using a java.sql.PreparedStatement() for improved performance via caching. While this is more of a practice and learned through experience, using raw JDBC leaves the programmer open to these types of mistakes.&lt;/li&gt;&lt;li&gt;Catching a java.sql.SQLException is required by the JDBC API as it is it's only exception type and typically reveals little about the root cause of your error. Wrapping it with the unchecked exception MyDataAccessException, adds little value, only that your calling code does not have to catch it. Your application code now is restricted in how it can deal with specific data access errors.&lt;/li&gt;&lt;li&gt;The finally block contains the closing of all resources used in the method, which makes it impossible for other methods to reuse it.&lt;/li&gt;&lt;/ul&gt;Poor handling of the concerns above can lead to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Resource exhaustion - loss of connection availability and loss of memory from improperly closed result sets and statements.&lt;/li&gt;&lt;li&gt;Poor performance - due to Statement vs. PreparedStatement as mentioned above.&lt;/li&gt;&lt;li&gt;Inappropriate connection life cycles - any operation where more than one SQL statement is executed can reuse connections and other resources for more appropriate life cycles. Even with connection pools, we should be careful not to spend CPU cycles and memory on obtaining and releasing connections.&lt;/li&gt;&lt;/ul&gt;To elaborate even further the inappropriate connection life cycles point, consider where a user registration is added with a payment for the registration. We would want to ensure that all the data access operations occurred or none at all. In a more appropriate world, we want to demarcate these operations at a transaction level, enabling the reuse of all related resources. &lt;br /&gt;&lt;br /&gt;The goal of many ORM's are to effectively handle the leakage of data access details into the view tier.  In addition, they support:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Transaction Demarcation - a mechanism to declare when transactions start and end, and support rollback.&lt;/li&gt;&lt;li&gt;Transaction Management API - an API to keep contracts clear and concise on transactions&lt;/li&gt;&lt;/ul&gt;It should be obvious, that writing a Transaction Management API is out of scope for most developers and only an adequately defined API can guarantee that applications remain flexible and adaptive.&lt;br /&gt;&lt;br /&gt;The benefits of ORM's are too many for you not to have looked heavily into their proposed benefits.  &lt;br /&gt;&lt;br /&gt;In my next article, I'll present ways on how Spring provides a constructive and flexible programming model which addresses the concerns above and much more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5429595994229095092?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5429595994229095092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/12/why-you-should-look-into-orm-if-you.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5429595994229095092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5429595994229095092'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/12/why-you-should-look-into-orm-if-you.html' title='Why you should look into ORM, if you haven&apos;t already?'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-2252372100604685872</id><published>2009-12-05T12:30:00.000-08:00</published><updated>2009-12-05T12:36:49.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='J2EE Core'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Data Access: Plain JDBC vs. ORM</title><content type='html'>I start this discussion, to try and organize some thoughts and comparisons on data access code, written in plain old JDBC (or Java Database Connectivity) vs. utilizing an ORM Framework (or Object Relational Management Framework), such as Hibernate or iBatis.&lt;br /&gt;&lt;br /&gt;A developer's goal when writing data access code is to properly contain the responsibilities of all data access operations.  Leaking data access operations into the application is referred to as &lt;i&gt;leakage of data-access details&lt;/i&gt; and has some adverse affects when the application has to adapt to changes on the data side.&lt;br /&gt;&lt;br /&gt;Let's take a look at a method that uses raw JDBC:&lt;br /&gt;&lt;pre&gt;public class UserRegistrationJDBC {&lt;br /&gt;&lt;br /&gt;   private javax.sql.DataSource dataSource;&lt;br /&gt;&lt;br /&gt;   public int getUserRegistrationCount() throws MyDataAccessException {&lt;br /&gt;&lt;br /&gt;      java.sql.Connection connection = null;&lt;br /&gt;      java.sql.Statement statement = null;&lt;br /&gt;      java.sql.ResultSet resultSet = null;&lt;br /&gt;      try{&lt;br /&gt;         connection = dataSource.getConnection();&lt;br /&gt;         statement = connection.createStatement();&lt;br /&gt;         resultSet = statement.executeQuery(&lt;br /&gt;            "SELECT COUNT(*) FROM USER_REGISTRATION");&lt;br /&gt;&lt;br /&gt;         rs.next();&lt;br /&gt;         return rs.getInt(1);&lt;br /&gt;      }catch(java.sql.SQLException sqle){&lt;br /&gt;         throw new MyDataAccessException(e);&lt;br /&gt;      }finally{&lt;br /&gt;         if(resultSet != null){ &lt;br /&gt;            try{ resultSet.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;         if(statement != null){ &lt;br /&gt;            try{ statement.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;         if(connection != null){ &lt;br /&gt;            try{ connection.close() }&lt;br /&gt;            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's look at some technical details of this data access code:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The call to getConnection() on the javax.sql.DataSource object can be problematic because it obtains its own database connection.  There may be an instance when this call depends entirely on the underlying DataSource object.  Not too bad, but it does restrict the application on how it can organize database transactions.&lt;/li&gt;&lt;li&gt;The call to createStatement() is problematic as well.  All sql should be rendered using a java.sql.PreparedStatement() for improved performance via caching.  While this is more of a practice and learned through experience, using raw JDBC leaves the programmer open to these types of mistakes.&lt;/li&gt;&lt;li&gt;Catching a java.sql.SQLException is required by the JDBC API as it is it's only exception type and typically reveals little about the root cause of your error.  Wrapping it with the unchecked exception MyDataAccessException, adds little value, only that your calling code does not have to catch it.  Your application code now is restricted in how it can deal with specific data access errors.&lt;/li&gt;&lt;li&gt;The finally block contains the closing of all resources used in the method, which makes it impossible for other methods to reuse it.&lt;/li&gt;&lt;/ul&gt;Some of the concerns also exist when using ORM tools, however, are often less visible.&lt;br /&gt;&lt;br /&gt;Poor handling of the concerns above can lead to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Resource exhaustion - loss of connection availability and loss of memory from improperly closed result sets and statements&lt;/li&gt;&lt;li&gt;Poor performance - due to Statement vs. PreparedStatement as mentioned above.&lt;/li&gt;&lt;li&gt;Inappropriate connection life cycles - any operation where more than one SQL statement is executed can reuse connections and other resources for more appropriate life cycles.  Even with connection pools, we should be careful not to spend CPU cycles and memory on obtaining and releasing connections.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To elaborate even further the inappropriate connection life cycles point, consider where a user registration is added with a payment for the registration.  We would want to ensure that all the data access operations occurred or none at all.  In a more appropriate world, we want to demarcate these operations at a transaction level, enabling the reuse of all related resources.  &lt;br /&gt;&lt;br /&gt;The goal of many ORM's are to handle the concerns above with:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Transaction Demarcation - a mechanism to declare when transactions start and end.&lt;/li&gt;&lt;li&gt;Transaction Management API - an API to keep contracts clear and concise on transactions&lt;/li&gt;&lt;/ul&gt;It should be obvious, that writing a Transaction Management API is out of scope for most developers and only an adequately defined API can guarantee that applications remain flexible and adaptive.&lt;br /&gt;&lt;br /&gt;In my next article, I'll present ways on how Spring provides a constructive and flexible programming model which addresses the concerns above and much more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-2252372100604685872?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/2252372100604685872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/12/data-access-plain-jdbc-vs-orm.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2252372100604685872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2252372100604685872'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/12/data-access-plain-jdbc-vs-orm.html' title='Data Access: Plain JDBC vs. ORM'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-8181894624502986783</id><published>2009-11-02T17:19:00.000-08:00</published><updated>2010-01-01T18:04:30.760-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Traversing through HTML &lt;optgroups&gt; and &lt;options&gt; in Javascript</title><content type='html'>I've posted some HTML + Javascript code to traverse through &amp;lt;optgroups&amp;gt; and &amp;lt;options&amp;gt; in Javascript.  &lt;br /&gt;&lt;br /&gt;Supposed we had a State/Province drop down box with the following entries:&lt;br /&gt;&lt;br /&gt;&lt;select name="theCountryState" id="theCountryState"&gt;&lt;optgroup label="United States" id="US"&gt;&lt;option value="NY"&gt;New York&lt;/option&gt;&lt;option value="MO"&gt;Missouri&lt;/option&gt;&lt;/optGroup&gt;&lt;optgroup label="Canada" id="CA"&gt;&lt;option value="TO"&gt;Toronto&lt;/option&gt;&lt;option value="ON"&gt;Ontario&lt;/option&gt;&lt;/optGroup&gt;&lt;optgroup label="Mexico" id="MX"&gt;&lt;option value="MO"&gt;Morales&lt;/option&gt;&lt;option value="PV"&gt;Puerto Vallerta&lt;/option&gt;&lt;/optGroup&gt;&lt;/select&gt;&lt;br /&gt;&lt;br /&gt;That was created with the following HTML:&lt;br /&gt;&lt;pre&gt;&amp;lt;select name="theCountryState" id="theCountryState"&amp;gt;&lt;br /&gt;   &amp;lt;optGroup label="United States" id="US"&amp;gt;&lt;br /&gt;      &amp;lt;option value="NY"&amp;gt;New York&amp;lt;/option&amp;gt;&lt;br /&gt;      &amp;lt;option value="MO"&amp;gt;Missouri&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;/optGroup&amp;gt;&lt;br /&gt;   &amp;lt;optGroup label="Canada" id="CA"&amp;gt;&lt;br /&gt;      &amp;lt;option value="TO"&amp;gt;Toronto&amp;lt;/option&amp;gt;&lt;br /&gt;      &amp;lt;option value="ON"&amp;gt;Ontario&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;/optGroup&amp;gt;&lt;br /&gt;   &amp;lt;optGroup label="Mexico" id="MX"&amp;gt;&lt;br /&gt;      &amp;lt;option value="MO"&amp;gt;Morales&amp;lt;/option&amp;gt;&lt;br /&gt;      &amp;lt;option value="PV"&amp;gt;Puerto Vallerta&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;/optGroup&amp;gt;&lt;br /&gt;&amp;lt;/select&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The appropriate option can be selected easily by traversing through the OPTGROUPS and OPTIONS.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;function selectCorrectOption(var countrySelected, var stateSelected) {&lt;br /&gt;    &lt;br /&gt;   //Traverse through Option Groups and options and mark correct option.&lt;br /&gt;   countryStateOptGroups = document.getElementById("theCountryState").childNodes;&lt;br /&gt;   for(i = 0; i &lt; countryStateOptGroups.length; i++)&lt;br /&gt;   {&lt;br /&gt;      if(countryStateOptGroups[i].id == countrySelected){&lt;br /&gt;         stateOptions = countryStateOptGroups[i].childNodes;&lt;br /&gt;         for(j = 0; j &lt; stateOptions.length; j++){&lt;br /&gt;            if(stateOptions[j].value == stateSelected){&lt;br /&gt;               stateOptions[j].selected = true;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Any questions, please feel free to comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-8181894624502986783?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/8181894624502986783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/11/traversing-through-html-and-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8181894624502986783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8181894624502986783'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/11/traversing-through-html-and-in.html' title='Traversing through HTML &amp;lt;optgroups&amp;gt; and &amp;lt;options&amp;gt; in Javascript'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-8281958574116043167</id><published>2009-10-18T07:54:00.000-07:00</published><updated>2010-01-01T18:04:11.305-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Tomcat DBCP DataSource falls idle overnight</title><content type='html'>If you have a low activity web server using Tomcat DBCP to retrieve connections to your database, the database server might time out connections in the pool.  &lt;br /&gt;&lt;br /&gt;Adding the following to your &amp;lt;Resource&amp;gt; configuration can address the problem.  &lt;/resource&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;testOnBorrow="true"&lt;/li&gt;&lt;li&gt;validationQuery="SELECT 1 /* ping */"&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-8281958574116043167?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/8281958574116043167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/tomcat-dbcp-datasource-falls-idle.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8281958574116043167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8281958574116043167'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/tomcat-dbcp-datasource-falls-idle.html' title='Tomcat DBCP DataSource falls idle overnight'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-884528590494156775</id><published>2009-10-18T07:43:00.000-07:00</published><updated>2010-01-01T18:03:47.690-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Forcing a JSP to recompile</title><content type='html'>You can force Tomcat to recompile a jsp from any web brower by making a request to:&lt;br /&gt;&lt;br /&gt;http://hostname/path/yourPage.jsp?jsp_precompile=true&lt;br /&gt;&lt;br /&gt;The jsp_recompile parameter in the request will force the request to compile the page and load it into the ClassLoader.  This is only true if you are jsps are outside of the WEB-INF folder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-884528590494156775?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/884528590494156775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/forcing-jsp-to-recompile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/884528590494156775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/884528590494156775'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/forcing-jsp-to-recompile.html' title='Forcing a JSP to recompile'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7698260961766271210</id><published>2009-10-07T20:49:00.000-07:00</published><updated>2010-01-01T18:03:03.997-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Build'/><title type='text'>How to make your webapp the Tomcat default application</title><content type='html'>It's always asked so, here's a link to the answer.&lt;br /&gt;&lt;a href="http://wiki.apache.org/tomcat/HowTo#How_do_I_make_my_web_application_be_the_Tomcat_default_application_.3F"&gt;&lt;br /&gt;http://wiki.apache.org/tomcat/HowTo#How_do_I_make_my_web_application_be_the_Tomcat_default_application_.3F&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7698260961766271210?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7698260961766271210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/how-to-make-your-webapp-tomcat-default.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7698260961766271210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7698260961766271210'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/10/how-to-make-your-webapp-tomcat-default.html' title='How to make your webapp the Tomcat default application'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-2295155825826230292</id><published>2009-09-24T12:38:00.000-07:00</published><updated>2010-01-01T18:02:23.477-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>How to Post a SaveAs Dialog</title><content type='html'>To prompt a 'Save As' dialog box when downloading a file, set the Content-Disposition to 'attachment' in the HTTP header.  &lt;br /&gt;&lt;br /&gt;Read &lt;a href="http://www.ietf.org/rfc/rfc2183.txt"&gt;RFC 2183&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also pre-set the saved filename by setting the filename parameter as well.&lt;br /&gt;&lt;br /&gt;Be sure to set the appropriate MIME type or content type as well.&lt;br /&gt;&lt;br /&gt;Below is a code example of how this would be achieved in a java servlet before committing the response.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;response.setContentType( "application/pdf" ); &lt;br /&gt;response.setHeader("Content-disposition","attachment; filename=" + "Example.pdf" );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Hope this helps, if it does, help me out by clicking on one of my sponsors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-2295155825826230292?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/2295155825826230292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/09/how-to-post-saveas-dialog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2295155825826230292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2295155825826230292'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/09/how-to-post-saveas-dialog.html' title='How to Post a SaveAs Dialog'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-3711586335021717683</id><published>2009-09-08T17:51:00.000-07:00</published><updated>2010-01-01T18:02:00.338-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Accessing HTTP Header with OGNL</title><content type='html'>&lt;a href="http://www.opensymphony.com/ognl/"&gt;OGNL&lt;/a&gt; stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects. You use the same expression for both getting and setting the value of a property. &lt;br /&gt;&lt;br /&gt;Struts2 adds on top of OGNL by providing support for a 'Value Stack'.  While OGNL operates under the assumption there is only one "root", XWork's ValueStack concept requires there be many "roots".  Have a quick read on &lt;a href="http://struts.apache.org/2.0.14/docs/ognl-basics.html"&gt;OGNL basics&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When referring to non-root objects are accessed with a (#) sign.&lt;br /&gt;&lt;br /&gt;Accessing an HTTP Header can be achieved by the following code.&lt;br /&gt;&lt;pre&gt;&amp;lt;s:property value="#header.myHeaderPropKey"/&amp;gt; or&lt;br /&gt;&amp;lt;s:property value="#header['myHeaderPropKey']"/&amp;gt; or&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-3711586335021717683?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/3711586335021717683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/09/accessing-http-header-with-ognl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3711586335021717683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3711586335021717683'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/09/accessing-http-header-with-ognl.html' title='Accessing HTTP Header with OGNL'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7820036024302994136</id><published>2009-07-15T07:40:00.000-07:00</published><updated>2010-01-01T17:59:16.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Business'/><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Branching in CVS with Eclipse</title><content type='html'>Sometimes you find such a well written article on a specific topic that you feel that it just needs to be shared.&lt;br /&gt;&lt;br /&gt;I have gone to this article on branching and merging in CVS with Eclipse numerous times for more confidence, particularly before a merge.&lt;br /&gt;&lt;a href=" http://www.eclipse.org/articles/article.php?file=Article-BranchingWithEclipseAndCVS/article1.html"&gt;&lt;br /&gt;http://www.eclipse.org/articles/article.php?file=Article-BranchingWithEclipseAndCVS/article1.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7820036024302994136?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7820036024302994136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/07/branching-in-cvs-with-eclipse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7820036024302994136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7820036024302994136'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/07/branching-in-cvs-with-eclipse.html' title='Branching in CVS with Eclipse'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-3664440312018230544</id><published>2009-07-06T18:43:00.000-07:00</published><updated>2010-01-01T17:58:35.813-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>Preparable CRUD actions with multiple prepare methods</title><content type='html'>Many of the Struts2 Tutorials guide you towards stuffing multiple CRUD operations for a single entity within a single action.  Sounds nice, but what happens when you need to prepare these actions differently?  &lt;br /&gt;&lt;br /&gt;Your first instinct might tell you to implement multiple actions for that one entity (one per CRUD operation, or maybe even stuff two inside one action).  &lt;br /&gt;&lt;br /&gt;However, you can add multiple prepare{METHOD}() like prepareDoDelete(),&lt;br /&gt;prepareDoUpdate().  If you follow this convention, the appropriate prepare method will be called before your action method.&lt;br /&gt;&lt;br /&gt;The following is a snippet from the Struts 2 Documentation at: &lt;br /&gt;http://struts.apache.org/2.0.11/docs/prepare-interceptor.html&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;In PrepareInterceptor&lt;br /&gt;&lt;br /&gt;Applies only when action implements Preparable&lt;br /&gt;&lt;br /&gt;1. if the action class have prepare{MethodName}(), it will be invoked&lt;br /&gt;2. else if the action class have prepareDo(MethodName()}(), it will be invoked&lt;br /&gt;3. no matter if 1] or 2] is performed, if alwaysinvokePrepare property of the interceptor is "true" (which is by default "true"), prepare() will be invoked.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-3664440312018230544?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/3664440312018230544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/07/preparable-crud-actions-with-multiple.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3664440312018230544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3664440312018230544'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/07/preparable-crud-actions-with-multiple.html' title='Preparable CRUD actions with multiple prepare methods'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-1695231851926965687</id><published>2009-06-23T13:40:00.000-07:00</published><updated>2010-01-01T17:57:15.989-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>junit.framework.AssertionFailedError: No tests found in</title><content type='html'>If you ever get the above error and you think your test class is set up and implemented correctly, you may have one more thing to check.&lt;br /&gt;&lt;br /&gt;Your test method names need to start with 'test'.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class name extent TestCase{&lt;br /&gt;public void method1() {}&lt;br /&gt;public void method1() {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Will result in an error.  Change the method names to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class name extent TestCase{&lt;br /&gt;public void testMethod1() {}&lt;br /&gt;public void testMethod1() {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You should be good to go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-1695231851926965687?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/1695231851926965687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/junitframeworkassertionfailederror-no.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1695231851926965687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1695231851926965687'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/junitframeworkassertionfailederror-no.html' title='junit.framework.AssertionFailedError: No tests found in'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-8731147368395903056</id><published>2009-06-22T07:05:00.000-07:00</published><updated>2010-01-01T17:56:38.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Setting up JUnit in your Eclipse Project</title><content type='html'>The following is the first steps to adding &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt; test cases to your Eclipse project.  It's the first step in working your processes towards Test Driven Development, which is the bread and butter of Agile and XP Programming methodologies and techniques.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Step 1: Download JUnit&lt;/h3&gt;&lt;br /&gt;The first step is to download the most recent version of &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt; (look for the 'Releases' link off the homepage).  At the time of this article, the latest version was 4.6.  &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Step 2: Add JUnit to your Eclipse project's build path.&lt;/h3&gt;&lt;br /&gt;Right click on your project and select 'Properties'.&lt;br /&gt;Click 'Java Build Path'.&lt;br /&gt;Click the 'Libraries' tab.&lt;br /&gt;Click 'Add JARs' (if you've added the JAR into your workspace)&lt;br /&gt;or &lt;br /&gt;Click 'Add External JARs' (if you are linking the JAR from outside your workspace)&lt;br /&gt;In the GUI, select the JUnit jar (junit-4.6.jar).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Step 3: Organize your source folders&lt;/h3&gt;&lt;br /&gt;One recommended practice is to organize your source folders into the following structure:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[project]&lt;br /&gt;-- src    &lt;br /&gt;-- main   (module code)&lt;br /&gt;-- test   (test code only)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create the above directory structure under your project in Eclipse.&lt;br /&gt;Right click on your project and select 'Properties'.&lt;br /&gt;Click 'Java Build Path'.&lt;br /&gt;Click the 'Source' tab.&lt;br /&gt;Add the 'main' and 'test' folders as source folders in your project and deselect 'src' as a source folder. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ready to go&lt;/h3&gt;&lt;br /&gt;You now have effectively integrated JUnit into your project, provided a clean way to separate your code base with your testing code.&lt;br /&gt;&lt;br /&gt;Any questions, feel free to comment and I'll get back to you as soon as I can.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-8731147368395903056?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/8731147368395903056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/adding-junit-test-cases-to-your-eclipse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8731147368395903056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8731147368395903056'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/adding-junit-test-cases-to-your-eclipse.html' title='Setting up JUnit in your Eclipse Project'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-1188579782792747143</id><published>2009-06-15T11:38:00.000-07:00</published><updated>2010-01-01T17:56:04.221-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Business'/><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Using Static Helper Classes - Java Memory and the Initialization on Demand Holder Idiom</title><content type='html'>A recent discussion about design patterns and data delegator classes was brought up recently in the tomcat-users mailing list. It is common to find that many web applications use several delegate classes providing access to some data source. Delegate classes are often implemented using the singleton-design pattern, which proposes that at any time there can only be one instance of a singleton (object) created by the JVM.&lt;br /&gt;&lt;br /&gt;Theoretically, questions come into mind concerning the governance surrounding instantiation and synchronization of these singleton classes, especially in a multi-threaded environment.  &lt;br /&gt;&lt;br /&gt;In this post, we'll go over some approaches posted in the thread and provide a best option. &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Static Initizialization&lt;/li&gt;&lt;li&gt;Double Checked Locking (later only on post 1.5 jvm)&lt;/li&gt;&lt;li&gt;Initialize-On-Demand Holder Class Idiom (MOST PREFERRED)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Static Initialization&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;class BeanBag {&lt;br /&gt;private static final SomeBean someBean = new SomeBean();&lt;br /&gt;private static final AnotherBean anotherBean = new AnotherBean();&lt;br /&gt;&lt;br /&gt;public static SomeBean getSomeBean() { return someBean; }&lt;br /&gt;public static AnotherBean getAnotherBean() { return anotherBean; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The initialization happens at the loading time of the class but there is no guarantee to be synchronized.  The static class property someBean will be available at first call to getSomeBean().  This works 99% of the time, I have never had a problem with it.  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Double Lock Checking&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;class BeanBag {&lt;br /&gt;private static volatile SomeBean someBean = null;&lt;br /&gt;&lt;br /&gt;public static SomeBean getSomeBean() {&lt;br /&gt;if (someBean==null){&lt;br /&gt;synchronized(BeanBag.class){&lt;br /&gt;if (someBean==null){&lt;br /&gt;someBean = new SomeBean();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return someBean;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The difference here, is the singleton instance is not actually instantiated until the getSomeBean() method is called.  This provides a more lazy instantiation paradigm if needed.  Here we can synchronize the block when SomeBean is instantiated.      &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Initialize-On-Demand Holder Class Idiom&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;class BeanBag {&lt;br /&gt;//Inner Class&lt;br /&gt;private static class BeanBagHolder {&lt;br /&gt;public static SomeBean someBean = new SomeBean();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static Something getInstance() {&lt;br /&gt;return BeanBagHolder.someBean;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This idiom derives its thread safety from the fact that operations that are part of class initialization, which is guaranteed by the JVM.  It derives its lazy initialization from the fact that the inner class is not loaded until some thread references one of its fields or methods.  This provides the best of both options and guaranteed to be thread-safe by the JVM.&lt;br /&gt;&lt;br /&gt;The last option is the most preferred and this article goes into greater detail about &lt;a href="http://www.ibm.com/developerworks/library/j-jtp03304/"&gt;Java Memory Model&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-1188579782792747143?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/1188579782792747143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/using-static-helper-classes-java-memory.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1188579782792747143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1188579782792747143'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/using-static-helper-classes-java-memory.html' title='Using Static Helper Classes - Java Memory and the Initialization on Demand Holder Idiom'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-4442912547403345513</id><published>2009-06-14T12:37:00.000-07:00</published><updated>2010-01-01T17:55:26.313-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Struts2: Accessing Session Variables in JSP's</title><content type='html'>Struts 2 places named objects including the session onto the OGNL stack.  Named objects can easily be retrieves using the &lt;a href="http://struts.apache.org/2.x/docs/property.html"&gt;s:property tag&lt;/a&gt;.  For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;s:property value="%{#session.User.firstName}"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Struts 2 supports other named objects that can be accessed the same way.  Suppose the attribute name attrName for all examples below.  &lt;br /&gt;&lt;br /&gt;Request parameter : #parameters['attrName ']&lt;br /&gt;Request attribute : #request.attrName &lt;br /&gt;Session attribute : #session.attrName&lt;br /&gt;Application Attribute : #application.attrName&lt;br /&gt;&lt;br /&gt;For more on &lt;a href="http://cwiki.apache.org/WW/ognl-basics.html"&gt;OGNL basics, click here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-4442912547403345513?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/4442912547403345513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/struts2-accessing-session-variables-in.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4442912547403345513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4442912547403345513'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/06/struts2-accessing-session-variables-in.html' title='Struts2: Accessing Session Variables in JSP&apos;s'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-8883351832741534750</id><published>2009-04-28T19:45:00.000-07:00</published><updated>2009-04-28T19:58:38.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>ALTER TABLE SQL - ADD COLUMN and Foreign Key Constraint</title><content type='html'>In this short tutorial, we will alter a table in a MySQL database by adding a column to the table along with a new foreign key constraint.&lt;br /&gt;&lt;br /&gt;First we will alter the table user and add a column called zipcodeId, which is an integer.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ALTER TABLE user ADD COLUMN zipcodeId INT&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The zipcodeId field references a field in another table called zipcode.  Next, we'll define the foreign key constraint.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ALTER TABLE User ADD CONSTRAINT FK_User_1 FOREIGN KEY (zipcodeId) REFERENCES Zipcode (id) &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That was quick and easy.  Note, all of this information is readily available in the MySQL online documentation at: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-8883351832741534750?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/8883351832741534750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/alter-table-sql-add-column-and-foreign.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8883351832741534750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/8883351832741534750'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/alter-table-sql-add-column-and-foreign.html' title='ALTER TABLE SQL - ADD COLUMN and Foreign Key Constraint'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7450482277902271745</id><published>2009-04-14T18:33:00.000-07:00</published><updated>2009-04-14T18:52:24.317-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='J2EE Core'/><title type='text'>Check if a file contains a string</title><content type='html'>I recently wrote some java code to check if a file contains a string.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class FileUtilities {&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Returns true if the file exists and contains aString, false otherwise.&lt;br /&gt;    * @param file&lt;br /&gt;    * @param aString&lt;br /&gt;    * @return&lt;br /&gt;    * @throws FileNotFoundException&lt;br /&gt;    */&lt;br /&gt;   public static boolean fileContainsString(File file, String aString) throws FileNotFoundException{&lt;br /&gt;  &lt;br /&gt;      FileInputStream fis = null;&lt;br /&gt;      BufferedReader in = null;&lt;br /&gt;  &lt;br /&gt;      try{&lt;br /&gt;         fis = new FileInputStream(file);&lt;br /&gt;         in = new BufferedReader(new InputStreamReader(fis));&lt;br /&gt;   &lt;br /&gt;         String currentLine = "";&lt;br /&gt;         while ((currentLine = in.readLine()) != null) {&lt;br /&gt;            if(currentLine.indexOf(aString) &gt; 0)  return true;&lt;br /&gt;         }&lt;br /&gt;   &lt;br /&gt;      }catch(IOException ioe){&lt;br /&gt;         ioe.printStackTrace();&lt;br /&gt;      }finally{&lt;br /&gt;         try{&lt;br /&gt;            if(in != null) in.close();&lt;br /&gt;            if(fis != null) fis.close();&lt;br /&gt;         }catch(IOException ioe){ }&lt;br /&gt;      }&lt;br /&gt;      return false;&lt;br /&gt;   } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7450482277902271745?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7450482277902271745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/check-if-file-contrains-string.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7450482277902271745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7450482277902271745'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/check-if-file-contrains-string.html' title='Check if a file contains a string'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5006384537996950052</id><published>2009-04-14T05:54:00.000-07:00</published><updated>2010-01-01T17:54:03.061-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>Converting Camelcase to SEO friendly strings</title><content type='html'>Recently, I've been working on a simple code generator that generates code, facilitating CRUD operations on a simple database table.  I quickly needed to find a way to turn a CamelCase string into an SEO friendly string, converting a string like, "camelCase" to "camel-case".&lt;br /&gt;&lt;br /&gt;Below is a code snippet that does just that.  It isn't the most efficient code, but it does get the job done.  I've been using this code to generate Struts2, Spring JDBC CRUD code, following conventions dictated by the Struts2 Convention Plugin.    &lt;br /&gt;&lt;br /&gt;There is a dependency on the commons-lang package, which you will need in your build path to compile:&lt;br /&gt;&lt;br /&gt;The code snippet follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.tools.generator;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.lang.StringUtils;&lt;br /&gt;import org.apache.commons.lang.WordUtils;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;public class StringConverter{&lt;br /&gt;&lt;br /&gt;private static final char [] capitalLetters = new char[] {'A','B','C','D','E','F',&lt;br /&gt;'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};&lt;br /&gt;&lt;br /&gt;public static String toSearchEngineOptimized(String aString){&lt;br /&gt;ArrayList&lt;string&gt; stringPieces = new ArrayList&lt;string&gt;();&lt;br /&gt;int firstCapital = StringUtils.indexOfAny(aString, capitalLetters);&lt;br /&gt;int tempIndex = 0;&lt;br /&gt;&lt;br /&gt;while(firstCapital &gt; 0){&lt;br /&gt;String snippet = aString.substring(tempIndex, firstCapitalIndex);&lt;br /&gt;tempIndex = firstCapital;&lt;br /&gt;stringPieces.add(StringUtils.uncapitalize(snippet));&lt;br /&gt;firstCapital = &lt;br /&gt;StringUtils.indexOfAny(aString.substring(firstCapital), capitalLetters);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;stringPieces.add(StringUtils.uncapitalize(aString.substring(tempIndex)));&lt;br /&gt;&lt;br /&gt;String foldername = "";&lt;br /&gt;for(int i = 0; i &lt; stringPieces.size(); i++){&lt;br /&gt;if(i == 0)&lt;br /&gt;foldername = stringPieces.get(i);&lt;br /&gt;else&lt;br /&gt;foldername = foldername + "-" + stringPieces.get(i);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return foldername;&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you have any questions, please just comment and I'll get back to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5006384537996950052?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5006384537996950052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/converting-camelcase-to-seo-friendly.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5006384537996950052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5006384537996950052'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/converting-camelcase-to-seo-friendly.html' title='Converting Camelcase to SEO friendly strings'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-4433895086081003677</id><published>2009-04-09T06:08:00.000-07:00</published><updated>2010-01-01T17:52:58.957-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Escape Sequence and Raw String Literal for ${} in FreeMarker</title><content type='html'>I use freemarker to generate JSP's to quickly generate simple CRUD actions.  During the development of this code generator I needed a way to escape ${} and print out that string literal.  &lt;br /&gt;&lt;br /&gt;To indicate that a string literal is a raw string literal, you have to put an r directly before the opening quotation mark or apostrophe-quote. &lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;${r"${example}"}&lt;br /&gt;&lt;br /&gt;will print:&lt;br /&gt;${example}&lt;br /&gt;C:\foo\bar&lt;br /&gt;&lt;br /&gt;Anymore questions about FreeMarker?  Just ask me by providing a comment and I'll mull over it.  Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-4433895086081003677?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/4433895086081003677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/escape-sequence-for-in-freemarker.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4433895086081003677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4433895086081003677'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/04/escape-sequence-for-in-freemarker.html' title='Escape Sequence and Raw String Literal for ${} in FreeMarker'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-7535664228864722913</id><published>2009-03-25T11:07:00.000-07:00</published><updated>2009-03-25T11:44:03.426-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Money'/><title type='text'>Geithner Outlines 'Resolution Authority'</title><content type='html'>Business week posted an article on Geithner's legislation proposal and outlined what 'Resolution Authority' is actually being requested.  The article is referenced below.  &lt;br /&gt;&lt;br /&gt;'The goal of the proposal is to give the government better tools to handle the failure of giant and deeply intertwined financial firms like insurance behemoth American International Group (AIG) and banking titan Citigroup (C)—companies'&lt;br /&gt;&lt;br /&gt;The key phrase being 'like AIG and Citigroup' .  Will this fate soon fall upon AIG and Citigroup themselves?  &lt;br /&gt;&lt;br /&gt;'The proposal would also effectively shift some authority now held by the judiciary to the executive branch in an effort to speed up what could otherwise be slow-moving bankruptcy proceedings.'&lt;br /&gt;&lt;br /&gt;When 'Resolution Authority' is applied, what effect will this have on effected financial institutions?&lt;br /&gt;&lt;br /&gt;The last section in the article called 'Preventing Firestorms', talks about stemming systemic risk.  &lt;br /&gt;&lt;br /&gt;Ultimately, if this legislation is passed, I feel that the US government will have the ability to ultimately say, 'We have the necessary tools in place to prevent big institutions, who are too big to fail, from failing'.  Systemic risk is exactly the failure of any of these type of institutions. The legislation proposes a US government mandated controlled bankruptcy, where all creditors and debtors expeditiously renegotiate terms of existing debt.  &lt;br /&gt;&lt;br /&gt;Will this even pass?  How will the contracts be renegotiated?  Will effected financial institutions sue the US government for full values of their contracts?  &lt;br /&gt;&lt;br /&gt;This 'Resolution Authority' is unconstitutional, and too vague.  If the government did have this power for AIG and Lehman, what would AIG and Lehman look like now?  &lt;br /&gt;&lt;br /&gt;FAZ is now the play.  &lt;br /&gt;&lt;br /&gt;Please share your thoughts and predictions below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.businessweek.com/bwdaily/dnflash/content/mar2009/db20090325_426418.htm?chan=top+news_top+news+index+-+temp_top+story"&gt;http://www.businessweek.com/bwdaily/dnflash/content/mar2009/db20090325_426418.htm?chan=top+news_top+news+index+-+temp_top+story&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-7535664228864722913?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/7535664228864722913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/geithner-outlines-resolution-authority.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7535664228864722913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/7535664228864722913'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/geithner-outlines-resolution-authority.html' title='Geithner Outlines &apos;Resolution Authority&apos;'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5613157527777935078</id><published>2009-03-24T10:30:00.000-07:00</published><updated>2009-03-24T11:31:03.050-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Money'/><title type='text'>Investing in FAZ and FAS (continued)</title><content type='html'>After watching the market rally on Geithner's plan, I looked for some details on the plan and some possibilities that the bears might begin to show their teeth again.&lt;br /&gt;&lt;br /&gt;I ended up reading a post on SeekingAlpha (referenced below).  That had some logical reasonings and views that will chime with investors on the short side of the financials.  But even so with all this logical reasoning in place, we have to inject US Treasury and Federal Reserve policy into our models when investing in FAZ and FAS.&lt;br /&gt;&lt;br /&gt;Let me be the first to say, that I have so far lost money investing in FAZ and FAS (10%) and am posting what I have learned playing FAZ and FAS over the last few months, hopefully to the benefit of others.  &lt;br /&gt;&lt;br /&gt;First, technical analysis is out the window as the performance of these funds have huge swing days on reactions to the news reporting US Treasury and Federal Reserve Policy on the economy.  As for all I know, there is no such technical analysis model that takes the news into account.  The valuations of financials in the future is all speculative and much more volatile than any other index right now.&lt;br /&gt;&lt;br /&gt;Second, do not bet on market corrections.  After large market swings on a trading day, buying the inverse fund is NOT a sure bet.  Supplement, your reasoning for buying the inverse fund with something other than a market correction. You may get caught on the wrong side of the train.  &lt;br /&gt;&lt;br /&gt;Third, know the tools that the US Treasury and Federal Reserve have left at their disposal and bet on public perception, not necessarily your own belief.  I maintain the position that these funds are leveraged and are for taking advantage of huge swing periods, not to hold long on your personal beliefs.  &lt;br /&gt;&lt;br /&gt;Over the last year, the US Treasury and Federal Reserve have timed their agendas and dissemination of information on policy and tools to effectively manipulate public perception on the market.  The more you understand these tools, which tools are left at their disposal, and what effect on public perception these tools may have, the position becomes an issue of timing.&lt;br /&gt;&lt;br /&gt;Last, I would like to begin the comment section on:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What tools and policies the US Treasury and Federal Reserve have at their disposal&lt;/li&gt;&lt;li&gt;When such tools would be deployed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The intended effect on public perception to valuations of the financials the tool or policy will have.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Hopefully, your comments will provide some insight on smart investing strategies in FAZ and FAS.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Referenced Article:&lt;br /&gt;&lt;a href="http://seekingalpha.com/article/127558-the-high-dividend-stock-investor-s-collapsing-dollar-survival-guide-part-6a?source=yahoo"&gt;http://seekingalpha.com/article/127558-the-high-dividend-stock-investor-s-collapsing-dollar-survival-guide-part-6a?source=yahoo&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5613157527777935078?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5613157527777935078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/investing-in-faz-and-fas-continued.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5613157527777935078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5613157527777935078'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/investing-in-faz-and-fas-continued.html' title='Investing in FAZ and FAS (continued)'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-6046584142250557041</id><published>2009-03-16T20:16:00.000-07:00</published><updated>2010-01-01T17:52:01.781-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>MySQL Import and Export</title><content type='html'>Two useful commands below to help you import and export data to and from MySQL databases. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Export&lt;/span&gt;&lt;br /&gt;To export data from a MySQL database, use the mysqldump utility.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysqldump -u(your_username) -p(password) (database_name) &gt; (BACKUPFILE.sql) &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Import&lt;/span&gt;&lt;br /&gt;The file produced can be used to pipe back into a different MySQL database.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysql -u(username) -p(password) (database_name) &lt; (BACKUPFILE.sql)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Remove the parenthesis and replace the values in both commands above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-6046584142250557041?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/6046584142250557041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/mysql-import-and-export.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6046584142250557041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6046584142250557041'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/mysql-import-and-export.html' title='MySQL Import and Export'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-3342483742396316003</id><published>2009-03-04T17:45:00.000-08:00</published><updated>2010-01-01T17:51:27.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>Sorting java.util.List with a java.util.Comparator using java.util.Collections</title><content type='html'>Sorting objects in a List is a piece of code that every java programmer will write more than once in their lifetime.  Any object that implements the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html"&gt;java.util.List&lt;/a&gt; interface can utilize the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)"&gt;sort method&lt;/a&gt; contained within the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html"&gt;java.util.Collections&lt;/a&gt; class to sort the list, using a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html"&gt;java.util.Comparator&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;Below is a short tutorial and code sample.&lt;br /&gt;&lt;br /&gt;First, let's define our object model.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.company.model;&lt;br /&gt;&lt;br /&gt;public class MilkDelivery {&lt;br /&gt;&lt;br /&gt;private int daysTilExpiration;&lt;br /&gt;&lt;br /&gt;public MilkDelivery(int daysTilExpiration){ &lt;br /&gt;this.daysTilExpiration = daysTilExpiration; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public int getDaysTilExpiration() { &lt;br /&gt;return daysTilExpiration; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setDaysTilExpiration(int daysTilExpiration) { &lt;br /&gt;this.daysTilExpiration = daysTilExpiration; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Second, let's write a Comparator and implement the compare method.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.company.model.comparator;&lt;br /&gt;&lt;br /&gt;import java.util.Comparator;&lt;br /&gt;&lt;br /&gt;import com.company.model.MilkDelivery;&lt;br /&gt;&lt;br /&gt;public class MilkDeliveryComparator implements Comparator&lt;milkdelivery&gt; {&lt;br /&gt;&lt;br /&gt;/** Supports sorting from days til expiration ascending */&lt;br /&gt;public int compare(MilkDelivery o1, MilkDelivery o2) {&lt;br /&gt;&lt;br /&gt;//Cast down&lt;br /&gt;MilkDelivery delivery1 = (MilkDelivery) o1;&lt;br /&gt;MilkDelivery delivery2 = (MilkDelivery) o2;&lt;br /&gt;&lt;br /&gt;if(delivery1.getDaysTilExpiration() &gt; delivery2.getDaysTilExpiration()){&lt;br /&gt;return 1;    &lt;br /&gt;}else if(delivery1.getDaysTilExpiration() == delivery2.getDaysTilExpiration()){&lt;br /&gt;return 0;&lt;br /&gt;}else if(delivery1.getDaysTilExpiration() &lt; delivery2.getDaysTilExpiration()){&lt;br /&gt;return -1;&lt;br /&gt;&lt;br /&gt;//or a much more graceful solution....&lt;br /&gt;//return (delivery1.getDaysTilExpiration() - delivery2.getDaysTilExpiration());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Last but not least, lets write a test class.&lt;pre&gt;package com.company.test;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.Collections;&lt;br /&gt;&lt;br /&gt;import com.company.model.MilkDelivery;&lt;br /&gt;import com.company.model.comparator.MilkDeliveryComparator;&lt;br /&gt;&lt;br /&gt;public class MilkTest {&lt;br /&gt;&lt;br /&gt;public static void main(String [] args) throws Exception{&lt;br /&gt;&lt;br /&gt;ArrayList&lt;milkdelivery&gt; deliveries = new ArrayList&lt;milkdelivery&gt;();&lt;br /&gt;&lt;br /&gt;deliveries.add(new MilkDelivery(2));&lt;br /&gt;deliveries.add(new MilkDelivery(3));&lt;br /&gt;deliveries.add(new MilkDelivery(1));&lt;br /&gt;deliveries.add(new MilkDelivery(4));&lt;br /&gt;&lt;br /&gt;//Sort&lt;br /&gt;Collections.sort(deliveries, new MilkDeliveryComparator());&lt;br /&gt;&lt;br /&gt;for(int i = 0; i &lt; deliveries.size(); i++){&lt;br /&gt;MilkDelivery milkDelivery = deliveries.get(i);&lt;br /&gt;System.out.println("Delivery(" + i + ")  Days til Expiration:" + &lt;br /&gt;milkDelivery.getDaysTilExpiration());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The output should read:&lt;br /&gt;Delivery(0) Days til Expiration:1&lt;br /&gt;Delivery(1) Days til Expiration:2&lt;br /&gt;Delivery(2) Days til Expiration:3&lt;br /&gt;Delivery(3) Days til Expiration:4&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-3342483742396316003?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/3342483742396316003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/sorting-javautillist-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3342483742396316003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3342483742396316003'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/03/sorting-javautillist-with.html' title='Sorting java.util.List with a java.util.Comparator using java.util.Collections'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-6860723864956375690</id><published>2009-02-17T14:57:00.001-08:00</published><updated>2010-01-01T17:50:51.844-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Customizing an HTML Struts2 Tag</title><content type='html'>The Struts2 Tags come with the notion of packaged themes or templates.  These packaged themes are not meant for changing the display of presentation, but enables a developer to align the package or theme selection, with the HTML presentation implementation (CSS, AJAX, XHTML, or even old school, simple HTML).  &lt;br /&gt;&lt;br /&gt;In addition the Struts2 Tag library comes with the ability to override the default package implementations provided.  Some of the default packaged themes may perform as desired, but in some instances, you may have to customize the tags display output. &lt;br /&gt;&lt;br /&gt;Below, I've provided two great starting points in helping you overload your templates and customizing the behaviour of your Struts2 tags.  &lt;br /&gt;&lt;br /&gt;http://struts.apache.org/2.0.14/docs/themes-and-templates.html&lt;br /&gt;http://struts.apache.org/2.0.14/docs/template-loading.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-6860723864956375690?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/6860723864956375690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/02/customizing-html-struts2-tag.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6860723864956375690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/6860723864956375690'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/02/customizing-html-struts2-tag.html' title='Customizing an HTML Struts2 Tag'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5247605024417902618</id><published>2009-01-27T17:11:00.000-08:00</published><updated>2010-01-01T17:50:00.674-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>java.util.List to Object array (Object []) of a specified type</title><content type='html'>The tip below can help you in the data access tier or the application tier.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Array.html"&gt;java.lang.reflect.Array&lt;/a&gt; class provides static methods to dynamically create and access Java arrays.  Any java collection or list can easily be converted into an Object array.  There are two method calls, that I preferably squish into one line to get the job done.   The first method call is:  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Array.html#newInstance(java.lang.Class,%20int[])"&gt;Array.newInstance(Class&lt;?&gt; componentType, int length) throws NegativeArraySizeException &lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The method creates a new array with the specified component type and length.  You can also cast down to have returned an array of your specified component type.  &lt;br /&gt;&lt;br /&gt;The second method call is defined in the &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html"&gt;java.util.List&lt;/a&gt; interface. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html#toArray(java.lang.Object[])"&gt;public Object[] toArray(Object[] a)&lt;/a&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The method returns an array containing all of the elements in the List in the correct order where the runtime type of the returned array is that of the specified array. &lt;br /&gt;&lt;br /&gt;Coupling the two calls above can allow you to quickly transform your ArrayList of objects into an object array of the specified object's component type.&lt;br /&gt;&lt;br /&gt;Have a look at the sample code below for an ArrayList of strings to be converted into a String [].&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ArrayList theStrings = new ArrayList();&lt;br /&gt;theStrings.add("Hello");&lt;br /&gt;theStrings.add("Aloha");&lt;br /&gt;theStrings.add("Bonjour");&lt;br /&gt;&lt;br /&gt;//Return String [].&lt;br /&gt;String [] theStringArray = &lt;br /&gt;(String[])theStrings.toArray(&lt;br /&gt;(String[])Array.newInstance(java.lang.String.class, theStrings.size())&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With one line, you'll be able to turn your list of Java objects into an array of objects of the object's component type.&lt;br /&gt;&lt;br /&gt;Questions, just comment and I'll be sure to get back to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5247605024417902618?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5247605024417902618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/01/convert-javautillist-into-array-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5247605024417902618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5247605024417902618'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2009/01/convert-javautillist-into-array-of.html' title='java.util.List to Object array (Object []) of a specified type'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-1900835874397769706</id><published>2008-12-29T20:52:00.000-08:00</published><updated>2010-01-01T17:47:50.462-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>javax.imageio.ImageIO and degrading JPEG</title><content type='html'>JPEG is a lossy compression encoding algorithm. Each time you encode a JPEG image, you lose image quality because of the cosine coefficients dropped in order to perform the compression.&lt;br /&gt;&lt;br /&gt;Using the read and write methods from &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/imageio/ImageIO.html#read(java.io.File)"&gt;javax.imageio.ImageIO.read&lt;/a&gt; and &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/imageio/ImageIO.html#write(java.awt.image.RenderedImage,%20java.lang.String,%20java.io.File)"&gt;javax.imageio.ImageIO.write&lt;/a&gt; method will amplify this quality loss, because of varying detail levels during the read and write. You may be reading a jpeg and 90% detail and writing it with 50% detail.&lt;br /&gt;&lt;br /&gt;Avoid jpeg interpretation of image files unless image processing is required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-1900835874397769706?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/1900835874397769706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/javaximageioimageio-and-degrading-jpeg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1900835874397769706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1900835874397769706'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/javaximageioimageio-and-degrading-jpeg.html' title='javax.imageio.ImageIO and degrading JPEG'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-2412075141741603870</id><published>2008-12-26T21:53:00.000-08:00</published><updated>2010-01-01T17:37:06.585-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data'/><title type='text'>Spring JDBC Tutorial</title><content type='html'>Below is a quick tutorial on how to get things up and running with Spring and JDBC. The code in the tutorial is intended to utilize a MySQL database as its data source.&lt;br /&gt;&lt;br /&gt;Let's start the tutorial off with getting MySQL database installed. If you do not have it installed, follow this link to the &lt;a href="http://dev.mysql.com/downloads/mysql/5.1.html#downloads"&gt;MySQL download site&lt;/a&gt;. Follow the installation instructions and remember your database username and password.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;REQUIRED LIBRARIES&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;Next, download all the necessary libraries needed to execute this tutorial:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JDBC driver for MySQL, &lt;a href="http://dev.mysql.com/downloads/connector/j/5.1.html"&gt;MySQL Connector/J&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The latest spring framework. &lt;a href="http://www.springsource.com/download/community?project=Spring%20Framework"&gt;3.0.0.M1&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.antlr&amp;amp;version=3.0.1"&gt;ANTLR 3.0.1&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://commons.apache.org/downloads/download_logging.cgi"&gt;Commons Logging&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;Because you won't need the whole spring framework, below is a list of all the required Spriong libraries to build and execute the code in this tutorial:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;spring beans&lt;/li&gt;&lt;li&gt;spring context&lt;/li&gt;&lt;li&gt;spring core&lt;/li&gt;&lt;li&gt;spring expression&lt;/li&gt;&lt;li&gt;spring jdbc&lt;/li&gt;&lt;li&gt;spring transaction&lt;/li&gt;&lt;li&gt;mysql connector/j&lt;/li&gt;&lt;li&gt;commons logging &lt;/li&gt;&lt;li&gt;antlr&lt;/li&gt;&lt;/ul&gt;Make sure you add these dependencies to your build path.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="COLOR: rgb(0,102,0)"&gt;CREATE THE DATABASE&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we'll need to create a database along with a table to act as the data source for this tutorial.&lt;br /&gt;&lt;br /&gt;For this example, we'll create a table called siteAdmin:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE siteAdmin (&lt;br /&gt;id MEDIUMINT NOT NULL AUTO_INCREMENT,&lt;br /&gt;username VARCHAR (20) NOT NULL,&lt;br /&gt;password VARCHAR (20) NOT NULL,&lt;br /&gt;firstName VARCHAR (20) NOT NULL,&lt;br /&gt;lastName VARCHAR (20) NOT NULL,&lt;br /&gt;email VARCHAR (40) NOT NULL,&lt;br /&gt;created TIMESTAMP NOT NULL,&lt;br /&gt;lastModified TIMESTAMP NOT NULL,&lt;br /&gt;status INT NOT NULL,&lt;br /&gt;PRIMARY KEY (id)&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: rgb(0,102,0)"&gt;CREATE YOUR DOMAIN MODEL&lt;/span&gt;&lt;br /&gt;Next, generate your &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_10cdsmssc5"&gt;domain model&lt;/a&gt; of the siteAdmin table you just created.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.model;&lt;br /&gt;&lt;br /&gt;import java.sql.Date;&lt;br /&gt;&lt;br /&gt;public class SiteAdmin{&lt;br /&gt;&lt;br /&gt;private int id;&lt;br /&gt;private String username;&lt;br /&gt;private String password;&lt;br /&gt;private String firstname;&lt;br /&gt;private String lastname;&lt;br /&gt;private String email;&lt;br /&gt;private Date created;&lt;br /&gt;private Date lastModified;&lt;br /&gt;private int status;&lt;br /&gt;&lt;br /&gt;/** @return the id */&lt;br /&gt;public int getId() {&lt;br /&gt;return id;&lt;br /&gt;}&lt;br /&gt;/** @param id the id to set */&lt;br /&gt;public void setId(int id) {&lt;br /&gt;this.id = id;&lt;br /&gt;}&lt;br /&gt;/** @return the username */&lt;br /&gt;public String getUsername() {&lt;br /&gt;return username;&lt;br /&gt;}&lt;br /&gt;/** @param username the username to set */&lt;br /&gt;public void setUsername(String username) {&lt;br /&gt;this.username = username;&lt;br /&gt;}&lt;br /&gt;/** @return the password */&lt;br /&gt;public String getPassword() {&lt;br /&gt;return password;&lt;br /&gt;}&lt;br /&gt;/** @param password the password to set */&lt;br /&gt;public void setPassword(String password) {&lt;br /&gt;this.password = password;&lt;br /&gt;}&lt;br /&gt;/** @return the firstname */&lt;br /&gt;public String getFirstname() {&lt;br /&gt;return firstname;&lt;br /&gt;}&lt;br /&gt;/** @param firstname the firstname to set */&lt;br /&gt;public void setFirstname(String firstname) {&lt;br /&gt;this.firstname = firstname;&lt;br /&gt;}&lt;br /&gt;/** @return the lastname */&lt;br /&gt;public String getLastname() {&lt;br /&gt;return lastname;&lt;br /&gt;}&lt;br /&gt;/** @param lastname the lastname to set */&lt;br /&gt;public void setLastname(String lastname) {&lt;br /&gt;this.lastname = lastname;&lt;br /&gt;}&lt;br /&gt;/** @return the email */&lt;br /&gt;public String getEmail() {&lt;br /&gt;return email;&lt;br /&gt;}&lt;br /&gt;/** @param email the email to set */&lt;br /&gt;public void setEmail(String email) {&lt;br /&gt;this.email = email;&lt;br /&gt;}&lt;br /&gt;/** @return the created */&lt;br /&gt;public Date getCreated() {&lt;br /&gt;return created;&lt;br /&gt;}&lt;br /&gt;/** @param created the created to set */&lt;br /&gt;public void setCreated(Date created) {&lt;br /&gt;this.created = created;&lt;br /&gt;}&lt;br /&gt;/** @return the lastModified */&lt;br /&gt;public Date getLastModified() {&lt;br /&gt;return lastModified;&lt;br /&gt;}&lt;br /&gt;/** @param lastModified the lastModified to set */&lt;br /&gt;public void setLastModified(Date lastModified) {&lt;br /&gt;this.lastModified = lastModified;&lt;br /&gt;}&lt;br /&gt;/** @return the status */&lt;br /&gt;public int getStatus() {&lt;br /&gt;return status;&lt;br /&gt;}&lt;br /&gt;/** @param status the status to set */&lt;br /&gt;public void setStatus(int status) {&lt;br /&gt;this.status = status;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: rgb(0,102,0)"&gt;CREATE YOUR DAO INTERFACE&lt;/span&gt;&lt;br /&gt;Next, generate your &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_11gbx75rcw"&gt;DAO interface&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.jdbc.dao;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;import javax.sql.DataSource;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public interface SiteAdminDAO {&lt;br /&gt;&lt;br /&gt;void setDataSource(DataSource ds);&lt;br /&gt;&lt;br /&gt;List&lt;siteadmin&gt; selectAll();&lt;br /&gt;&lt;br /&gt;void create(String username, String password, String firstName, String lastName,&lt;br /&gt;String email, int status);&lt;br /&gt;&lt;br /&gt;List&lt;siteadmin&gt; select(String username, String password);&lt;br /&gt;&lt;br /&gt;List&lt;siteadmin&gt; select(int id);&lt;br /&gt;&lt;br /&gt;List&lt;siteadmin&gt; selectAll();&lt;br /&gt;&lt;br /&gt;void delete(int id);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: rgb(0,102,0)"&gt;IMPLEMENT YOUR DAO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_12hqcd2zhs"&gt;implementing DAO class&lt;/a&gt;. &lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.jdbc.dao.impl;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import javax.sql.DataSource;&lt;br /&gt;&lt;br /&gt;import org.springframework.jdbc.core.JdbcTemplate;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;import com.edwardwebnerd.persistence.jdbc.dao.SiteAdminDAO;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;import com.edwardwebnerd.persistence.jdbc.dao.impl.mapper.SiteAdminMapper;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class SiteAdminDAOImpl implements SiteAdminDAO {&lt;br /&gt;&lt;br /&gt;private DataSource dataSource;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void setDataSource(DataSource ds) { dataSource = ds; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void create(String username, String password, String firstName, &lt;br /&gt;String lastName, String email, int status)&lt;br /&gt;{&lt;br /&gt;JdbcTemplate insert = new JdbcTemplate(dataSource);&lt;br /&gt;insert.update("INSERT INTO siteAdmin " +&lt;br /&gt;"(username, password, firstName, lastName, email, status)" +&lt;br /&gt;" VALUES(?,?,?,?,?)",&lt;br /&gt;new Object[] { username, password, firstName, lastName, email,&lt;br /&gt;status});&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void delete(int id) &lt;br /&gt;{&lt;br /&gt;JdbcTemplate delete = new JdbcTemplate(dataSource);&lt;br /&gt;delete.update("DELETE from siteAdmin where id= ?",&lt;br /&gt;new Object[] { id });&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public List&lt;siteadmin&gt; select(String username, String password) &lt;br /&gt;{&lt;br /&gt;JdbcTemplate select = new JdbcTemplate(dataSource);&lt;br /&gt;return select.query(&lt;br /&gt;"select * from siteAdmin where username = ? AND password = ?",&lt;br /&gt;new Object[] { username, password },&lt;br /&gt;new SiteAdminMapper());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public List&lt;siteadmin&gt; select(int id) &lt;br /&gt;{&lt;br /&gt;JdbcTemplate select = new JdbcTemplate(dataSource);&lt;br /&gt;return select.query(&lt;br /&gt;"select * from siteAdmin where id = ?",&lt;br /&gt;new Object[] { id },&lt;br /&gt;new SiteAdminMapper());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public List&lt;siteadmin&gt; selectAll() &lt;br /&gt;{&lt;br /&gt;JdbcTemplate select = new JdbcTemplate(dataSource);&lt;br /&gt;return select.query("select * from siteAdmin",&lt;br /&gt;new SiteAdminMapper());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The implementation also uses a &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_13ccjm5vdg"&gt;RowMapper&lt;/a&gt; class to help shorten the implementation and provide a single point of managing the mapping between the siteAdmin's table column names and the domain model's class members.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.jdbc.dao.impl.mapper;&lt;br /&gt;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;&lt;br /&gt;import org.springframework.jdbc.core.RowMapper;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;&lt;br /&gt;public class SiteAdminMapper implements RowMapper {&lt;br /&gt;&lt;br /&gt;public SiteAdminMapper(){}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public Object mapRow(ResultSet resultSet, int arg1) throws SQLException {&lt;br /&gt;SiteAdmin siteAdmin = new SiteAdmin();&lt;br /&gt;siteAdmin.setId(resultSet.getInt("id"));&lt;br /&gt;siteAdmin.setUsername(resultSet.getString("username"));&lt;br /&gt;siteAdmin.setPassword(resultSet.getString("password"));&lt;br /&gt;siteAdmin.setFirstname(resultSet.getString("firstname"));&lt;br /&gt;siteAdmin.setLastname(resultSet.getString("lastname"));&lt;br /&gt;siteAdmin.setEmail(resultSet.getString("email"));&lt;br /&gt;siteAdmin.setCreated(resultSet.getDate("created"));&lt;br /&gt;siteAdmin.setLastModified(resultSet.getDate("lastModified"));&lt;br /&gt;siteAdmin.setStatus(resultSet.getInt("status"));&lt;br /&gt;return siteAdmin;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,102,0)"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;CREATE A SERVICE LAYER INTERFACE OVER YOUR DAO IMPLEMENTATION&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, generate your &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_14qwjhbhfh"&gt;Service interface&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.jdbc.dao.SiteAdminDAO;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public interface LittleLeagueServices {&lt;br /&gt;&lt;br /&gt;void setSiteAdminDAO(SiteAdminDAO siteAdminDAO);&lt;br /&gt;&lt;br /&gt;List&lt;siteadmin&gt; siteAdminSelectAll();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,102,0)"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;CREATE A SERVICE LAYER INTERFACE OVER YOUR DAO IMPLEMENTATION&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, generate your &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_15zhftkkfp"&gt;implementing Service class&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com.edwardwebnerd.persistence.jdbc;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.LittleLeagueServices;&lt;br /&gt;import com.edwardwebnerd.persistence.jdbc.dao.SiteAdminDAO;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class LittleLeagueServicesImpl implements LittleLeagueServices {&lt;br /&gt;&lt;br /&gt;private SiteAdminDAO siteAdminDAO;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void setSiteAdminDAO(SiteAdminDAO siteAdminDao) &lt;br /&gt;{    &lt;br /&gt;siteAdminDAO = siteAdminDao;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public List&lt;siteadmin&gt; siteAdminSelectAll(){&lt;br /&gt;return siteAdminDAO.selectAll();&lt;br /&gt;}   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,102,0)"&gt;&lt;span style="COLOR: rgb(0,0,0)"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="color:#006600;"&gt;CONFIGURE SPRING&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Next, we'll define an &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_16gt4mrsdp"&gt;XML config file&lt;/a&gt; to have Spring inject the DAO Implementation into our services and inject a MySQL data source into the DAO Implmentation. Remember to replace the connection information appropriately.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="littleLeagueServices"&lt;br /&gt;class="com.edwardwebnerd.persistence.jdbc.LittleLeagueServicesImpl"&amp;gt;&lt;br /&gt;&amp;lt;property name="siteAdminDAO" ref="siteAdminDAO"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="siteAdminDAO" &lt;br /&gt;class="com.edwardwebnerd.persistence.jdbc.dao.impl.SiteAdminDAOImpl"&amp;gt;&lt;br /&gt;&amp;lt;property name="dataSource" ref="dataSource"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="dataSource" destroy-method="close" &lt;br /&gt;class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"&amp;gt;&lt;br /&gt;&amp;lt;property name="url" &lt;br /&gt;value="jdbc:mysql://localhost:3306/&lt;databasename&gt;?autoReconnect=true"/&amp;gt;&lt;br /&gt;&amp;lt;property name="user" value="&lt;databaseuser&gt;"/&amp;gt;&lt;br /&gt;&amp;lt;property name="password" value="&lt;databasepassword&gt;"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(0,102,0)"&gt;&lt;span style="COLOR: rgb(0,0,0)"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;TRY A TEST RUN&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Next, test your services with a &lt;a href="http://docs.google.com/Doc?id=dc58ggrv_17grwznvc3"&gt;test run class&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package com;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import org.springframework.beans.factory.BeanFactory;&lt;br /&gt;import org.springframework.context.support.ClassPathXmlApplicationContext;&lt;br /&gt;import org.springframework.context.ApplicationContext;&lt;br /&gt;&lt;br /&gt;import com.edwardwebnerd.persistence.LittleLeagueServices;&lt;br /&gt;import com.edwardwebnerd.persistence.model.SiteAdmin;&lt;br /&gt;&lt;br /&gt;import org.apache.log4j.BasicConfigurator;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;public class SpringTest {&lt;br /&gt;&lt;br /&gt;static Logger logger = Logger.getLogger(SpringTest.class );&lt;br /&gt;&lt;br /&gt;public static void main(String [] args){&lt;br /&gt;BasicConfigurator.configure();&lt;br /&gt;&lt;br /&gt;ApplicationContext applicationContext = &lt;br /&gt;new ClassPathXmlApplicationContext("config.xml");&lt;br /&gt;BeanFactory factory = applicationContext;&lt;br /&gt;&lt;br /&gt;logger.info("LittleLeagueServices Initializing");&lt;br /&gt;LittleLeagueServices littleLeagueServices = &lt;br /&gt;(LittleLeagueServices) factory.getBean("littleLeagueServices");&lt;br /&gt;logger.info("LittleLeagueServices Initialized");&lt;br /&gt;&lt;br /&gt;logger.info("LittleLeagueServices: Retrieving SiteAdmins");&lt;br /&gt;List&lt;siteadmin&gt; siteAdmins = littleLeagueServices.siteAdminSelectAll();&lt;br /&gt;for(int i = 0; i &lt; siteAdmins.size(); i++){&lt;br /&gt;SiteAdmin siteAdmin = siteAdmins.get(i);&lt;br /&gt;logger.info(siteAdmin.toString());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you have any questions on this tutorial, just comment on the blog and I'll be sure to get back to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-2412075141741603870?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/2412075141741603870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/spring-and-jdbc-tutorial.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2412075141741603870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/2412075141741603870'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/spring-and-jdbc-tutorial.html' title='Spring JDBC Tutorial'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-4172554931532976311</id><published>2008-12-12T16:58:00.000-08:00</published><updated>2008-12-20T08:38:03.146-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Money'/><title type='text'>Investing in FAZ (Financial Bear 3x) and FAS (Financial Bull 3x)</title><content type='html'>As I became more interested in investing in FAZ and FAS, I first looked at all the posts in the forums and tried to filter out all the "trolling" and it seems to me that many don't understand what they are investing in.&lt;br /&gt;&lt;br /&gt;This blog takes attempts to take out all the noise and attempts to look at the numbers objectively, to try and develop an investment strategy in FAZ or FAS.  I'm doing this research myself, so thought I'd share it and post it in other forums to help people figure out the maze.&lt;br /&gt;&lt;br /&gt;First the introduction, FAZ and FAS are 3X leveraged ETF's that track the &lt;a href="http://finance.google.com/finance?q=RIFIN.X"&gt;Russell 1000 Financial Services (RGS) Index&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);font-size:130%;" &gt;LEVERAGE&lt;/span&gt;&lt;br /&gt;The first thing to note about these ETF's is the leverage.  The leverage for these funds is at 3x.  There are other ETF's tracking indexes leveraged 2x and other's that are not leveraged at all.  The key here is to understand what "leverage" exactly means?  Does it mean that for every 1% change in the index, leads to a 3% change in the price of funds?  I wasn't too sure and plenty of the forums in these funds elude to buyer beware messages.   So let's crunch the numbers and see exactly what it means.  (&lt;a href="http://finance.google.com/finance?chdnp=1&amp;amp;chdd=1&amp;amp;chds=1&amp;amp;chdv=1&amp;amp;chvs=maximized&amp;amp;chdeh=0&amp;amp;chdet=1229186904437&amp;amp;chddm=12121&amp;amp;cmpto=NYSE:FAZ;NYSE:FAS&amp;amp;cmptzos=-18000;-18000&amp;amp;q=INDEXAMEX:RIFIN.X&amp;amp;ntsp=0"&gt;Click the graph&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Yv2d0B8sxyw/SUQ1gGlhdHI/AAAAAAAAAOE/PitrazAE7Co/s1600-h/rifin.x_fas_faz.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 129px;" src="http://4.bp.blogspot.com/_Yv2d0B8sxyw/SUQ1gGlhdHI/AAAAAAAAAOE/PitrazAE7Co/s400/rifin.x_fas_faz.JPG" alt="" id="BLOGGER_PHOTO_ID_5279403488825144434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The first thing to note is that the ETF's inception date was November 7 and if we had bought both funds and held onto it til the present date, we would of lost a great deal on both sides of the coin.  As of December 12:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;RIFIN.X (&lt;span style="color: rgb(255, 0, 0);"&gt;-14.5%&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;FAZ (&lt;span style="color: rgb(255, 0, 0);"&gt;-39.7%&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;FAS (&lt;span style="color: rgb(255, 0, 0);"&gt;-53.81%&lt;/span&gt;)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;By looking at the names of Finanacial Bull 3x and Financial Bear 3x alone, you might expect the following performance of funds in the funds with the RIFIN.x losing 14.5% since inception:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;RIFIN.X (&lt;span style="color: rgb(255, 0, 0);"&gt;-14.5%)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;FAZ (&lt;span style="color: rgb(51, 204, 0);"&gt;33.5%&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;FAS (&lt;span style="color: rgb(255, 0, 0);"&gt;-33.5%&lt;/span&gt;)&lt;/li&gt;&lt;/ul&gt;However, that is not the math that these funds are following and it is actually contained within their &lt;a href="http://www.direxionshares.com/pdfs/DRX_prospectus.pdf"&gt;prospectus&lt;/a&gt;.  If you have not viewed the prospectus, I highly recommend that you do.&lt;br /&gt;&lt;br /&gt;So let's look at the following hypothetical scenario to try and explain what it means to be 3x leveraged and try to explain the above scenario.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Yv2d0B8sxyw/SUQ-e_tUyUI/AAAAAAAAAOM/ejlwhpgS8uA/s1600-h/rifin.x_fas_faz_graph.JPG"&gt;&lt;img style="cursor: pointer; width: 367px; height: 347px;" src="http://2.bp.blogspot.com/_Yv2d0B8sxyw/SUQ-e_tUyUI/AAAAAAAAAOM/ejlwhpgS8uA/s400/rifin.x_fas_faz_graph.JPG" alt="" id="BLOGGER_PHOTO_ID_5279413365403601218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So as we see, ultimately, that over time, this fund will lose you money.  It gets increasingly more difficult for these funds to get back even, even more so as the RIFIN.X fluctuates up and down.  People holding this fund for over 3 days need to keep reading.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;STRATEGY FOR PLAYING FAZ OR FAS&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Holders beware, do not hold this for over a day in your portfolio for the reasons stated above.  This ETF is for day traders only, who can take advantage of a volatile swing in the index in less than 24 hours.  There is no reason to hold FAZ or FAS, because ultimately you are betting on multiple day bear or bull rallies.  It's a slippery slope, but most of it is downhill if you hold.&lt;br /&gt;&lt;br /&gt;On the google forums, fjordl...@gmail.com posted a spreadsheet with FAS and FAZ prices along side the RIFIN.X prices, to illustrate how FAZ and FAS are priced.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a target="_blank" rel="nofollow" href="http://spreadsheets.google.com/ccc?key=peyWe3CKKO3vpdyZuto56bQ"&gt;http://spreadsheets.google.com/ccc?key=peyWe3CKKO3vpdyZuto56bQ&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;If you have any questions about this, just fill out a comment below and I'll get back to you.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-4172554931532976311?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/4172554931532976311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/investing-in-fazfas.html#comment-form' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4172554931532976311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/4172554931532976311'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/investing-in-fazfas.html' title='Investing in FAZ (Financial Bear 3x) and FAS (Financial Bull 3x)'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Yv2d0B8sxyw/SUQ1gGlhdHI/AAAAAAAAAOE/PitrazAE7Co/s72-c/rifin.x_fas_faz.JPG' height='72' width='72'/><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-982315726224253698</id><published>2008-12-11T18:37:00.000-08:00</published><updated>2010-01-01T17:36:33.664-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Check for null in FreeMarker 2.4</title><content type='html'>With the preview of FreeMarker version 2.4 available, a few enhancements to the template language have really improved FreeMarker's appeal.&lt;br /&gt;&lt;br /&gt;Providing a check for "null" is one of the largest enhancements that make it easier for developers to transition to FreeMarker from other view technologies. View the (&lt;a href="http://freemarker.sourceforge.net/docs-24pre1/versions_2_4_pre1.html#autoid_137"&gt;preview announcement&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Previously in 2.3 and below, a "null" value was essentially treated as a missing variable. The &lt;a href="http://freemarker.org/docs/dgui_template_exp.html#dgui_template_exp_missing_test"&gt;missing value operator&lt;/a&gt; was the suggested way of testing for null, as the word "null" is not a reserved word in the template language. Here's a look at the 2.3 documentation on &lt;a href="http://freemarker.sourceforge.net/docs-24pre1/dgui_template_exp.html#dgui_template_exp_missing"&gt;treating undefined variables and null values&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;color:#009900;"&gt;FreeMarker 2.3 and Pre - Missing Value Operator&lt;/span&gt;&lt;br /&gt;Assume aVariable is null or not defined.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color:#666666;"&gt;&lt;#if aVariable??&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/#IF&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;&lt;span style="color:#000000;"&gt;If you wanted to check if a string was empty or null in FreeMarker, you might have used &lt;a href="http://freemarker.sourceforge.net/docs-24pre1/ref_builtins_expert.html#ref_builtin_has_content"&gt;has_content&lt;/a&gt;, one of the "Seldom used and expert built-ins"&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:times new roman;font-size:130%;color:#000000;"&gt;Assume aVariable is null or not defined. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;color:#666666;"&gt;&lt;#if aVariable?has_content&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;OR&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;color:#333333;"&gt;&lt;span style="color:#666666;"&gt;&lt;#if aVariable!?size &gt; 0 or aVariable!?length &gt; 0&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color:#009900;"&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;&lt;span style="font-size:130%;"&gt;FreeMarker 2.4 Enhancement&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;&lt;span style="color:#000000;"&gt;2.4 is now null-aware with other &lt;a href="http://freemarker.sourceforge.net/docs-24pre1/versions_2_4_pre1.html#autoid_137"&gt;template language enhancements&lt;/a&gt;, making null a reserved word in 2.4.&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-982315726224253698?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/982315726224253698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/check-for-null-in-freemarker-24.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/982315726224253698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/982315726224253698'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/check-for-null-in-freemarker-24.html' title='Check for null in FreeMarker 2.4'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-1809445469189951925</id><published>2008-12-07T19:55:00.000-08:00</published><updated>2010-01-01T17:36:02.763-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>JSTL  Expression Language (EL) not being resolved.</title><content type='html'>When the container is unable to resolve EL syntax ${}, in JSTL tags.  There are a couple of things that you can do to get EL syntax resolving in your JSP's.  I assume that you are running an application server supporting the JSP 1.2 and Servlet 2.3 specifications.&lt;br /&gt;&lt;br /&gt;In order to evaluate EL expressions, your web.xml file must be up to date.&lt;br /&gt;If your web.xml states that it is version 2.3 or less, EL evaluation is disabled by default for backwards compatibility.&lt;br /&gt;&lt;br /&gt;If your web.xml reads:&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;lt;?xml version=&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);" &gt;"1.0"&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt; encoding=&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);" &gt;"UTF-8"&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;lt;!DOCTYPE web-app PUBLIC &lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);" &gt;"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt; &lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);" &gt;"http://java.sun.com/dtd/web-app_2_3.dtd"&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;lt;web-app&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Replace it with:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;lt;web-app xmlns="&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;"http://java.sun.com/xml/ns/j2ee"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;   version="2.4"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;If you are unable to update your web.xml to a post 2.3 descriptor, then you can add the following to your jsp page to have EL evaluated:&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;&amp;lt;%@&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;page &lt;/span&gt;&lt;span style="color: rgb(102, 51, 102);"&gt;isElIgnored&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 153);"&gt;"false"&lt;/span&gt; &lt;span style="color: rgb(153, 51, 0);"&gt;%&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;overriding the default configuration for a pre 2.4 descriptor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-1809445469189951925?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/1809445469189951925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/jstl-expression-language-el-not-being.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1809445469189951925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/1809445469189951925'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/jstl-expression-language-el-not-being.html' title='JSTL  Expression Language (EL) not being resolved.'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-5207117438963115449</id><published>2008-12-04T20:21:00.000-08:00</published><updated>2010-01-01T17:34:01.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><title type='text'>Filtering IP traffic using a Java Filter - RemoteAddrFilter</title><content type='html'>I recently wrote a Java Filter, which is a replica of the &lt;a class="post-count-link" href="http://www.docjar.com/docs/api/org/apache/catalina/valves/RemoteAddrValve.html"&gt;org.apache.catalina.valves.RemoteAddrValve&lt;/a&gt; implementation. It performs filtering based on comparing the requestors remote IP address against a set of regular expressions, configured in the Filter's initialization parameters. If an IP addresses is to be rejected it is rejected with a Forbidden HTTP response.&lt;br /&gt;&lt;br /&gt;This provided useful because Valves are attached to the servlet container while a Filter can be mapped to any url pattern at the application level rather than at the container level.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(63, 127, 95);font-size:16;" &gt;GET THE CODE&lt;/span&gt;&lt;br /&gt;Here is a link to the filter code. (&lt;a class="post-count-link" href="http://docs.google.com/View?docid=dc58ggrv_9g3zcdjg9"&gt;RemoteAddrFilter.java&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;This filter is configured by setting the &lt;code&gt;allow&lt;/code&gt; and/or &lt;code&gt;deny&lt;/code&gt; properties to a comma-delimited list of regular expressions to which the requestors remote address will be compared.  Evaluation proceeds as follows:&lt;ul&gt;&lt;li&gt;The filter initializes reading the &lt;code&gt;allow&lt;/code&gt; and/or &lt;code&gt;deny&lt;/code&gt; properties and converting them to a comma-delimited list of regular expressions to which the requester's remote address will be compared.&lt;/li&gt;&lt;li&gt;If there are any deny expressions configured, the property will be compared to each such expression.  If a match is found, this request will be rejected with a "Forbidden" HTTP response.&lt;/li&gt;&lt;li&gt;If there are any allow expressions configured, the property will be compared to each such expression.  If a match is found, this request will be allowed to pass through to the next Filter in the current pipeline.&lt;/li&gt;&lt;li&gt;If one or more deny expressions was specified but no allow expressions, allow this request to pass through (because none of the deny expressions matched it).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The request will be rejected with a "Forbidden" HTTP response.&lt;/li&gt;&lt;/ul&gt;The filter is configured the same way all Java Filter's. This filter takes two initial parameters.   The value of those properties should be set to a comma-delimited list of regular expressions to which the requestors remote address will be compared.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(63, 127, 95);font-size:16;" &gt;CONFIGURE&lt;/span&gt;&lt;br /&gt;The filter is added to your context via the web.xml.  Below is an example configuration.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;filter&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;filter-name&amp;gt;RemoteAddrFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;filter-class&amp;gt;RemoteAddrFilter&amp;lt;filter-class&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;init-param&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;param-name&amp;gt;allow&amp;lt;/param-name&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;param-value&amp;gt;192.168.1.*&amp;lt;/param-value&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/init-param&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;init-param&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;param-name&amp;gt;deny&amp;lt;/param-name&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;param-value&amp;gt;163.122.111.*&amp;lt;/param-value&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/init-param&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/filter&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(63, 127, 95);font-size:16;" &gt;DEPENDENCIES&lt;/span&gt;&lt;br /&gt;There is a dependency with &lt;a class="post-count-link" href="http://jakarta.apache.org/regexp/"&gt;Jakarta Regexp&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-5207117438963115449?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/5207117438963115449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/filtering-ip-traffic-using-java-filter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5207117438963115449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/5207117438963115449'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/filtering-ip-traffic-using-java-filter.html' title='Filtering IP traffic using a Java Filter - RemoteAddrFilter'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3155249211158577195.post-3856953450337512281</id><published>2008-12-02T20:55:00.000-08:00</published><updated>2008-12-06T21:08:00.310-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Money'/><title type='text'>FINANCIAL BEAR 3X (Public, NYSE:FAZ)</title><content type='html'>Don't think the economy is doing well? Think that it will get worse? There is a fund out there for bears to sink their teeth into the market, tripling down their bet on the further decline of financial and capital markets.&lt;br /&gt;&lt;br /&gt;I'm bullish on financial bear, as I'll need to see one of three things to start selling off my holding:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unemployment rates decline.&lt;/li&gt;&lt;li&gt;Foreclosure rates decline.&lt;/li&gt;&lt;li&gt;Standard of living increase.&lt;/li&gt;&lt;/ul&gt;It recently ran to as high as 200 when news came out that Paulson would not use bailout money towards its original intention of buying troubled assets from financial firms and Citibank needed an additional cash infusion.  Comboed with the indexes at their lows in late November, this fund ran hyper. &lt;br /&gt;&lt;br /&gt;The next coming weeks this fund will see a decline, but this one could run through the same scenario, dependent on whether or not Congress will give Paulson the second half of this bailout.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3155249211158577195-3856953450337512281?l=j2eewebprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eewebprogrammer.blogspot.com/feeds/3856953450337512281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/financial-bear-3x-public-nysefaz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3856953450337512281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3155249211158577195/posts/default/3856953450337512281'/><link rel='alternate' type='text/html' href='http://j2eewebprogrammer.blogspot.com/2008/12/financial-bear-3x-public-nysefaz.html' title='FINANCIAL BEAR 3X (Public, NYSE:FAZ)'/><author><name>Edward Song</name><uri>http://www.blogger.com/profile/07441936400823087782</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
