<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Herbert Wu Blog</title>
	<atom:link href="http://herbertwu.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://herbertwu.wordpress.com</link>
	<description>About A Few Technology Related Things</description>
	<lastBuildDate>Fri, 25 Nov 2011 22:49:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='herbertwu.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/363fec680c174193f8abaebd0ad49e4f?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Herbert Wu Blog</title>
		<link>http://herbertwu.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://herbertwu.wordpress.com/osd.xml" title="Herbert Wu Blog" />
	<atom:link rel='hub' href='http://herbertwu.wordpress.com/?pushpress=hub'/>
		<item>
		<title>2010 SpringOne 2GX Groovy/Grails Session Notes</title>
		<link>http://herbertwu.wordpress.com/2010/10/24/2010-springone-2gx-groovygrails-session-notes/</link>
		<comments>http://herbertwu.wordpress.com/2010/10/24/2010-springone-2gx-groovygrails-session-notes/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 17:49:01 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[grails NOSQL]]></category>
		<category><![CDATA[grails tools]]></category>
		<category><![CDATA[groovy programming]]></category>
		<category><![CDATA[redpoint]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=79</guid>
		<description><![CDATA[The notes here are from 10000-ft view and some statements are merged from multiple sessions. * Externalized configuration of  Config.groovy grails.config.locations = [ "classpath:${appName}-config.properties", "classpath:${appName}-config.groovy", "file:${userHome}/.grails/${appName}-config.properties", "file:${userHome}/.grails/${appName}-config.groovy"] This way, you may remove production login/password from source control, along with  environment specific information from WAR. * liquibase (www.liquibase.org) for database migration management. * Securing JMX/VisualVM operations [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=79&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The notes here are from 10000-ft view and some statements are merged from multiple sessions.</p>
<div>* <strong>Externalized configuration of  Config.groovy</strong><br />
<em><br />
grails.config.locations = [ "classpath:${appName}-config.properties", </em></div>
<div><em> "classpath:${appName}-config.groovy", </em></div>
<div><em> "file:${userHome}/.grails/${appName}-config.properties", </em></div>
<div><em> "file:${userHome}/.grails/${appName}-config.groovy"]</em></div>
<div></div>
<div>This way, you may remove production login/password from source control, along with  environment specific information from WAR.</p>
<p>* <strong>liquibase (www.liquibase.org) for database migration management. </strong></p>
<p>* <strong>Securing JMX/VisualVM operations in production environment</strong></p>
<p>* <strong>GORM may not completely shield you from Hibernate</strong><br />
<a href="http://blog.springsource.com/2010/06/23/gorm-gotchas-part-1/">http://blog.springsource.com/2010/06/23/gorm-gotchas-part-1/</a> lists some common issues</p>
<p>* <strong>Performance tuning (warning: avoid premature tuning)</strong><br />
- tools<br />
Easiest one is to download tc-Server/Spring Insight and drop your war to see which operation is slow.<br />
Other tools include Profile Plugin, Hibernate logging, p6Spy at server side, and Chrome speed tracer and Firefox ySlow at client side.<br />
- fixes<br />
Database queries tuning, Service/View tier Caching(springcache plugin), Async. calling, Http tier tuning, such as “static resource” plugin</p>
<p>* <strong>NOSQL development</strong><br />
NOSQL may provide better scalability and easier domain object mapping compared with RDBMS in some emerging data processing applications, but it is currently still in some sort of hype stage.  RDMS will remain to be the core persistence platform for long time to come. The NOSQL applicability is based on the application requirements of Consistency, Availability and Partition-tolerance. See <a href="http://bit.ly/cap-theorem-proof">http://bit.ly/cap-theorem-proof</a> for details. It likely will take many more years for NOSQL to mature.<br />
Grails currently provides Redis and GemFire NOSQL plugins and more are coming.</p>
<p>* <strong>Grails release updates in short and medium terms</strong><br />
- Groovy-1.8, Spring-3.1 and Hibernate-3.6 upgrade<br />
- Agent-based reloading to improve performance<br />
- Better static resource management<br />
- NOSQL and RabbitMQ<br />
- Rest client and server enhancement<br />
- JQuery and Flex<br />
- Gradle Build<br />
- Spock and Jeb testing support</p>
<p><strong>* Groovy programming language</strong><br />
- Compile time meta-programming via AST transformation. @Singleton and @Immutable etc annotations are classical examples.<br />
- Run-time meta-programming via ExpandoMetaClass. <em>myPerson.save() and Person.findByLastName(“Mylastname”)</em> etc domain class persistent methods are typical examples.<br />
- Performance has been improved greatly in the last few releases, but more are coming. Some audience still concerns the issue, such as bootstrap-startup time etc.<br />
- Better modularization to allow customized and more efficient run-time deployment for different kinds of applications.</p>
<p><strong>* Groovy concurrency</strong><br />
- At its core, java concurrency is the foundation, such as jetlang, jppf.org, gruple, gridgain, multiverse etc. IBM’s <a href="http://alphaworks.ibm.com/tech/contest">http://alphaworks.ibm.com/tech/contest</a> remains the only thread testing tool to help improving thread safety.<br />
- GPars is a new tool to help simplify Groovy/Java concurrent tasking implementation.</p>
<p>* <strong>Spock unit testing framework</strong><br />
Implemented mostly via Groovy compile-time meta-programming(AST transformation), it claims to be state-based, data-driven and behavior-based testing. It also supports extension for testing customization and enhancement.<br />
However its core implementation is still based on jUnit spec and does not support parallel unit testing yet(It may come in the upcoming 1.0 release).</p>
<p><strong>* Gradle build tool</strong><br />
It’s aim is to combine best features from both Ant(simplicity and control) and Maven(dependency management). It’s using closure syntax DSL for build scripting. For now the adoption is limited as the release is not 1.0 yet and lacks IDE support.</p>
<p>* <strong>Git repository</strong><br />
Single word: distributed repository management tool with core operation as <em>add-commit-push</em>. Its underlying tools allow better parallel development and changes/cloud-support management.</p>
<p><strong>* AMQP/RabbitMQ</strong><br />
Protocol-based messaging tool to allow diversified clients interaction. RPC call via direct-exchange. No pre-determined content-type for messaging payload.<br />
No embedded MQ yet for writing unit/functional tests. Clustering support for high-availability operation is in the works.</p>
<p>* <strong>Mobile development</strong><br />
- Server side using Spring-Mobile/REST Service<br />
- Client side is all native code and no write-once-run-everywhere. Today is iPhone(you need a Mac) and tomorrow is Android, with Windows mobile 7 and Blackberry are wild-cards. Palm/WebOS may survive via tablet push by HP.<br />
- <em>PhoneGap</em> and <em>Appcelerator/Titanium</em> are two major CSS/javascript based cross platform development tools, with native wrapper to deploy the app to target native device. It’s unclear on future direction how the cross-platform standard may playout.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=79&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2010/10/24/2010-springone-2gx-groovygrails-session-notes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails spring-security-core Usage Tips</title>
		<link>http://herbertwu.wordpress.com/2010/09/06/grails-spring-security-core-usage-tips/</link>
		<comments>http://herbertwu.wordpress.com/2010/09/06/grails-spring-security-core-usage-tips/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 16:25:05 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[grails authentication and authorization]]></category>
		<category><![CDATA[grails password management]]></category>
		<category><![CDATA[grails security plug-in]]></category>
		<category><![CDATA[logout]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[redpoint]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=65</guid>
		<description><![CDATA[There are a number of web app-layer authentication and authorization plug-ins for Grails.  These plug-ins provide essential functionalities for user log-in, access control, single sign-on etc.  Spring-security-core is the latest one built on top of  the powerful Java security framework Spring-Security-3.0(formerly Acegi security).  Spring-Security-3.0 provides supports for numerous authentication methods, such as OpenID, LDAP, JAAS etc. Here [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=65&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There are a number of web app-layer authentication and authorization plug-ins for Grails.  These plug-ins provide essential functionalities for user log-in, access control, single sign-on etc.  Spring-security-core is the latest one built on top of  the powerful Java security framework Spring-Security-3.0(formerly Acegi security).  Spring-Security-3.0 provides supports for numerous authentication methods, such as OpenID, LDAP, JAAS etc. Here are a few common usage tips for this plug-in.</p>
<p><strong>1. Implement your own authentication provider</strong><br />
Spring-Security-Core is still pretty new and may not provide you with a default authentication provider. But fortunately Spring-Security framework is interface based framework and you can easily implement the <em>org.springframework.security.authentication.AuthenticationProvider</em> interface for your own authentication protocal. Your code sketch may look like this:</p>
<p><em>public class MyAuthenticationProvider implements AuthenticationProvider {<br />
</em><em>&#8230;&#8230;<br />
</em><em>public Authentication authenticate(Authentication authentication) throws AuthenticationException {<br />
</em><em>// Your custom authentication integration code goes here<br />
</em><em>}</em></p>
<p><em>public boolean supports(Class&lt;? extends Object&gt; authentication)  {<br />
</em><em>&#8230;&#8230;<br />
</em><em>}<br />
</em><em>}</em></p>
<p>The <em>Authentication</em> object can be viewed as a simple security token to hold information about your log-in status, user name/password, user information(<span style="font-family:monospace;line-height:normal;font-size:12px;">UserDetailsService)</span>etc, sort of like a building access badge. You need to refer to SpringSource reference doc on more about <em>Authentication</em> details.</p>
<p>Once you implement the provider interface, place it in Grails conf/spring/resource.xml with a bean name such as <strong>m</strong><em><strong>yAuthenticationProvider</strong></em>, and then activate the provider in Grails config.groovy with one line:<br />
grails.plugins.springsecurity.providerNames = ['<strong>m</strong><em><strong>yAuthenticationProvider</strong></em>']</p>
<p>Now, you are done with your own custom authentication integration and ready to use the log-in form and other security service in your application. Spring-Security-Core comes with most features you need at HTML form, service and GSP tag level for security integration and deployment.</p>
<p>Since Spring-Security web authentication is servlet filter based, it always automatically prefix your app-context-path in the process. So be careful when configure the application related URL properties. For example, when login failed, you want to redirect the user back to the log-in page wherever it is. The proper relative url should be the one w/o context path:<br />
<em>${request.forwardURI.substring(request.contextPath.length())} </em>Notice here we do not use http referer as it may not work with some older browser.</p>
<p><strong>2. Session Fixation Prevention</strong><br />
Spring-Security-Core by default automatically migrates your existing session into the new session upon successful authentication. This prevents sessionId based attack.<br />
Another added benefit is that it will integrate smoothly with your current session-based application, such as shopping-cart, Spring Webflow etc. User can log-in at any point of the session flow.  But notice log-out will wipe out the security session along with your application session data as well. So you may need a warning message for end-user to logout during middle of your application session flow. If some session data must be processed before logout, you can implement a logout handler and register it at config.groovy.</p>
<p><strong>3. Password management</strong><br />
Another common feature is managing expired, locked and or temporary password etc. Many applications have slightly different way to use it. Spring-Security-Core has four methods defined on <span style="font-family:monospace;line-height:normal;font-size:12px;">UserDetailsService(</span> a component in the above <em>Authentication</em> object)<br />
<span style="font-family:monospace;">- isAccountNonExpired()<br />
</span><span style="font-family:monospace;">- isAccountNonLocked()<br />
</span><span style="font-family:monospace;">- isCredentialsNonExpired()<br />
</span><span style="font-family:monospace;">- isEnabled()</span></p>
<p>You can implement any of these methods to suit your application needs to manage invalid password and redirect user to a proper error handling page when the exception happens.</p>
<p>Spring-Security-Core is a feature rich security plug-in that can satisfy most of you application authentication and authorization needs with easy-to-use interface for extending/customization. The underlying Spring Security-3.0 is also very powerful and you are assured most of your application security requirement can be met.</p>
<p><strong>References</strong></p>
<p>1. <a href="http://www.grails.org/plugin/spring-security-core">grails-spring-security-core/</a></p>
<p>2. <a title="Spring-Security" href="http://static.springsource.org/spring-security/site/">http://static.springsource.org/spring-security/site/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/65/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=65&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2010/09/06/grails-spring-security-core-usage-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Apache Commons JEXL for Java Object Validation</title>
		<link>http://herbertwu.wordpress.com/2010/03/14/using-apache-commons-jexl-for-java-object-validation/</link>
		<comments>http://herbertwu.wordpress.com/2010/03/14/using-apache-commons-jexl-for-java-object-validation/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 04:40:47 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache commons jexl application]]></category>
		<category><![CDATA[java bean validation]]></category>
		<category><![CDATA[java object validation]]></category>
		<category><![CDATA[JEXL object validation]]></category>
		<category><![CDATA[redpoint]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=49</guid>
		<description><![CDATA[Apache Commons JEXL is a simple generic  expression language that can be used for dynamic scripting. Among many possible applications, we apply it for dynamic Java object validation. Object validation is rather common in many applications and there are numerous ways to do it. But via JEXL, you can put validation rules in a configuration [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=49&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Apache Commons JEXL is a simple generic  expression language that can be used for dynamic scripting. Among many possible applications, we apply it for dynamic Java object validation.</p>
<p>Object validation is rather common in many applications and there are numerous ways to do it. But via JEXL, you can put validation rules in a configuration file or database table and JEXL can load them up at runtime to validate a given object.  Here is an example on how to do it.</p>
<p><strong>1. A Simple Validation Problem</strong><br />
Assuming a Person class with four attributes: <em>SSN</em>, <em>firstName, lastName and birthYear</em>. It has two different validation rules per different environment:<br />
(1) Rule 1:  SSN != null and birthYear &lt; 1990 when a Person object is processed in Bonus-prize-draw component.<br />
(2) Rule 2: firstName != null  and lastName != null when a Person object is processed in Guest-book sign-up component.</p>
<p>The Person class:</p>
<pre>public class Person {
  private String ssn;
  private String firstName;
  private String lastName;
  private Integer birthYear;

  public Person(String ssn, String firstName, String lastName,Integer birthYear) {
    this.ssn = ssn;
    this.firstName = firstName;
    this.lastName = lastName;
    this.birthYear = birthYear;
  }
  public String getSsn() {
    return ssn;
  }
  public String getFirstName() {
    return firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public Integer getBirthYear() {
    return birthYear;
  }
}<em>
</em></pre>
<p>Then an instance of Person class called p is subjected to two validation rules defined above. We can denote above rules as four expression-syntax Strings :<br />
&#8220;p.ssn != null&#8221;, &#8220;p.birthYear &lt; 1990&#8243;, &#8220;p.firstName != null&#8221;, and &#8220;lastName != null&#8221;</p>
<p><strong>2. The Validation Class</strong><br />
First we define a base abstract class called JexlObjectValidator</p>
<pre>import java.util.List;
public abstract class JexlObjectValidator {
 // A list of JEXL expressions
 protected List&lt;String&gt; jexlExprRules;

 public JexlObjectValidator() {
 }
 public JexlObjectValidator(List&lt;String&gt; jexlExprRules) {
 super();
 this.jexlExprRules = jexlExprRules;
 }
 /**
 *
 * JEXL expression based general object validation.
 * See latest JEXL details at http://commons.apache.org/jexl/
 *
 * @param o
 * @return Return null if no error found.
 *         Otherwise first error of the JEXL expression validation rules.
 */
 public abstract ValidationError validate(Object o) ;
}</pre>
<p>In this class the &#8220;<em>List&lt;String&gt; jexlExprRules</em>&#8221; attribute holds a list of String-based validation rules. The <em>ValidationError</em> <em>validate(Object o) </em> method validates<br />
a given object based the specified<em> jexlExprRules</em>.<br />
The <em>ValidationError </em>class simply holds the detailed message if the object is not valid. It may look like this:</p>
<pre>public class ValidationError {
 private String errCode;
 private String errMsgs;

 public ValidationError(String errCode, String errMsgs) {
 super();
 this.errCode = errCode;
 this.errMsgs = errMsgs;
 }

 public String getErrCode() {
 return errCode;
 }
 public String getErrMsgs() {
 return errMsgs;
 }
}</pre>
<p>Now we are ready to implement the validator for a person object.</p>
<pre>import java.util.List;
import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;
public class PersonObjectValidator extends JexlObjectValidator {
 public PersonObjectValidator(List&lt;String&gt; jexlExprRules) {
 super(jexlExprRules);
 }

 public ValidationError validate(Object o) {
 Person person = (Person)o;

 JexlEngine jexl = new JexlEngine();
 JexlContext context = new MapContext();
 context.set("p", person);
<strong> for (String expr : jexlExprRules ) {
 Expression e = jexl.createExpression( expr );
 Boolean isValid = (Boolean)e.evaluate(context);
 if (!isValid) {
 // Whoops, invalid object
 return new ValidationError("personErr", e.getExpression());
 }
 }       </strong> 
 // OMG, an valid object!
 return null;    
}

}</pre>
<p>In the <em>validate(Object o)</em> method, we first cast it to Person type and then initialize a JexlContext called &#8220;context&#8221;. Then we place the &#8220;person&#8221; object into the context with a name &#8220;p&#8221;.<br />
We then iterate through rule list &#8220;jexlExprRules&#8221; to evaluate each expression rule against the given object &#8220;person&#8221; stored in the context. If any rule fails, we stop and return the ValidationError object with failure message(highlighted in above bold text). Otherwise return null for a valid object.</p>
<p>From the above sample code, you can see Jexl in the works  in these three simple validation steps:<br />
(1) Use the JexlEngine object to create a Jexl Expression based a Jexl-syntax expression String<br />
(2) Use the JexlContext object to hold an object to be validated(It holds more than one object in real-word applications)<br />
(3) Use the jexl Expression created in step (1) to evaluate against the object stored in the context</p>
<p>You might wonder why the above expression&#8217;s <em>evaluate(context)</em> method call result can be cast to a Boolean object. The reason is the expression we defined earlier such as <em>p.ssn != null</em> always returns a boolean value. JEXL expression can return any object based on the expression defined by your application &#8211; it could be an Integer or a specific domain object etc.<br />
Please refer to http://commons.apache.org/jexl/index.html for more details.</p>
<p><strong>3. The Validation Process</strong><br />
The following unit test mocks the scenarios we defined in section 1(A Simple Validation Problem) &#8211; in which the same <em>person</em> object  is valid in Bonus-prize-draw application component while invalid in Guest-book sign-up component.</p>
<pre>package sandbox.util;

import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
public class PersonObjectValidatorTest extends TestCase {
 private List&lt;String&gt; rule1;
 private List&lt;String&gt; rule2;
 private Person p;

 protected void setUp() {
 // Rule 1
 rule1 = new ArrayList&lt;String&gt;();
 rule1.add("p.ssn != null");
 rule1.add("p.birthYear &lt; 1990");    
 // Rule 2
 rule2 = new ArrayList&lt;String&gt;();
 rule2.add("p.firstName != null");
 rule2.add("p.lastName != null");    
 // Person object to be validated
 p = new Person("123-45-1234","John", null, 1980);

 }
 // The person object is valid in one run-time application case
 public void testValidPersonObjectInBonusPrizeDrawComponent() {    
 PersonObjectValidator validator = new PersonObjectValidator(rule1);
 ValidationError err = validator.validate(p);
 assertNull(err);
 }
 // The same person object is invalid in another run-time application case
 public void testInValidPersonObjectInGuestbookSignupComponent() {
 PersonObjectValidator validator = new PersonObjectValidator(rule2);
 ValidationError err = validator.validate(p);
 assertNotNull(err); // The lastName is null to cause the person object being invalid
 }
}</pre>
<p>Notice JEXL uses Java Reflection API extensively and above &#8220;p.firstName != null&#8221; rule is actually invoked as &#8220;p.getFirstName() != null&#8221;. In real-world application, your expression can contain any method call on the object.</p>
<p><strong>4. Conclusion</strong></p>
<p>The example here is extremely simple to just demo the dynamic object validation. In above unit test code, you can see the validation rule is specified as List&lt;String&gt; and you can load them from a configuration file/DB table in your application. This way you can re-configure rules dynamically per your application needs.</p>
<p>The above sample code uses<strong> apache-commons-jexl-2.0</strong> and can be downloaded at <a href="http://commons.apache.org/jexl/">http://commons.apache.org/jexl/index.html</a>. Or if using Maven project build, the dependency entry is</p>
<pre>&lt;dependency&gt;
 &lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
 &lt;artifactId&gt;commons-jexl&lt;/artifactId&gt;
 &lt;version&gt;2.0&lt;/version&gt;
&lt;/dependency&gt;</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/49/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=49&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2010/03/14/using-apache-commons-jexl-for-java-object-validation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>A Simple String Cipher in Java 6</title>
		<link>http://herbertwu.wordpress.com/2010/03/06/a-simple-string-cipher-in-java-6/</link>
		<comments>http://herbertwu.wordpress.com/2010/03/06/a-simple-string-cipher-in-java-6/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 21:01:17 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Java security]]></category>
		<category><![CDATA[java encryption]]></category>
		<category><![CDATA[java password encryption]]></category>
		<category><![CDATA[java text cipher]]></category>
		<category><![CDATA[java text encryption]]></category>
		<category><![CDATA[redpoint]]></category>
		<category><![CDATA[simple java Cryptography]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=46</guid>
		<description><![CDATA[For regular simple application, Java Cryptography seems always complicated. But for Java 6, AES is included. Here is a simple cipher to encrypt a text string into another string which can be used safely in web environment with proper url encoding included. package sandbox.util; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * A [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=46&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For regular simple application, Java Cryptography seems always complicated. But for Java 6, AES is included. Here is a simple cipher to encrypt a text string into another string which can be used safely in web environment with proper url encoding included.</p>
<pre style="padding-left:30px;"><em>package sandbox.util;
</em><em>import javax.crypto.Cipher;
</em><em>import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;</em>
<em>/**
 * A simple text cipher to encrypt/decrypt a string.
 */
public class SimpleStringCipher {
 private static byte[] linebreak = {}; // Remove Base64 encoder default linebreak
 private static String secret = <strong>"tvnw63ufg9gh5392"</strong>; // secret key length must be 16
 private static SecretKey key;
 private static Cipher cipher;
 private static Base64 coder;

 static {
 try {
     key = new SecretKeySpec(secret.getBytes(), "AES");
     cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
     coder = new Base64(32,linebreak,true);
 } catch (Throwable t) {
     t.printStackTrace();
 }
 }

 public static synchronized String encrypt(String plainText) throws Exception {
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        return  new String(coder.encode(cipherText));
 }

 public static synchronized String decrypt(String codedText) throws Exception {
        byte[] encypted = coder.decode(codedText.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(encypted);  
        return new String(decrypted);
 }

}</em>
</pre>
<p>A few notes about this code:</p>
<p>1. Encryption for simple and fast text encryption with Java 6 built-in AES implementation and Apache commons-codec-1.4 for text encoding.<br />
2. The &#8220;secret&#8221; key is hard-coded in the source per your application compilation. You may expose it to configuration when needed.<br />
3.&#8221;<em> new Base64(32,linebreak,true)</em>&#8221; construct  is used to provide proper url encoding and remove default linebreak. The encrypted text is safe to be used in browser window.</p>
<p>Here is the unit test to demo the usage:</p>
<pre><em>public class SimpleStringCipherTest extends TestCase {

   public void testBasicEncrption() throws Exception {
                String plainText = "2010 starts new decade.";
                String encrypted = SimpleStringCipher.encrypt(plainText);
                assertTrue(!plainText.equals(encrypted));

                String decrypted = SimpleStringCipher.decrypt(encrypted);
                assertEquals(plainText, decrypted);
   }

}</em></pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/46/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=46&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2010/03/06/a-simple-string-cipher-in-java-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Java Tip: Deploy WAR to multiple Tomcat-6.x Nodes/Environments with Cargo Maven-plugin</title>
		<link>http://herbertwu.wordpress.com/2009/10/25/java-tip-deploy-war-to-multiple-tomcat-6-x-nodesenvironments-with-cargo-maven-plugin/</link>
		<comments>http://herbertwu.wordpress.com/2009/10/25/java-tip-deploy-war-to-multiple-tomcat-6-x-nodesenvironments-with-cargo-maven-plugin/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 18:21:10 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[JEE web application deployment]]></category>
		<category><![CDATA[Maven multiple tomcat instances deployment]]></category>
		<category><![CDATA[redpoint]]></category>
		<category><![CDATA[tomcat maven deployment]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=31</guid>
		<description><![CDATA[In JEE/Tomcat-6.x web development, if you use Maven you can easily deploy your build to local host via &#8220;mvn tomcat:redeploy&#8221; with these two simple changes: (1). In Tomcat context.xml,  disable jar locking by adding extra attributes(in bold text) to &#60;Context&#62; tag: &#60;Context path=&#8221;/&#60;your-webapp-path&#62;&#8221; reloadable=&#8221;true&#8221; antiJARLocking=&#8221;true&#8221; antiResourceLocking=&#8221;true&#8221;&#62; (2).   Set tomcat manager user/password as default &#8220;admin&#8221; and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=31&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In JEE/Tomcat-6.x web development, if you use Maven you can easily deploy your build to local host via &#8220;mvn tomcat:redeploy&#8221; with these two simple changes:<br />
(1). In Tomcat context.xml,  disable jar locking by adding extra attributes(in bold text) to &lt;Context&gt; tag:<br />
&lt;Context <strong>path=&#8221;/&lt;your-webapp-path&gt;&#8221;</strong><br />
<strong> reloadable=&#8221;true&#8221;<br />
antiJARLocking=&#8221;true&#8221;</strong><strong><br />
antiResourceLocking=&#8221;true&#8221;</strong>&gt;<br />
(2).   Set tomcat manager user/password as default &#8220;admin&#8221; and empty string &#8220;&#8221;</p>
<p>But Cargo maven-plugin(<a title="http://cargo.codehaus.org/Maven2+plugin" href="http://cargo.codehaus.org/Maven2+plugin">http://cargo.codehaus.org/Maven2+plugin</a>) is more powerful to deploy your build to QA/Production environments easily.</p>
<p><strong>1. Set up your default deployment target as dev environment</strong></p>
<p>In your POM.xml, add these entries with bold text indicating your environment related values :</p>
<p><em>&lt;!&#8211; default cargo deployment target &#8211;&gt;<br />
&lt;cargo.manager.url&gt;<strong>http://&lt;your_dev_server&gt;:&lt;dev_host_port&gt;/manager</strong>&lt;/cargo.manager.url&gt;<br />
&lt;cargo.username<strong>&gt;dev_username</strong>&lt;/cargo.username&gt;<br />
&lt;cargo.password&gt;<strong>dev_password</strong>&lt;/cargo.password&gt;</em></p>
<p><em>&lt;!&#8211; Cargo-Plugin: Hot deploy to remote tomcat6x running instance &#8211;&gt;<br />
&lt;plugin&gt;<br />
&lt;groupId&gt;org.codehaus.cargo&lt;/groupId&gt;<br />
&lt;artifactId&gt;cargo-maven2-plugin&lt;/artifactId&gt;<br />
&lt;configuration&gt;<br />
&lt;container&gt;<br />
&lt;containerId&gt;tomcat6x&lt;/containerId&gt;<br />
&lt;type&gt;remote&lt;/type&gt;<br />
&lt;/container&gt;<br />
&lt;configuration&gt;<br />
&lt;type&gt;runtime&lt;/type&gt;<br />
&lt;properties&gt;<br />
&lt;cargo.tomcat.manager.url&gt;${cargo.manager.url}&lt;/cargo.tomcat.manager.url&gt;<br />
&lt;cargo.remote.username&gt;${cargo.username}&lt;/cargo.remote.username&gt;<br />
&lt;cargo.remote.password&gt;${cargo.password}&lt;/cargo.remote.password&gt;<br />
&lt;/properties&gt;<br />
&lt;/configuration&gt;<br />
&lt;deployer&gt;<br />
&lt;type&gt;remote&lt;/type&gt;<br />
&lt;deployables&gt;<br />
&lt;deployable&gt;<br />
&lt;groupId&gt;<strong>***your group id***</strong>&lt;/your&gt;&lt;/groupId&gt;<br />
&lt;artifactId&gt;<strong>***your_build_id***</strong>&lt;/artifactId&gt;<br />
&lt;type&gt;war&lt;/type&gt;<br />
&lt;properties&gt;<br />
&lt;context&gt;<strong>***your_context****</strong>&lt;/context&gt;<br />
&lt;/properties&gt;<br />
&lt;/deployable&gt;<br />
&lt;/deployables&gt;<br />
&lt;/deployer&gt;<br />
&lt;/configuration&gt;</em></p>
<p><em>&lt;/plugin&gt;</em></p>
<p>Run &#8220;mvn clean build&#8221; and &#8220;mvn cargo:redeploy&#8221; to verify that your build can be deployed to dev box without problem.</p>
<p><strong>2. Assume we have one QA and one production tomcat-6.x instances. Simple add these two profile entries to your POM.xml:</strong></p>
<p><em>&lt;!&#8211;  QA env deployment target &#8211;&gt;<br />
&lt;profile&gt;<br />
&lt;id&gt;qa1&lt;/id&gt;</em></p>
<p><em>&lt;properties&gt;<br />
&lt;cargo.manager.url&gt;http://&lt;qa1_host&gt;:&lt;qa1_port&gt;/manager&lt;/cargo.manager.url&gt;<br />
&lt;cargo.username&gt;qa1_username&lt;/cargo.username&gt;<br />
&lt;cargo.password&gt;qa1_password&lt;/cargo.password&gt;<br />
&lt;/properties&gt;<br />
&lt;/profile&gt;<br />
&lt;!&#8211;  Production  env deployment target &#8211;&gt;<br />
&lt;profile&gt;<br />
&lt;id&gt;prod1&lt;/id&gt;</em></p>
<p><em>&lt;properties&gt;<br />
&lt;cargo.manager.url&gt;http://&lt;prod1_host&gt;:&lt;prod1_port&gt;/manager&lt;/cargo.manager.url&gt;<br />
&lt;cargo.username&gt;&lt;prod1_user&gt;&lt;/cargo.username&gt;<br />
&lt;cargo.password&gt;&lt;prod1_password&gt;&lt;/cargo.password&gt;<br />
&lt;/properties&gt;<br />
&lt;/profile&gt;</em></p>
<p>Now you can just run &#8220;mvn build&#8221;, then &#8220;mvn cargo:redeploy -Pqa1&#8243; and &#8220;mvn cargo:redeploy -Pprod1&#8243; to deploy your war file to tomcat-6x instances.  Of course in real application, you have multiple instances in each environment and you can simply add &#8220;qa2&#8243;, &#8220;prod2&#8243; etc entries in your POM.xml(if necessary, place production entries in  maven setting.xml to protect passwords)</p>
<p>Note, in tomcat hot deployment, you may run into JDK&#8217;s PermGen out of memory error after hot deployment.  So you should restart tomcat instances after deployment run. More details can be found at <a title="http://wiki.apache.org/tomcat/OutOfMemory" href="http://wiki.apache.org/tomcat/OutOfMemory">http://wiki.apache.org/tomcat/OutOfMemory</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=31&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/10/25/java-tip-deploy-war-to-multiple-tomcat-6-x-nodesenvironments-with-cargo-maven-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Java Tip: Using Open Source Selenium-Grid-1.x for Quick Performance Testing</title>
		<link>http://herbertwu.wordpress.com/2009/10/25/java-tip-using-open-source-selenium-grid-1-x-for-simple-performance-testing/</link>
		<comments>http://herbertwu.wordpress.com/2009/10/25/java-tip-using-open-source-selenium-grid-1-x-for-simple-performance-testing/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 17:20:23 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[JEE Performance]]></category>
		<category><![CDATA[Open source performance testing tool]]></category>
		<category><![CDATA[Testing tools list]]></category>
		<category><![CDATA[redpoint]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=22</guid>
		<description><![CDATA[When conducting performance testing of multi-step interactive web applications such as registration, shopping etc, not many open source solutions are available. Grinder(http://grinder.sourceforge.net/) is the primary choice, however it is not simple to use.  Selenium is well-known for its ease to use record-and-replay feature, but it is primarily for unit/functional testing. Thoughtworks recently put out a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=22&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When conducting performance testing of <strong>multi-step interactive</strong> web applications such as registration, shopping etc, not many open source solutions are available. Grinder(<a title="http://grinder.sourceforge.net/" href="http://grinder.sourceforge.net/">http://grinder.sourceforge.net/</a>) is the primary choice, however it is not simple to use.  Selenium is well-known for its ease to use record-and-replay feature, but it is primarily for unit/functional testing.</p>
<p>Thoughtworks recently put out a new tool called Selennium-Grid(<a title="http://selenium-grid.seleniumhq.org/" href="http://selenium-grid.seleniumhq.org/">http://selenium-grid.seleniumhq.org/</a>) to speed up integration tests. However  it can also be used for a quick developer-driven performance testing.  Here are the brief steps to do it:</p>
<p><strong>1. Development Setup</strong><br />
- Install Java6, latest Eclipse-3.x and latest Selenium IDE/RC/Grid<br />
- Download latest TestNG-5.X(for parallel unit tests run)<br />
- Install TestNG Eclipse-3.x plug-in(Start/Stop tests from your IDE)</p>
<p><strong>2. Create  Java Performance Test Code</strong><br />
The performance testing will be carried out in the form of running multiple unit tests&#8217; test methods in concurrent mode.</p>
<p>2.1 Use Selenium IDE to record your typical multi-step application user case for a given user and save it as Java code, and then refine this Java code as a base unit test class(make sure it is thread-safe). The code skeleton may look like this:</p>
<p><em>public abstract class SeleniumPerfTestBaseCase<br />
{</em></p>
<p><em>public static final String TIMEOUT = &#8220;120000&#8243;; // testing run timeout<br />
// @para User class is a value object to contain test parameters for a single User, such as ID, username, password etc<br />
protected void testMultiStepApplicationByOneUser(User user ) throws Exception {</em></p>
<p><em>// Your recorded test case code goes here</em></p>
<p><em>//Some Thread.sleep() calls may be needed to adjust user think time</em></p>
<p><em>}</em></p>
<p><em>}</em></p>
<p>2.2 Implement a test case with multiple users. Each user corresponding to a method call. The code skeloten may look like this:</p>
<p><em>import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.closeSeleniumSession;<br />
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.startSeleniumSession;<br />
import org.testng.annotations.Test;</em></p>
<p><em>public class ConcurrentUserLoadTest extends SeleniumPerfTestBaseCase  {<br />
// Testing env parameters, such as<br />
private String seleniumGridHost = &#8220;my_selenium_grid_host&#8221;;<br />
private int seleniumGridHostPort = xxxx;<br />
private String browser = &#8220;*firefox&#8221;;<br />
private String testingTargetWebSite = &#8220;http://blah-blah-blah/&#8221;;</em></p>
<p><em>// User 1 test<br />
User user1 = new User( &#8220;username1&#8243;, &#8220;passwd1&#8243;, &#8220;myemail1@gmail.com&#8221;, &#8220;checkout&#8221;);<br />
@Test(groups = {&#8220;demo&#8221;, &#8220;firefox&#8221;, &#8220;default&#8221;}, description = &#8220;test my shopping&#8221;)<br />
public void testUser1() throws Throwable {<br />
try {<br />
startSeleniumSession(seleniumGridHost, seleniumGridHostPort, browser, testingTargetWebSite);<br />
testMultiStepApplicationByOneUser(user1);<br />
} finally {<br />
closeSeleniumSession();<br />
}<br />
}</em></p>
<p><em>&#8230;&#8230;.. Repeat above code for X number of users, say we test 50 users here</em></p>
<p><em>// User 50 test<br />
User user50 = new User( &#8220;username50&#8243;, &#8220;passwd50&#8243;, &#8220;myemail50@gmail.com&#8221;, &#8220;checkout&#8221;);<br />
@Test(groups = {&#8220;demo&#8221;, &#8220;firefox&#8221;, &#8220;default&#8221;}, description = &#8220;test my shopping&#8221;)<br />
public void testUser50() throws Throwable {<br />
try {<br />
startSeleniumSession(seleniumGridHost, seleniumGridHostPort, browser, testingTargetWebSite);<br />
testMultiStepApplicationByOneUser(user50);<br />
} finally {<br />
closeSeleniumSession();<br />
}<br />
}</em></p>
<p><em>}</em></p>
<p>2.3 Finally in your testng cfg file, specify your test class,  parallel for methods and thread count for your performance test</p>
<p>&lt;!DOCTYPE suite SYSTEM &#8220;http://testng.org/testng-1.0.dtd&#8221;&gt;<br />
&lt;suite name=&#8221;my-webapp&#8221; parallel=&#8221;<strong>methods</strong>&#8221; thread-count=&#8221;<strong>25</strong>&#8220;&gt;<br />
&lt;test verbose=&#8221;2&#8243; name=&#8221;PeakUserLoadTest&#8221; annotations=&#8221;JDK&#8221;&gt;<br />
&lt;classes&gt;<br />
&lt;class name=&#8221;<strong>ConcurrentUserLoadTest</strong>&#8220;/&gt;<br />
&lt;/classes&gt;<br />
&lt;/test&gt;<br />
&lt;/suite&gt;<br />
Notice we set thread count as &#8220;25&#8243; here which means above 50 test methods will be finished in 2 iterations where each thread runs two test methods sequentially. You can adjust these parameters however you want to suit your test needs</p>
<p><strong>3. Testing environment  setup</strong><br />
3.1 Base on your performance testing goal, make available a number of PCs. Install Selenium-Grid on one of them and rest with Selenium RC along with Firefox. The PCs with Selenium RC are the ones to actually generate the testing traffic by firing up Firefox browsers to complete a user test case.<br />
3.2 Start up SeleniumGrid and SeleniumRC on all PCs and follow Selenium web site instructions on how to do it. Once it is done, check SeleniumGrid console page and verify that all the RC clients are available for testing.</p>
<p><strong>4. Running the Test</strong><br />
Last step is easy, just fire up your test case in Eclipse IDE  and watch firefox browsers pop-up all over the screens. Record your client and server site test results.</p>
<p>You may need to several test runs to iron out some wrinkles.<br />
-  You may need to adjust user think time in your base test class when running in parallel<br />
- Sometimes one PC may be less powerful and can not handle the traffic, you need to add more PCs or reduce thread count<br />
- Sometimes SeleniumGrid and its RC clients may be out of sync and you need to restart them all over again. This is a bit annoying and future Selenium releases sure will improve its reliability.<br />
- SeleniumGrid does not have Maven dep entry, and you need to install manually if Maven is used.</p>
<p><strong>5. Final comments</strong><br />
- Performance testing definition may be very broad. The above quick test is for a peak traffic run. You also can easily modify the code to add some loops to mimic long running user traffic and  see if you have slow memory leak etc<br />
- The Selenium Testing tools triggers real browser run during the testing and system resource overhead is high and hence this approach is not suitable for large-scale performance testing.  In our experience each PC roughly can handle 10 parallel users at a time, but again it is totally depends on how powerful your PC is.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=22&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/10/25/java-tip-using-open-source-selenium-grid-1-x-for-simple-performance-testing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick Scan of Free(mostly) Testing Tools</title>
		<link>http://herbertwu.wordpress.com/2009/05/19/quick-scan-of-freemostly-testing-tools/</link>
		<comments>http://herbertwu.wordpress.com/2009/05/19/quick-scan-of-freemostly-testing-tools/#comments</comments>
		<pubDate>Tue, 19 May 2009 03:36:30 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Agile testing]]></category>
		<category><![CDATA[Testing tools list]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=14</guid>
		<description><![CDATA[Today I spent a few hours Googling over some free testing tools and here are the list I came up &#8211; which are relatively active ones based on the release date.  I am no expert in testing tools and posted here just as sort of bookmarks for possible future reference. Database Tier Testing Tools 1. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=14&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today I spent a few hours Googling over some free testing tools and here are the list I came up &#8211; which are relatively active ones based on the release date.  I am no expert in testing tools and posted here just as sort of bookmarks for possible future reference.</p>
<p><strong>Database Tier Testing Tools</strong></p>
<p>1. <strong>AnyDbTest</strong> from http://www.anydbtest.com/: DBA/DB developers tool in which test case is written in XML. $1245.00 for 10 lic#<br />
2. <strong>DbFit</strong> from http://gojko.net/fitnesse/dbfit/: FIT/FitNesse tests for DBA/DB developer. Free<br />
3. <strong>DBUnit</strong> from http://www.dbunit.org/: Export real data to XML file as controlled dataset for unit test runs. Free<br />
4. <a href="http://code.google.com/p/ndbunit/"><strong>ndbunit</strong></a> from http://code.google.com/p/ndbunit/: .Net&#8217;s DBUnit<br />
5. <strong>Quest Code Tester</strong> from http://unittest.inside.quest.com/index.jspa: PL/SQL testing tool. Commercial Ware/Fee?<br />
6. <strong>SQLUnit</strong> from http://sqlunit.sourceforge.net/: A junit extension to test stored procedure easily via XML test case scripting.</p>
<p>Another one is <strong>tsqlunit</strong> from http://tsqlunit.sourceforge.net/index.html. Free<br />
7. If you are using Spring, you may use <strong>spring-mock.jar</strong> to test against either DBUnit or a real database. The nice feature of it is that it rolls back transaction automatically after test run and hence will not change the state of a real database. Free<br />
8. If you are using <strong>Google AppEngine/Java</strong> edition, it provides a local test persistence impl to present a clean DB in junit setUp() for your subsequent unit test runs. Free<br />
Google AppEngine/Java is using google&#8217;s own OO database(Big Table) and annotation of an entity class is the only thing needed to persist the data &#8211; no more ORM mapping to deal with which is quite nice and simple. See <em>http://code.google.com/appengine/docs/java/howto/unittesting.html</em></p>
<p><strong>General Unit Testing Tools</strong><br />
9. <strong> junit</strong> from http://junit.org/. Most popular. Free<br />
10. <strong>nunit</strong> from http://nunit.org. Free<br />
11. <strong>jExample</strong> from http://scg.unibe.ch/research/jexample/. It uses producer/consumer model for mocking and seems unique. Free<br />
12. <strong>JDave</strong> from http://www.jdave.org/ for behavior driven development among few others. Free<br />
13. <strong>GroboUtils</strong> from http://groboutils.sourceforge.net/. It supports both code-coverage and multi-thread tests which is not very common among xUnit like tools. Free<br />
14. <strong>testNG</strong> from  tehttp://testng.org/doc/ which provides more advanced features. Free<br />
15. <strong>csUnit</strong> from http://www.csunit.org/ it works with most .NET/Vista/XPsp3 platforms and compatible with NUnit/VS2008(i.e.MSTest). It also supports searching test cases.<br />
16. <strong>Mb.Unit</strong> from http://www.mbunit.com/ More feature rich testing tool which is running on the more general open source .NET platform http://www.gallio.org/. Free<br />
17  <strong>testDriven.NET</strong> from http://www.testdriven.net/<br />
18  <strong>specter</strong> from http://specter.sourceforge.net/ which integrates with NUnit. It is using Boo static-typed language(http://boo.codehaus.org/) for test case scripting. Free<br />
19. <strong>Pex</strong> from http://research.microsoft.com/en-us/projects/Pex/ It allows whitebox testing automation via Parameterized Unit Testing.</p>
<p><strong>Container Testing Tools</strong><br />
20. <strong>Cactus</strong> from http://jakarta.apache.org/cactus/. In-container testing and integrated with Cargo(http://cargo.codehaus.org/) andHttpUnit, so config files tests are covered. Free<br />
21. <strong>Mockrunner</strong> from http://mockrunner.sourceforge.net/ does not run real container and hence is simple, but cfg files may not be covered as API is used in the test cases. Free<br />
22. <strong>UncleBob</strong> shows primitive ways to test jsp http://blog.objectmentor.com/articles/category/testing-guis via apache Jasper &amp; HtmlUnit. This can avoid some fragile tests that break when the <em>format</em> of a page changes(such as Selenium, Mercury <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p>
<p><strong>WebService Testing Tools</strong><br />
23. <strong>soapUI</strong> from http://www.soapui.org/. Most popular web service testing tool and supports load testing as well. Free<br />
24. <strong>TestMaker</strong> from http://www.pushtotest.com/ and written in Jython. So it is extremely powerful to write test cases not just for web service, but for almost everything &#8211; HTTP, POP3, JDBC etc<br />
but it also triggers higher learning curve as well. Free<br />
25. <strong>WebInject</strong> from http://www.webinject.org/ It is a simple and light testing tool. Free</p>
<p><strong>RIA/Flex Testing Tools</strong><br />
26. <strong>FlexUnit</strong> from http://opensource.adobe.com/wiki/display/flexunit/FlexUnit(used to be http://code.google.com/p/as3flexunitlib/). Most popular one for Flex2&amp;3. Ant build and HTML output format. Free<br />
27. <strong>Reflex Unit</strong> from http://code.google.com/p/reflex-unit/. Using Reflection to specify target test methods and also allow async tests running in parallel. Multiple output formats. Free<br />
28. <strong>fluint</strong> from http://code.google.com/p/fluint/ Support Async UI action testing and cairngorm command/controller testing. ant build and XML output format. Free.</p>
<p><strong>Integration/Acceptance Testing Tools</strong><br />
29.<strong> fitnesse</strong> http://fitnesse.org/ general acceptance tool. Free<br />
30. <strong>concordion</strong> from http://www.concordion.org/ documentation driven testing. Free<br />
31. <strong>texttest</strong> from http://texttest.carmen.se/ which plain text is the focus of high level test cases for non-tech people. Free<br />
32. <strong>jbehave</strong> from http://jbehave.org/. Similar to item 12. for BDD testing.<br />
33. <strong>Selenium</strong> from http://seleniumhq.org/ for web tier testing. Free.<br />
ThoughtWorks also provides commercial ware <strong>Twist</strong> &#8211; http://studios.thoughtworks.com/twist-agile-test-automation</p>
<p>34. <strong>FlexMonkey</strong> from http://code.google.com/p/flexmonkey/ for Flex2&amp;3 integration tests.<br />
35. <strong>FunFx </strong>from http://funfx.rubyforge.org/ It is Ruby based functional testing tool for FLEX.</p>
<p><strong>Code Coverage Tools</strong><br />
36. <strong>NCover</strong> from http://www.ncover.com/ code coverage tool for C#, .NET. Commercial Ware.<br />
37. <strong>PartCover</strong> from http://sourceforge.net/projects/partcover/ for .Net, but it is free.<br />
38. <strong>cobertura</strong> from http://cobertura.sourceforge.net/ for Java unit test coverage. Free.<br />
39. <strong>codecover</strong> from http://codecover.org/ for Java unit test coverage. It supports more detailed coverage analysis such as correlation analysis. Free<br />
40. <strong>EMMA</strong> from http://emma.sourceforge.net/ for Java code coverage with test case filtering support<br />
41. <strong>Clover</strong> from http://www.atlassian.com/software/clover/ for Java code coverage. Commercial ware, but free for open source project only.</p>
<p><strong>Mocking Tools</strong><br />
42. <strong>typemock</strong> from http://www.typemock.com It supports most framework such as WCF, Sharepoint, LINQ, Silerlight. Commercial ware.<br />
43. <strong>jmockit</strong> from https://jmockit.dev.java.net/ It is for writing unit or integration tests via non-reflection based approach.Free<br />
44. <strong>Easymock</strong> from http://www.easymock.org/ Java proxy-based mock object. Free.<br />
45. <strong>jmock</strong> from http://www.jmock.org/ More popular java mock framework. Free<br />
46. <strong>Rhino Mock</strong> from http://ayende.com/projects/rhino-mocks.aspx for .Net unit test mocking. Free</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=14&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/05/19/quick-scan-of-freemostly-testing-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Adobe AIR Tip: Avoid File Drag-and-Drop Side Effect with DataGrid</title>
		<link>http://herbertwu.wordpress.com/2009/05/08/adobe-air-tip-avoid-file-drag-and-drop-side-effect-with-datagrid/</link>
		<comments>http://herbertwu.wordpress.com/2009/05/08/adobe-air-tip-avoid-file-drag-and-drop-side-effect-with-datagrid/#comments</comments>
		<pubDate>Fri, 08 May 2009 21:30:52 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Adobe AIR  FLEX development tip]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=12</guid>
		<description><![CDATA[In AIR application, if you enable drag-and-drop capability say for a file, be careful with dropEnabled=&#8221;true&#8221; attribute in a DataGrid control inside your application. If you have both turned on, the top-level drag-and-drop may not work smoothly.  The sample code here shows the issue: &#60;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&#62; &#60;mx:WindowedApplication xmlns:mx=&#8221;http://www.adobe.com/2006/mxml&#8221; creationComplete=&#8221;init()&#8221; layout=&#8221;vertical&#8221;&#62; &#60;mx:Script&#62; &#60;![CDATA[ import mx.managers.DragManager; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=12&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In AIR application, if you enable drag-and-drop capability say for a file, be careful with dropEnabled=&#8221;true&#8221; attribute in a DataGrid control inside your application. If you have both turned on, the top-level drag-and-drop may not work smoothly.  The sample code here shows the issue:</p>
<p><em>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;</em></p>
<p><em>&lt;mx:WindowedApplication xmlns:mx=&#8221;http://www.adobe.com/2006/mxml&#8221;<br />
creationComplete=&#8221;init()&#8221; layout=&#8221;vertical&#8221;&gt;</p>
<p>&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import mx.managers.DragManager;</p>
<p>import mx.collections.ArrayCollection;<br />
[Bindable]<br />
private var myData:ArrayCollection;</p>
<p>private function init():void<br />
{<br />
addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);<br />
addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onDropHandler);<br />
}<br />
private function dragEnter(event:NativeDragEvent):void<br />
{<br />
DragManager.acceptDragDrop(this);<br />
}<br />
private function onDropHandler(event:NativeDragEvent):void<br />
{<br />
trace(&#8220;Handle dropped file&#8230;&#8221;);<br />
}</p>
<p>]]&gt;<br />
&lt;/mx:Script&gt;</p>
<p>&lt;mx:Label text=&#8221;Control 1&#8243;/&gt;</p>
<p>&lt;mx:DataGrid id=&#8221;myGrid&#8221; <strong>dropEnabled=&#8221;true&#8221;</strong>/&gt;</p>
<p>&lt;mx:Label text=&#8221;Control 2&#8243;/&gt;</p>
<p>&lt;/mx:WindowedApplication&gt;</em></p>
<p>In above code, the init() enables application level drag-and-drop,  and at same time, the &#8220;myGrid&#8221; DataGrid has attribute<em><strong> dropEnabled=&#8221;true&#8221; </strong></em>.  When you drag-and-drop a file to the application, it may not work 100% of the time, particularly when your application has many controls.</p>
<p>In summary, you should avoid above case in which two-level drag-and-drop are enabled.</p>
<p><em><strong><br />
</strong></em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/12/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=12&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/05/08/adobe-air-tip-avoid-file-drag-and-drop-side-effect-with-datagrid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Handling Large Collection Data – Hibernate Pagination, ScrollableResults and Native SQL</title>
		<link>http://herbertwu.wordpress.com/2009/04/24/handling-large-collection-data-%e2%80%93-hibernate-pagination-scrollableresults-and-native-sql/</link>
		<comments>http://herbertwu.wordpress.com/2009/04/24/handling-large-collection-data-%e2%80%93-hibernate-pagination-scrollableresults-and-native-sql/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 15:58:33 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Hibernate Performance]]></category>
		<category><![CDATA[JEE Performance]]></category>
		<category><![CDATA[redpoint]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=10</guid>
		<description><![CDATA[In Hibernate it is common to fetch a collection of data like this: List l = session.createQuery(&#8220;select * from &#8230; &#8220;).list() However this solution may not scale well if the query returns large amount of data(such as in a batch job etc): -  Consuming a lot of memory -  Possible slow speed as large data [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=10&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In Hibernate it is common to fetch a collection of data like this:</p>
<p class="MsoNormal" style="font-family:Arial Narrow;">List l = session.createQuery(&#8220;select * from &#8230; &#8220;).list()</p>
<p class="MsoNormal">However this solution may not scale well if the query returns large amount of data(such as in a batch job etc):</p>
<p class="MsoNormal">-  Consuming a lot of memory</p>
<p class="MsoNormal">-  Possible slow speed as large data being moved and processed between middleware and database</p>
<p class="MsoNormal">
<p class="MsoNormal">Here we discuss a number of options to improve the performance of handling large data set.</p>
<p><strong>(1). Hibernate Pagination</strong></p>
<p>The idea here is to divide the large result set into a number of pages and fetch only one page at a time.  You need to specify the start position and the page size in the query parameter. If not in original query yet, you also need to add an &#8220;order by&#8221; clause to ensure the result data set is sorted and kept in a consistent view of data between pages.</p>
<p>The code itself is very simple:</p>
<pre><span style="font-family:Arial Narrow;">Query q = session.createQuery(select * from ... <em><span style="color:#000000;">order by ...</span></em>");</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">q.setFirstResult(startPosition);</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">q.setMaxResults(pageSize);</span>
<span style="font-family:Arial Narrow;">List l = q.list();</span></pre>
<p>This solution resolves the memory issue nicely and works with most major databases via different dialects offered by Hiberante. For instance in a search-like application, this works well as an user may click through different search result pages.</p>
<p>However if an application does need to process all the result set data this approach may significantly increase query execution time as previously a single query becomes a large number of queries. For example, if the original query returns 100k rows and the page size is 100, the total queries to be run in the pagination would be 1000. The &#8220;order by&#8221; clause may also impact the query time as well. You also need to figure out total number of pages in which another query &#8220;<em>select count(*) from</em> &#8230; &#8221; is added.</p>
<p><strong>(2) Hibernate ScrollableResults </strong></p>
<p>This approach loops through the entire results set in a stream fashion, thus will not incur significant slow-down in query execution time.</p>
<pre><span style="font-family:Arial Narrow;">      Query q = session.createQuery("select * from ...");</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">      ScrollableResults results = q.scroll();</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">       while (results.next() )</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">       {</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">         Long id = results.getLong(0);</span><span style="font-family:Arial Narrow;">
          ...<br style="font-family:Arial Narrow;" /></span><span style="font-family:Arial Narrow;">        }</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">      results.close();</span><br style="font-family:Arial Narrow;" /></pre>
<p>Moreover if session cache is enabled, you need to add explicit code to clear the session cache, such as a code snippet here to clear cache every 100 rows:</p>
<pre><span style="font-family:Times New Roman;"> <span style="font-family:Arial Narrow;">readCount++;</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;"> if ( readCount % 100 == 0) {</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;"> session.flush();</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;"> session.clear();</span><br style="font-family:Arial Narrow;" /><span style="font-family:Arial Narrow;">}</span>
</span></pre>
<p>Hibernate has different level of caching and be careful about it. If session cache is not cleared periodically and the results set data is large, you will soon get out-of-memory error.</p>
<p>This approach has some drawbacks as well: business logic may be moved to dao tier; the connection remains open during entire operation; some databases may not support this feature(need to check the related jdbc driver)</p>
<p><span style="font-family:Times New Roman;"><br />
</span></p>
<p><strong>(3) Native SQL</strong></p>
<p>If operation speed is a major issue and none of above solutions is fast enough, you may consider to move the entire operation to database side via native jdbc and/or stored procedure. This approach can leverage database specific features to improve performance, and may also reduce unnecessary data transportation between middleware and database. In some real applications, we have some very I/O intensive operations and execution time is reduced significantly(3~5 times) via direct jdbc sql.</p>
<p>However this approach makes your application database specific and actual performance improvement will be based on application&#8217;s specific behaviors. It also moves the cpu and I/O load to database server and all needs to be considered before hand.</p>
<p><strong>Summary</strong></p>
<p>When dealing with large data, we list three solutions to improve performance.</p>
<pre><span style="font-family:Times New Roman;">
<div>
<table id="sufa" style="height:166px;" border="1" cellspacing="0" cellpadding="3" width="472">
<tbody>
<tr>
<td width="20%"><strong>Solution </strong></td>
<td width="20%"><strong>Memory usage </strong></td>
<td width="20%"><strong>Speed</strong></td>
<td width="20%"><strong>Portablity across databases </strong></td>
<td width="20%"><strong>Simplicity </strong></td>
</tr>
<tr>
<td width="20%">Hibernate pagination</td>
<td width="20%">Bound</td>
<td width="20%">Slow</td>
<td width="20%">Most</td>
<td width="20%">Simplest</td>
</tr>
<tr>
<td width="20%">Hibernate ScrollableResults</td>
<td width="20%">Conditional bound (explicit clear session cache needed)</td>
<td width="20%">Fair</td>
<td width="20%">Somewhat(depends on driver)</td>
<td width="20%">More work(biz logic moved to dao tier)</td>
</tr>
<tr>
<td width="20%">Nativce SQL/Stored Procedure</td>
<td width="20%">Bound</td>
<td width="20%">Fast</td>
<td width="20%">No</td>
<td width="20%">Most amount of work</td>
</tr>
</tbody>
</table>
</div>

</span></pre>
<p>Each solution has its advantages and disadvantages. Based on each application&#8217;s specific requirements, you may choose a proper solution here.</p>
<pre><span style="font-family:Arial Narrow;">     </span></pre>
<p class="MsoNormal">
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=10&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/04/24/handling-large-collection-data-%e2%80%93-hibernate-pagination-scrollableresults-and-native-sql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
		<item>
		<title>Integrate Fluint Testing with Apache Ant in Adobe AIR Application build</title>
		<link>http://herbertwu.wordpress.com/2009/04/24/integrate-fluint-testing-with-apache-ant-in-adobe-air-application-build/</link>
		<comments>http://herbertwu.wordpress.com/2009/04/24/integrate-fluint-testing-with-apache-ant-in-adobe-air-application-build/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 15:57:14 +0000</pubDate>
		<dc:creator>herbertwu</dc:creator>
				<category><![CDATA[Adobe AIR Ant Build process]]></category>
		<category><![CDATA[Flex and AIR CI build]]></category>

		<guid isPermaLink="false">http://herbertwu.wordpress.com/?p=8</guid>
		<description><![CDATA[In my last post &#8220;Using Apache Ant to Compile, Test and Package Adobe AIR Application&#8221; we discussed how to do ant build with flexunit. In this post we replace flexunit with fluint for unit/integration tests. The main benifit of fluint is that it allows you to do sequenece tests &#8211; simulating an user&#8217;s click sequence [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=8&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In my last post &#8220;<strong>Using Apache Ant to Compile, Test and Package Adobe AIR Application</strong>&#8221; we discussed how to do ant build with flexunit. In this post we replace flexunit with fluint for unit/integration tests. The main benifit of fluint is that it allows you to do sequenece tests &#8211; simulating an user&#8217;s click sequence in a Flex application. It is a white-box testing as FlexMonkey is a black-box testing tool.</p>
<p>You first need to go to fluint home http://code.google.com/p/fluint/ to download the package and follow the instructions to install the AIR test runner.</p>
<p>Here are the steps after you have fluint installed:</p>
<p><strong>Step 1</strong>: fluint uses module to control the tests insteadof WindowedApplication in flexunit.The sample module here is called <strong>MyAIRUnitTestsModule.mxml</strong> which may look like this in which MyTestSuite class contains all your individual tests:</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<br />
&lt;mx:Module xmlns:mx=&#8221;http://www.adobe.com/2006/mxml&#8221; implements=&#8221;net.digitalprimates.fluint.modules.ITestSuiteModule&#8221;&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import test.com.mycompany.test.MyTestSuite;</p>
<p>public function getTestSuites() : Array<br />
{<br />
var suiteArray : Array = new Array();<br />
suiteArray.push( new MyTestSuite()() );<br />
return suiteArray;<br />
}<br />
]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;/mx:Module&gt;</p>
<p><strong>Step 2</strong>: In build.xml&#8217;s <strong>unittestcompile</strong> target, replace flexunit lib with fluint:</p>
<p>&lt;arg line=&#8221;-library-path+=&#8217;${basedir}/libs/fluint-1.1.0.swc&#8217;&#8221;/&gt;</p>
<p><strong>Step 3</strong>: In build.xml, replace <strong>unittest </strong>target with:</p>
<p>&lt;target name=&#8221;unittest&#8221; depends=&#8221;unittestcompile&#8221;&gt;<br />
&lt;delete dir=&#8221;${reports.dir}&#8221; /&gt;<br />
&lt;mkdir dir=&#8221;${reports.dir}&#8221;/&gt;</p>
<p>&lt;!&#8211; Run the tests &#8211;&gt;</p>
<p>&lt;taskdef name=&#8221;fluint&#8221;<br />
classname=&#8221;net.digitalprimates.ant.tasks.fluint.Fluint&#8221;<br />
/&gt;<br />
&lt;fluint<br />
debug=&#8221;true&#8221;<br />
headless=&#8221;true&#8221;<br />
failonerror=&#8221;true&#8221;<br />
workingDir=&#8221;${APP_ROOT_DIR}&#8221;<br />
testRunner=&#8221;C:\Program Files\FluintAIRTestRunner\FluintAIRTestRunner.exe&#8221;<br />
outputDir=&#8221;${reports.dir}&#8221;&gt;</p>
<p>&lt;fileset dir=&#8221;${UNITTEST_OUTPUT}&#8221;&gt;<br />
&lt;include name=&#8221;MyAIRUnitTestsModule.swf&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;/fluint&gt;</p>
<p>&lt;/target&gt;</p>
<p>unit test results are stored in the directory specified in above <em>outputDir</em> switch.</p>
<p><em>testRunner</em> switch indicates its location(win xp path in this example)</p>
<p><strong>Quick summary</strong></p>
<p>- fluint allows white-box integration tests against Flex UI components in addition to normal unit tests</p>
<p>- fluint uses Module for AIR unit tests</p>
<p>- fluint uses its own FluintAirTestRunner.exe(itself is an AIR application, so AIR runtime is required) to the tests.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/herbertwu.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/herbertwu.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/herbertwu.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=herbertwu.wordpress.com&amp;blog=7489790&amp;post=8&amp;subd=herbertwu&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://herbertwu.wordpress.com/2009/04/24/integrate-fluint-testing-with-apache-ant-in-adobe-air-application-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c015ef1293e667f2d431a2792408e04b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">herbertwu</media:title>
		</media:content>
	</item>
	</channel>
</rss>
