<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-19518284</atom:id><lastBuildDate>Tue, 22 Sep 2009 03:56:31 +0000</lastBuildDate><title>/src/blog</title><description>Kartik Shah</description><link>http://kartik-shah.blogspot.com/</link><managingEditor>noreply@blogger.com (Kartik Shah)</managingEditor><generator>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/kartikshah" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-9033276149481013550</guid><pubDate>Fri, 10 Jul 2009 05:25:00 +0000</pubDate><atom:updated>2009-07-09T22:27:15.959-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ast</category><category domain="http://www.blogger.com/atom/ns#">aop</category><category domain="http://www.blogger.com/atom/ns#">transformation</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><title>Groovy AST Transformation - AOP Style</title><description>In my last &lt;a href="http://kartik-shah.blogspot.com/2009/03/groovy-16-ast-transformation-example_5323.html"&gt;blog about AST Transformation&lt;/a&gt; I followed a sample example and created AssertParamsNotNull local transformation. Further, I wanted to create AST Transformation which is generic enough and performs any check before method is executed. In process, goal is to learn about AST Transformation. &lt;br /&gt;&lt;br /&gt;&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;BeforeAdvisor AST Transformation&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;Use case for BeforeAdvisor AST involves: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Authorization Checking - Security by checking role from context&lt;/li&gt;&lt;li&gt;Print Parameter values with which the method is called&lt;/li&gt;&lt;li&gt;Asserts Parameters are not null&lt;/li&gt;&lt;li&gt;Check various entry-conditions/Pre-Conditions of the method&lt;/li&gt;&lt;/ul&gt;To make transform generic enough, idea is to inject a method call to &lt;span style="font-style: italic;"&gt;before method&lt;/span&gt; of advice for each method annotated with @BeforeAdvisor(MyPreConditionAdvice). Advice method can choose to implement any checks/conditions to be performed before actual methods gets executed. &lt;br /&gt;&lt;br /&gt;Few of the subtle characteristics of this type of solution are &lt;br /&gt;&lt;ul&gt;&lt;li&gt;It does not allow changing the method parameters.&amp;nbsp; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;It does not allow to stop execution of method. However, you can throw runtime exception.&lt;/li&gt;&lt;li&gt;Advice needs no arg constructor and must implement method &lt;span style="font-style: italic;"&gt;before &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Usage and Client&lt;/span&gt;&lt;br /&gt;Starting with class that will use this transform. Following defines script-level method with annotation having advice information.&lt;br /&gt;&lt;pre name="code" class="groovy"&gt;&lt;br /&gt;package com.learn.sts.groovy.ast&lt;br /&gt;&lt;br /&gt;@com.learn.sts.groovy.ast.BeforeAdvisor(value= com.learn.sts.groovy.MyAdvice)&lt;br /&gt;def sayHello(name, name2)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; println "Hello " + name + name2&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sayHello("World", "Groovy") &lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Sample Advice&lt;/span&gt;&lt;br /&gt;The advice that we will try to invoke will be something like this. This advice just prints parameter value that method is being invoked with. But you can implement any of the use cases described above.&lt;br /&gt;&lt;pre name="code" class="groovy"&gt;&lt;br /&gt;package com.learn.sts.groovy&lt;br /&gt;&lt;br /&gt;public class MyAdvice&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def before(String methodName, List listArg)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; println 'Entering Method ' + methodName + ' with params ' + listArg&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Annotation&lt;/span&gt;&lt;br /&gt;Now lets create the Annotation&lt;br /&gt;&lt;pre name="code" class="groovy"&gt;&lt;br /&gt;package com.learn.sts.groovy.ast;&lt;br /&gt;&lt;br /&gt;import java.lang.annotation.Retention&lt;br /&gt;import java.lang.annotation.RetentionPolicy&lt;br /&gt;import java.lang.annotation.Target&lt;br /&gt;import java.lang.annotation.ElementType&lt;br /&gt;import org.codehaus.groovy.transform.GroovyASTTransformationClass&lt;br /&gt;@Retention(RetentionPolicy.SOURCE)&lt;br /&gt;@Target([ElementType.METHOD])&lt;br /&gt;@GroovyASTTransformationClass(["com.learn.sts.groovy.ast.BeforeAdvisorASTTransformation"])&lt;br /&gt;public @interface BeforeAdvisor {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Class value ();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;One difference to this annotation is that it declares a method value(). This allows us to get value being passed during annotation declaration on method.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;AST Transformation&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="groovy"&gt;&lt;br /&gt;package com.learn.sts.groovy.ast&lt;br /&gt;&lt;br /&gt;//Imports section skipped for brevity&lt;br /&gt;&lt;br /&gt;@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)&lt;br /&gt;public class BeforeAdvisorASTTransformation implements ASTTransformation &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void visit(ASTNode[] nodes, SourceUnit source)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AnnotationNode node = (AnnotationNode) nodes[0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; final Expression classNode = node.getMember("value")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;MethodNode&amp;gt; allMethods = source.AST?.classes*.methods.flatten()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List annotatedMethods = allMethods.findAll{ MethodNode method -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; method.getAnnotations(new ClassNode(BeforeAdvisor))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; annotatedMethods.each{MethodNode method -&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List existingStatements = method.getCode().getStatements()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Parameter[] parameters = method.getParameters()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int i = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; existingStatements.add(i++, initAdviceCall(classNode))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; existingStatements.add(i++, createMethodCall(method, parameters))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Statement initAdviceCall(classNode)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; return new ExpressionStatement(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; new DeclarationExpression(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; new VariableExpression("advice"),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; new ConstructorCallExpression(classNode.getType(), new ArgumentListExpression())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; public Statement createMethodCall(method, Parameter[] parameters){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; List parameterExpressionList = new ArrayList()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; parameters.each{ parameter -&amp;gt; parameterExpressionList.add(new VariableExpression(parameter))}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; return new ExpressionStatement(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new MethodCallExpression(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new VariableExpression("advice"),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "before",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new ArgumentListExpression(new ConstantExpression(method.getName()),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new ListExpression(parameterExpressionList)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Couple of things to notice here: &lt;br /&gt;&lt;br /&gt;First, creation of the AST tree involves &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Creating instance of Advice Class - This is done through method &lt;span style="font-style: italic;"&gt;initAdviceCall&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Invocation of the method before with methodName and Parameter List - This is done through method &lt;span style="font-style: italic;"&gt;createMethodCall&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Creating AST structure is not the easiest task. One approach that has worked for me is the write the sample code that you are trying to generate AST for and then use Groovy AST viewer in eclipse. &lt;br /&gt;&lt;br /&gt;Second, inspecting the value on ASTNode and getting Advice class value. First node contains information about the annotation and second node is the annotated node. &lt;br /&gt;&lt;br /&gt;&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;Lessons Learned&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font size="2"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="font-weight: bold;"&gt;Compilation&lt;/span&gt;&lt;br /&gt;It was required to compile Transformations files first and then compile the classes that use AST Transformation. If I compiled all three of them together the AST Transformation did not kick in. I used Eclipse IDE and it forced me to use Compile Groovy File explicitly each time I made change. "Build Automatically" or "Clean" option did not work. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Script Level Methods vs all Class Methods&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;In &lt;a href="http://kartik-shah.blogspot.com/2009/03/groovy-16-ast-transformation-example_5323.html"&gt;AssertParamsNotNull&lt;/a&gt; AST Transformation in previous blog, I used &lt;span style="font-style: italic;"&gt;source.getAST()?.getMethods()&lt;/span&gt;&amp;nbsp; what it did is that it only found top level (Script Level) methods. So AST Transformation did not apply to Class Methods, it only got applied to Script Level Method. For this one I changed to source.ast?.classes*.methods.flatten() (Line 12 in &lt;span style="font-style: italic;"&gt;BeforeAdvisorASTTransformation&lt;/span&gt;). This also become apparent once you see AST structure for a given class using Groovy AST View in eclipse. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Retrive value from annotations&lt;/span&gt;&lt;br /&gt;ASTNode being passed to &lt;span style="font-style: italic;"&gt;visit&lt;/span&gt; method carries information about the annotation. First element (node[0]) contains information about annotation. You can get the values passed in to annotation during the visit method and use it during the transformation. In case above we get class passed in as value and it gets instantiated and before method gets invoked.&lt;br /&gt;&lt;br /&gt;&lt;font size="2"&gt;&lt;span style="font-weight: bold;"&gt;Groovy Compilation&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;When groovy compiler is invoked, any sourcefile.groovy goes under series of transformations. &lt;br /&gt;From Source --&amp;gt; ANTLR Tokens --&amp;gt; ANTLR AST --&amp;gt; Groovy AST --&amp;gt; Bytecode&lt;br /&gt;&lt;br /&gt;Using AST Transformation, we manipulate the way groovy AST gets generated. It allows to insert additonal statements. &lt;br /&gt;&lt;br /&gt;There are various CompilerPhase that goes along with this process. I couldn't find much documentation on the process. Best information is found on &lt;a href="http://blackdragsview.blogspot.com/2006/11/chitchat-with-groovy-compiler.html"&gt;Jochen Theodorou's blog post&lt;/a&gt;&lt;div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;"&gt;Blogged with the &lt;a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser"&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-9033276149481013550?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=39Ur4tD56bo:SQsaXbvz1D8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=39Ur4tD56bo:SQsaXbvz1D8:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=39Ur4tD56bo:SQsaXbvz1D8:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=39Ur4tD56bo:SQsaXbvz1D8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=39Ur4tD56bo:SQsaXbvz1D8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/39Ur4tD56bo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/39Ur4tD56bo/groovy-ast-transformation-aop-style.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2009/07/groovy-ast-transformation-aop-style.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6920448346239865337</guid><pubDate>Sun, 21 Jun 2009 04:35:00 +0000</pubDate><atom:updated>2009-06-20T21:45:47.759-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">swingbuilder</category><category domain="http://www.blogger.com/atom/ns#">jfreechart</category><category domain="http://www.blogger.com/atom/ns#">jmx</category><category domain="http://www.blogger.com/atom/ns#">administration</category><category domain="http://www.blogger.com/atom/ns#">weblogic</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">dashboard</category><title>JMX, Groovy, JFreeChart and Swing</title><description>&lt;span style="font-weight: bold; font-family: Verdana;"&gt;&lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;Recently, I worked on creating JMX based dashboard application showing Weblogic instances' information. During the exercise I came across &lt;/span&gt;&lt;a style="font-family: Verdana;" href="http://groovy.codehaus.org/Groovy+and+JMX"&gt;JMX and Groovy examples &lt;/a&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;span style="font-family: Verdana;"&gt;Using JMX, Groovy, Swing and JFreeChart, I came up with a dashboard application which looks like this. &lt;/span&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;a style="font-family: Verdana;" href="http://www.flickr.com/photos/shahkartikr/3645249363/" title="Memory-Usage by shahkartikr, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2431/3645249363_1fb8dacf03.jpg" alt="Memory-Usage" height="202" width="500" /&gt;&lt;/a&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;span style="font-family: Verdana;"&gt;It show memory usage on two instances. It automatically updates every 10 seconds and redraws chart. &lt;/span&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;br style="font-family: Verdana;" /&gt;&lt;span style="font-family: Verdana;"&gt;Surprisingly (or not so surprisingly), code required to be written to perform this activity is minimal. Specifically thanks to Groovy's SwingBuilder and JMX libraries.&lt;/span&gt; Groovy makes the task of using 4 different technologies really easy and fun.&lt;br /&gt;&lt;pre class="java" name="code"&gt;&lt;br /&gt;import org.jfree.chart.ChartFactory&lt;br /&gt;import javax.swing.WindowConstants as WC&lt;br /&gt;import javax.management.remote.*&lt;br /&gt;import javax.naming.Context;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * WeblogicJMXReporter monitors Memory value for given node&lt;br /&gt; * @author kartik.shah&lt;br /&gt; */&lt;br /&gt;public class WeblogicJMXReporter&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    static void main(String[] args)&lt;br /&gt;    {&lt;br /&gt;    	def env = [:]&lt;br /&gt;    	env["java.naming.factory.initial"] = "weblogic.jndi.WLInitialContextFactory"&lt;br /&gt;    	env[Context.SECURITY_PRINCIPAL] = "system"&lt;br /&gt;    	env[Context.SECURITY_CREDENTIALS] = "*******" //Password is always stars&lt;br /&gt;    	env[JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES] = "weblogic.management.remote"&lt;br /&gt;    	def jmxServiceURL = new JMXServiceURL("http", "10.50.120.110", 19400,"/jndi/weblogic.management.mbeanservers.domainruntime")&lt;br /&gt;    	def server = JMXConnectorFactory.connect(jmxServiceURL, env).MBeanServerConnection&lt;br /&gt;&lt;br /&gt;    	def chart1Map = getChart("node1_svr", server);&lt;br /&gt;    	def piedata1 = chart1Map."pieData"&lt;br /&gt;    	def chart1 = chart1Map."Chart"&lt;br /&gt;    	def jvmInfo1 = chart1Map."MBean"&lt;br /&gt;    	&lt;br /&gt;    	def chart2Map = getChart("node2_svr", server);&lt;br /&gt;    	def piedata2 = chart2Map."pieData"&lt;br /&gt;    	def chart2 = chart2Map."Chart"&lt;br /&gt;    	def jvmInfo2 = chart2Map."MBean"&lt;br /&gt;    	&lt;br /&gt;    	def swing = new groovy.swing.SwingBuilder()&lt;br /&gt;&lt;br /&gt;    	def frame = swing.frame(title:'Weblogic INT Memory Usage', defaultCloseOperation:WC.EXIT_ON_CLOSE, &lt;br /&gt;    	                        size:[800,600], locationRelativeTo: null) {&lt;br /&gt;    	    borderLayout()&lt;br /&gt;    	    panel(id:'canvas') { rigidArea(width:700, height:250) }&lt;br /&gt;    	}&lt;br /&gt;&lt;br /&gt;    	def bounds1 = new java.awt.Rectangle(0,0, 350,250).bounds&lt;br /&gt;    	def bounds2 = new java.awt.Rectangle(351,0, 350, 250).bounds&lt;br /&gt;    	while(true)&lt;br /&gt;    	{&lt;br /&gt;    	    recalculatePieData(piedata1, jvmInfo1)&lt;br /&gt;    	    recalculatePieData(piedata2, jvmInfo2)&lt;br /&gt;        &lt;br /&gt;        	chart1.fireChartChanged()&lt;br /&gt;        	chart2.fireChartChanged()&lt;br /&gt;        	&lt;br /&gt;        	frame.pack()&lt;br /&gt;        	frame.show()&lt;br /&gt;        	chart1.draw(swing.canvas.graphics, bounds1)&lt;br /&gt;        	chart2.draw(swing.canvas.graphics, bounds2)&lt;br /&gt;        	sleep(10000)&lt;br /&gt;    	}&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    static getChart(nodeName, server)&lt;br /&gt;    {&lt;br /&gt;    	def jvmInfo = new GroovyMBean(server, 'com.bea:Location='+nodeName+',Name='+nodeName+',ServerRuntime='+nodeName+',Type=JVMRuntime')&lt;br /&gt;    	def piedata = new org.jfree.data.general.DefaultPieDataset()&lt;br /&gt;    	piedata.setValue "Free", jvmInfo.HeapFreeCurrent&lt;br /&gt;    	piedata.setValue "Used", jvmInfo.HeapSizeMax - jvmInfo.HeapFreeCurrent&lt;br /&gt;    	def options = [true, true, true]&lt;br /&gt;    	def chart = ChartFactory.createPieChart(nodeName, piedata, *options)&lt;br /&gt;    	chart.backgroundPaint = java.awt.Color.white&lt;br /&gt;        &lt;br /&gt;        ["MBean":jvmInfo, "pieData":piedata, "Chart":chart]&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    static recalculatePieData(piedata, jvmInfo)&lt;br /&gt;    {&lt;br /&gt;    	piedata.setValue "Free", jvmInfo.HeapFreeCurrent&lt;br /&gt;    	piedata.setValue "Used", jvmInfo.HeapSizeMax - jvmInfo.HeapFreeCurrent&lt;br /&gt;    	println piedata.getValue("Free")&lt;br /&gt;    	println piedata.getValue("Used")&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;For purpose of this blog and keeping it simple, I kept it all in one groovy class. &lt;br /&gt;  &lt;div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;"&gt;Blogged with the &lt;a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser"&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-6920448346239865337?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=WW0CeDUkUAs:LM-WOPBuTFo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=WW0CeDUkUAs:LM-WOPBuTFo:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=WW0CeDUkUAs:LM-WOPBuTFo:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=WW0CeDUkUAs:LM-WOPBuTFo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=WW0CeDUkUAs:LM-WOPBuTFo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/WW0CeDUkUAs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/WW0CeDUkUAs/jmx-groovy-jfreechart-and-swing.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2009/06/jmx-groovy-jfreechart-and-swing.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-3306965452601264220</guid><pubDate>Thu, 26 Mar 2009 21:02:00 +0000</pubDate><atom:updated>2009-04-02T15:07:05.876-07:00</atom:updated><title>Groovy 1.6 AST Transformation Example</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;font face='verdana'&gt;With Groovy 1.6 released and &lt;a target='_blank' href='http://www.infoq.com/articles/groovy-1-6'&gt;this article on InfoQ&lt;/a&gt; got me to try some new features. &lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;b&gt;AST Transformation&lt;/b&gt;&lt;br/&gt;With Groovy 1.6 you can define local and global transformation using annotations. &lt;/font&gt;&lt;font face='verdana'&gt;So let's define @AssertParamsNotNull annotation for method which would perform AST Transformation at compile time. It simply asserts parameters of method are not null. I am following &lt;a target='_blank' href='http://groovy.codehaus.org/Local+AST+Transformations'&gt;groovy documentation here&lt;/a&gt; and &lt;a target='_blank' href='http://hamletdarcy.blogspot.com/2009/03/local-ast-transformations-in-groovy-16.html'&gt;blog entry here by Hamlet D'Arcy&lt;/a&gt;&lt;/font&gt;.&lt;br/&gt;&lt;font face='verdana'&gt;&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;There are three components to defining local AST Transformation&lt;br/&gt;&lt;br/&gt;Step 1: Define Annotation&lt;br/&gt;Step 2: Define GroovyASTTransformation &lt;br/&gt;Step 3: Test and Usage&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;b&gt;Pre-requisites&lt;/b&gt;&lt;br/&gt;Download Groovy 1.6&lt;br/&gt;Download Groovy Eclipse plugin for 1.6, available from this update URL. &lt;/font&gt; &lt;blockquote&gt;&lt;a href='http://dist.groovy.codehaus.org/distributions/updateDev_1.6/'&gt; http://dist.groovy.codehaus.org/distributions/updateDev_1.6/&lt;/a&gt;&lt;font face='verdana'&gt; &lt;/font&gt;&lt;br/&gt;&lt;/blockquote&gt; &lt;font face='verdana'&gt;This url is different from their usual update url. I believe they will update their distributions update url (&lt;/font&gt;&lt;small&gt;&lt;a href='http://dist.codehaus.org/groovy/distributions/update/'&gt;http://dist.codehaus.org/groovy/distributions/update/&lt;/a&gt;&lt;/small&gt;&lt;font face='verdana'&gt;)&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;b&gt;Step 1: Define Annotation @AssertParamsNotNull&lt;/b&gt;&lt;br/&gt;&lt;/font&gt;&lt;pre class='groovy' name='code'&gt;&lt;br /&gt;package com.learn.groovy16.ast.local&lt;br /&gt;import java.lang.annotation.Retention&lt;br /&gt;import java.lang.annotation.RetentionPolicy&lt;br /&gt;import java.lang.annotation.Target&lt;br /&gt;import java.lang.annotation.ElementType&lt;br /&gt;import org.codehaus.groovy.transform.GroovyASTTransformationClass&lt;br /&gt;@Retention(RetentionPolicy.SOURCE)&lt;br /&gt;@Target([ElementType.METHOD])&lt;br /&gt;@GroovyASTTransformationClass(["com.learn.groovy16.ast.local.AssertParamsNotNullASTTransformation"])&lt;br /&gt;public @interface AssertParamsNotNull{&lt;br /&gt;&lt;/pre&gt;&lt;font face='verdana'&gt;One thing to notice is here defining the ASTTransformation class. It requires complete qualified class name. Rest of the things are standard annotation declaration.&lt;br/&gt;&lt;br/&gt;While working on getting this running in my environment I faced following errors/issues.&lt;br/&gt;&lt;br/&gt;&lt;small&gt;&lt;b&gt;&lt;i&gt;Unknown Type: ANNOTATION_DEF at line ... &lt;/i&gt;&lt;/b&gt;&lt;/small&gt;&lt;br/&gt;This error comes if for some reason eclipse environment is still using older groovy installation. Check your GROOVY_HOME points to Groovy 1.6. If you are able to run this through command line, but eclipse is giving your errors. Update your Groovy Eclipse plugin from dev update URL. You may have to wipe it clean for eclipse to understand it. &lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;small&gt;Expected '{' but &lt;newline&gt; was found...&lt;br/&gt;&lt;/newline&gt;&lt;/small&gt;&lt;/b&gt;&lt;/font&gt;&lt;font face='verdana'&gt;This error comes if for some reason there funny newline characters. I think I got this error if right after "public @interface AssertParamsNotNull&lt;/font&gt;" if { is in the next line. I believe I got funny character in between those two. I changed the text file encoding to UTF-8 and the error went away. It allowed me to have braces on the next line.&lt;br/&gt;&lt;font face='verdana'&gt;&lt;br/&gt;&lt;b&gt;Step 2: Define GroovyASTTransformation&lt;/b&gt;&lt;br/&gt;&lt;/font&gt;&lt;br /&gt;&lt;pre class='groovy' name='code'&gt;&lt;br /&gt;package com.learn.groovy16.ast.local&lt;br /&gt;import org.codehaus.groovy.transform.GroovyASTTransformation&lt;br /&gt;import org.codehaus.groovy.ast.ASTNode&lt;br /&gt;import org.codehaus.groovy.control.SourceUnit&lt;br /&gt;import org.codehaus.groovy.transform.ASTTransformation&lt;br /&gt;import org.codehaus.groovy.control.CompilePhase&lt;br /&gt;import org.codehaus.groovy.ast.MethodNode&lt;br /&gt;import org.codehaus.groovy.ast.ClassNode&lt;br /&gt;import org.codehaus.groovy.ast.Parameter&lt;br /&gt;import org.codehaus.groovy.ast.stmt.Statement&lt;br /&gt;import org.codehaus.groovy.ast.stmt.AssertStatement&lt;br /&gt;import org.codehaus.groovy.ast.expr.BooleanExpression&lt;br /&gt;import org.codehaus.groovy.ast.expr.NotExpression&lt;br /&gt;import org.codehaus.groovy.ast.expr.VariableExpression&lt;br /&gt;@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)&lt;br /&gt;public class AssertParamsNotNullASTTransformation implements ASTTransformation &lt;br /&gt;{&lt;br /&gt; public void visit(ASTNode[] nodes, SourceUnit source)&lt;br /&gt;  {&lt;br /&gt;   List methods = source.getAST()?.getMethods()&lt;br /&gt;    methods.findAll{MethodNode method -&gt;&lt;br /&gt;     method.getAnnotations(new ClassNode(AssertParamsNotNull))&lt;br /&gt;    }.each{MethodNode method -&gt; &lt;br /&gt;      List existingStatements = method.getCode().getStatements()&lt;br /&gt;      Parameter[] parameters = method.getParameters()&lt;br /&gt;      parameters.eachWithIndex(){ parameter, i -&gt;&lt;br /&gt;       existingStatements.add(i, createAssertStatement(parameter))&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public Statement createAssertStatement(Parameter parameter){&lt;br /&gt;   return new AssertStatement(&lt;br /&gt;    new BooleanExpression(&lt;br /&gt;     new VariableExpression(parameter))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;font face='verdana'&gt;&lt;font face='verdana'&gt;This is where most of the trick is happening. This class implements &lt;i&gt;ASTTransformation&lt;/i&gt; interface implementing &lt;i&gt;visit(ASTNode[], SourceUnit source)&lt;/i&gt; method. This method gets all methods marked with AssertParamsNotNull annotation, iterates over all method, iterates over all method parameters and calls createAssertStatement(parameter). createAssertStatement(parameter) creates Statements equivalent to assert parameter and inserts it into the AST tree. All this happens at compile time. So notice line&lt;br/&gt;&lt;/font&gt; &lt;/font&gt;&lt;blockquote&gt;&lt;font face='verdana'&gt;&lt;big&gt;&lt;font face='Courier New'&gt;&lt;small&gt;@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)&lt;/small&gt;&lt;/font&gt;&lt;/big&gt;&lt;br/&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;font face='verdana'&gt; &lt;font face='verdana'&gt;Creating Statement and Expression using API is really cumbersome. It is good they are working on builder support for the same. &lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;small&gt;&lt;font face='Courier New'&gt; &lt;/font&gt;&lt;/small&gt;&lt;/font&gt;&lt;br/&gt;&lt;font face='verdana'&gt;&lt;b&gt;Step 3: Test and Run &lt;/b&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;br /&gt;&lt;pre class="groovy" name="code"&gt;&lt;br /&gt;package com.learn.groovy16.ast.local  &lt;br /&gt;&lt;br /&gt;@com.learn.groovy16.ast.local.AssertParamsNotNull&lt;br/&gt;  &lt;br /&gt;def foo(String var)&lt;br /&gt;{&lt;br /&gt;  println var&lt;br /&gt;}&lt;br /&gt;foo("Hello")&lt;br /&gt;foo(null)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;font face='verdana'&gt; &lt;font face='verdana'&gt;&lt;br/&gt;Note the annotation with fully qualified name. &lt;br/&gt;&lt;br/&gt;Interesting thing is that all transformation happens at compile time. It does not stop &lt;br/&gt;&lt;br/&gt;&lt;b&gt;Other interesting AST Transformations...&lt;br/&gt;&lt;big&gt;&lt;br/&gt;&lt;/big&gt;&lt;/b&gt;&lt;i&gt;&lt;b&gt;@CatchExceptions(list=[exception1, exception2, ..],rethrow=AppException)&lt;/b&gt;&lt;/i&gt;&lt;br/&gt;Define AST transformation to remove clutterred exception handling logic and rethrow ApplicationException as noted by parameters of annotation. I think the challenge here will be to build AST Statement and Expression.&lt;br/&gt;&lt;/font&gt;&lt;br/&gt;&lt;b&gt;&lt;i&gt;&lt;big&gt;@&lt;/big&gt;&lt;small&gt;&lt;big&gt;SecureAccess(Role=Manager)&lt;/big&gt;&lt;br/&gt;&lt;/small&gt;&lt;/i&gt;&lt;/b&gt;&lt;small&gt;&lt;big&gt;Allows to define security over method execution.&lt;br/&gt;&lt;br/&gt;&lt;small&gt;&lt;i&gt;&lt;b&gt;&lt;big&gt;@Trace(isTraceEnabled=$GlobalTraceParameter)&lt;/big&gt;&lt;br/&gt;&lt;/b&gt;&lt;/i&gt;&lt;big&gt;Emits out trace of method. Entered, parameter values, exit, return type. This only gets emitted if GlobalTraceParameter is set to Y&lt;br/&gt;&lt;/big&gt;&lt;/small&gt;&lt;/big&gt;&lt;/small&gt;&lt;/font&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-3306965452601264220?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=q9kVD7aYtVQ:W7cJ2_EVJ5E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=q9kVD7aYtVQ:W7cJ2_EVJ5E:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=q9kVD7aYtVQ:W7cJ2_EVJ5E:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=q9kVD7aYtVQ:W7cJ2_EVJ5E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=q9kVD7aYtVQ:W7cJ2_EVJ5E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/q9kVD7aYtVQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/q9kVD7aYtVQ/groovy-16-ast-transformation-example_5323.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2009/03/groovy-16-ast-transformation-example_5323.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-8584213247971948689</guid><pubDate>Wed, 11 Mar 2009 16:46:00 +0000</pubDate><atom:updated>2009-03-11T09:47:29.276-07:00</atom:updated><title>Grails, Flex and MyEclipse</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;font face='verdana'&gt;This is a small exercise that I undertook following documentation I found on &lt;a href='http://www.grails.org/Flex+Plugin'&gt;grails website&lt;/a&gt;. Let's create small calculator application which adds two operands. The idea is to setup the flex plugin and see how it works.&lt;br/&gt;&lt;br/&gt;I used following tools&lt;br/&gt;&lt;/font&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;MyEclipse with flex builder&lt;/li&gt;&lt;li&gt;Grails&lt;/li&gt;&lt;li&gt;Groovy Eclipse plugin&lt;/li&gt;&lt;li&gt;&lt;font face='verdana'&gt;Grails Fex Plugin&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;font face='verdana'&gt;	&lt;/font&gt;&lt;font face='verdana'&gt;&lt;b&gt;Step 1: Install Groovy Eclipse plugin&lt;/b&gt;&lt;br/&gt;MyEclipse 6.5 installation that I had did not came with groovy/grails plugin. One of the nice thing about MyEclipse is that it is eclipse with additional tools. Use the following plugin update URL to get groovy plugin. &lt;br/&gt;&lt;br/&gt;Here is eclipse software update URL: &lt;a href='http://dist.codehaus.org/groovy/distributions/update/'&gt;http://dist.codehaus.org/groovy/distributions/update/&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;This plugin is optional. You can use grails command line commands and that will work as well.&lt;br/&gt;&lt;br/&gt;	&lt;b&gt;Step 2: Create Grails Project and Install Grails Flex Plugin&lt;/b&gt;&lt;br/&gt;Next thing is to install Grails Flex plugin. This is still under development. The one I used is version 0.2.&lt;br/&gt;&lt;br/&gt;Create Grails application using New --&amp;gt; Other... --&amp;gt; New Grails Project. This will create grails project. &lt;br/&gt; &lt;br/&gt;Alternatively you an use grails command line to create app. Go to command line, change directory to project root folder in your workspace and type command: &lt;br/&gt;              &lt;font face='Courier New'&gt;grails install-plugin flex.&lt;/font&gt; &lt;br/&gt;&lt;br/&gt;This will install flex plugin for grails. &lt;br/&gt;&lt;br/&gt;I was using MyEclipse with Flex Builder, it was easy to add flex nature to my project. To do that right click and add flex nature&lt;br/&gt;&lt;br/&gt;&lt;b&gt;Step 3: Create Calc UI&lt;/b&gt;&lt;br/&gt;Now project is setup, we are ready to create calc.mxml. I created this under webapp folder so that it is visible.&lt;br/&gt;&lt;br/&gt;Use following calc.mxml&lt;br/&gt;&lt;/font&gt;&lt;br/&gt;&lt;font face='Courier New'&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br/&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&amp;gt;&lt;br/&gt;    &amp;lt;mx:RemoteObject id="ro" destination="calcService"/&amp;gt;&lt;br/&gt;    &amp;lt;mx:Model id="myCalcData"&amp;gt;&lt;br/&gt;        &amp;lt;calc&amp;gt;&lt;br/&gt;            &amp;lt;operand1&amp;gt;{number1.text}&amp;lt;/operand1&amp;gt;&lt;br/&gt;            &amp;lt;operand2&amp;gt;{number2.text}&amp;lt;/operand2&amp;gt;&lt;br/&gt;        &amp;lt;/calc&amp;gt;&lt;br/&gt;    &amp;lt;/mx:Model&amp;gt;&lt;br/&gt;    &amp;lt;mx:Panel&amp;gt;&lt;br/&gt;        &amp;lt;mx:Form&amp;gt;&lt;br/&gt;            &amp;lt;mx:FormItem label="Operand 1:"&amp;gt;&lt;br/&gt;                &amp;lt;mx:TextInput id="number1"/&amp;gt;&lt;br/&gt;            &amp;lt;/mx:FormItem&amp;gt;&lt;br/&gt;            &amp;lt;mx:FormItem label="Operand 2:"&amp;gt;&lt;br/&gt;                &amp;lt;mx:TextInput id="number2"/&amp;gt;&lt;br/&gt;            &amp;lt;/mx:FormItem&amp;gt;&lt;br/&gt;            &amp;lt;mx:Button label="Calculate" click="ro.calc(myCalcData.operand1,myCalcData.operand2)"/&amp;gt;&lt;br/&gt;             &amp;lt;mx:Label text="Result: {ro.calc.lastResult} "  fontWeight="bold"/&amp;gt;&lt;br/&gt;        &amp;lt;/mx:Form&amp;gt;    &lt;br/&gt;    &amp;lt;/mx:Panel&amp;gt;        &lt;br/&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='verdana'&gt;Step 4: Create Grails HelloWorldService&lt;/font&gt;&lt;/b&gt; &lt;br/&gt;Create grails new service from IDE. You can also create service by typing command &lt;br/&gt;&lt;font face='Courier New'&gt;grails create-service HelloService&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&lt;font face='Courier New'&gt;public class CalcService&lt;br/&gt;{&lt;br/&gt;  static expose = ['flex-remoting']&lt;br/&gt;  def calc(int number1, int number2) { return number1 + number2 }&lt;br/&gt;}&lt;br/&gt;&lt;/font&gt;&lt;br/&gt;&lt;font face='verdana'&gt;&lt;b&gt;Step 5: Update configuration &lt;/b&gt;&lt;br/&gt;Next step is to update configuration file, Config.groovy to enables web tier compiler for flex. Again, I am using similar file as in the example provided on grails website.&lt;br/&gt;&lt;font face='Courier New'&gt;&lt;br/&gt;// enables the webtier compiler for all environments&lt;br/&gt;&lt;/font&gt;&lt;font face='verdana'&gt;&lt;br/&gt;&lt;b&gt;Step 6: Run using command line&lt;/b&gt;&lt;br/&gt;&lt;/font&gt;&lt;br/&gt;&lt;font face='verdana'&gt;We are almost done, type in command line at project root to run the projectgrails run-app&lt;br/&gt;&lt;br/&gt;Type in browser: http://localhost:8080/MyGrails/calc.mxml&lt;br/&gt;&lt;br/&gt;&lt;img src='http://lh3.ggpht.com/_Ij0FyB8Wu5Q/Sbfqn0U8m-I/AAAAAAAAAKM/1YP2AoCyeko/%5BUNSET%5D.jpg?imgmax=800' style='max-width: 800px;'/&gt;&lt;br/&gt;You may need to change port, application context if you are using different configuration.&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=fdf72649-52e9-42dc-b212-9ec0817f4e22' class='zemanta-pixie-img'/&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/19518284-8584213247971948689?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=nO8TGQzjeIc:QsgEvVqYk1Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=nO8TGQzjeIc:QsgEvVqYk1Y:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=nO8TGQzjeIc:QsgEvVqYk1Y:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=nO8TGQzjeIc:QsgEvVqYk1Y:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=nO8TGQzjeIc:QsgEvVqYk1Y:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/nO8TGQzjeIc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/nO8TGQzjeIc/grails-flex-and-myeclipse_2766.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2009/03/grails-flex-and-myeclipse_2766.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-216168348211293680</guid><pubDate>Sun, 25 May 2008 17:05:00 +0000</pubDate><atom:updated>2008-05-25T20:25:11.865-07:00</atom:updated><title>Webservices with return type List&lt;T&gt;</title><description>&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;I had written few web service which were returning List&lt;t&gt;. Following are my findings when working with that.&lt;br /&gt;&lt;br /&gt;Axis2 did not generate definition of T in wsdl. So to over come that problem I created a dummy method setT(T t) in order to get type definition of T generated in wsdl. Even though this is work around and it did not highlight or resolve the actual problem.&lt;br /&gt;&lt;br /&gt;Axis2 generated List&lt;t&gt; return type as anyType Object. Which created problem during client side code generation. The wsdl published the return type as anyType, Client had no way of determining what type of return object to be generated. So to be type safe I changed the implementation from List&lt;t&gt; to T[]. Now while I believe type List will always be generated as anyType, I do think that List&lt;t&gt; should not be generated as anyType. Tools should be smart enough to generate List&lt;t&gt; as ArrayOfSpecificType in wsdl.&lt;br /&gt;I think that is either due to two reasons,&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;Tools have not caught upto the JDK5 &lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;The specific way Java implements Generics, by using erasure, List&lt;t&gt; becomes List which creates problem for the tool as tools have no way of identifying what type of list was that.&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;t&gt;&lt;br /&gt;There are some other minor problems I faced while using array. I used method toArray(T[] t) to convert my List&lt;t&gt; to Array. The method required me to pass a type T[] t. I created T[] t = new T[?]. I put number 3 - just randomly- to see if it all works. Service worked it generated response and it also appended two more elements named item1 and item2. I was clueless for a while where this sub elements are getting generated. Then it occurred to me the creation of array with three elements is putting it there. Finally, I settled with T[0]. But the problem with that is when result set was 0, client threw error stating unexpected element of type XXXXResponse. I believe this is a bug.&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-216168348211293680?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ctiCgyl7v98:spcKkO5PspY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ctiCgyl7v98:spcKkO5PspY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ctiCgyl7v98:spcKkO5PspY:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ctiCgyl7v98:spcKkO5PspY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=ctiCgyl7v98:spcKkO5PspY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/ctiCgyl7v98" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/ctiCgyl7v98/webservices-with-return-type-list.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2008/05/webservices-with-return-type-list.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-5522788212508841255</guid><pubDate>Mon, 02 Jul 2007 16:36:00 +0000</pubDate><atom:updated>2007-07-02T11:54:04.582-07:00</atom:updated><title>Struts: Creating Custom Validator</title><description>&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;b&gt;Creating Custom Validator&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Idea was to create custom password validator which will not allow certain words to be password. This included common words like password, companyname, abc, 123 etc. Also this requirement will be extended in future to disallow password being same as first name, last name, phone numbers, email address etc.&lt;br /&gt;&lt;br /&gt;As direct implementation one can always override validate method in the Action Form class for the form. But since password field existed in multiple forms it made more sense to make generic validator which can be added to validation-rules.xml file for the application.&lt;br /&gt;&lt;br /&gt;Add following section in validation-rules.xml file. This describes validation rule.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-family:courier new,monospace;"&gt;&lt;span style="font-size:85%;"&gt;  &lt;blockquote&gt; &amp;lt;validator name="custompassword" classname="com.web.helper.CustomValidationUtility" method="validatePassword" methodparams="java.lang.Object,                             org.apache.commons.validator.ValidatorAction,                             org.apache.commons.validator.Field,                             org.apache.struts.action.ActionMessages,                             org.apache.commons.validator.Validator,                             javax.servlet.http.HttpServletRequest" depends="" msg="errors.password"&amp;gt;&amp;lt;/validator&amp;gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;validator name="custompassword" classname="com.web.helper.CustomValidationUtility" method="validatePassword" methodparams="java.lang.Object,                            org.apache.commons.validator.ValidatorAction,                            org.apache.commons.validator.Field,                            org.apache.struts.action.ActionMessages,                            org.apache.commons.validator.Validator,                            javax.servlet.http.HttpServletRequest" depends="" msg="errors.password"&gt;&lt;/validator&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Add the rule for the form that we need to validate.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&amp;lt;!-- change password --&amp;gt;&lt;br /&gt;&amp;lt;form name="/change-password"&amp;gt;&lt;br /&gt; ...&lt;br /&gt;&amp;lt;field property="newPassword" depends="&lt;b&gt;custompassword&lt;/b&gt;"&amp;gt;&lt;br /&gt; ...&lt;br /&gt;&amp;lt;/field&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Create custom validator classes as&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;&lt;span style="font-size:85%;"&gt;package com.web.helper;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.validator.Field;&lt;br /&gt;import org.apache.commons.validator.GenericValidator;&lt;br /&gt;import org.apache.commons.validator.Validator;&lt;br /&gt;import org.apache.commons.validator.ValidatorAction;&lt;br /&gt;import org.apache.commons.validator.util.ValidatorUtils;&lt;br /&gt;import org.apache.struts.action.ActionErrors;&lt;br /&gt;import org.apache.struts.action.ActionMessages;&lt;br /&gt;import org.apache.struts.validator.Resources;&lt;br /&gt;&lt;br /&gt;public class CustomValidationUtility implements Serializable&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public static boolean validatePassword(&lt;br /&gt;Object bean,&lt;br /&gt;ValidatorAction va,&lt;br /&gt;Field field,&lt;br /&gt;ActionMessages messages,&lt;br /&gt;Validator validator,&lt;br /&gt;HttpServletRequest request) {&lt;br /&gt;&lt;br /&gt;System.out.println("Here now");&lt;br /&gt;String value = ValidatorUtils.getValueAsString(bean,                                                   field.getProperty());&lt;br /&gt;List invalidPasswordList = new ArrayList();&lt;br /&gt;invalidPasswordList.add("password");&lt;br /&gt;invalidPasswordList.add("companyname");&lt;br /&gt;invalidPasswordList.add("abc");&lt;br /&gt;invalidPasswordList.add("123");&lt;br /&gt;&lt;br /&gt;if (!GenericValidator.isBlankOrNull(value)) {&lt;br /&gt;   try {&lt;br /&gt;       if (invalidPasswordList.contains(value)) {&lt;br /&gt;           messages.add(field.getKey(),&lt;br /&gt;           Resources.getActionError(&lt;br /&gt;                           request,&lt;br /&gt;                           va,&lt;br /&gt;                           field));&lt;br /&gt;&lt;br /&gt;           return false;&lt;br /&gt;       }&lt;br /&gt;   } catch (Exception e) {&lt;br /&gt;       messages.add(field.getKey(),&lt;br /&gt;       Resources.getActionError(&lt;br /&gt;       request,&lt;br /&gt;       va,&lt;br /&gt;       field));&lt;br /&gt;       return false;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;That's it.&lt;br /&gt;&lt;b&gt;Roadblocks:&lt;/b&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;One of the problem I faced while working on this in eclipse + wtp that the class was not included in class path automatically. I have to stop server + Compile Clean + Publish + Restart the server for each change I made. I struggled with following exceptions. First was loadValidationActionClass method threw ValidatorException. This is because the my ValidationAction class i.e. CustomValidationUtility was not in classpath. I hoped that WTP will take care of this dynamically, but for some reason it didn't&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Second exception was regarding the parameter of my validation method, they have to exactly match as given in validation-rules.xml.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Third problem faced was whether to use ActionErrors or ActionMessages as parameter. There are numerous example out on the web for custom validator to use ActionErrors. It gave me NullPointerException. On debugging I found out that errors parameter in the method was null. I switched it to ActionMessages (which is parent class of ActionError) and it worked. (Of course, WTP made me do entire trip of stopping, cleaning, compiling, publishing, and starting)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Some other problems other people faced working on this (which I found out while google-ing): You have to be absolutely sure which version of Struts and commons validator you are using. Struts 1.1 goes with commons-validator 1.1 and Struts 1.2 goes with Commons-validator 1.3. People spent frustrating amount of effort to resolve error only to find out they have mismatched library.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Usage and/or Extension of above idea&lt;/b&gt;&lt;br /&gt;If developing commons validator based validation mechanism, above methods can be used to come up with specific validation for those fields which are going to used at multiple places. Advantages of such mechanism is it will save you from writing and debugging java script, can come up with architecture where you can validate it with databases - though approach needs to be well thought out and used sparingly.  (e.g. list of password could have been stored in database tables), comparison with other fields on the page. In such case, I believe that validate method in form should be put to use rather than generic validations. Also above mechanism for validation can be used when your validation is interdependent on multiple fields on the same form.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&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/19518284-5522788212508841255?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=z4S7CexiMSw:NnjrXiW6XYc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=z4S7CexiMSw:NnjrXiW6XYc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=z4S7CexiMSw:NnjrXiW6XYc:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=z4S7CexiMSw:NnjrXiW6XYc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=z4S7CexiMSw:NnjrXiW6XYc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/z4S7CexiMSw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/z4S7CexiMSw/struts-creating-custom-validator.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2007/07/struts-creating-custom-validator.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-115325260431370650</guid><pubDate>Tue, 18 Jul 2006 19:56:00 +0000</pubDate><atom:updated>2006-07-23T17:14:09.060-07:00</atom:updated><title>Problem with mapping Nested Objects using Struts</title><description>&lt;span style="font-family:trebuchet ms;"&gt;I was working on designing a specific requirement where UI was a four step wizard. User will provide information in this four pages and submit the information to be stored in database. The way information was organized on UI (jsp) was different than the way it needed to be represented in DTO (or domain objects).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;However, a good review pointed out that use of series of request.getParameter is not good idea. There must be good way to get the data map to Domain objects by using struts. If the data elements were linear ( not mapped and not indexed) Struts does map it quite well with ActionForm. You can use commons beanutils' BeanProperties.copyProperties(Object dest, Object source). But normally the object representation is not linear. Objects have association and multiplicity. (See simple example below)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;It seems there is a problem with struts, when it comes to populating action form when jsp contains nested beans (or for that matter indexed beans). It simply does not work. Howerver, using nested tag library, i was able to get the JSP displayed properly with correct parameter name. The problem occurs when i try to submit the JSP page. It throws IllegalArgumentException: No Bean specified. I think I am not doing anything wrong. But, not sure.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Here is what I am trying to do. I have a JSP page with customer information(name, phone, email and address) where address contains(addres1, address2, city, state and zipcode). For purpose of simplicity I have kept all parameters as String. (Couldn't figure out easy way to link files, so I just pasted here.)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;Address.java&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;package com.learning.struts.action;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;public class Address {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String address1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String address2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String city;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String state;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String zipcode;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getAddress1() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return address1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setAddress1(String address1) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.address1 = address1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getAddress2() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return address2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setAddress2(String address2) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.address2 = address2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getCity() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return city;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setCity(String city) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.city = city;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getState() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return state;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setState(String state) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.state = state;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getZipcode() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return zipcode;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setZipcode(String zipcode) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.zipcode = zipcode;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;CustomerDTO.java&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;package com.learning.struts.action;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;public class CustomerDTO implements java.io.Serializable{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String name;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String phone;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String email;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private Address address;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public Address getAddress() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return address;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setAddress(Address address) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.address = address;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getEmail() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return email;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setEmail(String email) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.email = email;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getName() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return name;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setName(String name) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.name = name;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getPhone() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return phone;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setPhone(String phone) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.phone = phone;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;code&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;code&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;strust-config.xml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1" ?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE struts-config PUBLIC&lt;br /&gt;"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"&lt;br /&gt;"http://struts.apache.org/dtds/struts-config_1_2.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;struts-config&amp;gt;&lt;br /&gt;&amp;lt;form-beans&amp;gt;&lt;br /&gt;&amp;lt;form-bean name="customerForm" type="org.apache.struts.action.DynaActionForm"&amp;gt;&lt;br /&gt;&amp;lt;form-property name="page" type="java.lang.String"/&amp;gt;&lt;br /&gt;&amp;lt;form-property name="customer" type="com.learning.struts.action.CustomerDTO"/&amp;gt;&lt;br /&gt;&amp;lt;/form-bean&amp;gt;&lt;br /&gt;&amp;lt;form-bean name="customerForm1" type="com.learning.struts.action.PageActionForm"&amp;gt;&lt;br /&gt;&amp;lt;form-property name="page" type="java.lang.String"/&amp;gt;&lt;br /&gt;&amp;lt;form-property name="customer" type="com.learning.struts.action.CustomerDTO"/&amp;gt;&lt;br /&gt;&amp;lt;/form-bean&amp;gt;&lt;br /&gt;&amp;lt;/form-beans&amp;gt;&lt;br /&gt;&amp;lt;global-forwards&amp;gt;&lt;br /&gt;&amp;lt;/global-forwards&amp;gt;&lt;br /&gt;&amp;lt;action-mappings&amp;gt;&lt;br /&gt;&amp;lt;action path="/submit"&lt;br /&gt;type="com.learning.struts.action.IndexedNestedFormStrutsAction"&lt;br /&gt;validate="false"&lt;br /&gt;input="customer-address1.jsp"&lt;br /&gt;name="customerForm1"&amp;gt;&lt;br /&gt;&amp;lt;forward name="success" path="/jsp/index.jsp"/&amp;gt;&lt;br /&gt;&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/action-mappings&amp;gt;&lt;br /&gt;&amp;lt;/struts-config&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;customer-address.jsp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;%@ page language="java" contentType="text/html; charset=ISO-8859-1"&lt;br /&gt;pageEncoding="ISO-8859-1"%&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested" %&amp;gt;&lt;br /&gt;&amp;lt;html:html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;html:form action="submit.do" method="post"&amp;gt;&lt;br /&gt;&amp;lt;html:hidden property="page" value="page-1"/&amp;gt;&lt;br /&gt;customer.name :&amp;lt;html:text property="customer.name" value="k"/&amp;gt;&lt;br /&gt;customer.phone: &amp;lt;/p&amp;gt;&amp;lt;html:text property="customer.phone" value="k"/&amp;gt;&lt;br /&gt;customer.email: &amp;lt;/p&amp;gt;&amp;lt;html:text property="customer.email" value="k"/&amp;gt;&lt;br /&gt;&amp;lt;nested:nest property="customer.address"&amp;gt;&lt;br /&gt;customer.address.address1: &amp;lt;/p&amp;gt;&amp;lt;nested:text property="address1" value="k" /&amp;gt;&lt;br /&gt;customer.address.address2: &amp;lt;/p&amp;gt;&amp;lt;nested:text property="address2"  value="k"/&amp;gt;&lt;br /&gt;customer.address.city: &amp;lt;/p&amp;gt;&amp;lt;nested:text  property="city" value="k" /&amp;gt;&lt;br /&gt;customer.address.state: &amp;lt;/p&amp;gt;&amp;lt;nested:text property="state" value="k" /&amp;gt;&lt;br /&gt;customer.address.zipcode: &amp;lt;/p&amp;gt;&amp;lt;nested:text property="zipcode" value="k" /&amp;gt;&lt;br /&gt;&amp;lt;/nested:nest&amp;gt;&lt;br /&gt;&amp;lt;html:submit&amp;gt;&amp;lt;/html:submit&amp;gt;&lt;br /&gt;&amp;lt;/html:form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html:html&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;action path="/submit"&gt;&lt;/action&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;font-size:85%;"  &gt;IndexedNestedFormStrutsAction.java&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;public class IndexedNestedFormStrutsAction extends Action {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;&lt;br /&gt;public ActionForward execute(ActionMapping map, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;        DynaActionForm daForm = (DynaActionForm)form;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;        CustomerDTO customer = (CustomerDTO)daForm.get("customer");&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;        System.out.println("Customer : " + customer);&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;        return map.findForward("success");&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;    }&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;On debugging this, it throws up folloing exception :&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;java.lang.IllegalArgumentException: No bean specified&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptor(PropertyUtilsBean.java:751)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:937)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:811)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:298)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:493)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:816)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;    at java.lang.Thread.run(Thread.java:595)&lt;/span&gt;&lt;/blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;But I thought that it may be problem with DynaActionForm so I created ActionForm derivative and try if it properly maps the nested bean. Here is the code for that:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;font-size:100%;"  &gt;PageActionFrom.java &lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;package com.learning.struts.action;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;import org.apache.struts.action.ActionForm;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;public class PageActionForm extends ActionForm {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private String page;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    private CustomerDTO customer;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public CustomerDTO getCustomer() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return customer;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setCustomer(CustomerDTO customer) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.customer = customer;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public String getPage() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        return page;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    public void setPage(String page) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;        this.page = page;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;But it does not work and though it generated the JSP correctly. When you do view source on generated html it will create proper dot notaion name for each input element. However, submitting and getting the values even inside ActionForm parameter of Action does not work. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;I did find out some open source project in works which are working to deal with this problem. But they are in still 0.x version. I think this is something struts should do automatically rather than any plugin framework. Please correct me if I am wrong.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-115325260431370650?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=vxfFKwoenUA:4pk8DGyYCCw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=vxfFKwoenUA:4pk8DGyYCCw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=vxfFKwoenUA:4pk8DGyYCCw:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=vxfFKwoenUA:4pk8DGyYCCw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=vxfFKwoenUA:4pk8DGyYCCw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/vxfFKwoenUA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/vxfFKwoenUA/problem-with-mapping-nested-objects.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2006/07/problem-with-mapping-nested-objects.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-115266375686522317</guid><pubDate>Wed, 12 Jul 2006 00:16:00 +0000</pubDate><atom:updated>2006-10-12T00:35:42.696-07:00</atom:updated><title>Random Thoughts: EJB3 Vs Spring</title><description>&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;Following are just my random thoughts. I am not trying to determine which one is better. I think it is pretty much decided that both are going co-exists.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Spring: IoC Container and Framework Library&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;I think it is good idea to understand Spring in two aspects. &lt;a&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul  style="font-family:trebuchet ms;"&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;First &lt;/span&gt;it is IoC container. This container is its core concepts. EJB as the SPEC is in direct competition. Question is: Do you want to use Spring IoC container or EJB Container?&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Second &lt;/span&gt;aspects of the Spring Framework is all the helper classes which makes the development so easy. Like JdbcTemplate, Hibernate helper classes, etc. EJB does not provide such classes. Those gaps are filled up by the JBoss Seam Framework and the like. You can use EJB Container and still use Spring Framework Libraries.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:trebuchet ms;"&gt;So along with Spring Vs EJB, it is also Spring vs JBoss Seam and the like. &lt;a&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Spring Not a Spec&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Spring, though opensource, is controlled by Interface 21, a commercial company. Interface 21 controls (atleast decides) what needs to be in next phase and hires programmer to do it. Don't get me wrong, I really like Spring. As a developer, it is really nice experience. How simple it makes to develop application and test it. But the fact remains that in the long run, we have to "wish" (or influence) that Interface 21 makes correct choices. Also remember that once we use spring we are using "tool specific classes and libraries" so we cannot decide to change it to different platform overnight.&lt;br /&gt;Even though it uses its own library. It is based on very sound design principle. Design by Interface. Framework actually builds on top of it to provide re-usable code. For example, never worrying about handling connections. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;With EJB, if you dont like a vendor you can still move to different vendor. If you dont like EJB at all depending upon your design you can still convert it to different technologies as there is not dependance on specific libraries. (Meaning dependency is there but on little higher level)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;EJBs dont provide that kind of framework. It does not provide you reusable classes library. It does not provide helper classes for sending email for different implemenations.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Will Spring remain light?&lt;a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;But with all these introduction in Spring, how light is spring or how light will spring remain. But the answer lies in its core design. Since the core concepts behind it is Design by Interface and Inversion of Control. It allows to selectively use areas which we require. You dont want to use MVC dont incldue that jar. If you only want to use with regards to JDBC operations, only use spring-jdbc.jar. It will stay light as much your requirements demand it to remain light.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;EJB: Market Availability&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Though it is too early to say how light is JEE. It is just out and there are really few implementations available. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;EJB still implements "Remote-ness"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;One difference between these two choices still exists, that EJB3 will still do remoting. Spring on the other hand does not do remoting by default. So decision has to be made what kind of architecture is required keeping in mind business application scenario. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Thoughts about RPC&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Also one thing to notice here is that RPC eventually will go out of fashion (IMHO). Ultimately, architectures like SOA where core concept is to exchange data rather than invoking behavior remotely. It is more loosely coupled, more reusable, and it also has advantage of platform independance.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Separating JPA out of EJB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;One good things EJB Spec3 has done has separated JPA out of EJB Spec.&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Again Hibernate will be JPA compliant in coming days. There are already articles floating around how to use Spring with JPA.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;What are the other benefits of EJB3? &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;Container Managed Persistence&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;If you are using Container Managed Persistence, it manages the state of entities. Meaning it calls update insert methods on its own. It has container managed persistence. Meaning you dont have to call your insert update delete. Container will manage that for you. This is a really good advantage. With Spring Framework, you still need to call specific  classes, SimpleJDBCTemplate.update, or session.update if you are using Hibernate. With EJB once configured with CMP, you dont do anything. You save that one method call. Calls will be made for you before and after business methods. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Message Driven Beans&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;With EJB Container you will have MessageDrivenBeans. i.e. you will have mechanisms to write consumers of Messages. With Spring you have to choose a separate provider for the same. Which gives you more flexibility. Spring delegates that work. Again principle on which spring is based: Do not re-write it if somebody is already doing it in good way. Rather than that just provide the loose interface and bunch of classes with re-usable code. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Clustering&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Benefits of clustering and are anyways provided by application server. Even for that matter Tomcat provides clustering now. You can still develop Spring application and deploy it in different clusters in Tomcat. You dont need EJB Container to have component level clustering.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Spring is already a winner it. It has made EJB people change the spec. EJB3 now looks less similar to EJB2 and more similar to Spring. They have almost every aspect which spring got it correct. Aspects are now Interceptors. (Though this was any ways used by EJB container provider in their implementations, no programmatic mechanisms were provided for Bean Developer though)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;XML vs Annotations&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;&lt;span style="font-weight: bold;"&gt;Transactions&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;With regards to Transaction declaration as Annotations. I must say, I like XML. No matter how much verbose. It is still good. Rather than my transaction strategy littered over code, i would like to have it one place/area. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;&lt;span style="font-weight: bold;"&gt;Security&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Dont let me wander in code to find out what security rules are implemented. Anyways, Spring has also come us with Annotations specific declarations allowing you to do quick and dirty work though. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Do we need IoC Container Spec?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Do we need a spec so other providers can come up with their own implementations of IoC container? Or have we already convoluted J2EE area with so many specifications and implementation? &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Preference&lt;a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Spring will work inside container and outside container. Spring is really great for small application because it is really easy to develop. With Spring 2.0's goal being easier XML Config files and allowing Annotations and its integration with AspectJ. Spring does have capability of using it in bits and pieces, meaning you may just use it in Middel Tier, you choose to use JMS features.  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;JEE spec will need a container. Also the choice depend upon the business case for which the application is getting developed. If the application is big in terms of scope or it is expected that it live long time while going multiple phase changes then I think it is better to stick with Standard Spec. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-115266375686522317?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=jyeEzkJhx3U:h9r92dJVHx0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=jyeEzkJhx3U:h9r92dJVHx0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=jyeEzkJhx3U:h9r92dJVHx0:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=jyeEzkJhx3U:h9r92dJVHx0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=jyeEzkJhx3U:h9r92dJVHx0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/jyeEzkJhx3U" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/jyeEzkJhx3U/random-thoughts-ejb3-vs-spring.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2006/07/random-thoughts-ejb3-vs-spring.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-115113029031974805</guid><pubDate>Sat, 24 Jun 2006 06:13:00 +0000</pubDate><atom:updated>2006-12-13T09:57:23.146-08:00</atom:updated><title>Thoughts: Open-Closed Principle</title><description>&lt;p&gt;&lt;span style="font-family:trebuchet ms;"&gt;Just read an article about &lt;/span&gt;&lt;a href="http://www.objectmentor.com/resources/articles/ocp.pdf"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Open Closed Principle&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;[pdf]. It is good revision and insight into object oriented principles.&lt;br /&gt;&lt;br /&gt;Very briefly, &lt;strong&gt;&lt;em&gt;Open Closed Principle says to design your class which are close for modification and open for extension. &lt;/em&gt;&lt;/strong&gt;As author suggests one way of doing this is to program to interfaces. So that the classes in design are closed for modification and open for extension.&lt;br /&gt;How to ensure that the class designed is closed for modification? Though author points out that you can't close the class entirely. What is the generic questions checklist that we need to go through to verify that the class is closed for modification.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Is the class close for modification due to change in business requirements? &lt;/strong&gt;&lt;br /&gt;Business requirements change over time. The question we need to ask while reviewing the design is that have we designed the class in manner that it is able to display some flexibility of handling the changed requirement by extending it and not by modifying it. Are the safeguards in place which prevents changing the classes?&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Will the changes in classes on which this class depends bring change in this class?&lt;/strong&gt;&lt;br /&gt;List down all classes which are used by the class under review. All the objects which are part of pre-condition for this class to operate.&lt;br /&gt;Determine that how close is the current class' design in order to accomodate changes in these classes.&lt;br /&gt;Key question: Are the contract between these classes defined by interfaces? (This leads to another principle of &lt;/span&gt;&lt;a href="http://www.objectmentor.com/resources/articles/dip.pdf"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Dependancy Inversion Principle&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;[pdf])&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Will the changes in the classes which depends on this class bring change in this class?&lt;/strong&gt;&lt;br /&gt;List down all the classes which will use the current class.&lt;br /&gt;Determine that how close is the current class' design in order to service the changing demands of these classes/objects.&lt;br /&gt;Key question: Is Contract between these classes defined by interfaces?&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Has design considered multiplicity requirements?&lt;/strong&gt;&lt;br /&gt;Lets say that sound contract exists between the classes on which the class depends and the classes which depends on this particular class.&lt;br /&gt;Determine the impact of change in cardinality requirement of contract. A class may play different role. Does this class play role of "creator" of objects, "worker" on objects and/or "delegator" to objects. The contract defined in interface does it cover scenarios like: what if this class needs to "create" more than one objects in future. Is this class close enough for modification and open enough for extension to allow to "work" on multiple objects.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Again I think all this questions needs to be asked keeping in mind the domain for which it is getting designed. This questions are subjective to functional area application is trying to solve.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-115113029031974805?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ZybPl-bqIGg:ZCZCqauNvDU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ZybPl-bqIGg:ZCZCqauNvDU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ZybPl-bqIGg:ZCZCqauNvDU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ZybPl-bqIGg:ZCZCqauNvDU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=ZybPl-bqIGg:ZCZCqauNvDU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/ZybPl-bqIGg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/ZybPl-bqIGg/thoughts-open-closed-principle.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2006/06/thoughts-open-closed-principle.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-114069171217351831</guid><pubDate>Thu, 23 Feb 2006 10:32:00 +0000</pubDate><atom:updated>2006-02-23T03:16:25.453-08:00</atom:updated><title>Configuring Subversion with Netbeans</title><description>&lt;strong&gt;Configure Subversion with Netbeans&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Step 1: Download Subversion profile from site &lt;a href="http://vcsgeneric.netbeans.org/profiles/index.html"&gt;http://vcsgeneric.netbeans.org/profiles/index.html&lt;/a&gt;&lt;br /&gt;I configured it with Netbeans 4.1. The site also have profiles for other version of netbeans.&lt;br /&gt;&lt;br /&gt;Step 2: Open Netbeans&lt;br /&gt;&lt;br /&gt;Step 3: Click on Tools --&gt; Update Center&lt;br /&gt;&lt;br /&gt;Step 4: Select Install Manually downloaded Modules (.nbm Files)&lt;br /&gt;&lt;br /&gt;Step 5: Click on Add and select the file that you downloaded. Finish the Wizard&lt;br /&gt;&lt;br /&gt;Step 6: Click on Versioning --&gt; Versioning Manager. In this popup add the working directory of the project and repository URL for Subversion. For instance I added c:\projects\projectname\src and repository as &lt;a href="file:////svn"&gt;file:////svn&lt;/a&gt; ( mapped to c:\svn, if working on windows environment)&lt;br /&gt;&lt;br /&gt;Step 7: Done. Now you can right click the project and view the files and status for the same.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-114069171217351831?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=umemBicHQ2I:nzBBqKlXqIs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=umemBicHQ2I:nzBBqKlXqIs:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=umemBicHQ2I:nzBBqKlXqIs:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=umemBicHQ2I:nzBBqKlXqIs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=umemBicHQ2I:nzBBqKlXqIs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/umemBicHQ2I" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/umemBicHQ2I/configuring-subversion-with-netbeans.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2006/02/configuring-subversion-with-netbeans.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-114051887528220835</guid><pubDate>Tue, 21 Feb 2006 10:37:00 +0000</pubDate><atom:updated>2006-07-05T00:01:09.200-07:00</atom:updated><title>Properties file or XML File</title><description>While working on Java Projects we usually come to question whether to use properties file or to use XML files for reading configuration information.&lt;br /&gt;&lt;br /&gt;Before we consider what solution should be used, first let's see what kind of the configuration data is involved.&lt;br /&gt;&lt;br /&gt;Configuration data are range from simpler items like server urls, schema name, database environment, mailing servers, etc. This kind of data can be classified as name=value pair. No relationship or hierarchy exist between them.&lt;br /&gt;&lt;br /&gt;The other cases of configuration data that might be used within project contains relationship within data elements. One of the example of such data is struts-config.xml. For this kind of data they will be more or less stored as Java Objects.&lt;br /&gt;&lt;br /&gt;Once we made the classification decision is simple.&lt;br /&gt;&lt;br /&gt;Use properties file for configuration data which is flat in nature. Data elements does not contain any relationship or hierarchy. Using XML file to store will involve parsing overhead without any significant advantage.&lt;br /&gt;&lt;br /&gt;XML file usage is justified only when we are going to create Java Objects out of config data elements having relationship between them.&lt;br /&gt;&lt;br /&gt;One of the pitfalls using XML file to store config file is to go on overkill and start integrating logic in XML tags. Make sure that it is only config data and you are not actually programming in XML.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-114051887528220835?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ToZ8NRoRM-8:KLWErYcHzYQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ToZ8NRoRM-8:KLWErYcHzYQ:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ToZ8NRoRM-8:KLWErYcHzYQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=ToZ8NRoRM-8:KLWErYcHzYQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=ToZ8NRoRM-8:KLWErYcHzYQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/ToZ8NRoRM-8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/ToZ8NRoRM-8/properties-file-or-xml-file.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2006/02/properties-file-or-xml-file.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-113353910714941947</guid><pubDate>Fri, 02 Dec 2005 15:56:00 +0000</pubDate><atom:updated>2005-12-02T07:58:53.680-08:00</atom:updated><title>Sun Open sourcing JES</title><description>Sun has open sourced JES (Java Enterprise System) including Java application server platform and identity manager suite.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19518284-113353910714941947?l=kartik-shah.blogspot.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=d0LtiHBNL1k:-Mvp-nOq-aY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=d0LtiHBNL1k:-Mvp-nOq-aY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=d0LtiHBNL1k:-Mvp-nOq-aY:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/kartikshah?a=d0LtiHBNL1k:-Mvp-nOq-aY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/kartikshah?i=d0LtiHBNL1k:-Mvp-nOq-aY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/kartikshah/~4/d0LtiHBNL1k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/kartikshah/~3/d0LtiHBNL1k/sun-open-sourcing-jes.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://kartik-shah.blogspot.com/2005/12/sun-open-sourcing-jes.html</feedburner:origLink></item></channel></rss>
