<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8852543472291091913</id><updated>2011-12-22T05:32:45.116-06:00</updated><category term='Sound Processing'/><category term='Flex'/><category term='Java'/><category term='Web Programming'/><category term='Music'/><title type='text'>Software Everything</title><subtitle type='html'>General software engineering and related programming techniques and information.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-2159002951177426590</id><published>2011-12-20T09:37:00.001-06:00</published><updated>2011-12-20T09:37:22.389-06:00</updated><title type='text'>Upgrading JBoss 4 to JBoss 5 with Java 5 to Java 6</title><content type='html'>&lt;p&gt;The information presented here comes from an effort to upgrade a Java enterprise application to the most current versions of all of its parts; primarily to get onto Java 6. Its starting system specifications were the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;JBoss 4.2.2&lt;/li&gt;    &lt;li&gt;Java 1.5.0_27&lt;/li&gt;    &lt;li&gt;SEAM 2.1.0&lt;/li&gt;    &lt;li&gt;RichFaces 3.3.1&lt;/li&gt;    &lt;li&gt;JSF 1.2&lt;/li&gt;    &lt;li&gt;EJB 3.0&lt;/li&gt;    &lt;li&gt;Remote EJB’s&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For reasons that will be explained in detail, it was not possible to upgrade each of the system parts to their various current versions. The end result was the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;JBoss 5.1.0&lt;/li&gt;    &lt;li&gt;Java 1.6.0_27&lt;/li&gt;    &lt;li&gt;SEAM 2.2.2&lt;/li&gt;    &lt;li&gt;RichFaces 3.3.3&lt;/li&gt;    &lt;li&gt;JSF 1.2&lt;/li&gt;    &lt;li&gt;EJB 3.0&lt;/li&gt;    &lt;li&gt;Remote EJB’s&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Due to the size and scope of the enterprise application itself in combination with the incompatibilities between system components, the entire effort ended up taking me a long time. The following is a log of this endeavor with all of the errors I encountered and how they were resolved. The intention of this writing is for both a historical purpose, and to help others avoid the pitfalls of performing such an upgrade on a sufficiently large enterprise application.&lt;/p&gt;  &lt;h3&gt;Why didn’t it just work out of the box with Java 6?&lt;/h3&gt;  &lt;p&gt;JBoss 4.2.2 Web Services do not work with Java 1.6. It results in a runtime error with SOAP. This means in order to run with Java 6 we have to upgrade JBoss. &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;What about JBoss 7.0?&lt;/h3&gt;  &lt;p&gt;The configuration is so different that it in no way resembles any previous version, and it does not support Remote EJB’s. &lt;/p&gt;  &lt;p&gt;Remote EJB invocations isn't currently available in AS 7.0. That will be implemented by AS 7.1.   &lt;br /&gt;(&lt;a href="http://community.jboss.org/message/616635)"&gt;http://community.jboss.org/message/616635)&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;So, how about JBoss 6.1.0?&lt;/h3&gt;  &lt;p&gt;JBoss 6 supports Java 6, SEAM, RichFaces, JSF, EJB 3.0, and remote EJB’s. The question is now what versions of these will work? &lt;/p&gt;  &lt;h3&gt;What about RichFaces 4?&lt;/h3&gt;  &lt;p&gt;Yes, it works but with JBoss 6.1.0 and JSF 2.0. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://docs.jboss.org/richfaces/latest_4_0_X/Developer_Guide/en-US/html/chap-Developer_Guide-RichFaces_overview.html"&gt;http://docs.jboss.org/richfaces/latest_4_0_X/Developer_Guide/en-US/html/chap-Developer_Guide-RichFaces_overview.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;RichFaces supports the following JSF implementations and frameworks:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MyFaces 2 and higher&lt;/li&gt;    &lt;li&gt;Seam 3 and higher&lt;/li&gt;    &lt;li&gt;Mojara 2 and higher&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;So looks like you have to upgrade to SEAM 3&lt;/h3&gt;  &lt;p&gt;Thus far we have JBoss 6.1.0, RichFaces 4.0.0, and JSF 2.0. SEAM 3 has apparently changed everything, and is not backward compatible with a SEAM 2 configuration. I was never able to even get “Hello World” working with SEAM 3, which is to be expected since it is “not done” (&lt;a href="http://seamframework.org/157223.lace)"&gt;http://seamframework.org/157223.lace)&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;While according to compatibility it is supposed to work with JBoss 6 (&lt;a href="http://seamframework.org/Seam3/Compatibility)"&gt;http://seamframework.org/Seam3/Compatibility)&lt;/a&gt;, I again haven’t been able to get even the most simple example working. &lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Back to SEAM 2&lt;/h3&gt;  &lt;p&gt;Since SEAM 3 does not work we have no choice but to go back to SEAM 2. RichFaces requires JSF 2.0 and in its specification says it only works with SEAM 3. While I question how one could know that RichFaces 4 only works with SEAM 3 when no one to my knowledge has a working example on JBoss 6, the goal is to upgrade to Java 6. There is also some unspecified hack to get SEAM 2 working with JSF 2, but any type of hack would probably make upgrading harder in the future. Okay, back to to RichFaces 3. &lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Back to RichFaces 3, how about 3.3.3?&lt;/h3&gt;  &lt;p&gt;Sorry no, not on JBoss 6: &lt;a href="http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html_single/#SupportedServers"&gt;http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html_single/#SupportedServers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;JBoss 6 isn’t even listed as a supported server, and in my experience I haven’t been able to find anyone able to get RichFaces 3 working under JSF 1.2 or 2.0 on JBoss 6. I haven’t been able to get a “Hello World” working either. &lt;/p&gt;  &lt;p&gt;Wait, where are we now?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We can’t use SEAM 3 because it doesn’t work (or at least the community can’t get it to work) on JBoss 6&lt;/li&gt;    &lt;li&gt;We can’t use RichFaces 4 because it requires JSF 2 and SEAM 2 requires JSF 1.2&lt;/li&gt;    &lt;li&gt;RichFaces 3 isn’t supported (and won’t run apparently) on JBoss 6&lt;/li&gt;    &lt;li&gt;Finally, was can’t use JBoss 6 because SEAM 2 doesn’t support it (&lt;a href="http://seamframework.org/Seam2/GettingStarted)"&gt;http://seamframework.org/Seam2/GettingStarted)&lt;/a&gt;, and of course RichFaces 3 doesn’t work with it either&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;JBoss 5.1.0, Hello World&lt;/h3&gt;  &lt;p&gt;On paper RichFaces 3 and SEAM 2 work on JBoss 5, and JBoss 5 can run on Java 6. Take into account though the same is true for RichFaces 4, JSF 2, SEAM 3, and Remote EJB’s on JBoss 6. While an example exists for RichFaces 3 + SEAM 2 on JBoss, it of course doesn’t work out of the box on JBoss 5. &lt;/p&gt;  &lt;p&gt;As a starting point I used Eclipse 3.7 (Indigo), JBoss Tools 3.3.3 (&lt;a href="http://www.jboss.org/tools/download/installation/update_3_3)"&gt;http://www.jboss.org/tools/download/installation/update_3_3)&lt;/a&gt;, and Seam 2.2.2 (&lt;a href="http://seamframework.org/Seam2/Downloads)"&gt;http://seamframework.org/Seam2/Downloads)&lt;/a&gt;. JBoss Tools has a “Create Seam Web Project wizard,” so it should work right out of the box, right? &lt;/p&gt;  &lt;p&gt;First, you have to rename jboss-seam-2.2.2.jar to jboss-seam.jar in the seam-2.2.2/lib installation. This is because if you don’t the SEAM wizard won’t allow you to select where you put SEAM because it looks for the JAR of this name. &lt;/p&gt;  &lt;p&gt;Second, RichFaces component will not work out of the box. If you try to use something like a calendar or a TabPanel you will get this message:    &lt;br /&gt;&lt;font face="Courier New"&gt;Resources framework is not initialised, check web.xml for Filter configuration&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Not too hard; add this to the web.xml:   &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;lt;filter&amp;gt;     &lt;br /&gt; &amp;lt;display-name&amp;gt;Ajax4jsf Filter&amp;lt;/display-name&amp;gt;      &lt;br /&gt; &amp;lt;filter-name&amp;gt;ajax4jsf&amp;lt;/filter-name&amp;gt;      &lt;br /&gt; &amp;lt;filter-class&amp;gt;org.ajax4jsf.Filter&amp;lt;/filter-class&amp;gt;      &lt;br /&gt; &amp;lt;/filter&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;filter-mapping&amp;gt;      &lt;br /&gt; &amp;lt;filter-name&amp;gt;ajax4jsf&amp;lt;/filter-name&amp;gt;      &lt;br /&gt; &amp;lt;url-pattern&amp;gt;*.seam&amp;lt;/url-pattern&amp;gt;      &lt;br /&gt; &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;      &lt;br /&gt; &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;      &lt;br /&gt; &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;      &lt;br /&gt; &amp;lt;/filter-mapping&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Third, there are all sorts of problems with .xhtml files:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;layout/template.xhtml - Delete anything referencing authentication&lt;/li&gt;    &lt;li&gt;layout/menu.xhtml - Delete the content of the toolBarGroup &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Fourth, you have to delete the xerces and xml-apis jars out of the lib directory. These are in JBoss now.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;EARs containing Beans and WARs with shared libraries in the root of the EAR&lt;/h3&gt;  &lt;p&gt;A detail of the project I am converting is that it contains several WAR files, in which the library dependencies reside in the root level of the EAR, instead of the WEB-INF/lib directories of the WARs. &lt;/p&gt;  &lt;p&gt;There are a couple of interesting side-effects of this type of structure on JBoss 5:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The app no longer runs in Eclipse, because the libraries don’t actually reside in the root directory of the deployment&lt;/li&gt;    &lt;li&gt;Having these dependencies in the root of the EAR interferes with the admin-console deployment. There are several ways of dealing with this, but the easiest is just to remove it from deploy. (&lt;a href="https://issues.jboss.org/browse/JBAS-7032)"&gt;https://issues.jboss.org/browse/JBAS-7032)&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In terms of getting this configuration to work in Eclipse, you only would have to automatically copy the JAR files to the root of the deployment. The deployment assembly settings right? No. When they work, they only copy a few files. The files they choose to copy whether you use a filterset or add each one manually are seemingly random. &lt;/p&gt;  &lt;p&gt;How about a custom builder within Eclipse to copy the files? The JBoss server in eclipse deploys to a dynamic location within .metadata\.plugins\org.jboss.ide.eclipse.as.core within your workspace, so you would need to access it through an environment variable if you were trying to create custom builder. Is there an environment variable like ${jboss_config}? There would have to be but good look figuring it out. &lt;/p&gt;  &lt;p&gt;In order to have JBoss in a predictable place, you can modify the server settings by double-clicking on the JBoss Server in the service view, selecting the Deployment tab, and making it deploy to a custom location (&lt;a href="http://community.jboss.org/message/564310)"&gt;http://community.jboss.org/message/564310)&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Since you don’t want your Eclipse version of your EAR messing with your manually deployed one, it is best to create a second server/YOUR_PROJECT deployment directory which is a copy of the default minus deploy/admin-console. You also have to make sure to modify the JBoss runtime configuration to NOT use the default configuration, and to use the one you just created. &lt;/p&gt;  &lt;p&gt;For example under&amp;#160; JBoss Runtime Configuration -&amp;gt; Open Launch Configuration::   &lt;br /&gt;--configuration=eclipse&amp;#160; -b localhost&amp;#160; -Djboss.server.base.url=file:/C:/Java/jboss-5.1.0.GA/server/&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;The story of our app...&lt;/h3&gt;  &lt;p&gt;Jars over, application.xml changed, JBoss properties-service.xml changed to use environment.properties, build changed to use Java 6 and the JBoss 5 libraries, Eclipse project modified to compile using all the new libraries, and all of the other modifications made according to “Hello World”. It should deploy just fine right?&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #1: Error installing to PostClassLoader&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;[org.jboss.kernel.plugins.dependency.AbstractKernelController] (main) Error installing to PostClassLoader: name=vfsfile:/C:/Java/jboss-5.1.0.GA/server/myapp/deploy/MyApp.ear/ state=ClassLoader mode=Manual requiredState=PostClassLoader     &lt;br /&gt;org.jboss.deployers.spi.DeploymentException: Error during deploy: vfszip:/C:/Java/jboss-5.1.0.GA/server/myapp/deploy/MyApp.ear/account-application.jar/      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at org.jboss.deployers.spi.DeploymentException.rethrowAsDeploymentException(DeploymentException.java:49)      &lt;br /&gt;…      &lt;br /&gt;Caused by: java.lang.NullPointerException      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at java.lang.Class.forName0(Native Method)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at java.lang.Class.forName(Class.java:247)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at org.jboss.metadata.process.processor.ejb.jboss.SetDefaultLocalBusinessInterfaceProcessor.process(SetDefaultLocalBusinessInterfaceProcessor.java:114)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at org.jboss.metadata.process.chain.ejb.jboss.JBossMetaDataProcessorChain.process(JBossMetaDataProcessorChain.java:115)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at org.jboss.ejb3.deployers.Ejb3MetadataProcessingDeployer.deploy(Ejb3MetadataProcessingDeployer.java:115)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Possibilities:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A problem with the version declared in the ejb-jar.xml: &lt;a href="https://issues.jboss.org/browse/EJBTHREE-1976"&gt;https://issues.jboss.org/browse/EJBTHREE-1976&lt;/a&gt;. Nope, version is 3.0 in the HelloWorld as well&lt;/li&gt;    &lt;li&gt;The jboss.xml could be referencing a bean that is a pojo (&lt;a href="https://issues.jboss.org/browse/JBMETA-195)"&gt;https://issues.jboss.org/browse/JBMETA-195)&lt;/a&gt;. While commenting out the beans got the deployment farther, it didn’t get rid of this error. This indicates this is a problem with something else.&lt;/li&gt;    &lt;li&gt;EJB’s with zero parameters: &lt;a href="https://issues.jboss.org/browse/JBMETA-207"&gt;https://issues.jboss.org/browse/JBMETA-207&lt;/a&gt;. This seems pretty likely since the version of JBoss listed is 5.1.0 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This stack trace is pretty useless, and the only matches for any part of it on the internet are to those two JIRA issues. Resorting to just a “how to go from JBoss 4 to 5” search:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Persitence.xml and ejb-jar.xml must validate, remove xalan.jar, xercesImpl.jar, serializer.jar, xml-apis.jar from the application. (&lt;a href="http://community.jboss.org/wiki/MigrationFromJBoss4)"&gt;http://community.jboss.org/wiki/MigrationFromJBoss4)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;There are numerous guides relating to this; too many to list&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Nothing works, now what?&lt;/h3&gt;  &lt;p&gt;An issue with all these guides though is that they are for applications most likely smaller than the one we are upgrading. Sticking will all the advice still doesn’t have an effect on this startup error. The next resort is to break our application, which currently sits as one big Java project that can only be run by ant build and deploy, into its component pieces and get them working one at a time. Starting with the EJB that contains all the Java code that is causing this error. &lt;/p&gt;  &lt;p&gt;Our project’s directory structure is the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Application&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;src (EJB)&lt;/li&gt;      &lt;li&gt;ear&lt;/li&gt;      &lt;li&gt;WebEar&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Application WAR #1&lt;/li&gt;        &lt;li&gt;Application WAR #2&lt;/li&gt;        &lt;li&gt;Application WAR #3&lt;/li&gt;        &lt;li&gt;Application WAR #4&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;lib &lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;I have experimented with running this configuration out of Eclipse, and while it is possible the configuration is extremely complicated. I however also like to avoid developer setup documents which are 10 pages long, so sometimes the path of least resistance is the best way to go. &lt;/p&gt;  &lt;p&gt;The advantage of being able to run out of Eclipse is that you don’t have to Ant build, deploy it, and startup JBoss every time you want to see a change. A different project structure also lets things be broken apart and tested more easily, because they don’t rely on you having to modify an already complicated Ant build. &lt;/p&gt;  &lt;p&gt;The idea is that like “Hello World,” a project that we can get running easily in Eclipse should be in this project directory structure:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Application EAR (Enterprise Application Project)&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;lib&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Application Bean (EJB Project with no client)&lt;/li&gt;    &lt;li&gt;Application WAR #1 (Dynamic Web Project)&lt;/li&gt;    &lt;li&gt;Application WAR #2 (Dynamic Web Project)&lt;/li&gt;    &lt;li&gt;Application WAR #3 (Dynamic Web Project)&lt;/li&gt;    &lt;li&gt;Application WAR #4 (Dynamic Web Project) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The reliance on the Eclipse project wizards results in projects that run in Eclipse out-of-the-box. &lt;/p&gt;  &lt;p&gt;Checklist&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;EAR deploys with Bean&lt;/li&gt;    &lt;li&gt;EAR deploys with Bean and application.xml contains all of the needed libraries&lt;/li&gt;    &lt;li&gt;EAR deploys with Bean, libraries, and data sources&lt;/li&gt;    &lt;li&gt;Error: EAR deploys with Bean, libraries, data sources, and messaging config&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Error #2: Queue[/queue/myapp/bulkMessageQueue&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;ERROR [ExceptionUtil] Queue[/queue/myapp/bulkMessageQueue, name=myapp/bulkMessageQueue] startService     &lt;br /&gt;javax.naming.NameNotFoundException: myapp not bound&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The issue is that JMS configuration has changed between 4 and 5: &lt;a href="http://javabeanz.wordpress.com/2009/06/05/configuring-jms-in-jboss-5/"&gt;http://javabeanz.wordpress.com/2009/06/05/configuring-jms-in-jboss-5/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For myapp-jms-service.xml: &lt;/p&gt;  &lt;p&gt;JBoss 4:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;mbean code=&amp;quot;org.jboss.mq.server.jmx.Queue&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; name=&amp;quot;jboss.mq.destination:service=Queue,name=myapp/bulkMessageQueue&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;depends optional-attribute-name=&amp;quot;DestinationManager&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; jboss.mq:service=DestinationManager        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/depends&amp;gt;        &lt;br /&gt;&amp;lt;/mbean&amp;gt; &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;JBoss 5:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;mbean code=&amp;quot;org.jboss.jms.server.destination.QueueService&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name=&amp;quot;jboss.messaging.destination:service=Queue,name=myapp/bulkMessageQueue&amp;quot;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; xmbean-dd=&amp;quot;xmdesc/Queue-xmbean.xml&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;depends optional-attribute-name=&amp;quot;ServerPeer&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; jboss.messaging:service=ServerPeer        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/depends&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;depends&amp;gt;jboss.mq:service=DestinationManager&amp;lt;/depends&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;attribute name=&amp;quot;JNDIName&amp;quot;&amp;gt;queue/myapp/bulkMessageQueue&amp;lt;/attribute&amp;gt;        &lt;br /&gt;&amp;lt;/mbean&amp;gt; &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Back to the checklist:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;EAR deploys with Bean, libraries, data sources, messaging config, and mail config     &lt;br /&gt;… and the Seam interceptors in the ejb-jar.xml&lt;/li&gt;    &lt;li&gt;ERROR: … add all the source code for the bean&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Back to ERROR #1: Error installing to PostClassLoader&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;org.jboss.kernel.plugins.dependency.AbstractKernelController] (main) Error installing to PostClassLoader: name=vfsfile:/C:/Java/jboss-5.1.0.GA/server/myapp/deploy/MyApp.ear/ state=ClassLoader mode=Manual requiredState=PostClassLoader&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;We now know that this error has something to to with one or more of the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Java source - Can’t really remove this&lt;/li&gt;    &lt;li&gt;jboss.xml - Removing this gets rid of the error&lt;/li&gt;    &lt;li&gt;ehcache.xml&lt;/li&gt;    &lt;li&gt;persistence-container.xml&lt;/li&gt;    &lt;li&gt;The WSDL files &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ding, ding, ding! Something is wrong with the jboss.xml &lt;/p&gt;  &lt;p&gt;jboss.xml looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;jboss&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;enterprise-beans&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- Actions --&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;session&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ejb-name&amp;gt;BasketActionImpl&amp;lt;/ejb-name&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;jndi-name&amp;gt;&amp;lt;/jndi-name&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;clustered&amp;gt;false&amp;lt;/clustered&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/session&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;session&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ejb-name&amp;gt;ContractPricingActionImpl&amp;lt;/ejb-name&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;clustered&amp;gt;false&amp;lt;/clustered&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/session&amp;gt;        &lt;br /&gt;... &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The presence of one or more of those beans is what is causing the error. A cursory look has also revealed that several of the beans here don’t exist. I eventually found out that the reason for the failures was related to ejb-name classes that don’t exist. After removing classes (one at a time) jboss was able to launch with this configuration. Note though that removing the clustering settings causes error #12.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;ERROR #3: Can't find a persistence unit &lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;org.jboss.deployers.spi.DeploymentException: Error deploying MyEJB.jar: Exception while processing container metadata for EJB: DBServiceImpl in unit: MyEJB.jar     &lt;br /&gt;…      &lt;br /&gt;Caused by: java.lang.IllegalArgumentException: Can't find a persistence unit named 'MyPu' in AbstractVFSDeploymentContext@31521104{vfsfile:/C:/Java/jboss-5.1.0.GA/server/eclipse/deploy/MyApp.ear/MyEJBjar/}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;There is obviously a problem with the persistence-container.xml, as it is the one that defines the datasource which cannot be found. According to the thread at &lt;a href="http://community.jboss.org/thread/146523"&gt;http://community.jboss.org/thread/146523&lt;/a&gt;, there are a couple different ways to deal with persistence.xml. Note that is is always referred to as “persistence.xml”. If you change the name of the this XML file to persistence.xml, it works. This is an indication that JBoss 5 wants your persistence unit to be defined in persistence.xml by default. &lt;/p&gt;  &lt;p&gt;Back to the checklist:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;...and WAR #1 with a relatively empty configuration&lt;/li&gt;    &lt;li&gt;ERROR: ...and WAR #1 with RichFaces and SEAM in the configuration from Hello World&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Error #4: NoClassDefFoundError: org/jboss/resteasy/specimpl/UriInfoImpl &lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;java.lang.ClassNotFoundException: javax.ws.rs.ext.Provider     &lt;br /&gt;java.lang.NoClassDefFoundError: org/jboss/resteasy/specimpl/UriInfoImpl&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;This is because of the inclusion of jboss-seam-resteasy-2.2.2.jar, which does not include the REST Easy dependencies. This can just be removed from the application.xml.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #5: Server cycles between deploying and undeploying &lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;2011-10-17 12:14:03,137 INFO&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) deploy, ctxPath=/account     &lt;br /&gt;2011-10-17 12:14:03,199 INFO&amp;#160; [org.apache.catalina.startup.ContextConfig] (HDScanner) WARNING: Security role name NONE used in an &amp;lt;auth-constraint&amp;gt; without being defined in a &amp;lt;security-role&amp;gt;      &lt;br /&gt;2011-10-17 12:14:03,215 INFO&amp;#160; [javax.enterprise.resource.webcontainer.jsf.config] (HDScanner) Initializing Mojarra (1.2_12-b01-FCS) for context '/account'      &lt;br /&gt;2011-10-17 12:14:05,324 INFO&amp;#160; [javax.servlet.ServletContextListener] (HDScanner) Welcome to Seam 2.2.2.Final      &lt;br /&gt;2011-10-17 12:14:09,434 WARN&amp;#160; [org.jboss.seam.security.permission.PersistentPermissionResolver] (HDScanner) no permission store available - please install a PermissionStore with the name 'org.jboss.seam.security.jpaPermissionStore' if persistent permissions are required.      &lt;br /&gt;2011-10-17 12:14:09,621 INFO&amp;#160; [org.quartz.simpl.SimpleThreadPool] (HDScanner) Job execution threads will use class loader of thread: HDScanner      &lt;br /&gt;2011-10-17 12:14:09,637 INFO&amp;#160; [org.quartz.core.QuartzScheduler] (HDScanner) Quartz Scheduler v.1.5.2 created.      &lt;br /&gt;2011-10-17 12:14:09,637 INFO&amp;#160; [org.quartz.simpl.RAMJobStore] (HDScanner) RAMJobStore initialized.      &lt;br /&gt;2011-10-17 12:14:09,637 INFO&amp;#160; [org.quartz.impl.StdSchedulerFactory] (HDScanner) Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'      &lt;br /&gt;2011-10-17 12:14:09,637 INFO&amp;#160; [org.quartz.impl.StdSchedulerFactory] (HDScanner) Quartz scheduler version: 1.5.2      &lt;br /&gt;2011-10-17 12:14:09,637 INFO&amp;#160; [org.quartz.core.QuartzScheduler] (HDScanner) Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.      &lt;br /&gt;2011-10-17 12:14:09,902 WARN&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) Failed to setup clustering, clustering disabled. NoClassDefFoundError: org/jboss/cache/pojo/jmx/PojoCacheJmxWrapperMBean      &lt;br /&gt;2011-10-17 12:14:20,871 INFO&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) undeploy, ctxPath=/account &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;I encountered this issue earlier and just blamed it on Eclipse, but closer attention to the logs reveals there is a missing class. This JAR can be downloaded here: &lt;a href="http://www.java2s.com/Code/Jar/JKL/Downloadpojocachejar.htm"&gt;http://www.java2s.com/Code/Jar/JKL/Downloadpojocachejar.htm&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Followed by:   &lt;br /&gt;2011-10-17 13:15:05,809 WARN&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (main) Failed to setup clustering, clustering disabled. NoClassDefFoundError: org/jboss/cache/jmx/LifeCycle &lt;/p&gt;  &lt;p&gt;Apparently life has moved on past JBoss Cache, &lt;a href="http://community.jboss.org/wiki/JBossCache"&gt;http://community.jboss.org/wiki/JBossCache&lt;/a&gt;, but you can get jbosscache here: &lt;a href="http://www.java2s.com/Code/Jar/JKL/Downloadjbosscachejar.htm"&gt;http://www.java2s.com/Code/Jar/JKL/Downloadjbosscachejar.htm&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Followed by:   &lt;br /&gt;2011-10-17 13:23:37,277 WARN&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (main) Failed to setup clustering, clustering disabled. NoClassDefFoundError: org/jboss/cache/CacheManager &lt;/p&gt;  &lt;p&gt;The JAR can be downloaded here: &lt;a href="http://www.java2s.com/Code/Jar/JKL/Downloadjbosscachecorejar.htm"&gt;http://www.java2s.com/Code/Jar/JKL/Downloadjbosscachecorejar.htm&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Followed By:   &lt;br /&gt;2011-10-17 14:14:10,356 WARN&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (main) Failed to setup clustering, clustering disabled. NoClassDefFoundError: org/jgroups/blocks/MethodCall &lt;/p&gt;  &lt;p&gt;jgroups.jar, which can be obtained in the JBoss Cache release. &lt;/p&gt;  &lt;p&gt;Followed by:   &lt;br /&gt;2011-10-17 13:34:08,809 WARN&amp;#160; [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (main) Failed to setup clustering, clustering disabled. ClusteringNotSupportedException: Could not access CacheManager for JBossWeb clustering &lt;/p&gt;  &lt;p&gt;At this point I am baffled, as there are not any other obvious signs of why JBoss decided it doesn’t like this context and undeploys it. The message “Could not access CacheManager for JBossWeb clustering” on Google only points to the source code from where it came, so I am either way off or this is not related. &lt;/p&gt;  &lt;p&gt;Upon further research, these messages have nothing to do with the undeploy. There is a majorly annoying bug in all of JBoss 5: &lt;a href="http://stackoverflow.com/questions/1451614/jboss-deploy-undeploy-loop-caused-by-hdscanner-in-a-exploded-ear"&gt;http://stackoverflow.com/questions/1451614/jboss-deploy-undeploy-loop-caused-by-hdscanner-in-a-exploded-ear&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You pretty much can’t have anything but .xml files in your WAR WEB-INF directory. Removing a .jpg from here resolved this issue.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #6: SEAM Actions don’t resolve&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;2011-10-17 15:08:59,774 WARN&amp;#160; [org.jboss.ejb3.interceptors.aop.InterceptorsFactory] (http-localhost%2F127.0.0.1-8080-1) EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container     &lt;br /&gt;2011-10-17 15:08:59,805 WARN&amp;#160; [org.jboss.ejb3.interceptors.aop.InterceptorsFactory] (http-localhost%2F127.0.0.1-8080-1) EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container      &lt;br /&gt;2011-10-17 15:09:13,555 WARN&amp;#160; [org.jboss.seam.security.jaas.SeamLoginModule] (http-localhost%2F127.0.0.1-8080-2) Error invoking login method      &lt;br /&gt;javax.el.PropertyNotFoundException: Target Unreachable, identifier 'loginAction' resolved to null &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Apparently there is a problem with the SEAM security configuration, which is what controls login. This is to be expected since security changed in SEAM 2.2.2: &lt;a href="http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5/html/Seam_Reference_Guide/Migration20.Changes.html"&gt;http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5/html/Seam_Reference_Guide/Migration20.Changes.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There is also of course different XSD’s now available, which require that you change all the -2.1.xsd’s to 2.2.xsd’s. &lt;/p&gt;  &lt;p&gt;The following post indicates that the problem may be that the class inside the JAR within the EAR is not being picked up by SEAM, because there is no seam.properties files in the JAR: &lt;a href="http://stackoverflow.com/questions/3978976/can-the-seam-authenticator-reside-in-the-ear-file-lib-folder"&gt;http://stackoverflow.com/questions/3978976/can-the-seam-authenticator-reside-in-the-ear-file-lib-folder&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This was the problem. If you have beans in a JAR that JAR must define an empty seam.properties file in order for it to be scanned for beans.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #7: javax.naming.NameAlreadyBoundException: classPathEntries&lt;/h3&gt;  &lt;p&gt;Apparently there is an issue with the hibernate-core jar existing in both the ears in the deployment, this was resolved by deleting deleting the second ear. Eventually the second EAR was made to not include this JAR.   &lt;br /&gt;Also had the same problem with javassist&lt;/p&gt;  &lt;h3&gt;Error #8: Unit Tests no longer run out of Eclipse&lt;/h3&gt;  &lt;p&gt;The problem is running unit tests with a classpath that is too long in Eclipse. &lt;/p&gt;  &lt;p&gt;You have to edit the classpath of the target to not include external dependencies&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #9: Some pages are 404 not found &lt;/h3&gt;  &lt;p&gt;This was a really annoying problem that plagued me for a long time. Buttons that used to correctly direct to htm pages were no longer working. Upon closer inspection the link that works is going to pageC.htm while the one that doesn’t is going to pageB.xhtml. Something is not rewriting xhtml to htm in the page rendering. &lt;/p&gt;  &lt;p&gt;The problem the entire time has been these pages were named “xtml” instead of “xhtml” and I didn’t see it. Apparently the previous version of SEAM, JBoss, Java, or something else handled xtml even though it is not a part of the configuration.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #10: java.lang.InstantiationException: org.apache.log4j.Logger &lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;javax.ejb.EJBException: java.lang.RuntimeException: org.jboss.serial.exception.SerializationException: Could not create instance of org.apache.log4j.Logger - org.apache.log4j.Logger     &lt;br /&gt;...      &lt;br /&gt;caused by: java.lang.InstantiationException: org.apache.log4j.Logger&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Google only provided two solutions: make the logger static or declare it as @Transient &lt;/p&gt;  &lt;p&gt;Doing both of these didn’t get rid of the error.&lt;/p&gt;  &lt;p&gt;There was a warning about a @Destory method in a class that was using a log4j logger, so I changed it to be seam injected. This too didn’t work, even when marked with @Transient. &lt;/p&gt;  &lt;p&gt;As it turns out the way to fix this is simple, only use static transient Loggers. In my application this means I had to do this 890 times. A result of this problem is also a memory leak, because the beans can’t be destroyed.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #11: EJB Timer throws a null pointer exception&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;2011-10-28 09:19:54,584 ERROR [org.jboss.ejb.txtimer.TimerImpl] (EJB-Timer-1319811479419[target=jboss.j2ee:ear=Irio.ear,jar=jboss-seam-2.2.2.jar,name=TimerServiceDispatcher,service=EJB3]) Error invoking ejbTimeout     &lt;br /&gt;javax.ejb.EJBException: java.lang.RuntimeException: java.lang.NullPointerException &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;It doesn’t prevent startup and corrects itself, but slows the start up process down. There doesn’t appear to be anyway to get rid of getting this exception at least once on start up.&lt;/p&gt;  &lt;p&gt;However, it should be noted that if you start getting these errors several times during startup it is an indication that JBoss will fail to startup eventually. The only way to prevent this is to delete the tmp, work, and data directories every time you restart a JBoss instance.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #12: Caused by: java.lang.NoClassDefFoundError: org/jgroups/Channel&lt;/h3&gt;  &lt;p&gt;The solution is to add the jgroups jars to lib/endorsed for whatever server you are running. &lt;/p&gt;  &lt;p&gt;Reference: &lt;a href="http://community.jboss.org/message/440606"&gt;http://community.jboss.org/message/440606&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;But then you get a stack:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;2011-11-03 09:57:33,359 ERROR [org.jboss.ejb3.cache.simple.SimpleStatefulCache.SMSOptionsActionImpl] (SFSB Passivation Thread - jboss.j2ee:ear=Irio.ear,jar=IrioAccountApplication.jar,name=SMSOptionsActionImpl,service=EJB3) problem passivation thread       &lt;br /&gt;javax.ejb.EJBException: Could not passivate; failed to save state &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Reference: &lt;a href="http://seamframework.org/Documentation/HandlingPrePassivateCleanupInSFSBs"&gt;http://seamframework.org/Documentation/HandlingPrePassivateCleanupInSFSBs&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Reading this article lead me to take a look at clustering again, which has to do with Error #1. As is turned out setting the troublesome class to clustered = false in the jboss.xml seems to have resolved this issue. &lt;/p&gt;  &lt;p&gt;I again had to come back to this, and found that further down in the stacktrace there is a message about a missing class. &lt;/p&gt;  &lt;p&gt;Long story short, I had to add the following jars to lib/endorsed:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;mail.jar&lt;/li&gt;    &lt;li&gt;log4j.jar&lt;/li&gt;    &lt;li&gt;commons-logging.jar&lt;/li&gt;    &lt;li&gt;jbosscache.jar&lt;/li&gt;    &lt;li&gt;jgroups-all.jar&lt;/li&gt;    &lt;li&gt;pojocache.jar&lt;/li&gt;    &lt;li&gt;jbosscache-core.jar &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The error following the passivation error, was java.lang.NoClassDefFoundError: org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper &lt;/p&gt;  &lt;p&gt;When I looked in the logs prior to all of this and during startup, I found that there was a warning message stating the clustering was disabled because orjava.lang.NoClassDefFoundError: org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper. So I figured if I got rid of this startup error that it would get rid of the passivation error. The problem though is that they only way to get this error is to do something involving the bean, and then wait several hours.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #13: Database connection hangs forever (using MS SQL) &lt;/h3&gt;  &lt;p&gt;The reason for this has to do with a problem between Java 1.6.0_29 and the MS SQL JDBC driver. The only solution is to use Java 1.6.0_27, which is why that is the version of Java listed in the new spec even though it is not the most recent version of Java 6.&lt;/p&gt;  &lt;p&gt;Reference: &lt;a href="http://stackoverflow.com/questions/7841411/driver-getconnection-hangs-using-sqlserver-driver-and-java-1-6-0-29"&gt;http://stackoverflow.com/questions/7841411/driver-getconnection-hangs-using-sqlserver-driver-and-java-1-6-0-29&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #14: JBOSS_HOME and JAVA_HOME environment variables do to propagate into scheduled tasks &lt;/h3&gt;  &lt;p&gt;&lt;a href="http://community.installshield.com/showthread.php?t=147931"&gt;http://community.installshield.com/showthread.php?t=147931&lt;/a&gt; indicates that the only way Scheduled Tasks can pick up changes to environment variables is to reboot the machine. However, in my case I was not able to reboot the machine so I had to find a workaround. &lt;/p&gt;  &lt;p&gt;To do it without having to reboot:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Login as the non-running user&lt;/li&gt;    &lt;li&gt;Disable all Scheduled Tasks&lt;/li&gt;    &lt;li&gt;Change the environment variable&lt;/li&gt;    &lt;li&gt;Start the Task Manager and select to show all processes from all users&lt;/li&gt;    &lt;li&gt;In the Task Manager, kill all tasks being run by the Scheduled Task running user (taskeng.exe)&lt;/li&gt;    &lt;li&gt;Log Off&lt;/li&gt;    &lt;li&gt;Log on as the non-running user&lt;/li&gt;    &lt;li&gt;Enable all Scheduled Tasks&lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;ERROR #15: java.lang.OutOfMemoryError: unable to create new native thread &lt;/h3&gt;  &lt;p&gt;This issue has to do with the following things:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The amount of memory allocated with Xmx. This is in your conf if using the service wrapper.&lt;/li&gt;    &lt;li&gt;The amount of memory allocated with Xms. This is in your conf if using the service wrapper.&lt;/li&gt;    &lt;li&gt;The maximum number of AJP threads allowed in jbossweb.sar/server.xml&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The key is finding the balance between these values, which is dependent on Java version, what your application is doing, and how much memory is available on your machine.&lt;/p&gt;  &lt;p&gt;Reference: &lt;a href="http://blog.egilh.com/2006/06/2811aspx.html"&gt;http://blog.egilh.com/2006/06/2811aspx.html&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #16: Failed to parse source: {&lt;a href="http://java.sun.com/xml/ns/javaee}virtual-host"&gt;http://java.sun.com/xml/ns/javaee}virtual-host&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;org.jboss.xb.binding.JBossXBException: Failed to parse source: {&lt;/font&gt;&lt;a href="http://java.sun.com/xml/ns/javaee}virtual-host"&gt;&lt;font face="Courier New"&gt;http://java.sun.com/xml/ns/javaee}virtual-host&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; cannot appear in this position. Expected content of {&lt;/font&gt;&lt;a href="http://java.sun.com/xml/ns/javaee}web"&gt;&lt;font face="Courier New"&gt;http://java.sun.com/xml/ns/javaee}web&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; is unordered_sequence: {&lt;/font&gt;&lt;a href="http://java.sun.com/xml/ns/javaee}context-root?"&gt;&lt;font face="Courier New"&gt;http://java.sun.com/xml/ns/javaee}context-root?&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; {&lt;/font&gt;&lt;a href="http://java.sun.com/xml/ns/javaee}web-uri?"&gt;&lt;font face="Courier New"&gt;http://java.sun.com/xml/ns/javaee}web-uri?&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The following is no longer valid, as virtual-host isn’t allowed here.   &lt;br /&gt;&amp;lt;module&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;web&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;web-uri&amp;gt;foo.war&amp;lt;/web-uri&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;context-root&amp;gt;/foo&amp;lt;/context-root&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&amp;lt;virtual-host&amp;gt;myhost&amp;lt;/virtual-host&amp;gt;&lt;/font&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/web&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/module&amp;gt; &lt;/p&gt;  &lt;p&gt;Remove it because it should be defined in jboss-web.xml anyways.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Error #17: javax.ejb.EJBNoSuchObjectException: Could not find Stateful bean: 41z4l26-wb41k6-ev4j007b-1-ev4jirql-bw &lt;/h3&gt;  &lt;p&gt;I have been seeing this error in the logs quite often and in the previous version of JBoss, being 4.2.2. It didn’t appear to be critical so I jut let it be like the hundreds of other errors. I however stumbled across and article explaining the cause for this: &lt;a href="http://community.jboss.org/wiki/JbossTimeoutSettingForSeam"&gt;http://community.jboss.org/wiki/JbossTimeoutSettingForSeam&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To summarize, you get this problem with stateful session bean timeouts do not match the session timeout. This is great considering that the default session timeout (web.xml) is 30 minutes while the default stateful session bean timeout is 5 minutes (ejb3-intercepters-aop.xml).&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Warning #1: EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container &lt;/h3&gt;  &lt;p&gt;This is something that can be ignored entirely, and the developers even recommend that you do. Every time you access a bean you will get this warning, so it floods the log. &lt;/p&gt;  &lt;p&gt;Reference: &lt;a href="http://stackoverflow.com/questions/491007/jboss-what-does-the-warning-ejbthree-1246-from-the-interceptorregistry-mean"&gt;http://stackoverflow.com/questions/491007/jboss-what-does-the-warning-ejbthree-1246-from-the-interceptorregistry-mean&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-2159002951177426590?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/2159002951177426590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=2159002951177426590' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2159002951177426590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2159002951177426590'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2011/12/upgrading-jboss-4-to-jboss-5-with-java.html' title='Upgrading JBoss 4 to JBoss 5 with Java 5 to Java 6'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-8246644835541737613</id><published>2011-08-23T08:26:00.001-06:00</published><updated>2011-08-23T16:56:44.183-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Using DBUnit through Ant with a large MS SQL Database</title><content type='html'>&lt;p&gt;The following describes my experiences with using DBUnit through Ant with a large MS SQL database, and all of the adventures I had. The intention is to use DBUnit though Ant to export a database as an XML file, to clear the database, and to re-populate it using that XML file.&lt;/p&gt;  &lt;h3&gt;Why?&lt;/h3&gt;  &lt;p&gt;Automated acceptance testing. You start with an XML backup of what you want your base system to contain, refresh your database with that backup, run your suite of automated acceptance tests, and then restore the XML backup again. That way your tests can do things specific to the application like create users, invoices, etc, and otherwise mess around with every conceivable operation. When you are done you can restore everything to the way it was before.&lt;/p&gt;  &lt;p&gt;Running it though Ant lets you easily integrate this refresh into other automation tools such as Jenkins (Hudson), TeamCity, and so on.&lt;/p&gt;  &lt;h3&gt;Did you say large?&lt;/h3&gt;  &lt;p&gt;Yes I did, but in this context I am using it to refer to a database with a large number of tables, not a large number of records. A large number of tables is a catch-all for several circumstances which you cause you trouble, such as with tables which have keywords for names, foreign key dependencies between tables, tables with timestamp columns, and some more items I will get address.&lt;/p&gt;  &lt;h3&gt;But I want a lot of records!&lt;/h3&gt;  &lt;p&gt;There are a couple of problems with using a lot of records with DBUnit, the first of which is that if you are exporting and importing you will have to deal with very long save and load times. As a general rule you probably are aiming for an export XML file size of under 3 MB, which is around 2,000 records depending on what it is your tables. The second problem has to do with memory, but I have a workaround for that as well.&lt;/p&gt;  &lt;h3&gt;DBUnit with Ant&lt;/h3&gt;  &lt;p&gt;So you want to use Ant? You are then going to have to write your own task by extending the DBUnit Ant Task. This is because there are options that need to be set [at least to my knowledge] that cannot be set in the DBUnit Ant Task that is provided to you.&lt;/p&gt;  &lt;p&gt;To start out you will need to extend three things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The DbUnitTask, which is the &amp;lt;dbunit&amp;gt; tag. This allows you to define your own Export and Operation tags. &lt;/li&gt;    &lt;li&gt;The Export, which is the &amp;lt;export&amp;gt; tag. This is for changing how the export works. &lt;/li&gt;    &lt;li&gt;The Operation, which is the &amp;lt;operation&amp;gt; tag. This is for changing how the insert works. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;MSDBUnitTask.java&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;public class MSDBUnitTask extends DbUnitTask { &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; @SuppressWarnings(&amp;quot;unchecked&amp;quot;)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void addMSExport(MSExport export) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.getSteps().add(export);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @SuppressWarnings(&amp;quot;unchecked&amp;quot;)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void addMSOperation(MSOperation operation) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.getSteps().add(operation);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;MSExport.java&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;public class MSExport extends Export&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; private String tableNames;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @Override         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void execute(IDatabaseConnection arg0) throws DatabaseUnitException {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // code goes here         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; public String getTableNames() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return tableNames;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; public void setTableNames(String tableNames) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.tableNames = tableNames;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;MSOperation.java&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;public class MSOperation extends Operation&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @Override        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void execute(IDatabaseConnection arg0) throws DatabaseUnitException {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // code goes here         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt; &lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Including your custom task in Ant&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This assumes that the Ant classes from above are compiled into a JAR and present in the ${lib.dir} along with the dbunit.jar&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;path id=&amp;quot;classpath&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;fileset dir=&amp;quot;${lib.dir}&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;include name=&amp;quot;*.jar&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/fileset&amp;gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;lt;/path&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;taskdef name=&amp;quot;msdbunit&amp;quot; classname=&amp;quot;com.foo.ant.dbunit.MSDBUnitTask&amp;quot; classpathref=&amp;quot;classpath&amp;quot; /&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Adventures in Exporting&lt;/h3&gt;  &lt;p&gt;The Java code here goes in the execute method of MSExport.&lt;/p&gt;  &lt;p&gt;This is where the majority of problems start. As it turns out you can export with ease, but can end up with XML that had invalid characters and some other interesting things that cannot be imported.&lt;/p&gt;  &lt;p&gt;Let’s start with the result we want (and need): the XML to export the database:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;target name=&amp;quot;db-export&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msdbunit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; driver=&amp;quot;${db.driver}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;${db.url}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userid=&amp;quot;${db.username}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password=&amp;quot;${db.password}&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dbconfig&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;escapePattern&amp;quot; value=&amp;quot;[?]&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;datatypeFactory&amp;quot; value=&amp;quot;org.dbunit.ext.mssql.MsSqlDataTypeFactory&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dbconfig&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msexport format=&amp;quot;xml&amp;quot; tableNames=&amp;quot;${insert.table.names}&amp;quot; dest=&amp;quot;full_export.xml&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/msdbunit&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/target&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The msdbunit and msexport tags were explained earlier, and the base Java code for creating them was given.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Issue #1: Export Table Order&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You must specify the order of tables to do the export in insertion order. This is done by passing in a comma separated list of tables name from ${insert.table.names} into the &amp;lt;msexport&amp;gt; tag as the tableNames attribute.&lt;/p&gt;  &lt;p&gt;The reason for this order is that you must take into account FK dependencies when both inserting and deleting. For example if Foo.A is a FK to Bar.A, then you can’t start out by inserting records into Foo; you have to insert into Bar first. From the deletion perspective it is the opposite: You can’t delete from Bar since Foo can reference it and cause the delete to fail.&lt;/p&gt;  &lt;p&gt;The MSExport task already has tableNames defined, so in order to get the result as a list of tables all that needs to be done is this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;String[] tableNamesArray = tableNames.split(&amp;quot;,&amp;quot;);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;ITableFilter filter = new SequenceTableFilter(tableNamesArray);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;IDataSet dataset = new FilteredDataSet(filter, arg0.createDataSet());&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The second part of this is do use this array to define the table sequence. You must do this manually because even though it can be done automatically, with 100+ tables it will take minutes as opposed to a fraction of a second.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Issue #2: Columns that are of type TIMESTAMP or default DATETIME&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There is an issue if you export a column of the TIMESTAMP type or of the defaulted DATETIME, because when you try and import it you will get an error regarding not being able to insert a value into the column.&lt;/p&gt;  &lt;p&gt;The exact error you get is the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Cannot insert an explicit value into a timestamp column&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The solution is not to export these columns, which requires the use of a column filter. This was the primary reason for abandoning the default Ant task, as I couldn’t figure out a good way to do a large column filtering.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New" size="1"&gt;List&amp;lt;ITable&amp;gt; updatedTables = new ArrayList&amp;lt;ITable&amp;gt;();&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New" size="1"&gt;for (String tableName : tableNamesArray) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ITable table = dataset.getTable(tableName);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;Column&amp;gt; excludedColumns = new ArrayList&amp;lt;Column&amp;gt;();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Column[] columns = table.getTableMetaData().getColumns();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //For each column...         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (Column column : columns) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //TIMESTAMP columns have to be ignored in MSSQL because they cannot have an explicit insert         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //Unfortunately DATETIME in MSSQL also shows here as a TIMESTAMP so the only way to         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //determine defaulted DATETIME or TIMESTAMP is by looking for defaults and the SQL Type name         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ( (column.getDefaultValue() != null &amp;amp;&amp;amp; column.getDataType() == DataType.TIMESTAMP) ||         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; column.getSqlTypeName().equals(&amp;quot;timestamp&amp;quot;)) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; excludedColumns.add(column);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //convert the list of excluded columns to an array         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Column[] excluded =&amp;#160; excludedColumns.toArray(new Column[excludedColumns.size()]);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //create a new ITable that excludes the filtered columns         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ITable filteredTable = DefaultColumnFilter.excludedColumnsTable(table,excluded);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //keep track of the modified table         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; updatedTables.add(filteredTable);&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //Take all of the modified table and create a new dataset         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ITable[] updateTableArray =&amp;#160; updatedTables.toArray(new ITable[updatedTables.size()]);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CompositeDataSet compositeDataSet = new CompositeDataSet(updateTableArray);&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This code iterates over all of the tables, looks for datetime and timestamp columns, excludes them from that table, and adds them to a new list of tables with the appropriate columns excluded. It then constructs a new composite dataset containing all of the new tables and columns.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Issue #3: Exporting your customizations&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When you extend the Export task, you have to then define how to export.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New" size="1"&gt;//Get the format and file destination        &lt;br /&gt;String format = this.getFormat();         &lt;br /&gt;File dest = this.getDest();         &lt;br /&gt;//Output based on the format         &lt;br /&gt;if (format.equalsIgnoreCase(FORMAT_CSV)) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CsvDataSetWriter.write(compositeDataSet, dest);         &lt;br /&gt;else if (format.equalsIgnoreCase(FORMAT_FLAT)) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FlatXmlDataSet.write(compositeDataSet, new FileOutputStream(dest));         &lt;br /&gt;} else if (format.equalsIgnoreCase(FORMAT_XML)) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; XmlDataSet.write(compositeDataSet, new FileOutputStream(dest));         &lt;br /&gt;} else if (format.equalsIgnoreCase(FORMAT_DTD)) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FlatDtdDataSet.write(dataset, new FileOutputStream(dest));         &lt;br /&gt;} else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; throw new DatabaseUnitException(format+&amp;quot; is not a recognized format.&amp;quot;);         &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Issue #4: Exporting Tables that have keywords for names&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For example User is a keyword, but you can have a table of this name in MS SQL and access it using [User]. In order to deal with this you want to put all table names within [].&lt;/p&gt;  &lt;p&gt;This can be configured in the Ant XML using the escapePattern property of dbconfig:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;target name=&amp;quot;db-export&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msdbunit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; driver=&amp;quot;${db.driver}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;${db.url}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userid=&amp;quot;${db.username}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password=&amp;quot;${db.password}&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dbconfig&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;&amp;lt;property name=&amp;quot;escapePattern&amp;quot; value=&amp;quot;[?]&amp;quot; /&amp;gt;&lt;/font&gt;&amp;#160; &lt;/strong&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;datatypeFactory&amp;quot; value=&amp;quot;org.dbunit.ext.mssql.MsSqlDataTypeFactory&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dbconfig&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msexport format=&amp;quot;xml&amp;quot; tableNames=&amp;quot;${insert.table.names}&amp;quot; dest=&amp;quot;full_export.xml&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/msdbunit&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/target&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Issue #5: Data Type Factory&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In order to be able to insert records into a MS SQL database using DBUnit, you have to specify the data factory to use as a part of the export. If you don’t any time you try and import a result containing a primary key you will get the following error:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Cannot insert explicit value for identity column in table&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This issue can also be resolved in the default Ant using the dataTypeFactory property in the dbconfig:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;target name=&amp;quot;db-export&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msdbunit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; driver=&amp;quot;${db.driver}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;${db.url}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userid=&amp;quot;${db.username}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password=&amp;quot;${db.password}&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dbconfig&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;escapePattern&amp;quot; value=&amp;quot;[?]&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;&amp;lt;property name=&amp;quot;datatypeFactory&amp;quot; value=&amp;quot;org.dbunit.ext.mssql.MsSqlDataTypeFactory&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dbconfig&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msexport format=&amp;quot;xml&amp;quot; tableNames=&amp;quot;${insert.table.names}&amp;quot; dest=&amp;quot;full_export.xml&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/msdbunit&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/target&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Issue #6: Which table failed to export?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This issue is that when you are exporting your database and something goes wrong, it is not specified which table was the problem. You just get an error message such as “Cannot insert explicit value for identity column in table” and are left to figure out which table may have caused it.&lt;/p&gt;  &lt;p&gt;Since we have our own Ant task that iterates over tables, this is pretty easy to do: put a System.out.println with the table name at the start of the loop. That was if something breaks, you know which table caused it.&lt;/p&gt;  &lt;h3&gt;Deleting from the Database&lt;/h3&gt;  &lt;p&gt;If you exported correctly this isn’t a problem, and doesn’t require any custom work beyond the escapePattern and data type factory. It should be noted that before inserting into your database you want to clear it using your export file first. The CLEAN_INSERT operation is supposed to do this on insert for you, but in my experience I have never been able to get it work on a large database. It ends up throwing constraint violations, either because of the database, a bug, or my misuse of the operation.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;target name=&amp;quot;db-delete&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msdbunit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; driver=&amp;quot;${db.driver}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;${db.url}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userid=&amp;quot;${db.username}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password=&amp;quot;${db.password}&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dbconfig&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;escapePattern&amp;quot; value=&amp;quot;[?]&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;datatypeFactory&amp;quot; value=&amp;quot;org.dbunit.ext.mssql.MsSqlDataTypeFactory&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dbconfig&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;operation type=”DELETE_ALL” format=&amp;quot;xml&amp;quot; src=&amp;quot;full_export.xml&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/msdbunit&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/target&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Populating the Database&lt;/h3&gt;  &lt;p&gt;The Java code here goes in the execute method of MSOperation.&lt;/p&gt;  &lt;p&gt;The same as with deleting from the database, if you correctly exported the dataset you should not have any problems. There is one feature though that is nice to have, which is the ability in the case of an error to know which table cause the error.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //Only perform an operation for every table if doing a clean insert for MS SQL      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (this.getType().equalsIgnoreCase(&amp;quot;MSSQL_CLEAN_INSERT&amp;quot;)) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FileReader reader = new FileReader(this.getSrc());       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String format = this.getFormat();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IDataSet dataset = null;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (format.equalsIgnoreCase(FORMAT_XML)) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dataset = new XmlDataSet(reader);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } else {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new DatabaseUnitException(&amp;quot;xml is the only supported format.&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String[] tableNames = dataset.getTableNames();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //For each table, create a new dataset and execute the operation because:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int i = 0; i &amp;lt; tableNames.length; i++) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String tableName = tableNames[i];       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.out.println(&amp;quot;Populating table &amp;quot;+tableName);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ITable table = dataset.getTable(tableName);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ITable[] iTables = new ITable[1];       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; iTables[0] = table;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CompositeDataSet composite = new CompositeDataSet(iTables);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.getDbOperation().execute(connection, composite);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } catch (Exception e) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.printStackTrace();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new DatabaseUnitException(e);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } else {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; super.execute(connection);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Beyond that all you need is the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MSSQL_CLEAN_INSERT &lt;/li&gt;    &lt;li&gt;The MS SQL Data Type Factory &lt;/li&gt;    &lt;li&gt;The escapePattern for tables with keywords for names &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;target name=&amp;quot;db-populate&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msdbunit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; driver=&amp;quot;${db.driver}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;${db.url}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userid=&amp;quot;${db.username}&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password=&amp;quot;${db.password}&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;dbconfig&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;escapePattern&amp;quot; value=&amp;quot;[?]&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;property name=&amp;quot;datatypeFactory&amp;quot; value=&amp;quot;org.dbunit.ext.mssql.MsSqlDataTypeFactory&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/dbconfig&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;msoperation type=”MSSQL_CLEAN_INSERT” format=&amp;quot;xml&amp;quot; src=&amp;quot;full_export.xml&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/msdbunit&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/target&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Where did I get my information?&lt;/h3&gt;  &lt;p&gt;The internet combined with trial and error. Here are the sites I used for information:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Managing test data for integration tests using Spring and DBUnit (&lt;a href="http://www.theserverside.com/news/1363748/Manage-test-data-for-integration-tests-using-Spring-and-DBunit"&gt;http://www.theserverside.com/news/1363748/Manage-test-data-for-integration-tests-using-Spring-and-DBunit&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;Using DBUnit (&lt;a href="http://www.fm-berger.de/ora_webtest/ch03.php"&gt;http://www.fm-berger.de/ora_webtest/ch03.php&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;DBUnit Tip: Turn off FK constraints (&lt;a href="http://raibledesigns.com/rd/entry/dbunit_tip_turn_off_foreign"&gt;http://raibledesigns.com/rd/entry/dbunit_tip_turn_off_foreign&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;DBUnit FAQ (&lt;a href="http://ds.cc.yamaguchi-u.ac.jp/~joji/doc/dbunit/faq.html"&gt;http://ds.cc.yamaguchi-u.ac.jp/~joji/doc/dbunit/faq.html&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;Column Filtering (&lt;a href="http://old.nabble.com/comparing-actual-to-expected-tables-td17344245.html"&gt;http://old.nabble.com/comparing-actual-to-expected-tables-td17344245.html&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;DBUnit Testing Framework (&lt;a href="http://dbunit.sourceforge.net/xref-test/org/dbunit/ext/mssql/InsertIdentityOperationIT.html"&gt;http://dbunit.sourceforge.net/xref-test/org/dbunit/ext/mssql/InsertIdentityOperationIT.html&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;Using SelectMethod=cursor on a connection (&lt;a href="http://support.microsoft.com/kb/917054"&gt;http://support.microsoft.com/kb/917054&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-8246644835541737613?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/8246644835541737613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=8246644835541737613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/8246644835541737613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/8246644835541737613'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2011/08/using-dbunit-through-ant-with-large-ms.html' title='Using DBUnit through Ant with a large MS SQL Database'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-6838813892414147524</id><published>2011-08-16T13:34:00.001-06:00</published><updated>2011-08-16T17:59:00.541-06:00</updated><title type='text'>SQL query performance using a select on a large record set with Hibernate</title><content type='html'>&lt;p&gt;This title is partly a question because I am unsure that my solution is the best. I have come to the following solution based on trial and error, and settling on what seemed to have worked.&lt;/p&gt;  &lt;h3&gt;The Database&lt;/h3&gt;  &lt;p&gt;The database is MS SQL 2008 Enterprise, we are using the correct JDBC driver, and are using Hibernate 3.4.0.GA. The database is also located on the same physical machine as the application server.&lt;/p&gt;  &lt;h3&gt;The Table&lt;/h3&gt;  &lt;p&gt;There is only a single table that is the target of the problem, which has the following structure:&lt;/p&gt;  &lt;p&gt;Foo&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ID (UUID Primary Key)&lt;/li&gt;    &lt;li&gt;A (int, indexed)&lt;/li&gt;    &lt;li&gt;B (datetime, indexed)&lt;/li&gt;    &lt;li&gt;C (varchar, indexed)&lt;/li&gt;    &lt;li&gt;D (int, not indexed)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this table there are slightly over 2.5 million records, and I am trying to select less than 10 results.&lt;/p&gt;  &lt;h3&gt;The Query&lt;/h3&gt;  &lt;p&gt;This is the query that was slow, taking over 5 minutes to complete (in the SQL Variant). Take into account though that the different columns were used under different circumstances, making the query dynamic. The more columns used, the slower the query. In the case of using every column it looked like this:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SQL&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;FROM FOO&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;WHERE A = 1 AND B &amp;gt;= ‘2011-08-12’ AND C = ‘BAR’ AND D = 3&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Hibernate&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Query query = em.createQuery(&amp;quot;from Foo where a=:a and b &amp;gt;= :b and c = :c and d = :d”);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query.setParameter(“a”, 1);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query.setParameter(“b”, date);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query.setParameter(“c”, “BAR”);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query.setParameter(“d”, 3);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;List&amp;lt;Foo&amp;gt; list = query.getResultList();&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;&lt;strong&gt;The Obvious&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Column D isn’t indexed. Column D isn’t also used all of the time, and removing it from the query only cuts the 5 minute time by 30 seconds. There is also the preference that I do not change the existing database unless absolutely the only option.&lt;/p&gt;  &lt;p&gt;There are also probably better ways to deal with the datetime column type, for example see &lt;a href="http://diegworld.blogspot.com/2010/09/sql-server-performance-querying-by-date.html"&gt;http://diegworld.blogspot.com/2010/09/sql-server-performance-querying-by-date.html&lt;/a&gt;. However, if I remove this column from the query it doesn’t change the amount of time it takes.&lt;/p&gt;  &lt;h3&gt;The SQL Solution&lt;/h3&gt;  &lt;p&gt;Eventually I just started playing around with the SQL variant of the query to see if I could improve the performance. I started with running select statements with each individual column and found that they all worked in a second, for example:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D, FROM FOO WHERE A = 1&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D, FROM FOO WHERE B &amp;gt;= ‘2011-08-12’&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D, FROM FOO WHERE C = ‘BAR’&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D, FROM FOO WHERE D = 3&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;At this point I realized that the problem has to do with all of the restrictions I added in the where clause, but changing the order of the “ands” didn’t improve performance either. With this information I then tried building the query so that it would incorporate sub queries. The idea being that if I have select with A I have set A, in which I can select with B from that and have Set AB, select C from that and have Set ABC, and select D from that and have Set ABCD. The resulting Set of ABCD would contain only records which had the A, B, C, and D criteria.&lt;/p&gt;  &lt;p&gt;The resulting SQL that I came up with was the following:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D FROM FOO fooA WHERE fooA.ID IN (&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID FROM FOO fooB WHERE fooB.ID IN (&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; SELECT ID FROM FOO fooC WHERE fooC.ID IN (&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SELECT ID FROM FOO fooD WHERE D = 3&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ) AND fooC.C = ‘BAR’&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;) AND fooB.B &amp;gt;= ‘2011-08-12’ &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;) AND fooA.A = 1&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This query took less than a second to run, as opposed to the previous variant that was taking more than 5 minutes.&lt;/p&gt;  &lt;p&gt;My question is though, is this the best thing to do from both a SQL and MSSQL perspective?&lt;/p&gt;  &lt;h3&gt;The Hibernate Implementation&lt;/h3&gt;  &lt;p&gt;Hibernate has a lot of flexibility in terms of how you can do sub queries, but according to my research on the internet the preferred means for doing this is to use Criteria and DetachedCriteria. Here are some places which I used to come to this conclusion:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html#querycriteria-detachedqueries"&gt;http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html#querycriteria-detachedqueries&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://forum.hibernate.org/viewtopic.php?p=2317841"&gt;https://forum.hibernate.org/viewtopic.php?p=2317841&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.coderanch.com/t/415182/ORM/java/Write-Sub-Query-Hibernate"&gt;http://www.coderanch.com/t/415182/ORM/java/Write-Sub-Query-Hibernate&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The way this works in Hibernate is as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Session session = (Session) getEntityManager().getDelegate();&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;Criteria crit = session.createCriteria(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// First subquery to get A&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query1 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query1.add(Restrictions.eq(&amp;quot;a&amp;quot;, 1));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query1.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;crit.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query1));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Second subquery to get B&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query2 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query2.add(Restrictions.ge(&amp;quot;b&amp;quot;, date));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query2.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;crit.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query2));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Third subquery to get C&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query3 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query3.add(Restrictions.eq(&amp;quot;c&amp;quot;, “BAR”));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query3.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;crit.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query3));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Fourth subquery to get D&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query4 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query4.add(Restrictions.eq(&amp;quot;d&amp;quot;, 3));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query4.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;crit.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query4));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;List&amp;lt;Foo&amp;gt; results = crit.list();&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Each subquery reads as “get the id’s from Foo where the restriction holds true”, and the criteria represents the combined result of all of the added subqueries.&lt;/p&gt;  &lt;p&gt;This isn’t the exact equivalent of the previously specified SQL though. When looking at the HQL debug output it ends up being the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;FROM Foo&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;WHERE ID in (SELECT ID FROM Foo WHERE A = 1)&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;AND ID in (SELECT ID FROM Foo WHERE B &amp;gt;= ‘2011-08-12’)&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;AND ID in (SELECT ID FROM Foo WHERE C = ‘BAR’)&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;AND ID in (SELECT ID FROM Foo WHERE D = 3)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is better than what was there, but it still isn’t as efficient as it could be. In this code we are selecting 4 different times across the entire Foo record set. In the SQL I am trying to write each time we select it is from the previous subset. For example we are looking for condition B inside the A result set,which is smaller than all of the Foo records.&lt;/p&gt;  &lt;p&gt;As it turns out, it isn’t that hard. You just add your subqueries to other subqueries like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Session session = (Session) getEntityManager().getDelegate();&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;Criteria crit = session.createCriteria(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// First subquery to get A&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query1 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query1.add(Restrictions.eq(&amp;quot;a&amp;quot;, 1));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query1.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;crit.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query1));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Second subquery to get B&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query2 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query2.add(Restrictions.ge(&amp;quot;b&amp;quot;, date));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query2.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;query1.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query2));&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Third subquery to get C&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query3 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query3.add(Restrictions.eq(&amp;quot;c&amp;quot;, “BAR”));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query3.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;query2.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query3));&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;// Fourth subquery to get D&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;DetachedCriteria query4 = DetachedCriteria.forClass(Foo.class);&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query4.add(Restrictions.eq(&amp;quot;d&amp;quot;, 3));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;query4.setProjection(Projections.property(&amp;quot;id&amp;quot;));&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;query3.add(Subqueries.propertyIn(&amp;quot;id&amp;quot;, query4));&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;List&amp;lt;Foo&amp;gt; results = crit.list();&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This hibernate code results in the desired SQL:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID, A, B, C, D FROM FOO fooA WHERE fooA.ID IN (&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;SELECT ID FROM FOO fooB WHERE fooB.ID IN (&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; SELECT ID FROM FOO fooC WHERE fooC.ID IN (&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SELECT ID FROM FOO fooD WHERE D = 3&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ) AND fooC.C = ‘BAR’&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;) AND fooB.B &amp;gt;= ‘2011-08-12’ &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;) AND fooA.A = 1&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-6838813892414147524?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/6838813892414147524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=6838813892414147524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6838813892414147524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6838813892414147524'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2011/08/sql-query-performance-using-select-on.html' title='SQL query performance using a select on a large record set with Hibernate'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-1329058128815300787</id><published>2011-08-11T17:35:00.001-06:00</published><updated>2011-08-11T17:35:08.200-06:00</updated><title type='text'>Flex 3 Test Automation using QTP</title><content type='html'>&lt;p&gt;This information has been sitting in my “to publish” list for a while now, so I am finally going to put it out there since a couple people have been asking about it. It describes my experiences with automating user interface interaction testing using QTP, and all the things I had to workaround.&lt;/p&gt;  &lt;h2&gt;1. Setting up and running QTP&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;1.1 Add “automation_charts.swf” to the Flex SDK directory &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Example: C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\libs &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.2 Add the QTP libraries to your project compiler options &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Add the following to the compiler options on the project: &lt;/p&gt;  &lt;p&gt;-include-libraries &amp;quot;C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\libs\automation.swc&amp;quot; &amp;quot;C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\libs\automation_agent.swc&amp;quot; &amp;quot;C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\libs\automation_charts.swc&amp;quot; &amp;quot;C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\libs\qtp.swc&amp;quot; &lt;/p&gt;  &lt;p&gt;The absolute path must be used, relative will not work. &lt;/p&gt;  &lt;p&gt;This will force the libraries into your main application SWF, which should increase its size by about 1.2 MB &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.3 Run your Flex application on a web server.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You must run the application on a web server, it cannot run locally. If you attempt to run it locally you will get lots of browser scripting errors.&lt;/p&gt;  &lt;p&gt;Example: &lt;a href="http://myserver/foo/bar.html"&gt;http://myserver/foo/bar.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.4 You must be running Flash 9 &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The computer running the application and QTP must have Flash 9, otherwise system popups will be blocked by Flash Player security &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.5 You must run QTP and the browser window in the same monitor. &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The computer running the application and QTP must be doing so in the same monitor window in the event that two monitors are being used, more on this later.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;2. Required Code Changes&lt;/h2&gt;  &lt;p&gt;For various reasons when doing any type of user interface testing in Flex you have to make code changes.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.1 Create new build and deployment&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You will need to create a new variation of your build that compiles the automation libraries into the application binary (and all modules). This is because you don’t want to deploy your release binaries with the QTP automation classes compiled into them. This is because it significantly increases the size of your SWF.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.2 Recursively set the automation hierarchy when running for automation &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In order for the QTP to be able to playback button presses to objects deep within the component hierarchy, an automation value has to be set throughout the application at runtime, see “QTP Playback is slow” for information as to why and how.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.3 Creation of automation delegates for every custom components that QTP does not recognized.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;QTP will not recognized interactions with items that inherit directly from UIComponent directly, or are otherwise not a standard button, or text component, or control. See “Custom Automation Delegates” for more information.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;3. QTP Specifics and Problems&lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;3.1 Creating a Custom Flex Automation Delegate&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;References &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.benlondon.co.uk/2010/01/flexqtp-automation-delegates.html"&gt;http://www.benlondon.co.uk/2010/01/flexqtp-automation-delegates.html&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.adobe.com/devnet/flex/samples/randomwalk/"&gt;http://www.adobe.com/devnet/flex/samples/randomwalk/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=functest_components2_15.html"&gt;http://livedocs.adobe.com/flex/3/html/help.html?content=functest_components2_15.html&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Summary&lt;/p&gt;  &lt;p&gt;Delegates exist so that you do not have to place automation related code in you standard components, after all, most people don’t want to run their applications with automation support. Delegates are provided for all the framework classes and will generally work out of the box for any framework class you extend. The need to write custom delegates arises if you create a custom component that directly extends UIComponent or if you have complex requirements for a component which already has a framework provided delegate. &lt;/p&gt;  &lt;p&gt;A delegate has to be created for each custom class. Example: &lt;/p&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;package &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;{ &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import flash.display.DisplayObject; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.core.IInvalidating; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import randomWalkClasses.RandomWalkEvent; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.IAutomationObject; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.AutomationIDPart; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.delegates.core.UIComponentAutomationImpl; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.IAutomationObjectHelper; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.Automation; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import mx.automation.events.AutomationRecordEvent; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;import flash.events.Event; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;[Mixin] &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;public class RandomWalkDelegate extends UIComponentAutomationImpl &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;{ &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private var walker:RandomWalk &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public function RandomWalkDelegate(randomWalk:RandomWalk) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; super(randomWalk); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; randomWalk.addEventListener(RandomWalkEvent.ITEM_CLICK, itemClickHandler); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; randomWalk.addEventListener(AutomationRecordEvent.RECORD, labelRecordHandler); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; walker = randomWalk; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public static function init(obj:DisplayObject):void &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Automation.registerDelegateClass(RandomWalk, RandomWalkDelegate); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function itemClickHandler(event:RandomWalkEvent):void &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; recordAutomatableEvent(event); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public function labelRecordHandler(event:AutomationRecordEvent):void &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // if the event is not from the owning component reject it.&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if(event.replayableEvent.target != uiComponent) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //event.preventDefault(); can also be used. &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; event.stopImmediatePropagation(); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override public function get numAutomationChildren():int &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var numChildren:int = 0; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var renderers:Array = walker.getItemRenderers(); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for(var i:int = 0;i&amp;lt; renderers.length;i++) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; numChildren += renderers[i].length; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return numChildren; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override public function getAutomationChildAt(index:int):IAutomationObject &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var numChildren:int = 0; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var renderers:Array = walker.getItemRenderers(); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for(var i:int = 0;i &amp;lt; renderers.length;i++) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if(index &amp;gt;= numChildren) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if(i+1 &amp;lt; renderers.length &amp;amp;&amp;amp; (numChildren + renderers[i].length) &amp;lt;= index) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; numChildren += renderers[i].length; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; continue; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var subIndex:int = index - numChildren; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var instances:Array = renderers[i];&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return (instances[subIndex] as IAutomationObject); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return null; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override public function createAutomationIDPart(child:IAutomationObject):Object &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var help:IAutomationObjectHelper = Automation.automationObjectHelper; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return help.helpCreateIDPart(this, child);&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override public function resolveAutomationIDPart(part:Object):Array&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var help:IAutomationObjectHelper = Automation.automationObjectHelper; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return help.helpResolveIDPart(this, part as AutomationIDPart);&amp;#160;&amp;#160; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override public function replayAutomatableEvent(event:Event):Boolean &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var help:IAutomationObjectHelper = Automation.automationObjectHelper; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (event is RandomWalkEvent) &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var rEvent:RandomWalkEvent = event as RandomWalkEvent &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; help.replayClick(rEvent.itemRenderer); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (uiComponent as IInvalidating).validateNow(); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true; &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return super.replayAutomatableEvent(event); &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;} &lt;/font&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;font face="Courier New" size="1"&gt;} &lt;/font&gt;&lt;/h1&gt;  &lt;p&gt;The TEAFlexCustom.xml for Mercury on all machines that intend to do automation has to be updated to include details about the custom class. Example: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;TypeInformation xsi:noNamespaceSchemaLocation=&amp;quot;ClassesDefintions.xsd&amp;quot; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;Priority=&amp;quot;0&amp;quot; PackageName=&amp;quot;TEA&amp;quot; Load=&amp;quot;true&amp;quot; id=&amp;quot;Flex&amp;quot; xmlns:xsi=&amp;quot;http:/ &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;/www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ClassInfo Name=&amp;quot;FlexRandomWalk&amp;quot; GenericTypeID=&amp;quot;randomwalk&amp;quot; Extends=&amp;quot;FlexObject&amp;quot; SupportsTabularData=&amp;quot;false&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;FlexRandomWalk&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Implementation Class=&amp;quot;RandomWalk&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TypeInfo&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Operation Name=&amp;quot;Select&amp;quot; PropertyType=&amp;quot;Method&amp;quot; ExposureLevel=&amp;quot;CommonUsed&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Implementation Class=&amp;quot;randomWalkClasses::RandomWalkEvent&amp;quot; Type=&amp;quot;itemClick&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Argument Name=&amp;quot;itemRenderer&amp;quot; IsMandatory=&amp;quot;true&amp;quot; &amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot; Codec=&amp;quot;automationObject&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;User clicked item&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Argument&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Operation&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/TypeInfo&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Properties&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;automationClassName&amp;quot; ForDescription=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;To be written.&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;automationName&amp;quot; ForDescription=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;The name used by the automation system to identify an object.&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;className&amp;quot; ForDescription=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;To be written.&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;id&amp;quot; ForDescription=&amp;quot;true&amp;quot; ForVerification=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;Developer-assigned ID.&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;automationIndex&amp;quot; ForDescription=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;String&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;The object's index relative to its parent.&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Property Name=&amp;quot;openChildrenCount&amp;quot; ForVerification=&amp;quot;true&amp;quot; ForDefaultVerification=&amp;quot;true&amp;quot;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Type VariantType=&amp;quot;Integer&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Description&amp;gt;Number of children open currently&amp;lt;/Description&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Property&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Properties&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ClassInfo&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;lt;/TypeInformation&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3.2 File Selection fails to playback&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When playing back the selection of a file in a System32 file dialog, the following error is thrown in QTP with the message “Object not visible”: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-hML3msLz1v4/TkRnJon6ySI/AAAAAAAAAP0/pX1SBFVlcmI/s1600-h/image041%25255B3%25255D.png"&gt;&lt;img title="image041" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="211" alt="image041" src="http://lh5.ggpht.com/-zpQ0p7bBijc/TkRnKLo0nxI/AAAAAAAAAP4/ilE8Oyzo1zk/image041_thumb%25255B1%25255D.png?imgmax=800" width="374" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Dual Monitors    &lt;br /&gt;Reference: &lt;a href="http://forums11.itrc.hp.com/service/forums/questionanswer.do?threadId=1200371"&gt;http://forums11.itrc.hp.com/service/forums/questionanswer.do?threadId=1200371&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: This error is sometimes thrown when the browser, the secondary window (the file dialog), and QTP are not all in the same monitor. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Display all the windows in the same monitor. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3.3 QTP Playback is slow&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Cause #1&lt;/strong&gt;: Bug with automation in Flex 3 SDK&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Reference: &lt;a href="http://bugs.adobe.com/jira/browse/FLEXENT-749"&gt;http://bugs.adobe.com/jira/browse/FLEXENT-749&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: QTP playback is slower because of the implementation of automation libraries for Flex in the version 3 SDK. The issue does not exist in the version 2 SDK and has been resolved in the 4 SDK. &lt;/p&gt;  &lt;p&gt;This is specifically because deep container hierarchies are slow to iterate through. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Reference: &lt;a href="http://raniskumar.wordpress.com/2009/08/26/slow-replay-of-scripts-in-flex3/"&gt;http://raniskumar.wordpress.com/2009/08/26/slow-replay-of-scripts-in-flex3/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In the Flex 3 SDK automation scripts are significantly slower in deep component and container hierarchies. This is because the scripts have to iterate through the entire hierarchy in order to find the component that is being used. This issue was resolved in the Flex 4 SDK, &lt;/p&gt;  &lt;p&gt;For example pressing the upload button to open the file dialog took 4 minutes, because the button is so deep within the hierarchy. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Potential Workaround&lt;/strong&gt;: Set the automationName of the container and component&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Reference: &lt;a href="http://help.adobe.com/en_US/Flex/4.0/html/WS2db454920e96a9e51e63e3d11c0bf69084-7a4b.html"&gt;http://help.adobe.com/en_US/Flex/4.0/html/WS2db454920e96a9e51e63e3d11c0bf69084-7a4b.html&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Workaround Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The automationName is a property available every component which designates the name that is used to identify a component in test automation. If no automationName is specified in Flex containers use their id attribute, and if no id attribute is present the container will have an automationName generated for it prefixed with “index”. Buttons however use the value of their label as their automationName when it is not specified. &lt;/p&gt;  &lt;p&gt;It was theorized that setting the automationName may allow quicker access to the component, without having to iterate through the entire component container hierarchy, but this did not make a difference. &lt;/p&gt;  &lt;p&gt;For example a button without an automationName would be accessed in QTP like the following: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Browser(#).FlexApplication(“Client”).FlexButton(“Upload and Print”).Click &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Where “Upload and Print” is the generated automationName from the button label, but if automationName were set on the component in flex to “myButton” then the button would be accessed like the following: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Browser(#).FlexApplication(“Client”).FlexButton(“myButton”).Click &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Actual Workaround&lt;/strong&gt;: Set every container in the application hierarchy to showAutomationInHierarchy to true&lt;/p&gt;  &lt;p&gt;References: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://raniskumar.wordpress.com/2009/08/26/slow-replay-of-scripts-in-flex3/"&gt;http://raniskumar.wordpress.com/2009/08/26/slow-replay-of-scripts-in-flex3/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://bugs.adobe.com/jira/browse/FLEXENT-749"&gt;http://bugs.adobe.com/jira/browse/FLEXENT-749&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Workaround Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;By default when QTP has to access a Flex component, it has to access that component by automationName. That component is located within an application by iterating starting with the application container and all of its children until the component within that automationName is found. The result is that a component that is deep within a container hierarchy is slow to find. It is for this reason and others, that it is recommend that Flex applications do not overuse container components. Unfortunately in the case of a large already built application, it is too late to go back and redesign the component container structure. &lt;/p&gt;  &lt;p&gt;The solution is to specify every automationName within a hierarchy in order to limit the looping needed to find a component. This can be done by setting the showAutomtationInHierarchy value on a container to true, which will cause it to be detected in QTP even if that component is not directly involved in the interaction. If a Flex application uses modules to incrementally load itself over time, it is not possible on startup to recursively set the hierarchy value. Instead after a module is loaded, the module and the components within can recursively have this value set. &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;public function configureAutomation(obj:DisplayObject) : void &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;{ &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (obj is Container) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var c:Container = obj as Container; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c.showInAutomationHierarchy = true; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var children:Array = c.getChildren(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for(var i:int=0; i &amp;lt; children.length; i++) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var child:DisplayObject = c.getChildAt(i); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; configureAutomation(child); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="1"&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;For example without this change the Upload button in the Client is accessed using QTP like the following, which requires 4 minutes to process: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Browser(&amp;quot;#&amp;quot;).FlexApplication(&amp;quot;Client&amp;quot;).FlexDividedBox(&amp;quot;workflowUploadBox&amp;quot;).FlexButton(&amp;quot;uploadFirstBtn&amp;quot;).Click &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;When all of the containers have the automation hierarchy set to show, that same button is accessed like the following in QTP and happens instantly: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Browser(&amp;quot;#&amp;quot;).FlexApplication(&amp;quot;Client&amp;quot;).FlexContainer(&amp;quot;index:29&amp;quot;).FlexCanvas(&amp;quot;_DocumentViewModule_DocumentVi&amp;quot;).FlexDividedBox(&amp;quot;workflowUploadBox&amp;quot;).FlexBox(&amp;quot;index:0&amp;quot;).FlexCanvas(&amp;quot;newDocView&amp;quot;).FlexBox(&amp;quot;_NewDocument_VBox1&amp;quot;).FlexCanvas(&amp;quot;uploadView&amp;quot;).FlexBox(&amp;quot;_UploadView_HBox2&amp;quot;).FlexButton(&amp;quot;uploadFirstBtn&amp;quot;).Click &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Cause #2: QTP 9.1 is slow&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Script playback in QTP 9.1 is very slow, and switching to 9.5 makes the playback significantly faster. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;4. Maintainability Concerns&lt;/h2&gt;  &lt;p&gt;This is a concern with Flex and HTML based user interface drivers, in which the actor has to know the ID of the component in order to play back some action on it. In languages like JSF and Flex you don’t have to give an XML component an ID, which results in that component getting a dynamically generated ID.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-_7p7cQld-UE/TkRnKe8wRpI/AAAAAAAAAP8/l6gG_9TWUNg/s1600-h/image001%25255B5%25255D.png"&gt;&lt;img title="image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="416" alt="image001" src="http://lh3.ggpht.com/-PtGSHtErNXM/TkRnKhKQlDI/AAAAAAAAAQA/DLNh_V8vU2k/image001_thumb%25255B3%25255D.png?imgmax=800" width="536" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In Flex the problem is that when a component is not explicitly named, that name is calculated at compile time. The problem with the generated name is that it is based on a component’s position in its hierarchy. For example when a new Canvas is added, the names of the other two canvases change as shown by the highlighting in red. &lt;/p&gt;  &lt;p&gt;It should also be noted that buttons are labeled by their text, which means of the text on the button changes the script will also have to change. &lt;/p&gt;  &lt;p&gt;In order to ensure that a component’s name to QTP is always the same, the developer has to set the component’s automation name in the code for buttons and labels, and the component’s ID for boxes and canvases. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-1329058128815300787?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/1329058128815300787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=1329058128815300787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1329058128815300787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1329058128815300787'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2011/08/flex-3-test-automation-using-qtp.html' title='Flex 3 Test Automation using QTP'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-zpQ0p7bBijc/TkRnKLo0nxI/AAAAAAAAAP4/ilE8Oyzo1zk/s72-c/image041_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-3744786566453437785</id><published>2010-09-01T15:55:00.003-06:00</published><updated>2010-09-03T05:58:13.376-06:00</updated><title type='text'>Building a Custom 2D Map Component from Scratch using Virtual Earth</title><content type='html'>&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Bing Maps Tile System (http://msdn.microsoft.com/en-us/library/bb259689.aspx) - Describes the tiling system and gives C# code for converting between coordinate systems. &lt;/li&gt;    &lt;li&gt;Virtual Earth Deep Zooming (&lt;a href="http://www.silverlightshow.net/items/Virtual-earth-deep-zooming.aspx"&gt;http://www.silverlightshow.net/items/Virtual-earth-deep-zooming.aspx&lt;/a&gt;) - Among other things it describes the URL format for tiles. &lt;/li&gt;    &lt;li&gt;Calculate distance, bearing and more between two Latitude/Longitude points (http://www.movable-type.co.uk/scripts/latlong.html) &lt;/li&gt;    &lt;li&gt;Geographic coordinate system (&lt;a href="http://en.wikipedia.org/wiki/Geographic_coordinate_system"&gt;http://en.wikipedia.org/wiki/Geographic_coordinate_system&lt;/a&gt;) - Expressing latitude and longitude as linear units &lt;/li&gt;    &lt;li&gt;Ricky's Bing Map Blog (http://rbrundritt.spaces.live.com/) - Almost everything you would ever need to know about working with Virtual Earth with examples and math. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Why?&lt;/b&gt; Because in the technology you are using a map component does not exist, or you are unable to use the existing map component for some reason.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Coordinate Systems&lt;/b&gt; There are several coordinate systems involved with using a tile service like Virtual Earth. Virtual Earth and other tile services divide the world in to fixed size tiles at different zoom levels denoted by z, where the number total number of tiles is 2&lt;sup&gt;2z&lt;/sup&gt;. The map in this example is at zoom level 3 so there are 64 tiles total, and is derived from the images in Virtual Earth article in the Microsoft Bing Help Docs (http://msdn.microsoft.com/en-us/library/bb259689.aspx). &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/TIAa-46f_qI/AAAAAAAAAK0/zVXWf3TpAAM/s1600-h/01_coordinate_system%5B3%5D.png"&gt;&lt;img title="01_coordinate_system" style="border: 0px none; display: inline;" alt="01_coordinate_system" src="http://lh6.ggpht.com/_QipvL9yNmJU/TIAa_jZvAVI/AAAAAAAAAK4/2l5sYaUcrPE/01_coordinate_system_thumb%5B1%5D.png?imgmax=800" border="0" width="583" height="444" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The &lt;b&gt;world geographic coordinate system&lt;/b&gt; (represented in black) is in latitude and longitude and runs from approximately 85 to -85 latitudes and -180 to 180 longitudes. Due to the way the earth in compressed in a tiled map, the lines of latitude are now evenly spaced even through they are the same pixel distance apart. This requires a formula to be used to determining latitude that takes into account this difference.&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;tile coordinate system&lt;/b&gt; (represented in red) is in row and column, and describes the position of tiles on the world map. All tiles are of a fixed size, though typically at a size of 256 pixels as in the example map, and run from top left to bottom right. Positions in between the upper left corners of tiles are represented using decimal values, so for example (1.5, 0.5) would be in the exact center of tile (1.0, 0.0).&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;world pixel coordinate system&lt;/b&gt; (represented in blue) is in x and y, and runs from top left to bottom right. It is used to describe the tile coordinate system where tile (0, 0) corresponds to pixel (0, 0). The map size in pixels is t&lt;sub&gt;s&lt;/sub&gt;(2&lt;sup&gt;z&lt;/sup&gt;),where the tile size is denoted as t&lt;sub&gt;s&lt;/sub&gt; and is 256 while z denotes the zoom level and is 3 in the case of the example map.&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;screen pixel coordinate system&lt;/b&gt; (represented in green) is in x and y, and describes the position of the screen (actually the component displaying the map) in relation to the world map. Because at most zoom levels the world map in pixels is larger than any monitor can display, only the portion of the map which can be seen within the map component is rendered. This means that the size of the component being displayed is dynamic and dependent on the specific application’s usage, as well as how the local x and y relates to the global x and y of the world pixel coordinate system.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;General Formulas and Notations&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The following is a list of several commonly used formulas and terms.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbAeiYwwI/AAAAAAAAAK8/9ML2wKNitqs/s1600-h/02_formulas%5B3%5D.png"&gt;&lt;img title="02_formulas" style="border: 0px none; display: inline;" alt="02_formulas" src="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbBNizd7I/AAAAAAAAALA/kOVRvaTeWbk/02_formulas_thumb%5B1%5D.png?imgmax=800" border="0" width="602" height="505" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Latitude and longitude to row by column&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This formula is used to turn a latitude and longitude form the world geographic coordinate system into a and row by column value in the tile coordinate system.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbBaFqQTI/AAAAAAAAALE/ttlLAvTWrw8/s1600-h/03_lat_and_lon%5B3%5D.png"&gt;&lt;img title="03_lat_and_lon" style="border: 0px none; display: inline;" alt="03_lat_and_lon" src="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbBxObZ8I/AAAAAAAAALI/bZBx75UvanQ/03_lat_and_lon_thumb%5B1%5D.png?imgmax=800" border="0" width="275" height="246" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;World x and y to latitude and longitude&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This formula is used to convert and x and y position in the world pixel coordinate system to a latitude and longitude in the world geographic coordinate system.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbCFua1CI/AAAAAAAAALM/lRq0Td8lMHc/s1600-h/04_xy_to_lat_lon%5B3%5D.png"&gt;&lt;img title="04_xy_to_lat_lon" style="border: 0px none; display: inline;" alt="04_xy_to_lat_lon" src="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbCTqk1UI/AAAAAAAAALQ/B1nTP-x7vKo/04_xy_to_lat_lon_thumb%5B1%5D.png?imgmax=800" border="0" width="333" height="192" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Requesting Tiles &lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbCgukKNI/AAAAAAAAALU/wZQBf67KhL8/s1600-h/05_requesting_tiles%5B8%5D.png"&gt;&lt;img title="05_requesting_tiles" style="border: 0px none; display: inline;" alt="05_requesting_tiles" src="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbDAC-xjI/AAAAAAAAALY/1MqjRB310dA/05_requesting_tiles_thumb%5B6%5D.png?imgmax=800" border="0" width="644" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Tiles are requested based on retrieving them one at a time from a URL. How a URL is generated depends on the particular tile server and in the case of this map component only the Virtual Earth tile servers are used. The URL is used to specify the type of image, its zoom and location, and its file type. All files types in Virtual Earth are of PNG or JPG, and the location must be given using the quad key. The quad key is a compressed representation of the tile location using the row, column, and zoom.&lt;/p&gt;  &lt;p&gt;The following shows how to generate a quad key using the row, column, and zoom using a Java-like syntax:&lt;/p&gt;  &lt;p&gt;String tileToQuadKey(int r, int c, int z) { &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;String quadKey = ""; &lt;/p&gt;    &lt;p&gt;for (int i = z; i &amp;gt; 0; i—) { &lt;/p&gt;    &lt;p&gt;    char digit = '0'; int mask = 1 &amp;lt;&amp;lt; (i - 1); &lt;/p&gt;    &lt;p&gt;    if ((c &amp;amp; mask) != 0) &lt;/p&gt;    &lt;p&gt;        digit++; &lt;/p&gt;    &lt;p&gt;    if ((r &amp;amp; mask) != 0) { &lt;/p&gt;    &lt;p&gt;        digit++; digit++; &lt;/p&gt;    &lt;p&gt;    } &lt;/p&gt;    &lt;p&gt;    quadKey += (digit + ""); &lt;/p&gt;    &lt;p&gt;} &lt;/p&gt;    &lt;p&gt;return quadKey;&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;Tile Request and Display Optimization&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Only the tiles which are within view of the screen (component) need to be displayed, which means that those should be the only ones to be requested. Once a tile is displayed in order to cut down on loading and rendering time the map component stores the tile, and when it is no longer in view keeps the tile in memory but removes it from the display. For example if the map is to be centered at the tile location of (3.5, 3.5) and is component displaying the map is only large enough to display half of each surrounding tile, than only 9 tiles need to be requested.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbDmndb-I/AAAAAAAAALc/l7QIGZWe-Bc/s1600-h/06_tile_request_1%5B2%5D.png"&gt;&lt;img title="06_tile_request_1" style="border: 0px none; display: inline;" alt="06_tile_request_1" src="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbEMx6tAI/AAAAAAAAALg/qMQrwMJs0mg/06_tile_request_1_thumb.png?imgmax=800" border="0" width="126" height="125" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In the event that the screen moves up into the next row of tiles the tiles that are now in view should be requested and displayed, while the three tiles that are no longer displayed should be cached.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbEYtdkqI/AAAAAAAAALk/NOFjDQtGPyE/s1600-h/07_tile_request_2%5B2%5D.png"&gt;&lt;img title="07_tile_request_2" style="border: 0px none; display: inline;" alt="07_tile_request_2" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbE7jZ8cI/AAAAAAAAALo/Z1XZITX_s_U/07_tile_request_2_thumb.png?imgmax=800" border="0" width="128" height="169" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In order to know which tiles to display and where a center coordinate must be known. Given that center coordinate and the size of the area that will display the map, the tiles to be displayed and their position within that component can be determined.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Determining the tiles to be displayed in the current screen using a center coordinate&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbFDlbMsI/AAAAAAAAALs/fDVQNOGTDJ4/s1600-h/08_tiles_current_screen%5B3%5D.png"&gt;&lt;img title="08_tiles_current_screen" style="border: 0px none; display: inline;" alt="08_tiles_current_screen" src="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbFcB48FI/AAAAAAAAALw/YksnHR6W1oA/08_tiles_current_screen_thumb%5B1%5D.png?imgmax=800" border="0" width="247" height="420" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Given a coordinate in latitude and longitude to be the center on the map to be displayed, that coordinate can be converted to a tile location in row by column. By using that row and column the range of tiles to be retrieved and displayed can be determined using the amount of space available on the screen and the tile size. The row and column minimums and maximums denote the range of tiles to be displayed, and the delta x and y are used to calculate the pixel distance from the center of the center tile to its upper left corner. This is used to determine how many tiles can fit above, below, to the right of, and to the left of the center tile according to its current position in the center of the screen.&lt;/p&gt;  &lt;p&gt;For example if the center coordinate translated to (c, r) = (2.5, 4.5 ) at zoom level 3 and the screen was 512 by 512 pixels, then the column and row minimums and maximums would be calculated as approximately the tiles needed to cover the size of the current screen.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbF6kTw3I/AAAAAAAAAL0/uhmrEFPYrKU/s1600-h/09_tiles_current_screen_example%5B3%5D.png"&gt;&lt;img title="09_tiles_current_screen_example" style="border: 0px none; display: inline;" alt="09_tiles_current_screen_example" src="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbGB-foOI/AAAAAAAAAL4/5dDqF_2gPto/09_tiles_current_screen_example_thumb%5B1%5D.png?imgmax=800" border="0" width="452" height="150" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Positioning tiles relative to center&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;With the range or rows and columns for all tiles to display, given the row and column of a tile its local position in x,y is calculated in the following way:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbGrnfgRI/AAAAAAAAAL8/x2ek2fkgHyQ/s1600-h/10_position_tiles_relative_to_center%5B3%5D.png"&gt;&lt;img title="10_position_tiles_relative_to_center" style="border: 0px none; display: inline;" alt="10_position_tiles_relative_to_center" src="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbHIOnhrI/AAAAAAAAAMA/_xmfgGMJ02k/10_position_tiles_relative_to_center_thumb%5B1%5D.png?imgmax=800" border="0" width="248" height="333" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The x,y local of the tile of the given row and column is calculated relative to the position of the center image. This is done so that panning movement can be calculated relative to the center position of the screen, in order to calculate a simple offset that can be applied to all tiles in order to handle map panning. For example if the center tile location was (c,r) = (2.5, 4.5) and the screen was 512 by 512 pixels, the position of the tile at (c,r) = (1, 3) relative to the center tile would be at (x,y) = (-256, -256).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbHXHE5FI/AAAAAAAAAME/bYfphqC49w0/s1600-h/11_position_tiles_relative_example%5B3%5D.png"&gt;&lt;img title="11_position_tiles_relative_example" style="border: 0px none; display: inline;" alt="11_position_tiles_relative_example" src="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbHqH3kEI/AAAAAAAAAMI/DYZEINNsljU/11_position_tiles_relative_example_thumb%5B1%5D.png?imgmax=800" border="0" width="407" height="210" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Handling Map Panning&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The end result is that the user should be able to click and drag the map in order to move it around (or to pan). This requires keeping track of where the mouse was clicked, where it was dragged to, and when it was released (to stop worrying about where it is being dragged). During a drag the difference between the current mouse location and the location of the original click can be calculated, and then used to determine the new offset to apply to the map along with the new visible rows and columns.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbINKXVwI/AAAAAAAAAMM/2L2890NNnVM/s1600-h/12_map_panning%5B3%5D.png"&gt;&lt;img title="12_map_panning" style="border: 0px none; display: inline;" alt="12_map_panning" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbIemTQaI/AAAAAAAAAMQ/X56_0FKEZSI/12_map_panning_thumb%5B1%5D.png?imgmax=800" border="0" width="365" height="491" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The variables such as the x,y and r,c min and max values need to be kept track of through the map component life cycle. This is because positioning is done using an offset based on the starting location of the center tile. The offset is calculated using the inverse of the change in mouse position during the click and drag. For example if the user clicks on the map and drags right, more of the map needs to be proportionally drawn to the left. The x and y min and max are used to track the size of the tile area in pixels, in order to determine the how many more tiles are needed at the new map boundaries in terms of rows and columns.&lt;/p&gt;  &lt;p&gt;The following shows how the variables in the map panning equation are changed when the screen view (512 by 512 pixels) is moved up on the map by 256 pixels:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbI_-eJUI/AAAAAAAAAMU/ETSDGC92s2w/s1600-h/13_map_panning_example%5B4%5D.png"&gt;&lt;img title="13_map_panning_example" style="border: 0px none; display: inline;" alt="13_map_panning_example" src="http://lh3.ggpht.com/_QipvL9yNmJU/TIAbJc6B0PI/AAAAAAAAAMY/WVSqTPOsopY/13_map_panning_example_thumb%5B2%5D.png?imgmax=800" border="0" width="644" height="302" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Zooming in on a Set of Locations&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbJ3clw9I/AAAAAAAAAMc/6cE64pPg7iI/s1600-h/14_zooming%5B4%5D.png"&gt;&lt;img title="14_zooming" style="border: 0px none; display: inline;" alt="14_zooming" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbKbbvT8I/AAAAAAAAAMg/1hDMvUHe6sc/14_zooming_thumb%5B2%5D.png?imgmax=800" border="0" width="644" height="214" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A function available within most maps is the ability for the map to determine the zoom level to best fit a series of points, and center appropriately. This is generally done by determining the area required in order to display a number of points, and determining the closest matching meters/pixels zoom level and then centering appropriately. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Determining the geographic display area&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The geographic display area is determined by taking the minimum and maximum latitudes and longitudes of the list of geographic position, which can be used to construct the geographic positions denoted as A,B, and C. Note that this method for determining geographic bounds will not work across the corners of the map.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbLXgeREI/AAAAAAAAAMk/l3BH_Wq4_3I/s1600-h/15_geo_display_area%5B3%5D.png"&gt;&lt;img title="15_geo_display_area" style="border: 0px none; display: inline;" alt="15_geo_display_area" src="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbL91UIPI/AAAAAAAAAMo/TyEyl47a__8/15_geo_display_area_thumb%5B1%5D.png?imgmax=800" border="0" width="260" height="248" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Calculating the distance between two geographic points&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;After determining the geographic display area that is required in terms of the rectangle ABC, the distance from geographic coordinates A to B and B to C needs to be calculated. This requires the ability to calculate the distance between two geographic coordinates, which is described in the following as the function d(A, B):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/TIAbMFmvtLI/AAAAAAAAAMs/_xsmqAKk3-c/s1600-h/16_calc_geo_distance%5B3%5D.png"&gt;&lt;img title="16_calc_geo_distance" style="border: 0px none; display: inline;" alt="16_calc_geo_distance" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbMlw-4TI/AAAAAAAAAMw/NNkTaX7cghQ/16_calc_geo_distance_thumb%5B1%5D.png?imgmax=800" border="0" width="541" height="387" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Calculating the Desired Meters per Pixel&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;With the the ability to calculate the distance between geographic coordinates, the size of the geographic area to be zoomed in on can be calculated by determining the meters per pixel required to cover the area. This formula assumes a fairly square screen, because it takes the largest distance and meters against the smallest pixel length of the required screen area.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbM6sGuDI/AAAAAAAAAM0/6fhMmsE5-lY/s1600-h/17_meters_per_pixel%5B3%5D.png"&gt;&lt;img title="17_meters_per_pixel" style="border: 0px none; display: inline;" alt="17_meters_per_pixel" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbNRHfBMI/AAAAAAAAAM4/K1PDASGNAfQ/17_meters_per_pixel_thumb%5B1%5D.png?imgmax=800" border="0" width="229" height="347" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For example using the distances AB and BC, since AB is the largest it is used to calculate the meters per pixels required to display all of the points within the area of rectangle ABC with center G.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbNz8-ImI/AAAAAAAAAM8/seo0_7qnFak/s1600-h/18_meters_per_pixel_example%5B3%5D.png"&gt;&lt;img title="18_meters_per_pixel_example" style="border: 0px none; display: inline;" alt="18_meters_per_pixel_example" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbOVTvCMI/AAAAAAAAANA/zjtwtvzkVw8/18_meters_per_pixel_example_thumb%5B1%5D.png?imgmax=800" border="0" width="326" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Finding Zoom Level based on Meters Per Pixel&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/TIAbO5OCm2I/AAAAAAAAANE/KOzjH6o1RzA/s1600-h/19_table_meters%5B3%5D.png"&gt;&lt;img title="19_table_meters" style="border: 0px none; display: inline;" alt="19_table_meters" src="http://lh5.ggpht.com/_QipvL9yNmJU/TIAbPPdwGLI/AAAAAAAAANI/FN_upwyOpC8/19_table_meters_thumb%5B1%5D.png?imgmax=800" border="0" width="600" height="846" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Table from http://msdn.microsoft.com/en-us/library/bb259689.aspx)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-3744786566453437785?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/3744786566453437785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=3744786566453437785' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3744786566453437785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3744786566453437785'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2010/09/building-custom-2d-map-component-in-any.html' title='Building a Custom 2D Map Component from Scratch using Virtual Earth'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_QipvL9yNmJU/TIAa_jZvAVI/AAAAAAAAAK4/2l5sYaUcrPE/s72-c/01_coordinate_system_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-3638573190223648674</id><published>2010-03-24T18:14:00.011-06:00</published><updated>2010-03-24T18:43:27.945-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>A Flex Ant Build: Optimized Modules, Libraries, Runtime CSS, HTML Wrapper,  Runtime Images</title><content type='html'>&lt;div&gt;A common need in a system involving Flex is for the ability to build the Flex portion using Ant. While there are some online examples, there is not one that I have been able to find that does and describes all of the things I typically need to do in Flex . The things which I typically need to do are the following:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Build optimized modules without having to declare a separate compile target for every module&lt;/li&gt;&lt;li&gt;Include one or more SWC libraries&lt;/li&gt;&lt;li&gt;Compile the CSS into a SWF to be loaded at runtime&lt;/li&gt;&lt;li&gt;Create a custom HTML wrapper, that is also responsible for setting the application endpoint&lt;/li&gt;&lt;li&gt;Including images to be loaded at runtime&lt;/li&gt;&lt;li&gt;Uses a properties file to define all the elements&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This build also assumes the following:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;There is one source directory called "src"&lt;/li&gt;&lt;li&gt;Runtime images are somewhere under the source directory&lt;/li&gt;&lt;li&gt;CSS is somewhere under the source directory&lt;/li&gt;&lt;li&gt;All modules are in a single directory, that contains nothing but the modules&lt;/li&gt;&lt;li&gt;You have the Flex ant task JAR in libs&lt;/li&gt;&lt;li&gt;You have the Ant Contrib JAR in libs&lt;/li&gt;&lt;li&gt;You have a separate index.template.html for the build that contains ${} variables for the endpoint&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For example the following is my example project directory structure:&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_QipvL9yNmJU/S6qt6NXT38I/AAAAAAAAAKY/l8ayMUQUThY/s400/dir_structure.png" style="cursor:pointer; cursor:hand;width: 185px; height: 400px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5452361514416857026" /&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;The build works by executing these targets as part of its default target:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;clean&lt;/b&gt; - deletes the deployment directory&lt;/li&gt;&lt;li&gt;&lt;b&gt;compile&lt;/b&gt; - compiles the main application into its SWF&lt;/li&gt;&lt;li&gt;&lt;b&gt;compile-modules&lt;/b&gt; - uses a "for" loop on all the MXML files in the modules directory and calls the "compile-module" target on them&lt;/li&gt;&lt;li&gt;&lt;b&gt;compile-module &lt;/b&gt;- compiles a module into a SWF file, optimized for the main application&lt;/li&gt;&lt;li&gt;&lt;b&gt;compile-css&lt;/b&gt; - compiles the CSS into a SWF&lt;/li&gt;&lt;li&gt;&lt;b&gt;compile-wrapper&lt;/b&gt; - builds the HTML wrapper for the application, and includes the endpoint using FlashVars&lt;/li&gt;&lt;li&gt;&lt;b&gt;copy-images&lt;/b&gt; - Copies runtime images from source into deployment&lt;/li&gt;&lt;li&gt;&lt;b&gt;clean-up&lt;/b&gt; - deletes any generated files&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Here are the build files:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://modular.theflexsite.net/blog/ant/build.properties"&gt;build.properties&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://modular.theflexsite.net/blog/ant/build.xml"&gt;build.xml&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://modular.theflexsite.net/blog/ant/index.template.build.jsp"&gt;index.template.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&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/8852543472291091913-3638573190223648674?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/3638573190223648674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=3638573190223648674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3638573190223648674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3638573190223648674'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2010/03/flex-ant-build-optimized-modules_24.html' title='A Flex Ant Build: Optimized Modules, Libraries, Runtime CSS, HTML Wrapper,  Runtime Images'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_QipvL9yNmJU/S6qt6NXT38I/AAAAAAAAAKY/l8ayMUQUThY/s72-c/dir_structure.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-3357716525757166183</id><published>2010-02-09T22:35:00.004-06:00</published><updated>2010-02-09T22:41:07.017-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Dear John, what is the easiest way to use Flex modules?</title><content type='html'>&lt;i&gt;Question asked by Ezra.&lt;/i&gt;
&lt;div&gt;
&lt;/div&gt;&lt;div&gt;When it comes to modules there are two general schools of practice:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Load and cache&lt;/li&gt;&lt;li&gt;Load and unload&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Option 1 is by far the most simple, but since content is never unloaded the application has to be small enough to theoretically be loaded in its entirety. I tend to build most Flex applications under this model.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Option 2 is near impossible depending on the specific implementation. There are many areas beyond what I have written about that can prevent a module from from unloading. I have built applications under this model, and getting things to unload correctly is a massive undertaking.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Implementing option 1 can be as simple as putting a view stack in your main application file and using states to add ModuleLoaders to it, and as complicated as writing your own module manager utility to load modules based on some external configuration. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;An important concept with modules that you must always consider though is compile by reference. When compiling a Flex application into a SWF file, it is that class which inherits from “mx.core.Application” and the referenced classes within its class hierarchy that are compiled into that SWF file along with other embedded resources. Classes that are not referenced in that class hierarchy are not compiled into the application SWF file. This concept of compilation by reference in a Flex application also applies to a Flex module. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Knowledge of compilation by reference and their effects on modules and applications is important, because if an application has reference to a module class in its class hierarchy that module class is compiled into both the module SWF file and application SWF file. This duplication of module class definitions is undesired behavior, since the main purpose of modules is to have code and resources in a location outside of the application SWF file and not within it. Beware that the several examples I have seen in Adobe documentation and elsewhere show the main application give direct reference to the module class that it is trying to load. This results in that module class being compiled into both the main application SWF and the module SWF, which defeats the purpose of using modules. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Modules are also effected greatly by optimization by eliminating class duplication. For example if your main application, ModuleA, and ModuleB reference FOO, if ModuleA and ModuleB are optimized for that application the class definition for FOO is compiled into the main application SWF file. If those modules were not optimized then the class definition for FOO would be compiled into the main application, ModuleA, and ModuleB SWF files.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;All of this means that your modules should be optimized for your specific application, and that your application should not directly reference modules and your modules should not directly reference your application. The following is some pseudo-code that shows how to use states and modules loaders to create a modules application:&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;img src="http://1.bp.blogspot.com/_QipvL9yNmJU/S3I4cAFoVuI/AAAAAAAAAJ0/EGdMNPMcoX0/s400/modules.png" style="cursor:pointer; cursor:hand;width: 400px; height: 235px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5436469753900717794" /&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;This example requires that both a ModuleA.mxml and ModuleB.mxml exist as Flex modules, which results in them getting compiled into their own SWF files. In order to interact with the application I typically create a singleton business object that maintains the current state of the application, shared data, and has the ability to change state.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;For example:&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;[Bindable]&lt;/div&gt;&lt;div&gt;public class AppStateBO {&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static const STATE_A:String = "STATE_A";&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static const STATE_B:String = "STATE_B";&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public var currentState:String = "";&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;//singleton stuff here&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;That why both the main application and each module can have access to the data they need to share and the ability to change the state of the application:&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;[Bindable]&lt;/div&gt;&lt;div&gt;var appState:AppStateBO = AppStateBO.getInstance();&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;...&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;appState.currentState = AppStateBO.STATE_A;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;If the currentState attribute of the main application were bound to appState.currentState then any module with the app state singleton could change the state. There are of course many other ways to do this, but at a minimum you need something to be shared across the app and modules.&lt;/div&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/8852543472291091913-3357716525757166183?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/3357716525757166183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=3357716525757166183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3357716525757166183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3357716525757166183'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2010/02/dear-john-what-is-easiest-way-to-use.html' title='Dear John, what is the easiest way to use Flex modules?'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_QipvL9yNmJU/S3I4cAFoVuI/AAAAAAAAAJ0/EGdMNPMcoX0/s72-c/modules.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-2524665341771114537</id><published>2010-02-09T22:12:00.004-06:00</published><updated>2010-02-09T22:20:40.978-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Dear John, How do I remove Flex bindings on an object?</title><content type='html'>&lt;div&gt;&lt;div&gt;&lt;i&gt;Question asked by Joshua.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia, serif;"&gt;&lt;div&gt;Removing bindings requires a trick with include namespace mx_internal, which will give you access to parts of components that you would normally not have access to.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;According to the source code for Binding.as (which I believe is not included in the SDK), the bindings are stored in the following places within objects:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;mx_internal _bindings:Array&lt;/li&gt;&lt;li&gt;mx_internal _watchers:Array&lt;/li&gt;&lt;li&gt;mx_internal _bindingsByDefinitions&lt;/li&gt;&lt;li&gt;mx_internal _bindingsBeginWithWord&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The following function can then be used to clear bindings on an object:&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_QipvL9yNmJU/S3Iz-Q2q9qI/AAAAAAAAAJk/jBRhw_5sPLc/s1600-h/removeBindings.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 278px; height: 320px;" src="http://4.bp.blogspot.com/_QipvL9yNmJU/S3Iz-Q2q9qI/AAAAAAAAAJk/jBRhw_5sPLc/s320/removeBindings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5436464844958791330" /&gt;&lt;/a&gt;
&lt;div&gt;&lt;i&gt;
&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia, serif;"&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-2524665341771114537?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/2524665341771114537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=2524665341771114537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2524665341771114537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2524665341771114537'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2010/02/dear-john-how-do-i-remove-flex-bindings.html' title='Dear John, How do I remove Flex bindings on an object?'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_QipvL9yNmJU/S3Iz-Q2q9qI/AAAAAAAAAJk/jBRhw_5sPLc/s72-c/removeBindings.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-1300974700094799276</id><published>2010-02-09T21:58:00.003-06:00</published><updated>2010-02-09T22:10:25.922-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Dear John, How do I unload Flex modules?</title><content type='html'>&lt;div&gt;&lt;i&gt;Question asked by Joshua.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Unloading modules is a difficult thing to do, and is near to impossible in Flash Player 9. Originally this article clued my into what was going on: &lt;a href="http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html"&gt;http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html&lt;/a&gt;. Essentially to get modules to truly unload you have to get rid of all the references to them, and be using the "Copied Domain Method." The copied domain method is described here in detail, along with its effects on memory: &lt;a href="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html"&gt;http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Assuming you are using the Copied Domain Method, you then have to deal with the following areas of leakage as mentioned in the originating article:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;State and AddChild&lt;/b&gt; – This can cause a leak, sort of, see &lt;a href="http://www.nbilyk.com/flex-states-memory-leak"&gt;http://www.nbilyk.com/flex-states-memory-leak&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Bindings&lt;/b&gt; – Bindings can sometime leak, see http://bugs.adobe.com/jira/browse/SDK-14875&lt;/li&gt;&lt;li&gt;&lt;b&gt;Forcing Garbage Collection&lt;/b&gt; – You have to force GC most of the time to get modules to move along, see &lt;a href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Listeners&lt;/b&gt; – You have to remove listeners when you are done with them.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Using the Current Domain Method&lt;/b&gt; – prevents modules from truly unloading, see &lt;a href="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html"&gt;http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Effects&lt;/b&gt; – Effects in a module will cause it to leak, see &lt;a href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I essentially handled these area of leakages by iterating recursively through every component within a module class after unloading, removing state, removing bindings, removing common listeners, reseting the EffectManager, and then forcing garbage collection using what is called the &lt;a href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html"&gt;local connection hack&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;The problem with this though is that there will always be memory accumulation even if references are removed. This is due to a largely unknown and undocumented issue known as "Rendering memory fragmentation." I have discussed this issue with several engineers at Adobe through a client which I cannot name, and they are at least passively aware of it but it is an issue with the Flash Player itself. The article at &lt;a href="http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/"&gt;http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/&lt;/a&gt; hinted at what was going on, which lead me into a full investigation to verify the problem. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Basically the Flash Player operates on what is called an Elastic Racetrack (h&lt;a href="ttp://www.onflex.org/ted/2005/07/flash-player-mental-model-elastic.php"&gt;ttp://www.onflex.org/ted/2005/07/flash-player-mental-model-elastic.php&lt;/a&gt;), which ends up with the memory used of AS3 object allocation and the memory used for rendering getting on the same page in memory. When the garbage collection runs the allocation space is not cleaned because the blocks contain active rendering memory and vice versa. This makes it to where the garbage collector fails to clean things, which causes leaks. Since the issue is rendering related it is more prevalent in application that are graphically intense and run at large resolutions, like kiosks. It is for these reasons that I recommend that most applications pool modules, so that the rendering and object instantiations through allocations are minimal. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;In the end it will depend on how many "modules" are in your application, how big they are, and if they are really modules. It is quite common for application to incorrectly use modules because they followed the examples released by Adobe, which cause the module definitions themselves to be compiled into both the module SWF and the main application SWF. Flex operates on a compile by reference basis, so if your application has direct reference to a module class that module class gets compiled into both the module SWF and the main application SWF.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-1300974700094799276?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/1300974700094799276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=1300974700094799276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1300974700094799276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1300974700094799276'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2010/02/dear-john-how-do-i-unload-flex-modules.html' title='Dear John, How do I unload Flex modules?'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-4515594826875676350</id><published>2009-07-18T14:38:00.001-06:00</published><updated>2009-08-24T16:01:16.923-06:00</updated><title type='text'>Flex: Building Modular Rich Internet Applications</title><content type='html'>&lt;h3&gt;Why? Because you want to incrementally deliver content&lt;/h3&gt;  &lt;p&gt;A typical model for building a Flex application is to just use one SWF file. That is because by default when you create a Flex project in Flex Builder your main application MXML and all of the classes that it references are compiled into a single SWF file. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SmIysdnH28I/AAAAAAAAAIQ/z_kRxa9MpRw/s1600-h/image%5B2%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SmIys278yFI/AAAAAAAAAIU/gsP_Kd7N2wE/image_thumb.png?imgmax=800" width="226" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Flex Builder then embeds that SWF file in an HTML page where you can then upload it and the Flex content somewhere, and when people visit that page it and the SWF file are downloaded by their browser and Flex application is executed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SmIytEYpruI/AAAAAAAAAIY/aRkxOQA8mnc/s1600-h/image%5B8%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="243" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SmIythOHFLI/AAAAAAAAAIc/NdrW2LaMtzA/image_thumb%5B4%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It helps to conceptualize as an application in terms of its views or screens. For example an application may consist of a screen to login, a screen to create an account, and so on. In the single SWF model that single file contains all of these different views. You begin to get into trouble when you have a lot of different views, which causes the single SWF file to become large.&lt;/p&gt;  &lt;p&gt;For example you could have an application that has 10 different views where each view adds about 200 KB to the application size, the result is that you end up with a 1.95 MB file that the user has to download at one time to run it. This of course would be come a problem when you have a lot more views, views that are larger, or a combination of both.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SmIytysSg9I/AAAAAAAAAIg/c_4NOhRIAjg/s1600-h/image%5B16%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="225" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SmIyuZzT98I/AAAAAAAAAIk/POk0Y189A54/image_thumb%5B8%5D.png?imgmax=800" width="809" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Flex has the ability to use Modules, which allows you to break an application up into parts. Typically one would break an application up into its views (or screens). The result is an application that the end user downloads piece by piece and as needed. For large applications this is a requirement, since users don’t want to have to wait for several minutes of downloading every time they need to use your application.&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SmIyu2Hp9WI/AAAAAAAAAIo/QOY6Sr8HRRA/s1600-h/image%5B20%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="216" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SmIyvQbbbBI/AAAAAAAAAIs/A93-4ZO2AOA/image_thumb%5B10%5D.png?imgmax=800" width="807" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;How?&lt;/h3&gt;  &lt;p&gt;I really haven’t been ever able to find a definitive source that explains all of the different ways to use modules, which is why I am writing this. When it comes to modules there are two general approaches:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;The text-book approach&lt;/strong&gt; – This is the way modules are described in documentation and other Adobe writings, which does not take into account real world functional uses problems. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The pragmatic approach&lt;/strong&gt; – This is the way they are actually used in functioning applications, taking into account the &lt;a href="http://www.imdb.com/title/tt0092086/quotes"&gt;plethora&lt;/a&gt; of bugs. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I will attempt to explain both approaches, with more emphasis on the pragmatic since a working application accompanies this writing.&lt;/p&gt;  &lt;h3&gt;Modules and Application Domains&lt;/h3&gt;  &lt;p&gt;Application Domains in the case of modules are used to determine what parts of a module are actually unloaded when they are unloaded. The following are the two methods in which this functionality is controlled:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Current Domain Method&lt;/strong&gt; – This makes it do modules never really unload, and that their definitions are kept around for the lifetime of the application. The result is modules load faster the second time they are loaded because they never really unloaded in the first place. &lt;img alt="[image9.png]" src="http://lh6.ggpht.com/_QipvL9yNmJU/SjMo_fM9aKI/AAAAAAAAAE4/dmssqUohY1w/s1600/image9.png" border="0" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Copied Domain Method&lt;/strong&gt; – This is the default behavior and is supposed to allow modules to truly unload. The result is that modules always take the same amount of time to after unload since they have to be completely reloaded.&lt;/p&gt;  &lt;p&gt;&lt;img alt="[image17.png]" src="http://lh6.ggpht.com/_QipvL9yNmJU/SjMpAjsYU_I/AAAAAAAAAFI/evXhYHeiitE/s1600/image17.png" border="0" /&gt;&lt;/p&gt;  &lt;p&gt;For more information see the following: &lt;a title="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html" href="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html"&gt;http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;The Realities of Modules&lt;/h3&gt;  &lt;p&gt;Basically looking at a module wrong will cause it not to unload when using the Copied Domain (Default) Method. The following are culprits for the modules persisting, each of which I have implemented resolutions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;State and AddChild&lt;/strong&gt; – This can cause a leak, sort of, see &lt;a title="http://www.nbilyk.com/flex-states-memory-leak" href="http://www.nbilyk.com/flex-states-memory-leak"&gt;http://www.nbilyk.com/flex-states-memory-leak&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Bindings&lt;/strong&gt; – Bindings can sometime leak, see &lt;a title="http://bugs.adobe.com/jira/browse/SDK-14875" href="http://bugs.adobe.com/jira/browse/SDK-14875"&gt;http://bugs.adobe.com/jira/browse/SDK-14875&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Forcing Garbage Collection&lt;/strong&gt; – You have to force GC most of the time to get modules to move along, see &lt;a title="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html" href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Listeners&lt;/strong&gt; – You have to remove listeners when you are done with them. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Using the Current Domain Method&lt;/strong&gt; – prevents modules from truly unloading, see &lt;a title="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html" href="http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html"&gt;http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Effects&lt;/strong&gt; – Effects in a module will cause it to leak, see &lt;a title="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html" href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Even with these resolutions there is ultimately a problem that is an article unto itself regarding how the memory required to render components becomes fragmented over time, eventually preventing objects that should be eligible for collection from by collected. I will get around writing about it and the proof of its existence later, but for right now just be aware of its effects. Its effects are most noticeable in Flex applications that run at high resolutions, because the larger in size the component the more memory that is required for rendering it. &lt;/p&gt;  &lt;p&gt;This basically means that in larger and/or graphically rich applications if you have to render a lot of content over and over you will run out of memory and there is nothing you can do about it. Using the current domain method will mitigate this problem, but then you have to be sure that your application’s definitions can fit within whatever the requirement is for client memory. Even then you will still encounter the problem within rendering memory fragmentation.&lt;/p&gt;  &lt;h3&gt;What can be done?&lt;/h3&gt;  &lt;p&gt;Pool your modules.&lt;/p&gt;  &lt;p&gt;Once a module has been created store its instance and then retrieve it the next time it is needed. This however requires enough memory available to be able to go to every module in the application, or however modules it is possible to go to.&lt;/p&gt;  &lt;p&gt;The result is a memory profile that looks like the following with modules in which the instance never go away:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SmIyvsV3g5I/AAAAAAAAAIw/FhvsHKI1Jws/s1600-h/image%5B28%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="270" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/SmIyv86_zLI/AAAAAAAAAI0/4-Jrvm9isnM/image_thumb%5B14%5D.png?imgmax=800" width="546" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Using this method you can load modules over and over again without having to worry about the issue with rendering memory fragmentation (unless there is a substantial amount of dynamic manually drawn content).&lt;/p&gt;  &lt;p&gt;The resulting secondary load times are also much faster than when using the Current Domain Method:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SmIywKOwaJI/AAAAAAAAAI4/Xp8mNs_DU6A/s1600-h/image%5B32%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="269" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SmIywS8P_UI/AAAAAAAAAI8/x7gzjKJD6KM/image_thumb%5B16%5D.png?imgmax=800" width="546" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;What are my options?&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Pool your modules or don’t&lt;/strong&gt; – If you pool your modules then you need to have enough memory available for the possibility that the user loads a lot of modules. Otherwise you are going to hit the problem with rendering memory fragmentation and run out of memory. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Use the Current Application Domain or the Copied Application Domain Method&lt;/strong&gt; – If you use the copied domain method it will be extremely difficult to get modules to actually unload, and you will eventually run out of memory in most applications due to the problem with rendering memory fragmentation. If you use the current domain method you will mitigate the the rendering memory fragmentation problem, but you will need to be able to have enough space in memory to deal with the possibility of having to store the definitions for a large number of modules. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Force Garbage Collection or don’t&lt;/strong&gt; – If you don’t force garbage collection and you are not pooling modules, then modules sometimes won’t unload. When pooling it will help memory along, but in both cases be aware then forcing garbage collection can cause problems with remoting. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Cleanup on module unload or don’t&lt;/strong&gt; – If you don’t “cleanup” when not using pooling then various instances within modules are likely to leak. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;How are all these options implemented?&lt;/h3&gt;  &lt;p&gt;The following is a test application featuring a ModuleManagerUtil class and a MemoryManager class.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Application&lt;/strong&gt;: &lt;a title="http://modular.theflexsite.net/" href="http://modular.theflexsite.net/"&gt;http://modular.theflexsite.net/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Please be aware that &lt;strong&gt;&lt;font color="#ff0000"&gt;the debug version of the Flash Player always leaks modules&lt;/font&gt;&lt;/strong&gt;, so if you are using the debug player just about everything is going to leak. See the following for more information: &lt;a title="http://jvalentino.blogspot.com/2009/05/flex-memory-tip-1-debug-player-always.html" href="http://jvalentino.blogspot.com/2009/05/flex-memory-tip-1-debug-player-always.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-tip-1-debug-player-always.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SmIyw6yXrpI/AAAAAAAAAJA/mpQOrYOAayQ/s1600-h/image%5B24%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="484" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/SmIyxS3RNZI/AAAAAAAAAJE/pi3exGbZm7I/image_thumb%5B12%5D.png?imgmax=800" width="505" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;About the Sample Application&lt;/h3&gt;  &lt;p&gt;The ModuleManagerUtil class is used to handle loading and pooling modules.&lt;/p&gt;  &lt;p&gt;The MemoryManager class is used to get the current amount of memory in use by the Flash Player and force garbage collection.&lt;/p&gt;  &lt;p&gt;The buttons on the left are used to load different modules. The simple modules just contain panels, the complex modules contain DataGrids, and the popup module will load a module as a popup.&lt;/p&gt;  &lt;p&gt;The bottom of the page is a JavaScript plotting application done using Flot, so display memory without interfering with what is going on in the Flex application.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-4515594826875676350?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/4515594826875676350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=4515594826875676350' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4515594826875676350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4515594826875676350'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/07/flex-building-modular-rich-internet.html' title='Flex: Building Modular Rich Internet Applications'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_QipvL9yNmJU/SmIys278yFI/AAAAAAAAAIU/gsP_Kd7N2wE/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-7899104921524856352</id><published>2009-06-22T21:45:00.001-06:00</published><updated>2009-06-22T21:45:21.864-06:00</updated><title type='text'>Flex + BlazeDS + Google App Engine + Java + Eclipse</title><content type='html'>&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Because you want to write a Flex application that requires that the server be able to push data to the client, you want a highly scalable server so you decided on the Google App Engine, when provided with the option of Python versus Java you found Java more accessible, and Eclipse is an easy way to link it all together.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Flex – used for the graphical user interface &lt;/li&gt;    &lt;li&gt;BlazeDS – used for Flex to Server remote objects and provides the ability for the server to push data to the Flex client &lt;/li&gt;    &lt;li&gt;Google App Engine – used for hosting the server portion of the application &lt;/li&gt;    &lt;li&gt;Java – the language used for constructing the server potion of the application &lt;/li&gt;    &lt;li&gt;Eclipse – an easy way to build, manage, write code, and deploy &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are lots of other options though, in general with Flex you are aiming for a way to deal with remote objects and/or server data push + some way to persist data on a server that ties to some language + some IDE. This is just one of many possible configurations with an emphasis on relatively free parts.&lt;/p&gt;  &lt;p&gt;It is also apparently difficult to get all of things working together, so I thought it would help for others if I shared the steps.&lt;/p&gt;  &lt;p&gt;In this example I basically combined the two following projects into one to use the Google App Engine to show basic remote objects and messaging:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="http://learn.adobe.com/wiki/display/Flex/Creating+a+BlazeDS+messaging+application+in+Flex+Builder" href="http://learn.adobe.com/wiki/display/Flex/Creating+a+BlazeDS+messaging+application+in+Flex+Builder"&gt;http://learn.adobe.com/wiki/display/Flex/Creating+a+BlazeDS+messaging+application+in+Flex+Builder&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a title="http://www.flexlive.net/?p=92" href="http://www.flexlive.net/?p=92"&gt;http://www.flexlive.net/?p=92&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you want more details into the how remote objects and messaging works see those examples.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Eclipse - &lt;a title="http://www.eclipse.org/europa/" href="http://www.eclipse.org/europa/"&gt;http://www.eclipse.org/europa/&lt;/a&gt; (FREE) &lt;/li&gt;    &lt;li&gt;Google App Engine Developer Account - &lt;a title="http://appengine.google.com/" href="http://appengine.google.com/"&gt;http://appengine.google.com/&lt;/a&gt; (FREE) &lt;/li&gt;    &lt;li&gt;Install the Google App Engine Java plug-in for Eclipse - &lt;a title="http://code.google.com/appengine/docs/java/tools/eclipse.html" href="http://code.google.com/appengine/docs/java/tools/eclipse.html"&gt;http://code.google.com/appengine/docs/java/tools/eclipse.html&lt;/a&gt; (FREE) &lt;/li&gt;    &lt;li&gt;Flex Builder plug-in for Eclipse - &lt;a title="http://www.adobe.com/products/flex/features/flex_builder/" href="http://www.adobe.com/products/flex/features/flex_builder/"&gt;http://www.adobe.com/products/flex/features/flex_builder/&lt;/a&gt; ($$$) &lt;/li&gt;    &lt;li&gt;The BlazeDS Binary Distribution- &lt;a title="http://opensource.adobe.com/wiki/display/blazeds/Release+Builds" href="http://opensource.adobe.com/wiki/display/blazeds/Release+Builds"&gt;http://opensource.adobe.com/wiki/display/blazeds/Release+Builds&lt;/a&gt; (FREE) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;1. Creating the Server&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1.1 Press the “New Web Application” button in the Eclipse toolbar&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SkBPo3_WG6I/AAAAAAAAAGA/zjev4cwqUlw/s1600-h/image2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="63" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SkBPpFT9zII/AAAAAAAAAGE/AGsGRHosaAE/image_thumb.png?imgmax=800" width="203" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;1.2 In the “New Web Application Project” window specify a project name, the package, and for the rest use the default settings then press the “Finish” button.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPplc5FxI/AAAAAAAAAGI/AG5xVdllacA/s1600-h/image6.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="601" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPqHh7EoI/AAAAAAAAAGM/d2jNL6POm0I/image_thumb2.png?imgmax=800" width="529" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;1.3 If you are like me and already run another server on port 8080, then you need to change the project settings to use a different port. You can do this by opening the debug menu and selecting “Open Debug Dialog…”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPqZ1HjbI/AAAAAAAAAGQ/mZWGGaKK1KU/s1600-h/image12.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="206" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPqhbd_iI/AAAAAAAAAGU/I1aIHLoiJjE/image_thumb4.png?imgmax=800" width="208" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;1.4 Specify a new port to be used and save these settings.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPq-NDXAI/AAAAAAAAAGY/TZBny8WfvnI/s1600-h/image16.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="223" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPrF3KC3I/AAAAAAAAAGc/eGs6dMHyq5o/image_thumb6.png?imgmax=800" width="389" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. Adding BlazeDS to the Server&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;2.1 Assuming you have obtained the BlazeDS WAR file, unzip it using some ZIP program&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPrZTpSyI/AAAAAAAAAGg/PcHtKh5UuUw/s1600-h/image20.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="336" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPrhZER0I/AAAAAAAAAGk/8wWMQbITTh8/image_thumb8.png?imgmax=800" width="612" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2.2 Open the BlazeDS &lt;strong&gt;web.xml&lt;/strong&gt; file and copy the mappings into the web.xml in your Google test project.&lt;/p&gt;  &lt;p&gt;The web.xml file is located in MyGoogleServer/war/WEB-INF&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPr7VVI6I/AAAAAAAAAGo/akQn8wyKJ1k/s1600-h/image23.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="183" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPsFgQYmI/AAAAAAAAAGs/04C6BW01oy4/image_thumb9.png?imgmax=800" width="225" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The resulting &lt;strong&gt;web.xml&lt;/strong&gt; file should look like the following:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;!DOCTYPE web-app       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PUBLIC &amp;quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&lt;/font&gt;&lt;a href="http://java.sun.com/dtd/web-app_2_3.dtd&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://java.sun.com/dtd/web-app_2_3.dtd&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;web-app&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160; &amp;lt;!-- Default page to serve --&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;welcome-file-list&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;welcome-file&amp;gt;MyGoogleServer.html&amp;lt;/welcome-file&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/welcome-file-list&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;!-- Servlets --&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;servlet&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;greetServlet&amp;lt;/servlet-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-class&amp;gt;com.example.myproject.server.GreetingServiceImpl&amp;lt;/servlet-class&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/servlet&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;servlet-mapping&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;greetServlet&amp;lt;/servlet-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;url-pattern&amp;gt;/mygoogleserver/greet&amp;lt;/url-pattern&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/servlet-mapping&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;!-- Begin BlazeDS Stuff --&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;!-- Http Flex Session attribute and binding listener support --&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listener&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listener-class&amp;gt;flex.messaging.HttpFlexSession&amp;lt;/listener-class&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/listener&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- MessageBroker Servlet --&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;MessageBrokerServlet&amp;lt;/servlet-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;display-name&amp;gt;MessageBrokerServlet&amp;lt;/display-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-class&amp;gt;flex.messaging.MessageBrokerServlet&amp;lt;/servlet-class&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;init-param&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;param-name&amp;gt;services.configuration.file&amp;lt;/param-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;param-value&amp;gt;/WEB-INF/flex/services-config.xml&amp;lt;/param-value&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/init-param&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/servlet&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-mapping&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;MessageBrokerServlet&amp;lt;/servlet-name&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;url-pattern&amp;gt;/messagebroker/*&amp;lt;/url-pattern&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/servlet-mapping&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;/web-app&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;2.3 Copy the BlazeDS &lt;strong&gt;flex&lt;/strong&gt; directory into MyGoogleServer/war/WEB-INF&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPsU-bmuI/AAAAAAAAAGw/3wV4wRfk7_8/s1600-h/image27.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="207" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPsntkX-I/AAAAAAAAAG0/Q0Q7Z8cOp_A/image_thumb11.png?imgmax=800" width="251" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2.4 Open the &lt;strong&gt;services-config.xml&lt;/strong&gt; file and change the three instances of &lt;strong&gt;&lt;font color="#ff0000"&gt;{server.name}:{server.port}/{context.root}&lt;/font&gt;&lt;/strong&gt; to your server name, which in the case of this example is &lt;strong&gt;&lt;font color="#ff0000"&gt;localhost:9000&lt;/font&gt;&lt;/strong&gt;. When you deploy this thing to Google you will of course need to change it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPsz2X76I/AAAAAAAAAG4/gF7LfBtQimU/s1600-h/image31.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="205" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPtIwXuYI/AAAAAAAAAG8/z4ouKloi5UU/image_thumb13.png?imgmax=800" width="252" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;2.5 Open the &lt;strong&gt;appengine-web.xml&lt;/strong&gt; file and add the node &lt;strong&gt;&lt;font color="#ff0000"&gt;&amp;lt;sessions-enabled&amp;gt;true&amp;lt;/sessions-enabled&amp;gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPtdz-yVI/AAAAAAAAAHA/hI9E8gRl9oQ/s1600-h/image35.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="200" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPtqzBfDI/AAAAAAAAAHE/3yzgz6OOlWI/image_thumb15.png?imgmax=800" width="256" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2.6 Copy all of the JAR file in the BlaseDS lib directory to your lib directory, which in this example is MyGoogleServer/war/WEB-INF/lib&lt;/p&gt;  &lt;p&gt;Before copy:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPt1e5J7I/AAAAAAAAAHI/Z6IjhIWJnO8/s1600-h/image39.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="287" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPuWLW-RI/AAAAAAAAAHM/D8auHoezz6g/image_thumb17.png?imgmax=800" width="326" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After copy:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPunVpEFI/AAAAAAAAAHQ/vrlPMPGakA8/s1600-h/image43.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="379" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPu7nkKfI/AAAAAAAAAHU/kMaQue5YHn8/image_thumb19.png?imgmax=800" width="275" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2.7 If your server will be at a different location than your client, then you need to create a &lt;strong&gt;crossdomain.xml&lt;/strong&gt; file to grant the client access.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPvDW0fOI/AAAAAAAAAHY/jDqr4OWu8Q0/s1600-h/image%5B22%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="149" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPvb9pBkI/AAAAAAAAAHc/ZI-Y6j4IvA8/image_thumb%5B10%5D.png?imgmax=800" width="239" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this case I like to share, so I am granting the entire internet access to the web services here. Normally you wouldn’t want to do this for reasons that should be obvious:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;!DOCTYPE cross-domain-policy SYSTEM &amp;quot;&lt;/font&gt;&lt;a href="http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;     &lt;br /&gt;&amp;lt;cross-domain-policy&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;allow-access-from domain=&amp;quot;*&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;/cross-domain-policy&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Creating server-side logic&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;3.1 Create a class that will be used as a remote object that will just return “Hello”&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;package com.example.myproject.hello; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public class Hello {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public String sayHello() {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return &amp;quot;Hello World&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;3.2 Open the &lt;strong&gt;remoting-config.xml&lt;/strong&gt; file and add the following node to map the Hello remote object:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;destination id=&amp;quot;Hello&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;properties&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;source&amp;gt;com.example.myproject.hello.Hello&amp;lt;/source&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/properties&amp;gt;      &lt;br /&gt;&amp;lt;/destination&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;3.3 Open the &lt;strong&gt;messaging-config.xml&lt;/strong&gt; file and add the following node to be able to use the chat variable for messaging:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;destination id=&amp;quot;chat&amp;quot;/&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. Creating the Flex client&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;4.1 Run the Google Server project&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPvWiZJpI/AAAAAAAAAHg/EdsuN9s9ha4/s1600-h/image%5B3%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="97" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/SkBPvm5u2pI/AAAAAAAAAHk/5BTmgJMkskI/image_thumb%5B1%5D.png?imgmax=800" width="207" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.2 From the File menu create a new Flex Project&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPvyHAkTI/AAAAAAAAAHo/o6Aux_pj168/s1600-h/image%5B7%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="115" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPwHcCOEI/AAAAAAAAAHs/hOmOzLXjNVg/image_thumb%5B3%5D.png?imgmax=800" width="575" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.3 Specify the project name and set it to be a J2EE application server and don’t use WTP.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SkBPwqs3RYI/AAAAAAAAAHw/Z2SGkQnhkxI/s1600-h/image%5B36%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPxbRC5vI/AAAAAAAAAH0/RjqWKDNbxHM/image_thumb%5B18%5D.png?imgmax=800" width="517" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.4 Uncheck the box to use the default LiceCycle Data services server and specify the location of the war directory of the Google Server project, and change the URL to reflect the the location of the server. Since I am planning on running the client on a different machine than the server, specify the Output folder to be bin-debug.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SkBPxiUrpgI/AAAAAAAAAH4/bWrtntxznkw/s1600-h/image%5B37%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPyM-yiWI/AAAAAAAAAH8/BruKEqvuVWM/image_thumb%5B19%5D.png?imgmax=800" width="483" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.5 Specify the output folder URL to match the location on your local test server.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPyv8IA9I/AAAAAAAAAIA/G_S4S5GacXI/s1600-h/image%5B38%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SkBPzKFzIUI/AAAAAAAAAIE/_T9PVTahw-s/image_thumb%5B20%5D.png?imgmax=800" width="460" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.6 Run two instance of the Flex application, and notice how the sayHello button tests the Hello.java class, and you can use the Send B button to send message back and forth the the “chat” variable.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SkBPzq34r_I/AAAAAAAAAII/F6NjLnlisy0/s1600-h/image%5B39%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="442" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SkBP0KLS5XI/AAAAAAAAAIM/pTwqvD_pBVw/image_thumb%5B21%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.7 The Flex Code&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;mx:Application xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; creationComplete=&amp;quot;consumer.subscribe()&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:RemoteObject id=&amp;quot;blazeService&amp;quot; fault=&amp;quot;faultHandler(event)&amp;quot; source=&amp;quot;hello.Hello&amp;quot; destination=&amp;quot;Hello&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:method name=&amp;quot;sayHello&amp;quot; result=&amp;quot;resultHandler(event)&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:RemoteObject&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Consumer id=&amp;quot;consumer&amp;quot; destination=&amp;quot;chat&amp;quot; message=&amp;quot;messageHandler(event.message)&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Producer id=&amp;quot;producer&amp;quot; destination=&amp;quot;chat&amp;quot;/&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.rpc.events.ResultEvent;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.rpc.events.FaultEvent;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.messaging.messages.AsyncMessage;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.messaging.messages.IMessage;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function send():void{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var message:IMessage = new AsyncMessage();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; message.body.chatMessage = msg.text;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; producer.send(message);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; msg.text = &amp;quot;&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function messageHandler(message:IMessage):void{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; log.text += message.body.chatMessage + &amp;quot;\n&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function faultHandler(fault:FaultEvent):void {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result_text.text = &amp;quot;code:\n&amp;quot; + fault.fault.faultCode + &amp;quot;\n\nMessage:\n&amp;quot; + fault.fault.faultString + &amp;quot;\n\nDetail:\n&amp;quot; + fault.fault.faultDetail;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function resultHandler(evt:ResultEvent):void {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result_text.text = evt.message.body.toString();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button x=&amp;quot;10&amp;quot; y=&amp;quot;132&amp;quot; label=&amp;quot;sayHello&amp;quot; width=&amp;quot;79&amp;quot; click=&amp;quot;blazeService.getOperation('sayHello').send();&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:TextArea x=&amp;quot;10&amp;quot; y=&amp;quot;27&amp;quot; width=&amp;quot;319&amp;quot; height=&amp;quot;100&amp;quot; id=&amp;quot;result_text&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Chat&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:TextArea id=&amp;quot;log&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:ControlBar&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:TextInput id=&amp;quot;msg&amp;quot; width=&amp;quot;100%&amp;quot; enter=&amp;quot;send()&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;Send B&amp;quot; click=&amp;quot;send()&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:ControlBar&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;5. Last Thoughts&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I haven’t tried it, but apparently if you want to get remoting-only BlazeDS to work you have to do the following hack: &lt;a title="http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html" href="http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html"&gt;http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-7899104921524856352?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/7899104921524856352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=7899104921524856352' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/7899104921524856352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/7899104921524856352'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/06/flex-blazeds-google-app-engine-java.html' title='Flex + BlazeDS + Google App Engine + Java + Eclipse'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_QipvL9yNmJU/SkBPpFT9zII/AAAAAAAAAGE/AGsGRHosaAE/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-369594486737987105</id><published>2009-06-12T22:20:00.001-06:00</published><updated>2009-07-01T11:58:40.245-06:00</updated><title type='text'>Flex Memory Issue #4: Modules and Application Domains</title><content type='html'>&lt;p&gt;“ApplicationDomains are pretty much a neverending source of confusion and suffering…”&lt;/p&gt;  &lt;p&gt;- Roger Gonzales, helped in the design of Application Domains in Flex&lt;/p&gt;  &lt;p&gt;If you are using modules in Flex whether you are aware of it or not, you are using Application Domains. In particular I have had several issues with them and their effects on memory. An Application Domain is a container for discrete groups of classes, which are used to partition classes that are in the same security domain.&lt;/p&gt;  &lt;p&gt;What? Yes, I know. That definition is from Adobe’s asdoc for the ApplicationDomain class, and it really doesn't tell you what it has to do with modules. For a start Roger Gonzales did a great job of explaining the history and purpose of the Application Domain on his blog, located at &lt;a title="http://blogs.adobe.com/rgonzalez/2006/06/applicationdomain.html" href="http://blogs.adobe.com/rgonzalez/2006/06/applicationdomain.html"&gt;http://blogs.adobe.com/rgonzalez/2006/06/applicationdomain.html&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To attempt to summarize the Application Domain it is essentially a way to contain AS3 definitions, which effects how modules load and unload. With modules Application Domains let you do one of two things, which I refer to as the “Current Domain Method” and the “Copied Domain Method”&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Current Domain Method&lt;/strong&gt; &lt;/h3&gt;  &lt;p&gt;Example Usages:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;var info:IModuleInfo = ModuleManager.getModule(&amp;quot;com/foo/FooModule.swf&amp;quot;);      &lt;br /&gt;info.load(ApplicationDomain.currentDomain);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This loads a module into the current Application Domain, so that when it unloads the class definition stays in memory but the rest of the module related instances are supposed to go. The next time the module is loaded the class definitions are already there so it loads faster.&lt;/p&gt;  &lt;p&gt;For example if you have an Application that has 3 modules and you load one module at a time using the Current Domain Method, unload them, and load the next module in the sequence you get the following memory profile assuming you force garbage collection (&lt;a title="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html" href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html&lt;/a&gt;) after each unload:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SjMo_fM9aKI/AAAAAAAAAE4/dmssqUohY1w/s1600-h/image9.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="305" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SjMo_uZZUaI/AAAAAAAAAE8/eOF9u5pRXP8/image_thumb3.png?imgmax=800" width="539" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;* &lt;em&gt;Assumes modules are all the same size, garbage collection is forced after unload, memory snapshot is taken using System.totalMemory, and memory snapshot is taken between unload of previous and load of new&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Notice that the memory peaks after all of the modules are loaded, levels off when those three modules are again loaded, and then only drops down slightly after all the modules are unloaded. The remaining memory isn’t just Flash Player stuff, it is also the definitions for the modules classes. This means that when using the Current Domain Method, modules will never truly unload.&lt;/p&gt;  &lt;p&gt;For another example if you look at the time it takes those module to load for the 3 module scenario using the Current Domain Method, you get the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SjMo__JMUKI/AAAAAAAAAFA/L7rMuoNi-Jk/s1600-h/image3.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="273" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SjMpAY6jvBI/AAAAAAAAAFE/yTFKIAFCdWc/image_thumb1.png?imgmax=800" width="539" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The initial load times for each module are much greater than the amount of time for next time the same module is loaded. This is because the definitions for those modules are stored in the current Application Domain for the application when using the Current Domain Method.&lt;/p&gt;  &lt;h3&gt;Theoretically, when would one use the Current Domain Method?&lt;/h3&gt;  &lt;p&gt;You would want to use the current domain method if you were not worried about the user loading enough modules to cause the application to go out of memory. When you are using this method you are essentially caching the module definitions when you load them, allowing for the module to be loaded much faster the next time it is needed. To summarize it requires more memory in order to achieve faster load times.&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Copied Domain Method&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;This is what happens when you use the load function of the ModuleManager and specify the parameter as a new Application Domain using the current Application Domain. This is also the default behavior when not using a parameter at all.&lt;/p&gt;  &lt;p&gt;Example Usage:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;var info:IModuleInfo = ModuleManager.getModule(&amp;quot;com/foo/FooModule.swf&amp;quot;);      &lt;br /&gt;info.load();&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;or…&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;var info:IModuleInfo = ModuleManager.getModule(&amp;quot;com/foo/FooModule.swf&amp;quot;);      &lt;br /&gt;info.load(new ApplicationDomain(ApplicationDomain.currentDomain));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This loads the module into a new Application Domain so that they are no references to keep module definitions from unloading. The result is that when you unload a module all of the related classes are supposed to entirely unload. The amount of time required to load a module never changes, because it has to be completely loaded each time.&lt;/p&gt;  &lt;p&gt;For example if you have an Application that has 3 modules and you load one module at a time using the Copied Domain Method, unload them, and load the next module in the sequence you get the following memory profile assuming you force garbage collection (&lt;a title="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html" href="http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html"&gt;http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html&lt;/a&gt;) after each unload:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SjMpAjsYU_I/AAAAAAAAAFI/evXhYHeiitE/s1600-h/image17.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SjMpA1pveBI/AAAAAAAAAFM/3KzwpAD9fXI/image_thumb7.png?imgmax=800" width="535" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;* &lt;em&gt;Assumes modules are all the same size, garbage collection is forced after unload, memory snapshot is taken using System.totalMemory, and memory snapshot is taken between unload of previous and load of new&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Notice that when the all modules are unloaded the memory is supposed to go back down to where it was before the first module was loaded. &lt;/p&gt;  &lt;p&gt;For another example if you look at the time it takes those module to load for the 3 module scenario using the Copied Domain Method, you get the following:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SjMpBC-1b4I/AAAAAAAAAFQ/hO76ZwanURw/s1600-h/image7.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="279" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SjMpBWhF28I/AAAAAAAAAFU/w6iKz56Ir3w/image_thumb3%5B1%5D.png?imgmax=800" width="537" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The amount of time that it takes to load each module never changes, because each time the module has to be completely loaded. It is my understanding that the reason for this is because when using the Copied Domain Method you are not adding AS3 definitions to the current domain, so those definitions can fully unload when the module is unloaded.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Theoretically, when would one use the Copied Domain Method?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You want want to use this method if your application was under some kind of memory constraint, or if there were so many modules that it could cause the Flash VM to run out of memory. The down side to this is that you have to fully load each module every time you need it, whether it has already been loaded or not.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Current Domain Method versus Copied Domain Method in the real world&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In large and stylistically complex applications in the real world, the copied domain method has provided me with a world of trouble when it comes to memory. The memory behavior is erratic to say the least in the following ways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Even when forcing garbage collection the memory jumps around erratically like nothing is being done at all. &lt;/li&gt;    &lt;li&gt;If you run the same exact scenario over and over again you get different results. One time memory averages 30 MB, another 50 MB, and another time it just runs out of memory &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I know what you are thinking, “there are other memory leaks in the application!” That would be incorrect, as the profiler shows no leaking and if you change to the Current Domain Method the problem is gone in the particular scenario in which this happens. It is that point which I became completely confused and I was even able to talk to Adobe about it through a third party, but I was never able to get an answer.&lt;/p&gt;  &lt;p&gt;The scenario in particular was the loading and unloading of two different modules over and over again about 100 times. Load Module 1, unload Module 1 and load Module 2, unload Module 2 and load Module 1, etc.&lt;/p&gt;  &lt;p&gt;When using the Copied Domain Method each time I ran this scenario I got different results:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SjMpB1-pExI/AAAAAAAAAFY/iYbajjZBXSg/s1600-h/image%5B8%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="302" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SjMpCIQ_FGI/AAAAAAAAAFc/EEdqidTZD8w/image_thumb%5B3%5D.png?imgmax=800" width="519" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For example the first attempt at this scenario was fine, the second attempt ran out of memory, and the third attempt went up in memory and never came back down. &lt;/p&gt;  &lt;p&gt;If you take that same exact scenario and make it use the Current Domain Method you get the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SjMpCaEwBSI/AAAAAAAAAFg/QO_K4ilzzQs/s1600-h/image%5B12%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="291" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SjMpCl7ZGYI/AAAAAAAAAFk/bZYGCV9lW6g/image_thumb%5B5%5D.png?imgmax=800" width="520" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Using the Current Domain Method seemed to have fixed the memory issue in this scenario, but by using this method I was stuck with modules with definitions that never get unloaded.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-369594486737987105?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/369594486737987105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=369594486737987105' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/369594486737987105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/369594486737987105'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html' title='Flex Memory Issue #4: Modules and Application Domains'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_QipvL9yNmJU/SjMo_uZZUaI/AAAAAAAAAE8/eOF9u5pRXP8/s72-c/image_thumb3.png?imgmax=800' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-6263886340210976857</id><published>2009-05-28T18:48:00.001-06:00</published><updated>2009-05-28T18:48:37.265-06:00</updated><title type='text'>Flex Memory Issue #3: Garbage Collection</title><content type='html'>&lt;p&gt;Garbage collection is an in depth subject when it comes to modern programming languages. Wikipedia provides a general statement that summarizes what it is:&lt;/p&gt;  &lt;p&gt;“…garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory used by objects that will never be accessed or mutated again by the application.“ &lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)"&gt;http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The expectation of a programmer in a language like Flex or Java, is that when widget X is no longer being used in the application that it gets removed from memory. That it is pretty simple scenario that is unrealistic, considering all graphical user interface components maintain references to other components which contain references to other components and so on and so forth. Flex also adds a few more layers of complexity by including modules and binding.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Flash Garbage Collection Basics&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;There is a must-read presentation on an atomic view of Flash Player garbage collection written by Alex Harui sometime in 2005, from which I obtained a lot of my high level information. Somehow I located the presentation through the internet and downloaded it, but I have since lost the link.&lt;/p&gt;  &lt;p&gt;Flex garbage collection is synonymous with Flash garbage collection, since the memory being talked about is that of the Flash Player. Flash memory allocation basically works by grabbing chunks of memory from the Operating System, and carving those chunks when needed into smaller blocks of fixed size that together as a group are called a pool. When a pool is used up then another chunk is taken from the OS and becomes another pool.&lt;/p&gt;  &lt;p&gt;A block of memory can be used, freed, or unused. Used means that there is something in there, freed means that something is still in there but it no longer used and can be garbage collected, and unused means that the block was freed and had been set to unused by the garbage collector.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/Sh8w4CS3ApI/AAAAAAAAAEo/s6I-3dqMY0c/s1600-h/clip_image002%5B4%5D.jpg"&gt;&lt;img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="287" alt="clip_image002" src="http://lh4.ggpht.com/_QipvL9yNmJU/Sh8w4XfT7vI/AAAAAAAAAEs/mMDaEZMkt3I/clip_image002_thumb%5B1%5D.jpg?imgmax=800" width="628" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This means that Flash garbage collection is based on allocation since more memory is not obtained from the OS until Flash needs some for itself but is out. Before Flash decides that another pool is needed though, it might attempt to run garbage collection. The garbage collector will move through Flash memory looking for freed blocks that can be set to unused.&lt;/p&gt;  &lt;p&gt;There are also a few important things to note about garbage collection when looking at its effect on memory:&lt;/p&gt;  &lt;p&gt;1. You generally can’t predict when garbage collection will run by itself&lt;/p&gt;  &lt;p&gt;2. Garbage collection is based on allocation, so memory will remain constant in an idle application&lt;/p&gt;  &lt;p&gt;3. Garbage collection is not guaranteed to mark all the blocks is can as unused in one pass, which means that memory may never returned to its initial point&lt;/p&gt;  &lt;p&gt;For a more details about the Flash garbage collector Grant Skinners has several writings about it in his AS Resource Management series: &lt;a title="http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html" href="http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html"&gt;http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;So why do I care about garbage collection?&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It doesn’t always collect what you want it to when you want it to, and when dealing especially with modules it can lead to some behaviors that look like memory leaks. I have personally found that if you want to get memory under control with modules you absolutely have to force garbage collection. For example consider a test application in which I am loading and unloading the same three modules over an over again into the current application domain. I know, what is an application domain? For now don’t worry about because it is complicated and something that I intend to explain later in another article. All you need to be aware of that this is the default module behavior if you use the Module Manager to load a module without using any parameters.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/Sh8w4lN-9CI/AAAAAAAAAEw/-5ZfFjwfulk/s1600-h/image%5B11%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="285" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/Sh8w5J7P3mI/AAAAAAAAAE0/98c_YerChWk/image_thumb%5B5%5D.png?imgmax=800" width="400" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Without getting into the details of application domains and their specific effects on memory behavior, you can at least see that if you don’t force garbage collection memory just keeps going up with little breaks in between. In the case of the application that I am describing it will eventually cause my browser to run out of memory and lock up once the Flash Player gets upwards of 120 MB.&amp;#160; &lt;/p&gt;  &lt;p&gt;I have also found that the larger the modules and the more detailed the styles the more pronounced this problem. I believe that when I averaged out the increase in memory over time,&amp;#160; it ended up being about 1.5 MB per module load. If you force garbage collection after each module unload it ends up being pretty much a flat line, granted though other techniques were incorporated in this application to help memory along to be discussed in future articles. The important thing to note is the positive effect forced garbage collection has by itself.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Force garbage collection?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Junior Java programmers love to ask the question about how to force garbage collection, to which the reply is always that you can only suggest it. The same is not true for Flex, as there are unsupported techniques that have various effects in the debug and non-debug Flash Player as well as with AIR.&lt;/p&gt;  &lt;p&gt;Method 1: System.gc()&lt;/p&gt;  &lt;p&gt;According to the Adobe documentation (&lt;a title="http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html" href="http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html"&gt;http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html&lt;/a&gt;) this forces garbage collection, but only in AIR and the debug version of the Flash Player. In practice though this method doesn’t seem to be very effective for reasons listed below.&lt;/p&gt;  &lt;p&gt;Method 2: System.gc() twice in a row&lt;/p&gt;  &lt;p&gt;According to Sean Christmann’s post about kick starting the garbage collector (&lt;a href="http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/"&gt;http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/&lt;/a&gt;), if you call System.gc() twice in a row it is far more effective. Unfortunately though this only works in the debug Flash Player and AIR.&lt;/p&gt;  &lt;p&gt;Method 3: The local connection hack&lt;/p&gt;  &lt;p&gt;According to Grant Skinner’s third installment of this AS Resource Management Series (&lt;a href="http://www.gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html"&gt;http://www.gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html&lt;/a&gt;), you can force garbage collection by calling two local connections in a row:&lt;/p&gt;  &lt;pre&gt;try {&lt;/pre&gt;

&lt;pre&gt;&amp;#160;&amp;#160; new LocalConnection().connect('foo');&lt;/pre&gt;

&lt;pre&gt;&amp;#160;&amp;#160; new LocalConnection().connect('foo');&lt;/pre&gt;

&lt;pre&gt;} catch (e:*) {}&lt;/pre&gt;

&lt;p&gt;In testing this I find that it works in AIR, the debug Flash Player, and the non-debug Flash Player. It is also the my preferred way of forcing garbage collection, even though it it not supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When do I force garbage collection?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have engaged in several debates regarding when to force garbage collection and why, and the most important thing you need to understand is that forcing garbage collection will only clear objects that are eligible for collection in the first place. This means that if you write a loop in your application to force garbage collection at 70 MB until it goes down to 50 MB you are probably going to loop infinitely. Forcing garbage collection is not the silver bullet to all of your memory problems.&lt;/p&gt;

&lt;p&gt;When to force garbage collection really depends on what your application is doing. For example if your application just consists of several screens you might try forcing garbage collection in between screens. In other applications it may be more appropriate to force it every few minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I make objects eligible for garbage collection?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that is the million dollar question, and unfortunately there is no one answer. The purpose of this series on Flex memory issues is designed to help one thing at a time. Binding, states, modules, effects, application domains, complex components, listeners, and more will have their memory issues explained.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-6263886340210976857?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/6263886340210976857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=6263886340210976857' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6263886340210976857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6263886340210976857'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html' title='Flex Memory Issue #3: Garbage Collection'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_QipvL9yNmJU/Sh8w4XfT7vI/AAAAAAAAAEs/mMDaEZMkt3I/s72-c/clip_image002_thumb%5B1%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-1402618493322573580</id><published>2009-05-27T16:05:00.001-06:00</published><updated>2009-05-27T16:05:00.146-06:00</updated><title type='text'>Flex Memory Issue #2: Component effects cause leaks</title><content type='html'>&lt;p&gt;An &lt;em&gt;effect&lt;/em&gt; is a change to a component that occurs over a brief period of time (&lt;a title="http://www.adobe.com/devnet/flex/quickstart/adding_effects/" href="http://www.adobe.com/devnet/flex/quickstart/adding_effects/"&gt;http://www.adobe.com/devnet/flex/quickstart/adding_effects/&lt;/a&gt;). Flex provides a series of predefined effects which you can be played individually, simultaneously, and one after another as a group. They are useful for adding that “wow” factor to your application by giving it animation. There is a problem though with using these effects, which is that if you remove a component that has had an effect played on it that component will still reside in memory until another effect is played.&lt;/p&gt;  &lt;p&gt;This is because all effects are controlled through the EffectManager, which keeps track of the last effect played through the “lastCreatedEffect” property. This may not seem like a big deal since it will just change when you play another effect, but is a big deal of you are limited on the amount of memory you can use and the component being held onto is large. It is also an annoyance if you are trying to track down leaks and components that shouldn’t be there because of this are floating around in memory.&lt;/p&gt;  &lt;p&gt;The solution to this problem is pretty simple, which is to just call EffectManager.lastCreatedEffect = null when you are done with your effect. After figuring this out on my own I Googled around and was able to find that someone created a defect for it back in 2008.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Component effects via EffectManager cause memory leak&lt;/strong&gt; (&lt;a title="http://bugs.adobe.com/jira/browse/SDK-18061" href="http://bugs.adobe.com/jira/browse/SDK-18061"&gt;http://bugs.adobe.com/jira/browse/SDK-18061&lt;/a&gt;)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Steps to reproduce:      &lt;br /&gt;1. Create an MXML component with an effect, e.g.       &lt;br /&gt;&amp;#160; &amp;lt;mx:HBox id=&amp;quot;myBox&amp;quot; resizeEffect=&amp;quot;{new Resize()}&amp;quot;/&amp;gt;       &lt;br /&gt;2. Use the component such that the effect gets played, e.g. set its size explicitly in this case       &lt;br /&gt;3. Remove the component. &lt;/p&gt;    &lt;p&gt;Actual Results: the component is not garbage collected. &lt;/p&gt;    &lt;p&gt;Expected Results: the component is garbage colloected. &lt;/p&gt;    &lt;p&gt;Workaround (if any): Explicitly register an EFFECT_START listener on the effect to set EffectManager.lastCreatedEffect = null when the effect plays. &lt;/p&gt;    &lt;p&gt;This leak occurs because lastCreatedEffect is a static variable and thus hangs on the the last played effect, which then hangs on to its target component, etc. I recommend removing this static field completely. If it is really needed, make it a weak reference instead.&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-1402618493322573580?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/1402618493322573580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=1402618493322573580' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1402618493322573580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1402618493322573580'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/05/flex-memory-issue-2-component-effects.html' title='Flex Memory Issue #2: Component effects cause leaks'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-7766132237347586891</id><published>2009-05-26T19:27:00.001-06:00</published><updated>2009-05-27T15:38:21.901-06:00</updated><title type='text'>Flex Memory Issue #1: The debug player always leaks</title><content type='html'>&lt;p&gt;In the 9 and 10 versions of the Flash Player there are both debug and non-debug versions of those players. If you are writing Flex application you most certainly have the debug version, which lets you output to trace as well as write those trace statements to a log on the local file system of you have the correct settings. There is a problem with the debug version of the Flash Player though, which is that it is full of memory leaks.&lt;/p&gt;  &lt;p&gt;This is important if you are trying to get memory under control in a Flex application, because if you are just looking at the System.totalMemory in the debug player you are wasting your time. This problem with memory and the debug player is most evident if you are using modules, which you can see by loading modules over and over again and comparing System.totalMemory over time in the debug and non-version of the Flash Player.&lt;/p&gt;  &lt;p&gt;Using the latest in computer modeling technology the result looks like the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/ShyW-YNv17I/AAAAAAAAAEI/16n8BorgmdI/s1600-h/image%5B8%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="313" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/ShyW-ma1k4I/AAAAAAAAAEM/BSVz0mO4prY/image_thumb%5B6%5D.png?imgmax=800" width="574" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This means that if you want to get a realistic picture of memory behavior using System.totalMemory, or by looking at the effect on the containing browser or AIR executable, you have to use the non-debug version of the Flash Player. The debug version of the Flash Player is still useful for looking at memory usage though, but you have to use the profiler.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/ShyW-6nUhdI/AAAAAAAAAEQ/b7Gv0KOPOA8/s1600-h/image%5B12%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="193" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/ShyW_HHsKjI/AAAAAAAAAEU/PAKNgtceiMc/image_thumb%5B8%5D.png?imgmax=800" width="585" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The profiler memory usage panel displays the amount of memory used by object allocation, and will not correlate with System.totalMemory. How do I know this? Well, I took the time to add up all of the objects listed in Live Objects panel and it always adds up to the amount listed for Current Memory. Overtime System.totalMemory will further diverge from the displayed Current Memory, because the actual memory used will continue to grow because you are using the debug player.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/ShyW_TwTSyI/AAAAAAAAAEY/VXuQUMxhSt4/s1600-h/image%5B16%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="208" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/ShyW_skTpxI/AAAAAAAAAEc/mGQkBAOXlbs/image_thumb%5B10%5D.png?imgmax=800" width="388" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I was never able to find a good explanation of the huge difference between Current Memory and the actual memory consumed by the application when running with the profiler versus the non-debug version of the Flash Player, but I have also found that the memory usage overtime of an application in the profiler according to Current Memory will roughly match the memory usage of that same application overtime run using the non-debug version of the Flash Player. It is a rough match because there is of course other stuff in memory than just object allocations.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/ShyW_6gQGfI/AAAAAAAAAEg/5r_gauOPg28/s1600-h/image%5B20%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="210" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/ShyXAHdFF0I/AAAAAAAAAEk/PUUfEMY5iXo/image_thumb%5B12%5D.png?imgmax=800" width="382" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The non-debug version of the Flash Player is good for locating a generic problem with memory at the level of “hey, this little application started at 30 MB and is now at 300 MB,” while the profiler is good for narrowing down which instances are leaking. When investigating memory in Flex applications you just have to be aware of how whether you are using the debug or non-debug version of the Flash Player effects your results.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-7766132237347586891?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/7766132237347586891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=7766132237347586891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/7766132237347586891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/7766132237347586891'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/05/flex-memory-tip-1-debug-player-always.html' title='Flex Memory Issue #1: The debug player always leaks'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_QipvL9yNmJU/ShyW-ma1k4I/AAAAAAAAAEM/BSVz0mO4prY/s72-c/image_thumb%5B6%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-2690072191157722470</id><published>2009-05-26T18:04:00.001-06:00</published><updated>2009-05-26T18:04:20.572-06:00</updated><title type='text'>Flex: event.target versus event.currentTarget</title><content type='html'>&lt;p&gt;The event system in Flex allows you catch an Event and its instance to get reference to the component that generated the event.&lt;/p&gt;  &lt;p&gt;For example if you do make the following declaration in MXML: &lt;/p&gt;  &lt;p&gt;&amp;lt;mx:Button click=”clicked(event)” /&amp;gt;&lt;/p&gt;  &lt;p&gt;When that button is clicked it calls in ActionScript the function “clicked(event:MouseEvent):void”&lt;/p&gt;  &lt;p&gt;So how do you get reference to the button that generated the event in that function?&lt;/p&gt;  &lt;p&gt;Well, according to the Adobe Event API (&lt;a href="http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html"&gt;http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html&lt;/a&gt;) you can use:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;event.target&lt;/b&gt; - The event target. This property contains the target node. For example, if a user clicks an OK button, the target node is the display list node containing that button. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;event.currentTarget&lt;/b&gt; - The object that is actively processing the Event object with an event listener. For example, if a user clicks an OK button, the current target could be the node containing that button or one of its ancestors that has registered an event listener for that event. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So what does that mean and which should I use?&lt;/p&gt;  &lt;p&gt;You can’t tell from that description, but I can tell you about a problem I was having with a component displaying lots of buttons. So there was a component with lots of buttons on it, where when a button was pressed it would call a function that would determine which button was pressed and do all sorts of fancy stuff.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/ShyDgiGmG3I/AAAAAAAAAEA/kUbq3GfHOqs/s1600-h/image%5B3%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="125" alt="image" src="http://lh5.ggpht.com/_QipvL9yNmJU/ShyDhNREtYI/AAAAAAAAAEE/yqI-HH-0rcA/image_thumb%5B1%5D.png?imgmax=800" width="285" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The callback function looked something like the following:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font face="Courier New"&gt;private function clicked(event:MouseEvent):void&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;font face="Courier New"&gt;var button:button = event.target as Button;&lt;/font&gt;&lt;/b&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;font face="Courier New"&gt;trace(button.label);&lt;/font&gt;&lt;/b&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The problem with this was that if the user started clicking on buttons really fast a null pointer exception would occur, because the “button” instance was null. After debugging this I realized that the button was null because for a few cases when the button was clicked the &lt;b&gt;event.target&lt;/b&gt; was a &lt;b&gt;UITextField&lt;/b&gt;, what?&lt;/p&gt;  &lt;p&gt;That is when a stumbled onto some more event documentation currently located at &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=16_Event_handling_5.html"&gt;http://livedocs.adobe.com/flex/3/html/help.html?content=16_Event_handling_5.html&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;The target property&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;The target property holds a reference to the object that is the target of the event. In some cases, this is straightforward, such as when a microphone becomes active, the target of the event object is the Microphone object. If the target is on the display list, however, the display list hierarchy must be taken into account. For example, if a user inputs a mouse click on a point that includes overlapping display list objects, Flash Player and AIR always choose the object that is farthest away from the Stage as the event target. &lt;/p&gt;    &lt;p&gt;For complex SWF files, especially those in which buttons are routinely decorated with smaller child objects, the target property may not be used frequently because it will often point to a button's child object instead of the button. In these situations, the common practice is to add event listeners to the button and use the currentTarget property because it points to the button, whereas the target property may point to a child of the button. &lt;/p&gt;    &lt;p&gt;&lt;b&gt;The currentTarget property&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;The currentTarget property contains a reference to the object that is currently processing the event object. Although it may seem odd not to know which node is currently processing the event object that you are examining, keep in mind that you can add a listener function to any display object in that event object's event flow, and the listener function can be placed in any location. Moreover, the same listener function can be added to different display objects. As a project increases in size and complexity, the currentTarget property becomes more and more useful.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Pay attention to the following statement in the section about the target property: &lt;/p&gt;  &lt;p&gt;“…common practice is to add event listeners to the button and use the &lt;b&gt;currentTarget&lt;/b&gt; property because it points to the button, whereas the target property may point to a child of the button.”&lt;/p&gt;  &lt;p&gt;So after reading this I changed my code to use &lt;b&gt;event.currentTarget&lt;/b&gt; from &lt;b&gt;event.target&lt;/b&gt;, and it always returned the instance of the button that was clicked.&lt;/p&gt;  &lt;p&gt;I also found another article (&lt;a href="http://mysticnomad.wordpress.com/2008/03/21/difference-between-eventtarget-and-eventcurrenttarget-properties-in-an-event-object/"&gt;http://mysticnomad.wordpress.com/2008/03/21/difference-between-eventtarget-and-eventcurrenttarget-properties-in-an-event-object/&lt;/a&gt;) that clearly laid out the distinction between these two properties, and made the conclusion that “…you should always use event.currentTarget property instead of event.target.”&lt;/p&gt;  &lt;p&gt;I agree.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-2690072191157722470?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/2690072191157722470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=2690072191157722470' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2690072191157722470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2690072191157722470'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/05/flex-eventtarget-versus.html' title='Flex: event.target versus event.currentTarget'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_QipvL9yNmJU/ShyDhNREtYI/AAAAAAAAAEE/yqI-HH-0rcA/s72-c/image_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-5936084240486315168</id><published>2009-05-10T15:29:00.001-06:00</published><updated>2009-05-10T15:29:37.608-06:00</updated><title type='text'>Command Module Framework</title><content type='html'>&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Command Module Framework is a series of classes for working with modules in Flex, which extends the default module behavior to compensate for numerous known problems as well as to add needed functionality.&lt;/p&gt;  &lt;p&gt;In particular the following is a list of some of the more important functional differences:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The ability to queue events on the module loader which get dispatched to the module implementation once it is loaded and ready &lt;/li&gt;    &lt;li&gt;Modules when unloaded go through a series of magic tricks to help them actually unload. Some day I will get around to explaining what a lot of these tricks are and why they are needed. &lt;/li&gt;    &lt;li&gt;The ability to configure a manager to handle loading and unloading modules in view stacks &lt;/li&gt;    &lt;li&gt;The built in ability to share data between all modules &lt;/li&gt;    &lt;li&gt;The built in ability to optionally display module loading progress &lt;/li&gt;    &lt;li&gt;Makes it easier to communicate between modules &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;What is it intended to be used for?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This library is intended to be used for Flex applications that need to load and unload modules, with a lot of the common code used for doing this already written.&lt;/p&gt;  &lt;p&gt;Modules are used so that the user of your application only has to download the parts they need when they need it. For example if an application is a series of 100 different forms, it makes sense that the user should only have to download the forms they intend to use. The is a big deal in web applications because is means the difference (depending on your connection speed) between spending 15 minutes downloading a large application versus spending 5 seconds downloading an application framework and 3 seconds for each additional module.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There are two general ways to use it:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Using the Command Module Loader, which is similar to the Module Loader &lt;/li&gt;    &lt;li&gt;Using the Command Module Manager, which is similar to the Module Manager &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Using the Command Module Loader (Example #1)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Command Module Loader is very similar to the Module Loader, and can be used as in the same way in a basic example:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Application.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;mx:Application       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;commandmodulefr:CommandModuleLoader url=&amp;quot;valentino/modules/ModuleA.swf&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The code for Module A is the following:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ModuleA.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;commandmodulefr:CommandModule       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Module A&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;I am a button&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt;       &lt;br /&gt;&amp;lt;/commandmodulefr:CommandModule&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The result is an application that loads the module at the given URL, assuming it inherits from the CommandModule class, which in the case of this module results in a panel with a button in it:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SgdHNdAnYUI/AAAAAAAAADQ/zFMis69hXA8/s1600-h/image2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="86" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SgdHNrPq1JI/AAAAAAAAADU/_tDIqadg2O8/image_thumb.png?imgmax=800" width="148" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sending events to modules (Example #2)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Let’s say that for some reason you want to send an event to your module, but being a smart Flex developer you are aware of the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I can’t reference an instance of my custom module class in my main application because that would cause that class to get compiled in with my main application, which would defeat the purpose of modules &lt;/li&gt;    &lt;li&gt;If I dispatch an event directly to the loader using dispatchEvent, my module could miss that event if it is not already loaded &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For these reasons the CommandModuleLoader class has a queueEvent function which ensures that the module always gets the event no matter when it is dispatched.&lt;/p&gt;  &lt;p&gt;For this example there is a button in the main application that when pressed sends some custom event to the module:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Application.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;mx:Application       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function sendSomeEvent():void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var event:Event = new Event(&amp;quot;someCustomEvent&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; moduleLoader.queueEvent(event);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;Send Some Custom Event&amp;quot; click=&amp;quot;sendSomeEvent()&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;commandmodulefr:CommandModuleLoader id=&amp;quot;moduleLoader&amp;quot; url=&amp;quot;valentino/modules/ModuleA.swf&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In the module there is a listener created on initialization for the custom event, which when the event is dispatched displays a popup window:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ModuleA.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;commandmodulefr:CommandModule       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; initialize=&amp;quot;onInit()&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.controls.Alert;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function onInit():void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.addEventListener(&amp;quot;someCustomEvent&amp;quot;, someHandler);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function someHandler(event:Event):void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Alert.show(&amp;quot;Some Custom Event!&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Module A&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;I am a button&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt;       &lt;br /&gt;&amp;lt;/commandmodulefr:CommandModule&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SgdHN3eWZeI/AAAAAAAAADY/nciFR_hihZ0/s1600-h/image20.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="209" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SgdHOMDCIkI/AAAAAAAAADc/4BeNRJ_u1as/image_thumb8.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Receiving events from modules (Example #3)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In order to receive an event from a module you must attach some listener on the actual module, and being a smart Flex developer you are aware of the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I can’t reference an instance of my custom module class in my main application because that would cause that class to get compiled in with my main application, which would defeat the purpose of modules &lt;/li&gt;    &lt;li&gt;Being able to reference an event function using an attribute in the MXML of the loader would require the loader to already have the desired event metadata declarations &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For these reasons the base implementation of the loader has an event for when the module is loaded, which can be caught in order to obtain a reference to the CommandModule class. This instance can then have a listener for anything you want added to it.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Application.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;mx:Application       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import mx.controls.Alert;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.commandmodulefr.CommandModule;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.commandmodulefr.event.CommandModuleEvent;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function moduleLoaded(event:CommandModuleEvent):void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var module:CommandModule = event.module;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; module.addEventListener(&amp;quot;someCustomEvent&amp;quot;, someHandler);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function someHandler(event:Event):void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Alert.show(&amp;quot;Some event from a module!&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;commandmodulefr:CommandModuleLoader       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; moduleLoaded=&amp;quot;moduleLoaded(event)&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;valentino/modules/ModuleA.swf&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;When the button is pressed in the module, it dispatches the expected event which is then picked&amp;#160; up in the main application.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ModuleA.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;commandmodulefr:CommandModule       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function sendEvent():void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var event:Event = new Event(&amp;quot;someCustomEvent&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.dispatchEvent(event);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Module A&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;I am a button&amp;quot; click=&amp;quot;sendEvent()&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt;       &lt;br /&gt;&amp;lt;/commandmodulefr:CommandModule&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The result is a window that is displayed when the button within the module is pressed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QipvL9yNmJU/SgdHOU1D6yI/AAAAAAAAADg/DCKnoBlW0kg/s1600-h/image23.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="170" alt="image" src="http://lh6.ggpht.com/_QipvL9yNmJU/SgdHOqHoHgI/AAAAAAAAADk/OvqqQh41Vkg/image_thumb9.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sharing data between modules and the main application (Example #4)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Besides just using a singleton, the Command Module Loader accepts an Application Context object that is passed to all of the modules that are loaded. This class contains a data attribute which is an object that can be populated with anything, or you can just extend this class and defined a shared structure.&lt;/p&gt;  &lt;p&gt;In this example the main application declares the Application Context, and sets the data so that “someVar” has a value.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Application.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;mx:Application initialize=&amp;quot;onInit()&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.commandmodulefr.data.ApplicationContext;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Bindable]       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private var _context:ApplicationContext = new ApplicationContext();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private function onInit():void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _context.data.someVar = &amp;quot;This is some text&amp;quot;;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Script&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;commandmodulefr:CommandModuleLoader       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context=&amp;quot;{_context}&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;valentino/modules/ModuleA.swf&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The module then uses that value from the Application Context in order to get the text that it displays on the button.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ModuleA.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;commandmodulefr:CommandModule       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Module A&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;{context.data.someVar}&amp;quot;&amp;#160; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt;       &lt;br /&gt;&amp;lt;/commandmodulefr:CommandModule&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The result is the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SgdHOydOk2I/AAAAAAAAADo/EoitmS47mB8/s1600-h/image26.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="83" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SgdHPPTzZBI/AAAAAAAAADs/zbwp5EiP6N8/image_thumb10.png?imgmax=800" width="166" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Using the Command Module Manager (Example #5)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Command Module Manager is far more generic, and is actually intended to be used as part of some other framework in an application. The module manager class is useful for when you do not want to have to declare every module that you intended to use. An example usage would be in an application that has a list of the URL’s of all of the module that it can load in some external XML file, where various events in that application would result in modules from that XML file being loaded.&lt;/p&gt;  &lt;p&gt;The two most notable things about the Command Module Loader class are the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It takes a view stack as a parameter and loads and unloads module into and out of that view stack. &lt;/li&gt;    &lt;li&gt;It cleans up modules so that they can actually be unloaded (somewhat, but this is for a later lengthy discussion) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now consider an application that just has a series of buttons for loading and unloading modules, and a general area that the modular content is displayed in using a view stack. Though this usage seems really simple, it is a quite common template for an application.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Application.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;mx:Application      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;    &lt;br /&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;commandmodulefr:CommandModuleManager id=&amp;quot;manager&amp;quot; viewStack=&amp;quot;{view}&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;Load Module A&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; click=&amp;quot;manager.requestLoadModule('valentino/modules/ModuleA.swf')&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;Unload Modules&amp;quot; click=&amp;quot;manager.unloadAll()&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:ViewStack id=&amp;quot;view&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The idea behind the module manager is to allow an application an easy way to change out dynamic content which comes from modules. The generic nature of the Command Module Manager then allows the individual application to decide about the details of how module communication occurs.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ModuleA.mxml&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;commandmodulefr:CommandModule      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:commandmodulefr=&amp;quot;net.sourceforge.commandmodulefr.*&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Panel title=&amp;quot;Module A&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:Button label=&amp;quot;I am a button&amp;quot;&amp;#160; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:Panel&amp;gt;      &lt;br /&gt;&amp;lt;/commandmodulefr:CommandModule&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The result is a simple application that lets you load and unload modules using buttons from the main application.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QipvL9yNmJU/SgdHPWdEL4I/AAAAAAAAADw/FXNGr00ZKzM/s1600-h/image%5B3%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="148" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SgdHPiHyMCI/AAAAAAAAAD0/ouJpGIbW3gc/image_thumb%5B1%5D.png?imgmax=800" width="205" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In Practice&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;How you would go about using this library really depends on what you are doing, but for most implementations the Command Module Manager is probably going to be the most useful. This is because for any application of a medium to large size and for many reasons including maintainability and user experience, you are going to want to divide the application into modules. If you are using a considerable number of modules, the application is a lot easier to modify if the usage of those modules are externally defined.&lt;/p&gt;  &lt;p&gt;For example if you have an application that has 100 modules and you wanted to use a module loader for each one, you would have to have 100 module loader declarations in your application. Every time someone added a module they would also have to add a module loader declaration, which would become very cumbersome. You could of course deal with the module loaders programmatically but you would essentially be recreating the equivalent of a module manager.&lt;/p&gt;  &lt;p&gt;A technique which I have used on various projects that seems to be pretty straight forward is to have some external file, almost always XML, which specifies the module locations as well as other information. This file at its most basic level is just a way to declare module names and locations outside of your code, giving more flexibility at runtime. &lt;/p&gt;  &lt;p&gt;For example if I had the following file:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Modules&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Module name=”ModuleA” url&amp;quot;=”valentino/modules/ModuleA.swf” /&amp;gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Module name=”ModuleB” url&amp;quot;=”valentino/modules/ModuleB.swf” /&amp;gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Module name=”ModuleC” url&amp;quot;=”valentino/modules/ModuleC.swf” /&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;/Modules&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;I would then write some type of manager (referred to as a State Process Manager) class in my application to listen for particular events, and then based on those events look up a module’s URL in the external XML file and then pass them to the Command Module Loader to do the loading.&lt;/p&gt;  &lt;p&gt;The resulting architecture looks something like the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QipvL9yNmJU/SgdHP0dTpUI/AAAAAAAAAD4/MW5r5G2ymO8/s1600-h/image%5B7%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="301" alt="image" src="http://lh3.ggpht.com/_QipvL9yNmJU/SgdHQC4TRQI/AAAAAAAAAD8/kjbsrzzw1pw/image_thumb%5B3%5D.png?imgmax=800" width="500" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;State Process Manager&lt;/em&gt; - The objective of the state process manager is to control the event flow of the application, requiring reference to the one or more command module managers, the external module definitions, and the modules. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Command Module Manager&lt;/em&gt; - The command module manager is just an easy way to load an unload modules in and out of a view stack using URL’s.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Module Definitions&lt;/em&gt; – A list of the URL’s that contain the modules to load, which can also include any other information regarding module runtime configuration.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Modules&lt;/em&gt; – Portions of the UI to be loaded and unloaded.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Link to the Open Source Project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="https://sourceforge.net/projects/commandmodulefr/" href="https://sourceforge.net/projects/commandmodulefr/"&gt;https://sourceforge.net/projects/commandmodulefr/&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-5936084240486315168?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/5936084240486315168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=5936084240486315168' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/5936084240486315168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/5936084240486315168'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2009/05/command-module-framework.html' title='Command Module Framework'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_QipvL9yNmJU/SgdHNrPq1JI/AAAAAAAAADU/_tDIqadg2O8/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-1610153566154472633</id><published>2008-12-21T22:39:00.001-06:00</published><updated>2008-12-21T22:39:16.102-06:00</updated><title type='text'>FlexB – XML mapping for Flex/ActionScript classes and web services</title><content type='html'>&lt;p&gt;Flex has built it support for working with XML as well as built in support for mapping XML to ActionScript classes and back to XML again if you have an XSD file. What about mapping to and from XML if you don’t have an XSD file, and what about this XML web service stuff? FlexB is a Flex/ActionScript library for more easily working with XML and web services. It consists of a combination of classes that I originally made for my own personal use while teaching myself Flex a little over 2 years ago, which I have recently decided to renovate and make public.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Where can I get the code, library, and/or participate?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://flexb.sourceforge.net"&gt;http://flexb.sourceforge.net&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why don’t you just use an XSD file and the built in XML mappings?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Because I am lazy and don’t want to use an XSD file. There are also equivalents to this idea in other languages such as with XStream and Java.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why map XML to ActionScript classes with all of the direct component XML support?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Components such as the DataGrid allow you to directly reference XML in order to do useful things with your data.&amp;#160; The following example shows how to populate a DataGrid using XML:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;mx:Application xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:XML xmlns=&amp;quot;&amp;quot; id=&amp;quot;CompoundFoo&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;CompoundFoo my_name=&amp;quot;wii&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SimpleFoo&amp;gt;&amp;lt;name&amp;gt;Moo Cow&amp;lt;/name&amp;gt;&amp;lt;foo&amp;gt;Bar&amp;lt;/foo&amp;gt;&amp;lt;/SimpleFoo&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SimpleFoo&amp;gt;&amp;lt;name&amp;gt;Meow Cat&amp;lt;/name&amp;gt;&amp;lt;foo&amp;gt;BarBar&amp;lt;/foo&amp;gt;&amp;lt;/SimpleFoo&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/CompoundFoo&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:XML&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGrid dataProvider=&amp;quot;{CompoundFoo.SimpleFoo}&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:columns&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGridColumn headerText=&amp;quot;Name&amp;quot; dataField=&amp;quot;name&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGridColumn headerText=&amp;quot;Foo&amp;quot; dataField=&amp;quot;foo&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:columns&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:DataGrid&amp;gt;       &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_QipvL9yNmJU/SU8Z8OhXXmI/AAAAAAAAADI/Ia4kFphqJuk/s1600-h/image2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="173" alt="image" src="http://lh4.ggpht.com/_QipvL9yNmJU/SU8Z8kMqKzI/AAAAAAAAADM/ozmDhXoR1xU/image_thumb.png?imgmax=800" width="218" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Using XML directly in a DataGrid is one of the fastest ways possible to display data in a Flex application, but what about maintainability? The XML in the DataGrid is a popular Flex example, but it is unrealistic. In a real world application that XML or data will most likely come from some external source, an external source which is subject to change. It is also likely that the data will be used in the application in more than once place, and its usage is likely to involve other customizations. It is also common for data to need to be converted to other types, such as with a String to a Date. Mapping XML to ActionScript classes and then using those classes makes change easier, especially if those mapped classes are used in several places throughout the application.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How is mapping XML to ActionScript better for change then mapping XML directly to several components like the DataGrid?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you were to change any part of the XML from the first example, you would then have to change all of these references to it; the dataProvider, dataFields, and any other references. Use that XML in several places and you have several changes to make. These direct references to the XML are mapping, which can be spread out throughout components. If you use an ActionScript class to do the mappings, then all of your mappings are in the same place so it is easier to find and change. Since references are then to ActionScript classes you also gain the advantage of those references being type and name safe.&lt;/p&gt;  &lt;p&gt;For example a reference to SimpleFoo.foo as XML would always compile whether it existed or not. If there were a class called SimpleFoo then access to the property foo would cause a compile error if it didn’t exist.&lt;/p&gt;  &lt;p&gt;The following example shows the same DataGrid and XML, but this time the DataGrid is populated using an ActionScript class:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;     &lt;br /&gt;&amp;lt;mx:Application       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:valentino=&amp;quot;valentino.*&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; xmlns:mx=&amp;quot;&lt;/font&gt;&lt;a href="http://www.adobe.com/2006/mxml&amp;quot;"&gt;&lt;font face="Courier New"&gt;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:XML xmlns=&amp;quot;&amp;quot; id=&amp;quot;xml&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;CompoundFoo my_name=&amp;quot;wii&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SimpleFoo&amp;gt;&amp;lt;name&amp;gt;Moo Cow&amp;lt;/name&amp;gt;&amp;lt;foo&amp;gt;Bar&amp;lt;/foo&amp;gt;&amp;lt;/SimpleFoo&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SimpleFoo&amp;gt;&amp;lt;name&amp;gt;Meow Cat&amp;lt;/name&amp;gt;&amp;lt;foo&amp;gt;BarBar&amp;lt;/foo&amp;gt;&amp;lt;/SimpleFoo&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/CompoundFoo&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:XML&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#ff0000"&gt;&amp;lt;valentino:CompoundFoo id=&amp;quot;compoundFoo&amp;quot; xml=&amp;quot;{xml}&amp;quot; /&amp;gt;       &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGrid dataProvider=&amp;quot;{&lt;font color="#ff0000"&gt;compoundFoo.foos&lt;/font&gt;}&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:columns&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGridColumn headerText=&amp;quot;Name&amp;quot; dataField=&amp;quot;{&lt;font color="#ff0000"&gt;valentino.SimpleFoo.NAME&lt;/font&gt;}&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mx:DataGridColumn headerText=&amp;quot;Foo&amp;quot; dataField=&amp;quot;{&lt;font color="#ff0000"&gt;valentino.SimpleFoo.FOO&lt;/font&gt;}&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:columns&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mx:DataGrid&amp;gt;      &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This example uses the ActionScript classes CompoundFoo and SimpleFoo to contain all the instructions for XML Mapping. In the event that the XML were to change the only places in the application that would have to change would be those mappings. All current references to that data throughout the application could remain the same. &lt;/p&gt;  &lt;p&gt;The difference is where you do the mapping. FlexB places the mappings in the ActionScript classes so that those are the only places that have change.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How does the XML mapping work?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My preference would be to eventually have a factory class look at annotations of plain old ActionScript classes and do the mappings, but for right now I am providing a class to extend that gives this mapping functionality. Using inheritance also provides the ability to easily override all of the mapping behavior.&lt;/p&gt;  &lt;p&gt;The following ActionScript class defines the node, attribute, and class mappings from a “CompoundFoo” XML document:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;package valentino     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.flexb.core.IMap;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.flexb.mapper.XmlMappedObject; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160; [Bindable]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public class CompoundFoo extends XmlMappedObject      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public var myName:String;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [ArrayElementType(&amp;quot;valentino.SimpleFoo&amp;quot;)]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public var foos:Array = new Array();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override protected function mapNodeToFunction(nodeToFunctionMap:IMap):void      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToFunctionMap.put(&amp;quot;SimpleFoo&amp;quot;, &amp;quot;foos&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override protected function mapAttributeNodeToFunction(attributeNodeToFunctionMap:IMap):void      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; attributeNodeToFunctionMap.put(&amp;quot;my_name&amp;quot;, &amp;quot;myName&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override protected function mapNodeToClass(nodeToClassMap:IMap):void      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToClassMap.put(&amp;quot;SimpleFoo&amp;quot;, SimpleFoo);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToClassMap.put(&amp;quot;CompoundFoo&amp;quot;, CompoundFoo);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The node to function mappings specify the name of each node and the set/get functions of the class to map to. For example when the node “SimpleFoo” is encountered during mapping its value is associated with the class property of “&amp;quot;foos.”&lt;/p&gt;  &lt;p&gt;The node to attribute mappings specify the name of each attribute and the set/get functions of the class to map to. For example when the attribute “my_name” is encountered during the mapping its value is associated with the class property of “myName.” &lt;/p&gt;  &lt;p&gt;The node to class mappings specify the name of each node and the associated ActionScript class. For example when the node “SimpleFoo” is encountered during the mapping its value is mapped as the “SimpleFoo” ActionScript class.&lt;/p&gt;  &lt;p&gt;Behavior such as needed for the conversion of data can also be handled by using set/get functions instead of providing publically accessible class variables.&lt;/p&gt;  &lt;p&gt;“SimpleFoo” is also a reference to another ActionScript class:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;package valentino     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.flexb.core.IMap;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; import net.sourceforge.flexb.mapper.XmlMappedObject; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160; public class SimpleFoo extends XmlMappedObject     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public var name:String;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public var foo:String;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public static const FOO:String = &amp;quot;foo&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public static const NAME:String = &amp;quot;name&amp;quot;;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;     &lt;br /&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override protected function mapNodeToFunction(nodeToFunctionMap:IMap):void       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToFunctionMap.put(FOO, &amp;quot;foo&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToFunctionMap.put(NAME, &amp;quot;name&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; override protected function mapNodeToClass(nodeToClassMap:IMap):void        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeToClassMap.put(&amp;quot;SimpleFoo&amp;quot;, SimpleFoo);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What about web service mapping?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;It is actually an HTTPService mapping, and it is just an easy way to get XML data from an external source and map it to an ActionScript class. In FlexB it is called XmlService.&lt;/p&gt;  &lt;p&gt;There are 3 ways to use it:&lt;/p&gt;  &lt;p&gt;1. Just like an HTTPService where you handle the ResultEvent and call the mapping functions.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;service:XmlService      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; id=&amp;quot;xmlServiceResultID&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result=&amp;quot;xmlServiceResult(event)&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;../testdata/CompoundFoo.xml&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;private function xmlServiceResult(event:ResultEvent):void     &lt;br /&gt;{&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var compoundFoo:CompoundFoo = new CompoundFoo();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; compoundFoo.map(XML(event.result));      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;2. Specify to handle an XmlResultEvent which does the mapping for you.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;service:XmlService      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; id=&amp;quot;xmlResultService&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resultClass=&amp;quot;{CompoundFoo}&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; xmlResult=&amp;quot;onXmlResult(event)&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;../testdata/CompoundFoo.xml&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;private function onXmlResult(event:XmlResultEvent):void     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var compoundFoo:CompoundFoo = event.xmlMappedObject as CompoundFoo;      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;3. Specify a function to call with the mapped instance of the object.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;service:XmlService      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; id=&amp;quot;xmlFunctionService&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resultClass=&amp;quot;{CompoundFoo}&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resultFunction=&amp;quot;{xmlServiceXmlResult}&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url=&amp;quot;../testdata/CompoundFoo.xml&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;public function xmlServiceXmlResult(compoundFoo:CompoundFoo):void     &lt;br /&gt;{&lt;/font&gt;&lt;/p&gt; &lt;font face="Courier New"&gt;}&lt;/font&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-1610153566154472633?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/1610153566154472633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=1610153566154472633' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1610153566154472633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/1610153566154472633'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/12/flexb-xml-mapping-for-flexactionscript.html' title='FlexB – XML mapping for Flex/ActionScript classes and web services'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_QipvL9yNmJU/SU8Z8kMqKzI/AAAAAAAAADM/ozmDhXoR1xU/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-532475625939992062</id><published>2008-07-06T13:05:00.001-06:00</published><updated>2008-07-06T13:07:07.296-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>In Response to the Easiest Java XML Binding. What About XStream?</title><content type='html'>&lt;p&gt;Originally I asked the following question in
&lt;a href="http://jvalentino.blogspot.com/2008/06/easiest-java-xml-binding.html"&gt;
this posting&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
 &lt;p&gt;&lt;i&gt;I have an XML document and I want to use that document to populate a 
 corresponding set of Java objects. This is a commonly encountered scenario 
 when working with Java, so what is the easiest method for Java XML Binding 
 that requires the least amount of code?&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;b&gt;What do I want? The 5 requirements of Java XML laziness.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I then went on to explain past methods of XML binding in Java, and what it 
was that I was exactly looking for. To summarize that endeavor, I was unable to 
locate something that fit my exact needs:&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;I don't want to have to manually iterate through XML documents and 
 manually map values.&lt;/li&gt;
 &lt;li&gt;I don't want to have to use XSD files.&lt;/li&gt;
 &lt;li&gt;I don't want to have to use libraries for binding compilers to use 
 external binding definitions to map to Java classes.&lt;/li&gt;
 &lt;li&gt;I don't want to have to modify existing XML documents so that I can use 
 them as beans.&lt;/li&gt;
 &lt;li&gt;I want to be able to have class and class field names that are different 
 then their corresponding XML node names.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;What is available?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I was aware that something had to exist that did this; I just couldn't find 
it. I searched the usual places such as sourcefoge.net, google, java.sun.com and 
so on, but everywhere I went I was bombarded with results that didn't fit my 
exact needs. After posting regarding this conundrum and my solution to it, which 
was to contribute to the problem of too many Java XML bindings by creating my 
own, several recommendations were made to me. The following is a list of Java 
XML bindings that have used and that were recommended to me:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;b&gt;JAXB&lt;/b&gt; - Requires Java Web Services Developer Pack v1.1 or later 
 and the use of XSD's to bind the corresponding XML to Java interfaces (&lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/jaxb/"&gt;http://java.sun.com/developer/technicalArticles/WebServices/jaxb/&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;JiBX&lt;/b&gt; - Open source project that uses binding definition documents 
 to describe how XML is mapped to Java objects at binding runtime, where 
 enhanced class files generated by the binding compiler build objects from an 
 XML input document and can be outputted as XML documents (&lt;a href="http://jibx.sourceforge.net/"&gt;http://jibx.sourceforge.net/&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;SAX/DOM/JAXP/Xerces-J&lt;/b&gt; - These are all types of Java XML parsers 
 that require the manual handling of XML documents, meaning that you have to 
 [in general] manually map the values from an XML document to the 
 corresponding Java object (&lt;a href="http://www.cafeconleche.org/books/xmljava/chapters/ch05.html"&gt;http://www.cafeconleche.org/books/xmljava/chapters/ch05.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Spring&lt;/b&gt; &lt;b&gt;Beans&lt;/b&gt; - Uses the Inversion of Control container 
 from the Spring Framework in order to bind values from special &amp;quot;bean&amp;quot; xml 
 documents to Java classes. This is not useful for reading a specific XML 
 document, but it is the binding that is of interest ; the automatic mapping 
 of XML value to Java object field. (&lt;a href="http://jvalentino.blogspot.com/2007/10/introduction-to-spring-framework.html"&gt;http://jvalentino.blogspot.com/2007/10/introduction-to-spring-framework.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;EJB Beans&lt;/b&gt; - Enterprise Java Beans are a subject unto themselves, 
 far to broad for discussion here. What is important though as with the 
 inversion of control container from the Spring Framework, is the ability to 
 bind values from XML documents to Java object fields (&lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnblr.html"&gt;http://java.sun.com/javaee/5/docs/tutorial/doc/bnblr.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Castor&lt;/b&gt; - Uses marshalling and unmarshalling to go from XML to 
 POJO and POJO to XML. The documentation is unfinished, but from what I can 
 gather in order to go from XML to POJO and POJO to XML the POJO needs to 
 implement serializable, and if the XML node names do not match class field 
 names a binding file has to be used (&lt;a href="http://www.castor.org/xml-framework.html"&gt;http://www.castor.org/xml-framework.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Codehaus XFire&lt;/b&gt; - Another method for going from XML to POJO and 
 POJO to XML, and requires the use of XSD files to do so (&lt;a href="http://xfire.codehaus.org/Aegis+Binding"&gt;http://xfire.codehaus.org/Aegis+Binding&lt;/a&gt;).
 &lt;/li&gt;
 &lt;li&gt;&lt;b&gt;XStream&lt;/b&gt; - Another method for going from XML to POJO and POJO to 
 XML, but instead of having to use XSD files and other forms of external 
 mappings it allows the use of annotations for aliasing (&lt;a href="http://xstream.codehaus.org/"&gt;http://xstream.codehaus.org/&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;What about XStream?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As it turns out XStream was exactly was I was looking for; it meets my 5 
requirements of Java XML laziness. So how does it work?&lt;/p&gt;
&lt;p&gt;Consider an RSS 2.0 document and what it represents:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding: 1px 4px;"&gt;
 &lt;pre class="source-xml"&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;?xml&lt;/span&gt; &lt;span class="re0"&gt;version&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;rss&lt;/span&gt; &lt;span class="re0"&gt;version&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;2.0&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;channel&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Lift Off News&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Liftoff to Space Exploration.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;language&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;en-us&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/language&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 10 Jun 2003 04:00:00 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;lastBuildDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 10 Jun 2003 09:41:01 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/lastBuildDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;docs&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://blogs.law.harvard.edu/tech/rss&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/docs&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;generator&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Weblog Editor 2.0&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/generator&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;managingEditor&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;editor@example.com&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/managingEditor&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;webMaster&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;webmaster@example.com&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/webMaster&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;ttl&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;5&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/ttl&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Star City&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;How do Americans get ready to work with Russians aboard the
        International Space Station? They take a crash course in culture, language
        and protocol at Russia's Star City.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 03 Jun 2003 09:39:21 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/06/03.html#item573&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Space Exploration&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Sky watchers in Europe, Asia, and parts of Alaska and Canada
        will experience a partial eclipse of the Sun on Saturday, May 31st.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Fri, 30 May 2003 11:06:42 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/30.html#item572&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;The Engine That Does More&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Before man travels to Mars, NASA hopes to design new engines
        that will let us fly through the Solar System more quickly.  The proposed
        VASIMR engine would do that.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 27 May 2003 08:37:32 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/27.html#item571&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Astronauts' Dirty Laundry&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Compared to earlier spacecraft, the International Space
        Station has many luxuries, but laundry facilities are not one of them.
        Instead, astronauts have other options.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 20 May 2003 08:56:02 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/20.html#item570&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/channel&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/rss&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p align="right"&gt;&lt;i&gt;Document from
&lt;a href="http://en.wikipedia.org/wiki/RSS_(file_format%2529"&gt;
http://en.wikipedia.org/wiki/RSS_(file_format)&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;An &amp;quot;rss&amp;quot; node has a &amp;quot;channel&amp;quot; node, a &amp;quot;channel&amp;quot; node has &amp;quot;item&amp;quot; nodes, and 
every node has their own properties and attributes. These relationships can then 
be represented in terms of objects using a class diagram (ignoring methods for 
getters and setters):&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.vdrillpro.net/blogs/xmlbinder/rss_uml.PNG" border="0" width="509" height="213"&gt;&lt;/p&gt;
&lt;p&gt;From this class diagram it is then possible to generate the corresponding 
Java classes, assuming that the class fields have the same names as their 
corresponding XML nodes. This can't always work though since class fields can be 
represented in XML as nodes or attributes of nodes, so it would be necessary to 
designate this in Java. You may also not want to have the Java class field names 
the same as the XML node names, so there would need to be a way to designate 
this as well. This is why there will always need to be some form of mapping, 
which is why XStream provides annotations and also methods for their service to 
specify aliasing at runtime.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Bad use of annotations?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;With my previous posting where I used annotations in the same manner as 
XStream, there was discussion regarding whether this use of annotations was 
necessary. The answer is absolutely yes for two reasons:&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;For when XML node names are not the same as class and class field names.&lt;/li&gt;
 &lt;li&gt;In order to translate the representation of a class field as an XML node 
 or XML node attribute.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Consider the following class and the following XML document:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;b&gt;&lt;font color="#800000"&gt;public&lt;/font&gt; &lt;font color="#800000"&gt;class&lt;/font&gt; &lt;/b&gt;Example {
 &lt;font color="#800000"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;myValue&lt;/font&gt;;
 &lt;font color="#800000"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;version&lt;/font&gt;;
}

&amp;lt;example ver=&amp;quot;1.0&amp;quot;&amp;gt;
 &amp;lt;my_value&amp;gt;value&amp;lt;/my_value&amp;gt;
&amp;lt;/example&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;How would one map the XML to the class when the class name and the field 
names are different then the XML node names? While some XML documents may be 
able to have their class field names interfered based on similarities, types, 
and positions this would not work for all cases. This is one reason why 
annotations or other mechanisms are need to map between class fields and XML 
nodes.&lt;/p&gt;
&lt;p&gt;Also consider when converting the class to XML, how would one determine 
whether a class field should be represented as an XML node or a node attribute? 
The following XML documents all could be used to represent the data in the 
Example class:&lt;/p&gt;
&lt;pre&gt;&amp;lt;example&amp;gt;
 &amp;lt;ver&amp;gt;1.0&amp;lt;/ver&amp;gt;
 &amp;lt;my_value&amp;gt;value&amp;lt;/my_value&amp;gt;
&amp;lt;/example&amp;gt;

&amp;lt;example ver=&amp;quot;1.0&amp;quot; my_value=&amp;quot;value&amp;quot; /&amp;gt;

&amp;lt;example my_value=&amp;quot;value&amp;quot;&amp;gt;
 &amp;lt;ver&amp;gt;1.0&amp;lt;/ver&amp;gt;
&amp;lt;/example&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;How does XStream do what you need?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;XStream allows the use of annotations or object aliasing methods to specify 
mappings and attributes. For example here is my previous RSS 2.0 POJP example marked 
up for XStream using annotations:&lt;/p&gt;
&lt;pre&gt;@&lt;font color="#808080"&gt;XStreamAlias&lt;/font&gt;(&amp;quot;&lt;font color="#0000FF"&gt;rss&lt;/font&gt;&amp;quot;)
&lt;font color="#800080"&gt;&lt;b&gt;public class&lt;/b&gt;&lt;/font&gt; Rss2 {
 @&lt;font color="#808080"&gt;XStreamImplicit&lt;/font&gt;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; List&amp;lt;Channel&amp;gt; &lt;font color="#0000FF"&gt;channel&lt;/font&gt;;
 @&lt;font color="#808080"&gt;XStreamAsAttribute&lt;/font&gt;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;version&lt;/font&gt;;
 
 &lt;font color="#008000"&gt;//getters and setters go here...&lt;/font&gt;
}

@&lt;font color="#808080"&gt;XStreamAlias&lt;/font&gt;(&amp;quot;&lt;font color="#0000FF"&gt;channel&lt;/font&gt;&amp;quot;)
&lt;font color="#800080"&gt;&lt;b&gt;public class&lt;/b&gt;&lt;/font&gt; Channel {
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;title&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;link&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;description&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;language&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;pubDate&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;lastBuildDate&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;docs&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;generator&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;managingEditor&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;webMaster&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; int &lt;font color="#0000FF"&gt;ttl&lt;/font&gt;;
 @&lt;font color="#808080"&gt;XStreamImplicit&lt;/font&gt;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; List&amp;lt;Item&amp;gt; &lt;font color="#0000FF"&gt;item&lt;/font&gt;;
 
 &lt;font color="#008000"&gt;//getters and setters go here...&lt;/font&gt;
}

@&lt;font color="#808080"&gt;XStreamAlias&lt;/font&gt;(&amp;quot;&lt;font color="#0000FF"&gt;item&lt;/font&gt;&amp;quot;)
&lt;font color="#800080"&gt;&lt;b&gt;public class&lt;/b&gt;&lt;/font&gt; Item {
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;title&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;link&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;description&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;pubDate&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;guid&lt;/font&gt;;
 
 &lt;font color="#008000"&gt;//getters and setters go here...&lt;/font&gt;
}
&lt;/pre&gt;
&lt;p&gt;The following code can be used to populate an RSS object using XML:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;XStream xstream = &lt;font color="#0000FF"&gt;new&lt;/font&gt; XStream(new DomDriver());
xstream.processAnnotations(Rss2.&lt;font color="#0000FF"&gt;class&lt;/font&gt;);

&lt;font color="#008000"&gt;//Create an RSS object and populate it using an XML file&lt;/font&gt;
Rss2 rssA = &lt;font color="#0000FF"&gt;new&lt;/font&gt; Rss2();
xstream.fromXML(&lt;font color="#0000FF"&gt;new&lt;/font&gt; FileReader(&lt;font color="#0000FF"&gt;new&lt;/font&gt; File(&lt;font color="#000080"&gt;&amp;quot;test/Rss2Test.xml&amp;quot;&lt;/font&gt;)), rssA);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The following code can then be used to convert a POJO to XML:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;String xml = xstream.toXML(rssA);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Why did you reinvent the wheel with your RE: JAXB project?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As I have said before I created a factory for binding XML to POJOs and back 
because I could not find anything at the time that suited my exact needs. To me 
it is really not that big of a deal, because it only took a single afternoon and 
only consisted of several hundred lines of code.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-532475625939992062?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/532475625939992062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=532475625939992062' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/532475625939992062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/532475625939992062'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/07/in-response-to-easiest-java-xml-binding.html' title='In Response to the Easiest Java XML Binding. What About XStream?'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-8201149339176755488</id><published>2008-06-30T21:28:00.001-06:00</published><updated>2008-07-02T06:44:47.421-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>The Easiest Java XML Binding</title><content type='html'>&lt;p&gt;I have an XML document and I want to use that document to populate a 
corresponding set of Java objects. This is a commonly encountered scenario when 
working with Java, so what is the easiest method for Java XML Binding that 
requires the least amount of code? You can't answer that question without first 
defining what &amp;quot;easy&amp;quot; is in relation to the bindings between Java and XML. To me 
&amp;quot;easy&amp;quot; is synonymous with &amp;quot;simple,&amp;quot; so I am equating easiness to complexity. 
Complexity is of interest because things that are complex take longer to 
implement and are generally harder to maintain, based on my experiences with 
software in a variety of languages and platforms. Less code written means less 
code to maintain, and less code to write means less time is required to write 
that code.&lt;/p&gt;
&lt;p&gt;So what are the methods for binding Java and XML?&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;b&gt;JAXB&lt;/b&gt; - Requires Java Web Services Developer Pack v1.1 or later 
 and the use of XSD's to bind the corresponding XML to Java interfaces (&lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/jaxb/"&gt;http://java.sun.com/developer/technicalArticles/WebServices/jaxb/&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;JiBX&lt;/b&gt; - Open source project that uses binding definition documents 
 to describe how XML is mapped to Java objects at binding runtime, where 
 enhanced class files generated by the binding compiler build objects from an 
 XML input document and can be outputted as XML documents (&lt;a href="http://jibx.sourceforge.net/"&gt;http://jibx.sourceforge.net/&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;SAX/DOM/JAXP/Xerces-J&lt;/b&gt; - These are all types of Java XML 
 parsers that require the manual handling of XML documents, meaning that you 
 have to [in general] manually map the values from an XML document to the 
 corresponding Java object (&lt;a href="http://www.cafeconleche.org/books/xmljava/chapters/ch05.html"&gt;http://www.cafeconleche.org/books/xmljava/chapters/ch05.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Spring&lt;/b&gt; &lt;b&gt;Beans&lt;/b&gt; - Uses the Inversion of Control container 
 from the Spring Framework in order to bind values from special &amp;quot;bean&amp;quot; xml 
 documents to Java classes. This is not useful for reading a specific XML 
 document, but it is the binding that is of interest ; the automatic mapping 
 of XML value to Java object field. (&lt;a href="http://jvalentino.blogspot.com/2007/10/introduction-to-spring-framework.html"&gt;http://jvalentino.blogspot.com/2007/10/introduction-to-spring-framework.html&lt;/a&gt;).&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;EJB Beans&lt;/b&gt; - Enterprise Java Beans are a subject unto themselves, 
 far to broad for discussion here. What is important though as with the 
 inversion of control container from the Spring Framework, is the ability to 
 bind values from XML documents to Java object fields (&lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnblr.html"&gt;http://java.sun.com/javaee/5/docs/tutorial/doc/bnblr.html&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have used all of these methods in depth before, but this isn't exactly what 
I want though:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;I don't want to have to manually iterate through XML documents and 
 manually map values.&lt;/li&gt;
 &lt;li&gt;I don't want to have to use XSD files.&lt;/li&gt;
 &lt;li&gt;I don't want to have to use libraries for binding compilers to use 
 binding definitions to map to Java classes.&lt;/li&gt;
 &lt;li&gt;I don't want to have to modify existing XML documents so that I can use 
 them as beans.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My usage of Adobe Flex (&lt;a href="http://jvalentino.blogspot.com/2008/02/flex-tutorial-part-ii-language-concepts.html"&gt;http://jvalentino.blogspot.com/2008/02/flex-tutorial-part-ii-language-concepts.html&lt;/a&gt;) 
over the last couple of years has spoiled my expectations for language and XML 
interaction; I want more with less.&lt;/p&gt;
&lt;p&gt;I know exactly what I want: I want to have a series of Java objects that are 
representations of nodes within an XML document, and pass the XML document to 
the Java object representing the root XML node and have all of the corresponding 
Java objects populate using that XML. I then want to be able to go from Java 
back to XML, and I don't want to have to do anything other then say &amp;quot;XML, go to 
Java&amp;quot; and then &amp;quot;Java, go to XML.&amp;quot;&lt;/p&gt;
&lt;p&gt;Why should there need to be complex mappings and external definitions when 
Java and XML are being used to representing the same thing?&lt;/p&gt;
&lt;p&gt;Consider an RSS 2.0 document and what it represents:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
 &lt;pre class="source-xml"&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;?xml&lt;/span&gt; &lt;span class="re0"&gt;version&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;rss&lt;/span&gt; &lt;span class="re0"&gt;version&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;2.0&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;channel&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Lift Off News&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Liftoff to Space Exploration.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;language&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;en-us&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/language&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 10 Jun 2003 04:00:00 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;lastBuildDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 10 Jun 2003 09:41:01 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/lastBuildDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;docs&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://blogs.law.harvard.edu/tech/rss&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/docs&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;generator&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Weblog Editor 2.0&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/generator&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;managingEditor&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;editor@example.com&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/managingEditor&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;webMaster&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;webmaster@example.com&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/webMaster&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;ttl&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;5&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/ttl&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Star City&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;How do Americans get ready to work with Russians aboard the
        International Space Station? They take a crash course in culture, language
        and protocol at Russia's Star City.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 03 Jun 2003 09:39:21 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/06/03.html#item573&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Space Exploration&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Sky watchers in Europe, Asia, and parts of Alaska and Canada
        will experience a partial eclipse of the Sun on Saturday, May 31st.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Fri, 30 May 2003 11:06:42 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/30.html#item572&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;The Engine That Does More&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Before man travels to Mars, NASA hopes to design new engines
        that will let us fly through the Solar System more quickly.  The proposed
        VASIMR engine would do that.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 27 May 2003 08:37:32 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/27.html#item571&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Astronauts' Dirty Laundry&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/title&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/link&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Compared to earlier spacecraft, the International Space
        Station has many luxuries, but laundry facilities are not one of them.
        Instead, astronauts have other options.&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/description&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Tue, 20 May 2003 08:56:02 GMT&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/pubDate&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;http://liftoff.msfc.nasa.gov/2003/05/20.html#item570&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/guid&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/item&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/channel&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/rss&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p align="right"&gt;&lt;i&gt;Document from
&lt;a href="http://en.wikipedia.org/wiki/RSS_(file_format)"&gt;
http://en.wikipedia.org/wiki/RSS_(file_format)&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;An &amp;quot;rss&amp;quot; node has a &amp;quot;channel&amp;quot; node, a &amp;quot;channel&amp;quot; node has &amp;quot;item&amp;quot; nodes, and 
every node has their own properties and attributes. These relationships can then 
be represented in terms of objects using a class diagram (ignoring methods for 
getters and setters):&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/xmlbinder/rss_uml.PNG" width="509" height="213"&gt;&lt;/p&gt;
&lt;p&gt;From this class diagram it is then possible to generate the corresponding 
Java classes, assuming that the class fields have the same names as their 
corresponding XML nodes. This can't always work though since class fields can be 
represented in XML as properties or attributes, so it would be necessary to 
designate this in Java. You may also not want to have the Java class field names 
the same as the XML node names, so there would need to be a way to designate 
this as well. One easy way to designate specific things about classes, fields, 
and methods is to use annotations, so consider the following 3 annotations:&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;@ClassXmlNodeName - used on a Java class to specify its corresponding 
 node name in an XML document. This is required in order to designate a class 
 as being bound to an XML document.&lt;/li&gt;
 &lt;li&gt;@XmlAttributeName - used on a Java field to specify its corresponding 
 attribute name in an XML document. This is required in order to specify that 
 a particular class field should be represented in XML as an attribute 
 instead of a property.&lt;/li&gt;
 &lt;li&gt;@XmlNodeName - used on a Java field to specify its corresponding node 
 name in an XML document. This is only required when a Java class field name 
 is different than its corresponding XML node name.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;@&lt;font color="#808080"&gt;ClassXmlNodeName&lt;/font&gt;(&lt;font color="#008080"&gt;&amp;quot;rss&amp;quot;&lt;/font&gt;)
&lt;font color="#800080"&gt;&lt;b&gt;public class&lt;/b&gt;&lt;/font&gt; Rss {
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; List&amp;lt;Channel&amp;gt; &lt;font color="#0000FF"&gt;channels&lt;/font&gt;;
 @&lt;font color="#808080"&gt;XmlAttributeName&lt;/font&gt;(&lt;font color="#008080"&gt;&amp;quot;version&amp;quot;&lt;/font&gt;)
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;version&lt;/font&gt;;
 
 &lt;font color="#008000"&gt;//getters and settings go here...&lt;/font&gt;
}

@&lt;font color="#808080"&gt;ClassXmlNodeName&lt;/font&gt;(&lt;font color="#008080"&gt;&amp;quot;channel&amp;quot;&lt;/font&gt;)
&lt;font color="#800080"&gt;&lt;b&gt;public class &lt;/b&gt;&lt;/font&gt;Channel {
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;title&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;link&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;description&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;language&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;pubDate&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;lastBuildDate&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;docs&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;generator&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;managingEditor&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;webMaster&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; &lt;font color="#800080"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; &lt;font color="#0000FF"&gt;ttl&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; List&amp;lt;Item&amp;gt; &lt;font color="#0000FF"&gt;items&lt;/font&gt;;

 &lt;font color="#008000"&gt;//getters and settings go here...&lt;/font&gt;
}

@&lt;font color="#808080"&gt;ClassXmlNodeName&lt;/font&gt;(&lt;font color="#008080"&gt;"item"&lt;/font&gt;)
&lt;font color="#800080"&gt;&lt;b&gt;public class&lt;/b&gt;&lt;/font&gt; Item {
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;title&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;link&lt;/font&gt;;
 &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;description&lt;/font&gt;;
     &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;pubDate&lt;/font&gt;;
     &lt;font color="#800080"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt; String &lt;font color="#0000FF"&gt;guid&lt;/font&gt;;
    
     &lt;font color="#008000"&gt;//getters and settings go here... &lt;/font&gt;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With the exception of the annotations, these Java classes are just like any 
other data transfer objects (DTOs) that would be used to represent a RSS XML 
document. These annotations act as the mappings between Java and XML when names 
and types do not provide enough information. With this information, the class 
representing the XML document root node, and the XML document it is possible to 
recursively map XML nodes to Java class fields and Java class fields back to XML 
nodes using Reflection. So using Reflection I wrote a library that can take any 
Plain Old Java Object (POJO) and an XML document, and use that XML document to 
populate that object and all of its child objects using one line of code. The 
same can then be done to convert a Java object back to its XML representation 
using a single line of code. All of this assuming that the Java classes 
correspond to the XML document.&lt;/p&gt;
&lt;p&gt;Using this &amp;quot;XML Binder&amp;quot; library the following code takes the the given 
instance of an Rss object and populates it and its channels and items using the 
given XML document:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;Rss rss = &lt;font color="#0000FF"&gt;new&lt;/font&gt; Rss();
XmlBinderFactory.newInstance().bind(rss, &lt;font color="#0000FF"&gt;new&lt;/font&gt; File(&lt;font color="#008080"&gt;&amp;quot;Rss2Test.xml&amp;quot;&lt;/font&gt;));&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The following code can then be used to take that same Rss object once changes 
have been made to it and converts it back to XML:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;String xml = XmlBinderFactory.newInstance().toXML(rss);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I assert that this can work with most XML documents that have appropriate 
corresponding Java classes, but I have only tested it out so far with RSS 1.0, 
RSS 2.0, and a general test XML document in no particular format. The question 
now is what do I do with this library; anyone interested?&lt;/p&gt;
&lt;p&gt;Since there seems to be some interest I have started a sourceforge.net project called "Really Easy Java XML Binding" or "RE:JAXB" since this is sort of a reply to JAXB. Here is the &lt;a href="http://sourceforge.net/projects/rejaxb/"&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have included POJOs for RSS 1.0 and RSS 2.0 along with unit tests to verify that the mappings from XML and to XML are working correctly. What I am looking for are ways to improve the efficiency of the to and from binding code, as well as POJOs for other common XML formats.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-8201149339176755488?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/8201149339176755488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=8201149339176755488' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/8201149339176755488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/8201149339176755488'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/06/easiest-java-xml-binding.html' title='The Easiest Java XML Binding'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-6338828021036245368</id><published>2008-05-17T16:54:00.014-06:00</published><updated>2008-12-12T23:39:50.867-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>The Flexsite</title><content type='html'>&lt;p&gt;Social networking websites such as MySpace and Facebook have many common 
themes regarding the reasons for their popularity. One common theme in 
particular is that each website gives the average user the ability to have a 
persistent, customizable, and maintainable online presence. These websites 
though typically are intended for individual users, meaning that there is not 
anything equivalent for businesses. If a business wants a website they have to 
either already have someone or hire someone to build and maintain the website. 
The more visually appealing and interactive that a websites needs to be the 
higher the cost and the more difficult it is to maintain. Flexsite solves this 
problem by providing a highly configurable, visually appealing, inexpensive, and 
easily maintainable website that operates like familiar social networking 
websites for small businesses with all of the setup included.&lt;/p&gt;
&lt;p&gt;Flexsite uses numerous web technologies in order to provide services and 
interact with existing services: &lt;br&gt;
&lt;br&gt;
• HTML&lt;br&gt;
• XML&lt;br&gt;
• Flash&lt;br&gt;
• DTD&lt;br&gt;
• Flex&lt;br&gt;
• RSS&lt;br&gt;
• WordPress&lt;br&gt;
• PayPal&lt;br&gt;
• PHP&lt;br&gt;
• MySQL&lt;br&gt;
• JavaScript&lt;br&gt;
• CSS &lt;/p&gt;
&lt;p&gt;The Flexsite application itself is divided into systems based on function, 
which incorporate one or more of the previously listed technologies and/or third 
party services. The visuals for Flexsite are done as an Adobe Flex application, 
which communicates with other services specified by the XML layout vocabulary. 
All communication with the Adobe Flex application is done through XML as well. 
Of all of the systems only the XML layout vocabulary is required, everything 
else is optional and Flexsite can run without them. The following is a diagram 
of all the involved systems:&lt;br&gt;
&lt;img border="0" src="http://2.bp.blogspot.com/_QipvL9yNmJU/SC9o16a5jZI/AAAAAAAAAA8/FxLumsx7Oyo/s320/figure1.PNG" width="320" height="249"&gt;&lt;br&gt;
Figure 1: Systems&lt;/p&gt;
&lt;p&gt;The XML layout vocabulary is just an XML document used to specify website 
sizing, sections, menu items, content, Flash skins, and web services. There is 
also a corresponding DTD which is used to validate the layout XML. For web 
services that support PHP there are Flexsite Services that can be used to 
manipulate the XML using an Adobe Flex graphical user interface. &lt;br&gt;
&lt;img border="0" src="http://2.bp.blogspot.com/_QipvL9yNmJU/SC9o16a5jaI/AAAAAAAAABE/YS-Lg8ssvFA/s1600-h/figure2.PNG"&gt;&lt;br&gt;
Figure 2: Layout Manager&lt;/p&gt;
&lt;p&gt;Flexsite also incorporates the use of Flash Skins for the look and feel of 
the website. Flash skins are CSS files that refer to Flex components instead of 
HTML tags, compiled into SWF format. Through the layout manager users can 
specify the Flash skin to use for the website. Users can select from a variety 
of pre-made Flash skins or build and upload their own.&lt;br&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/_QipvL9yNmJU/SC9o2Ka5jbI/AAAAAAAAABM/eDPNRQC9Lac/s320/figure3.PNG" width="320" height="209"&gt;&lt;br&gt;
Figure 3: Some Example Flash Skins&lt;/p&gt;
&lt;p&gt;There is also a Pay Per Download system that allows a web master to specify 
files that are available to download and how much they want to charge to 
download those files. This works by linking to PayPal through the Instant 
Payment Notification (IPN) API, which provides the user the file to download 
after successful payment. The user is then emailed a dynamic URL which can be 
used to download the file up to 24 hours after purchase.&lt;br&gt;
&lt;img border="0" src="http://4.bp.blogspot.com/_QipvL9yNmJU/SC9o2aa5jcI/AAAAAAAAABU/vTsEFm9Ch1k/s320/figure4.PNG" width="320" height="178"&gt;&lt;br&gt;
Figure 4: Pay Per Download System&lt;/p&gt;
&lt;p&gt;WordPress is a state-of-the-art publishing platform with a focus on 
aesthetics, web standards, and usability (WordPress.org). Flexsite has the 
ability to integrate WordPress, so that it can be used to manage the content 
that the site displays. WordPress supports multiple users with varying account 
permissions so that site content can be concurrently managed by multiple users. 
Another benefit of using WordPress is that is accessible to all levels of users 
since it operates like many familiar Word Processors, and it doesn’t require the 
download of installation of any software.&lt;br&gt;
&lt;img border="0" src="http://4.bp.blogspot.com/_QipvL9yNmJU/SC9o2aa5jdI/AAAAAAAAABc/SAG8-r8aXIA/s320/figure5.PNG" width="320" height="163"&gt;&lt;br&gt;
Figure 5: WordPress HTML Editor&lt;/p&gt;
&lt;p&gt;Flexsite is also used to host its own website, and particular to this 
installation there is another PayPal integration that allows users to pay for 
Flexsite hosting services through the website. A graphical user interface is 
provided which displays all of the service pricing, and allows the user to 
select a domain name as well as a starting Flash skin for their new website.&lt;br&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/_QipvL9yNmJU/SC9o-Ka5jeI/AAAAAAAAABk/agnam33Vy6k/s320/figure6.PNG" width="320" height="287"&gt;&lt;br&gt;
Figure 6: Buying Hosting Services&lt;/p&gt;
&lt;p&gt;The result is visually appealing and easily maintainable website that doesn’t 
require the installation of any software, and doesn’t require computer knowledge 
beyond that of operating a Word Processor. This technology is also accessible to 
everyone since it cost about the same as regular hosting, but includes the 
setup, domain name registration, website setup, WordPress setup, and 
customization.&lt;br&gt;
&lt;br&gt;
www.theflexsite.com and www.theflexsite.net&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-6338828021036245368?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/6338828021036245368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=6338828021036245368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6338828021036245368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/6338828021036245368'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/05/flexsite.html' title='The Flexsite'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_QipvL9yNmJU/SC9o16a5jZI/AAAAAAAAAA8/FxLumsx7Oyo/s72-c/figure1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-2863922093530033426</id><published>2008-02-09T21:00:00.000-06:00</published><updated>2008-02-10T08:55:23.560-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>The Flex Tutorial: Part II - Language Concepts and Basics</title><content type='html'>&lt;h3&gt;The two languages of Flex&lt;/h3&gt;
&lt;p&gt;The Flex language consists of two flavors: ActionScript 3 and XML. 
ActionScript is a scripting language based on ECMAScript (JavaScript), used 
primarily for the development of websites and software using the Adobe Flash 
Player platform (&lt;a href="http://en.wikipedia.org/wiki/ActionScript"&gt;http://en.wikipedia.org/wiki/ActionScript&lt;/a&gt;). 
The Extensible Markup Language (XML) is a general-purpose markup language, which 
is classified as an extensible language because it allows its users to define 
their own elements (&lt;a href="http://en.wikipedia.org/wiki/XML"&gt;http://en.wikipedia.org/wiki/XML&lt;/a&gt;). 
In Flex ActionScript files have the extension &amp;quot;.as&amp;quot; while the XML files have the 
extension &amp;quot;.mxml.&amp;quot;&lt;/p&gt;
&lt;p&gt;XML is used in Flex to represent static objects such as a button on a 
graphical user interface or an HTTP Service. For graphical user interface this 
provides a fast and efficient way of laying out components. For example consider 
an application that consists or a single panel and a single button:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/example_app.PNG" width="278" height="227"&gt;&lt;/p&gt;
&lt;p&gt;Using MXML this would require the following code:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&lt;font color="#0000FF"&gt;&amp;lt;mx:Application&lt;/font&gt; xmlns:mx=&lt;font color="#CC0000"&gt;&amp;quot;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;mx:Panel&lt;/font&gt; width=&lt;font color="#CC0000"&gt;&amp;quot;250&amp;quot;&lt;/font&gt; height=&lt;font color="#CC0000"&gt;&amp;quot;200&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot;&lt;/font&gt; horizontalAlign=&lt;font color="#CC0000"&gt;&amp;quot;center&amp;quot; &lt;/font&gt;
 verticalAlign=&amp;quot;&lt;font color="#CC0000"&gt;middle&amp;quot;&lt;/font&gt; title=&lt;font color="#CC0000"&gt;&amp;quot;This is a panel&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:Button&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;This is a button&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Panel&amp;gt;&lt;/font&gt;
&lt;font color="#0000FF"&gt;&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this Flex (MXML) code you are essentially creating an &lt;i&gt;&lt;b&gt;Application&lt;/b&gt;&lt;/i&gt; 
with a vertical layout that contains a &lt;i&gt;&lt;b&gt;Panel&lt;/b&gt;&lt;/i&gt; with some size, 
layout, and text attributes. The panel then contains a &lt;i&gt;&lt;b&gt;Button&lt;/b&gt;&lt;/i&gt; with 
some text. This is easy to conceptualize since the in the code the application 
contains the panel, which then contains the button.&lt;/p&gt;
&lt;p&gt;Using Java this same equivalent application would require the following code:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; javax.swing.JFrame;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; javax.swing.JPanel;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; javax.swing.JButton;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; javax.swing.BorderFactory;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; java.awt.Color;

&lt;font color="#0000FF"&gt;public class&lt;/font&gt; Application &lt;font color="#0000FF"&gt;extends&lt;/font&gt; JFrame {
    
    &lt;font color="#0000FF"&gt;public static void&lt;/font&gt; main(String[] args) {
        JFrame frame = &lt;font color="#0000FF"&gt;new&lt;/font&gt; Application();
        frame.setSize(400,400);
        frame.setVisible(&lt;font color="#0000FF"&gt;true&lt;/font&gt;);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    &lt;font color="#0000FF"&gt;public&lt;/font&gt; Application() {
        JPanel panel = &lt;font color="#0000FF"&gt;new&lt;/font&gt; JPanel();
        panel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createLineBorder(Color.black), 
            &lt;font color="#CC0000"&gt;"This is a panel"&lt;/font&gt;));
        JButton button = &lt;font color="#0000FF"&gt;new&lt;/font&gt; JButton(&lt;font color="#CC0000"&gt;"This is a button"&lt;/font&gt;);
        panel.add(button);
        setContentPane(panel);
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In the Java code the concept remains the same, that an Application contains a 
Panel that contains a Button, but the code is not as easy to read (even when 
ignoring the extra stuff that was thrown in there to close the frame and set the 
border).&lt;/p&gt;
&lt;p&gt;This just serves an example of how much less coding and complexity there is 
with constructing graphical user interface in MXML than with other object 
oriented languages. Less complexity means that the application will be easier to 
maintain, which is extremely important considering that the vast majority of 
time in the software lifecycle is spent in maintenance. Complexity is not only 
reduced with Flex and the layout out of graphical user interface components, 
Flex has numerous other features that do the same across the entire framework.&lt;/p&gt;
&lt;p&gt;Though Flex is less complex that doesn't mean that it loses any capability. 
The genius of Flex is its ability to represent the same conceptual models as in 
other object oriented languages, only with less code and complexity. Consider 
the class diagrams of the example Flex and Java applications:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/class_diagram.PNG" width="417" height="201"&gt;&lt;/p&gt;
&lt;p&gt;The same relationships are maintained: an application has a panel that has a 
button. Flex can be used to represent almost any object oriented design exactly. 
I use the term &amp;quot;almost&amp;quot; because ActionScript 3 currently doesn't support 
abstract classes.&lt;/p&gt;

&lt;p&gt;Flex also has the ability to represent objects using ActionScript, which can 
be used in place of or in conjunction with MXML. For example you could create a 
&amp;quot;Person&amp;quot; ActionScript class and use it to represent data in an MXML component. 
The actual instantiation and value assignments of the &amp;quot;Person&amp;quot; class could then 
be done in either MXML or ActionScript.&lt;/p&gt;
&lt;p&gt;The following is an ActionScript representation of a &amp;quot;Person&amp;quot; class:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#800080"&gt;package&lt;/font&gt; example.data
{
 &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#800080"&gt;class&lt;/font&gt; Person
 {
  &lt;font color="#0000FF"&gt;public var&lt;/font&gt; firstName:String;
  &lt;font color="#0000FF"&gt;public var &lt;/font&gt;lastName:String;
  &lt;font color="#0000FF"&gt;public var&lt;/font&gt; favoriteFood:String;
 }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Inside XML this class could be instantiated (assuming the class was included 
as &amp;quot;ex&amp;quot;) like so:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;&amp;lt;ex:Person&lt;/font&gt; id=&lt;font color="#CC0000"&gt;&amp;quot;person&amp;quot;&lt;/font&gt; firstName=&lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt; lastName=&lt;font color="#CC0000"&gt;&amp;quot;Valentino&amp;quot;&lt;/font&gt; favoriteFood=&lt;font color="#CC0000"&gt;&amp;quot;Steak&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Inside of ActionScript this class could be instantiated like the following:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#0000FF"&gt;var&lt;/font&gt; person:Person = &lt;font color="#0000FF"&gt;new&lt;/font&gt; Person();
person.firstName = &lt;font color="#CC0000"&gt;"John"&lt;/font&gt;;
person.lastName = &lt;font color="#CC0000"&gt;"Valentino"&lt;/font&gt;;
person.favoriteFood = &lt;font color="#CC0000"&gt;"Steak"&lt;/font&gt;;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;What the heck are you doing? Where are the getters and setters?&lt;/h3&gt;
&lt;p&gt;Getters and setters are something that I feel have gotten a bit out of hand 
in object-oriented programming. The purpose of using getters and setters is to 
decouple objects and to provide hidden functionality when assigning values to 
attributes of objects. For example if the &amp;quot;Person&amp;quot; class contained an instance 
of &amp;quot;Person&amp;quot; called &amp;quot;child&amp;quot; you probably wouldn't want to make it (and all of its 
attributes) publicly accessible to prevent coupling. An example of hidden 
functionality would be if you wanted to check modify special characters in the 
first and last names when setting their values.&lt;/p&gt;
&lt;p&gt;No matter how you or I feel about getters and setters and their under usage 
or over usage, Flex provides its own special functions for getters and setters. 
This allows classes to define methods to handle the getting and setting of 
attributes within classes, but those functions can be called (by lazy 
programmers like myself) as if they were publicly accessible attributes. &lt;/p&gt;
&lt;p&gt;Consider the &amp;quot;Person&amp;quot; class redone to use the special get and set functions:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#800080"&gt;package&lt;/font&gt; example.data
{
 &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#800080"&gt;class&lt;/font&gt; PersonII
 {
  &lt;font color="#0000FF"&gt;private var&lt;/font&gt; _firstName:String, _lastName:String, 
        _favoriteFood:String;
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;get&lt;/b&gt;&lt;/font&gt; firstName():String
  {
   &lt;font color="#0000FF"&gt;return&lt;/font&gt; _firstName;
  }
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;get&lt;/b&gt; &lt;/font&gt;lastName():String
  {
   &lt;font color="#0000FF"&gt;return&lt;/font&gt; _lastName;
  }
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;get&lt;/b&gt; &lt;/font&gt;favoriteFood():String
  {
   &lt;font color="#0000FF"&gt;return&lt;/font&gt; _favoriteFood;
  }
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;set&lt;/b&gt;&lt;/font&gt; firstName(value:String):&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   _firstName = value;
  }
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;set&lt;/b&gt;&lt;/font&gt; lastName(value:String):&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   _lastName = value;
  }
  
  &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;b&gt;set&lt;/b&gt;&lt;/font&gt; favoriteFood(value:String):&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   _favoriteFood = value;
  } 
 }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;These special get and set functions are what allow these functions to be 
called as if they were attributes. Using this new person classes the example 
instantiations in MXML and ActionScript to not need to be changed; they work the 
same as before.&lt;/p&gt;
&lt;p&gt;Inside XML this class could be instantiated (assuming the class was included 
as &amp;quot;ex&amp;quot;) like so:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;&amp;lt;ex:PersonII&lt;/font&gt; id=&lt;font color="#CC0000"&gt;&amp;quot;person&amp;quot;&lt;/font&gt; firstName=&lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt; lastName=&lt;font color="#CC0000"&gt;&amp;quot;Valentino&amp;quot;&lt;/font&gt; favoriteFood=&lt;font color="#CC0000"&gt;&amp;quot;Steak&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Inside of ActionScript this class could be instantiated like the following:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#0000FF"&gt;var&lt;/font&gt; person:PersonII = &lt;font color="#0000FF"&gt;new&lt;/font&gt; PersonII();
person.firstName = &lt;font color="#CC0000"&gt;"John"&lt;/font&gt;;
person.lastName = &lt;font color="#CC0000"&gt;"Valentino"&lt;/font&gt;;
person.favoriteFood = &lt;font color="#CC0000"&gt;"Steak"&lt;/font&gt;;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Bringing MXML and ActionScript together&lt;/h3&gt;
&lt;p&gt;One of the most important concepts in Flex is that every object has 2 
aspects: the XML and the ActionScript. In a constant effort to eliminate 
complexity I have found that XML is preferable to ActionScript in most 
situations. A good rule of thumb to know when to use what is to ask yourself the 
question &amp;quot;Can I do this in MXML?&amp;quot; If the answer is no than you can go with 
ActionScript, otherwise stick with MXML to cut down on code size and complexity. 
You must exercise common sense though; if you find yourself having to do 
something that seems unintuitive in MXML than you should probably use 
ActionScript.&lt;/p&gt;
&lt;p&gt;Typically in graphical user interface components ActionScript is used within 
MXML components. This allows graphical user interfaces to be statically laid out 
in MXML, and then use ActionScript to handle complex logic. For example consider 
the original example application that has been modified to use ActionScript to 
display a message when a button is pressed:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&lt;font color="#0000FF"&gt;&amp;lt;mx:Application&lt;/font&gt; xmlns:mx=&lt;font color="#CC0000"&gt;&amp;quot;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;

 &lt;font color="#0000FF"&gt;&amp;lt;mx:Script&amp;gt;&lt;/font&gt;
  &amp;lt;![CDATA[
  &lt;font color="#0000FF"&gt;import&lt;/font&gt; mx.controls.Alert;

  &lt;font color="#0000FF"&gt;private&lt;/font&gt; &lt;font color="#008000"&gt;function&lt;/font&gt; &lt;span style="background-color: #FFFF00"&gt;buttonPressed()&lt;/span&gt;:&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   Alert.show(&lt;font color="#CC0000"&gt;&amp;quot;The button was pressed&amp;quot;&lt;/font&gt;);
  }
  ]]&amp;gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Script&amp;gt;&lt;/font&gt;

 &lt;font color="#0000FF"&gt;&amp;lt;mx:Panel&lt;/font&gt; width=&lt;font color="#CC0000"&gt;&amp;quot;250&amp;quot;&lt;/font&gt; height=&lt;font color="#CC0000"&gt;&amp;quot;200&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot;&lt;/font&gt; horizontalAlign=&lt;font color="#CC0000"&gt;&amp;quot;center&amp;quot;&lt;/font&gt; 
  verticalAlign=&lt;font color="#CC0000"&gt;&amp;quot;middle&amp;quot;&lt;/font&gt; title=&lt;font color="#CC0000"&gt;&amp;quot;This is a panel&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:Button&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;This is a button&amp;quot;&lt;/font&gt; &lt;span style="background-color: #FFFF00"&gt;click=&lt;/span&gt;&lt;font color="#CC0000"&gt;&lt;span style="background-color: #FFFF00"&gt;&amp;quot;buttonPressed()&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Panel&amp;gt;
&amp;lt;/mx:Application&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now when the button is pressed the following message is displayed:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/button_pressed.PNG" width="274" height="246"&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Binding&lt;/h3&gt;
&lt;p&gt;One of the most important features of Flex is the ability to bind objects to 
components. This is basically instant model-view-controller without having to 
use listeners or worry about observers and observables. A common need in 
programming graphical user interfaces is the ability to display some type of 
information to the user through some sort of component, that is then updated 
through some event. For example consider a series of text fields that display 
information about a person:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/person_panel.PNG" width="319" height="189"&gt;&lt;/p&gt;
&lt;p&gt;The following code shows how the data is bound to different fields within the 
graphical user interface:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&lt;font color="#0000FF"&gt;&amp;lt;mx:Panel&lt;/font&gt; xmlns:mx=&lt;font color="#CC0000"&gt;&amp;quot;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot; &lt;/font&gt;
 title=&lt;font color="#CC0000"&gt;&amp;quot;Person Panel&amp;quot;&lt;/font&gt; horizontalAlign=&lt;font color="#CC0000"&gt;&amp;quot;center&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;

 &lt;font color="#0000FF"&gt;&amp;lt;mx:Script&amp;gt;&lt;/font&gt;
  &amp;lt;![CDATA[

  &lt;font color="#0000FF"&gt;[&lt;b&gt;Bindable&lt;/b&gt;]&lt;/font&gt;
  &lt;font color="#0000FF"&gt;private&lt;/font&gt; &lt;font color="#0000FF"&gt;var&lt;/font&gt; firstName:String = &lt;font color="#0000FF"&gt;new&lt;/font&gt; String();
  &lt;font color="#0000FF"&gt;[&lt;b&gt;Bindable&lt;/b&gt;]
  private var&lt;/font&gt; lastName:String = &lt;font color="#0000FF"&gt;new&lt;/font&gt; String();
  &lt;font color="#0000FF"&gt;[&lt;b&gt;Bindable&lt;/b&gt;]
  private var&lt;/font&gt; favoriteFood:String = &lt;font color="#0000FF"&gt;new&lt;/font&gt; String();

  &lt;font color="#0000FF"&gt;private &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;/font&gt;john():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   firstName = &lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt;;
   lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino II&amp;quot;&lt;/font&gt;;
   favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Steak&amp;quot;&lt;/font&gt;;
  }

  &lt;font color="#0000FF"&gt;private&lt;/font&gt; &lt;font color="#008000"&gt;function&lt;/font&gt; sarah():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   firstName = &lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt;;
   lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino&amp;quot;&lt;/font&gt;;
   favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Pizza&amp;quot;&lt;/font&gt;;
  }

  ]]&amp;gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Script&amp;gt;
 &amp;lt;mx:Form&lt;/font&gt; width=&lt;font color="#CC0000"&gt;&amp;quot;100%&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;First Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{firstName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;Last Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{lastName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Favorite Food:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{favoriteFood}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
 &amp;lt;/mx:Form&amp;gt;
 &amp;lt;mx:HBox&amp;gt;
  &amp;lt;mx:Button&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;john()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:Button &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;sarah()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:HBox&amp;gt;

&amp;lt;/mx:Panel&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The variables &lt;i&gt;firstName&lt;/i&gt;, &lt;i&gt;lastName&lt;/i&gt;, and &lt;i&gt;favoriteFood&lt;/i&gt;, are 
made &amp;quot;Bindable&amp;quot; so that when ever they are changed anything that is referencing 
them is also changed. This means that since those variables are referenced by 
the TextInputs, when those variables are changed what is displayed in those 
TextInputs will also change.&lt;/p&gt;
&lt;p&gt;For example the following is displayed when the &amp;quot;John&amp;quot; button is pressed:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/john.PNG" width="323" height="194"&gt;&lt;/p&gt;
&lt;p&gt;The following is displayed when the &amp;quot;Sarah&amp;quot; button is pressed:&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_2/sarah.PNG" width="321" height="191"&gt;&lt;/p&gt;
&lt;p&gt;It should also be noted that if you declare instances in MXML that are 
automatically bindable, so the following example retains the same functionality:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&lt;font color="#0000FF"&gt;&amp;lt;mx:Panel&lt;/font&gt; xmlns:mx=&lt;font color="#CC0000"&gt;&amp;quot;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot; &lt;/font&gt;
 title=&lt;font color="#CC0000"&gt;&amp;quot;Person Panel&amp;quot;&lt;/font&gt; horizontalAlign=&lt;font color="#CC0000"&gt;&amp;quot;center&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
 
 &lt;font color="#0000FF"&gt;&amp;lt;mx:String&lt;/font&gt; id=&lt;font color="#CC0000"&gt;&amp;quot;firstName&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;mx:String&lt;/font&gt; id=&lt;font color="#CC0000"&gt;&amp;quot;lastName&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;mx:String&lt;/font&gt; id=&lt;font color="#CC0000"&gt;&amp;quot;favoriteFood&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;

 &lt;font color="#0000FF"&gt;&amp;lt;mx:Script&amp;gt;&lt;/font&gt;
  &amp;lt;![CDATA[

  &lt;font color="#0000FF"&gt;private &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;/font&gt;john():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   firstName = &lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt;;
   lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino II&amp;quot;&lt;/font&gt;;
   favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Steak&amp;quot;&lt;/font&gt;;
  }

  &lt;font color="#0000FF"&gt;private&lt;/font&gt; &lt;font color="#008000"&gt;function&lt;/font&gt; sarah():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   firstName = &lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt;;
   lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino&amp;quot;&lt;/font&gt;;
   favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Pizza&amp;quot;&lt;/font&gt;;
  }

  ]]&amp;gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Script&amp;gt;
 &amp;lt;mx:Form&lt;/font&gt; width=&lt;font color="#CC0000"&gt;&amp;quot;100%&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;First Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{firstName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;Last Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{lastName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Favorite Food:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{favoriteFood}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
 &amp;lt;/mx:Form&amp;gt;
 &amp;lt;mx:HBox&amp;gt;
  &amp;lt;mx:Button&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;john()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:Button &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;sarah()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:HBox&amp;gt;

&amp;lt;/mx:Panel&amp;gt;&lt;/font&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to use binding with a custom class however, such as with the 
Person class, you have to declare the class itself or its individual attributes 
as bindable. This allowing the class to be bound, but the instance still has to 
be declared as bindable. For example consider the bindable Person class:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;
&lt;font color="#800080"&gt;package&lt;/font&gt; example.data
{
 &lt;span style="background-color: #FFFF00"&gt;[&lt;/span&gt;&lt;font color="#0000FF"&gt;&lt;b&gt;&lt;span style="background-color: #FFFF00"&gt;Bindable&lt;/span&gt;&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #FFFF00"&gt;]&lt;/span&gt;
 &lt;font color="#0000FF"&gt;public &lt;/font&gt;&lt;font color="#800080"&gt;class&lt;/font&gt; Person
 {
  &lt;font color="#0000FF"&gt;public var&lt;/font&gt; firstName:String;
  &lt;font color="#0000FF"&gt;public var &lt;/font&gt;lastName:String;
  &lt;font color="#0000FF"&gt;public var&lt;/font&gt; favoriteFood:String;
 }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To use the bindable Person class in the application example the Person 
instance has to be marked as &amp;quot;Bindable.&amp;quot; The following is the 
application redone to use the Person class:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&lt;font color="#0000FF"&gt;&amp;lt;mx:Panel&lt;/font&gt; xmlns:mx=&lt;font color="#CC0000"&gt;&amp;quot;http://www.adobe.com/2006/mxml&amp;quot;&lt;/font&gt; layout=&lt;font color="#CC0000"&gt;&amp;quot;vertical&amp;quot; &lt;/font&gt;
 title=&lt;font color="#CC0000"&gt;&amp;quot;Person Panel&amp;quot;&lt;/font&gt; horizontalAlign=&lt;font color="#CC0000"&gt;&amp;quot;center&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;

 &lt;font color="#0000FF"&gt;&amp;lt;mx:Script&amp;gt;&lt;/font&gt;
  &amp;lt;![CDATA[
  &lt;font color="#0000FF"&gt;import&lt;/font&gt; example.data.Person;
  
  &lt;font color="#0000FF"&gt;&lt;span style="background-color: #FFFF00"&gt;[&lt;b&gt;Bindable&lt;/b&gt;]&lt;/span&gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&lt;span style="background-color: #FFFF00"&gt;private&lt;/span&gt;&lt;/font&gt;&lt;span style="background-color: #FFFF00"&gt; &lt;/span&gt;&lt;font color="#0000FF"&gt;&lt;span style="background-color: #FFFF00"&gt;var&lt;/span&gt;&lt;/font&gt;&lt;span style="background-color: #FFFF00"&gt; person:Person = &lt;/span&gt;&lt;font color="#0000FF"&gt;&lt;span style="background-color: #FFFF00"&gt;new&lt;/span&gt;&lt;/font&gt;&lt;span style="background-color: #FFFF00"&gt; Person();&lt;/span&gt;

  &lt;font color="#0000FF"&gt;private &lt;/font&gt;&lt;font color="#008000"&gt;function&lt;/font&gt;&lt;font color="#0000FF"&gt; &lt;/font&gt;john():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   person.firstName = &lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt;;
   person.lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino II&amp;quot;&lt;/font&gt;;
   person.favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Steak&amp;quot;&lt;/font&gt;;
  }

  &lt;font color="#0000FF"&gt;private&lt;/font&gt; &lt;font color="#008000"&gt;function&lt;/font&gt; sarah():&lt;font color="#0000FF"&gt;void&lt;/font&gt;
  {
   person.firstName = &lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt;;
   person.lastName = &lt;font color="#CC0000"&gt;&amp;quot;Valentino&amp;quot;&lt;/font&gt;;
   person.favoriteFood = &lt;font color="#CC0000"&gt;&amp;quot;Pizza&amp;quot;&lt;/font&gt;;
  }

  ]]&amp;gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:Script&amp;gt;
 &amp;lt;mx:Form&lt;/font&gt; width=&lt;font color="#CC0000"&gt;&amp;quot;100%&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;First Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{person.firstName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;Last Name:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{person.lastName}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
  &amp;lt;mx:FormItem &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Favorite Food:&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;
   &lt;font color="#0000FF"&gt;&amp;lt;mx:TextInput&lt;/font&gt; text=&lt;font color="#CC0000"&gt;&amp;quot;{person.favoriteFood}&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;/mx:FormItem&amp;gt;
 &amp;lt;/mx:Form&amp;gt;
 &amp;lt;mx:HBox&amp;gt;
  &amp;lt;mx:Button&lt;/font&gt; label=&lt;font color="#CC0000"&gt;&amp;quot;John&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;john()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
  &lt;font color="#0000FF"&gt;&amp;lt;mx:Button &lt;/font&gt;label=&lt;font color="#CC0000"&gt;&amp;quot;Sarah&amp;quot;&lt;/font&gt; click=&lt;font color="#CC0000"&gt;&amp;quot;sarah()&amp;quot;&lt;/font&gt;&lt;font color="#0000FF"&gt;/&amp;gt;&lt;/font&gt;
 &lt;font color="#0000FF"&gt;&amp;lt;/mx:HBox&amp;gt;

&amp;lt;/mx:Panel&amp;gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-2863922093530033426?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/2863922093530033426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=2863922093530033426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2863922093530033426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2863922093530033426'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/02/flex-tutorial-part-ii-language-concepts.html' title='The Flex Tutorial: Part II - Language Concepts and Basics'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-2895056894425840264</id><published>2008-01-09T22:13:00.000-06:00</published><updated>2008-02-08T16:51:18.268-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>The Flex Tutorial: Part I - Setup and Organization</title><content type='html'>&lt;p&gt;&lt;b&gt;What is this tutorial?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;Flex development&amp;quot; refers to the use of the Adobe Flex to develop web 
applications that are deployed in the Adobe Flash runtime. The term &amp;quot;Enterprise&amp;quot; 
in the context of software development is usually used to indicate that 
something is large-scale, supports a large user base, and consists of many 
different systems or services. So I use the term &amp;quot;Flex Enterprise Development&amp;quot; 
to refer to large-scale flex web applications with emphasis on taking advantage 
of Flex features such as Data Binding and Web Services, and the use of 
architectures such as SOA, Three-Tier, and MVC. In particular Data Binding can 
be used to easily implement a MVC framework in an application with little to no 
extra code, and on a larger scale a combination of&amp;nbsp; Three-Tier and SOA can 
be used to organize components and make a system easily scalable. This tutorial 
intends to explain how to setup a development environment, show the important 
features of the Flex language, and show how to organize and implement small to 
large-scale systems.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Setting up a Flex Development Environment&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In terms of treating web systems as three-tier architectures, meaning that on 
a high level they can be divided into presentation, service, and data tiers, 
Flex applications reside in the presentation tier. This means that for servicing 
it is required that server side scripting languages are used. Flex is not 
dependent on a single server side scripting language though, since Flex provides 
the ability to work with data formats such as WSDL, SOAP, Remote Objects, and 
HTTP Services. I tend to prefer using HTTP Services since is is just plain XML 
that you can define yourself without headers or envelopes, and is not specific 
to scripting language remote object technologies.&lt;/p&gt;
&lt;p&gt;Adobe provides a free SDK for Flex, but the Flex Builder development 
environment (&lt;a href="http://www.adobe.com/products/flex/flexbuilder/"&gt;http://www.adobe.com/products/flex/flexbuilder/&lt;/a&gt;) 
is a huge time saver since it allows you to rapidly develop GUIs by dragging and 
dropping pre-made components and editing them accordingly. The first step for 
setting up a development environment is therefore to download and install Flex 
Builder.&lt;/p&gt;
&lt;p&gt;The next step is to install and configure some sort of web service so that 
you can develop web services using a server side scripting language. You should 
also be aware that this choice will also affect which database you can use if 
you choose to use one. You should take into account that if you intend to deploy 
your system on someone else's hardware, meaning a web hosting service, you want 
to setup a similar environment. You should also be aware that most hosting 
services such as GoDaddy.com provide two options: a Windows (IIS) hosting plan 
that includes ASP/.NET with MS SQL and MS Access, and a Linux (Apache) hosting 
plan that includes PHP with MySQL. If you want to use something else like J2EE 
or ColdFusion you will need use a less traditional web hosting service or use 
your own hardware.&lt;/p&gt;
&lt;p&gt;Personally I run IIS on port 80, Apache on port 8000, and JAS (Java 
Application Server for J2EE) on port 8080 on my Windows XP MCE laptop. I would 
like to point out though that setting up IIS on Windows XP MCE was difficult 
because of a lot of missing components and other issues that can be found with a 
quick web search. Apache is both free and easy to install, and I actually 
pointed its PHP services to the same one that I use for IIS, but there is really 
no need to have more than one web service and server side scripting language 
unless you are using more than one.&lt;/p&gt;
&lt;p&gt;If you want to use IIS you have to be running Windows XP Pro or MCE, and can 
get it by putting in the Windows Installation CD and choosing to add IIS as an 
additional component. If you want to use Apache you can download it from the 
Apache website at &lt;a href="http://httpd.apache.org/"&gt;http://httpd.apache.org/&lt;/a&gt;. 
IIS comes .NET and ASP ready which cannot used at all on Apache, but both Apache 
and IIS can be configured to use PHP. PHP can be downloaded for both Windows and 
Linux at &lt;a href="http://www.php.net/downloads.php"&gt;
http://www.php.net/downloads.php&lt;/a&gt;, along with instructions for how to 
configure on both IIS and Apache. If you want to use Java you can ether download 
JAS from &lt;a href="http://java.sun.com/"&gt;http://java.sun.com/&lt;/a&gt; along with the 
NetBeans IDE, or you can download Tomcat from
&lt;a href="http://tomcat.apache.org/"&gt;http://tomcat.apache.org/&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;For PHP, Java, and JSP though I prefer to use the Eclipse IDE. The Eclipse 
IDE can be downloaded from &lt;a href="http://www.eclipse.org/downloads/"&gt;
http://www.eclipse.org/downloads/&lt;/a&gt;, and comes with the ability to do Java. If 
you want to do PHP you can download a free plug-in from
&lt;a href="http://www.zend.com/en/community/pdt"&gt;
http://www.zend.com/en/community/pdt&lt;/a&gt;, and if you want to do JSP I recommend 
paying for the MyEclipse plug-ins at &lt;a href="http://www.myeclipseide.com/"&gt;
http://www.myeclipseide.com/&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Once you have decided on web services and language you will end up with with 
two IDEs: FlexBuilder and one dedicated to your server side scripting language 
of choice.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Setting up a Project&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;You want to create a project directory (through FlexBuilder) in your web root 
directory. Your web root directory is the directory setup to run web services 
you your computer. If you are running IIS the default web root directory is C:\inetpub\wwwroot, 
on Apache Windows the default directory is C:\Program Files\Apache Software 
Foundation\Apache2.2\htdocs, and on Apache Linux the default directory is /var/www/html/. 
All of these locations correspond to http://localhost/ using the web service 
that you are running.&lt;/p&gt;
&lt;p&gt;You want to layout your project directory as follows:&lt;/p&gt;
&lt;pre&gt;
- &amp;lt;Project Directory&amp;gt;: HTML page and scripts that execute your Flash SWF.
 - src: Flex source code, MXML and AS
 - html-template: templates for generating the HTML page used to run the Flash
 - service: service side scripting used to represent web services
 - data: data structure representations used by the server side scripting
 - settings: miscellaneous files for static content, for example CSS, a web services list...
&lt;/pre&gt;
&lt;p&gt;It should also be noted that for larger projects the web servicing (the 
server side scripting in the service and data directories) may be located on 
another machine. In order for your Flex application to access content in an 
external location on the web, the root web directory of the server &lt;/p&gt;
&lt;p&gt;This can be initiated in Flex Builder by specifying your root web directory 
as the workspace and creating a new project there. Then in the &amp;quot;New Flex 
Project&amp;quot; window specify the main source folder as &amp;quot;src&amp;quot; and the output folder as 
blank.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/create_project.PNG" width="438" height="550"&gt;&lt;/p&gt;
&lt;p&gt;Once the project is created you also have to make sure that the runtime 
settings point to the HTTP location of the SWF file instead of the File 
location. This is done by changing the &amp;quot;URL or path to launch&amp;quot; in the Run Dialog 
for the project.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/run_config.PNG" width="592" height="331"&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Laying Out the GUI&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Once the project is created there is a single MXML file in your &amp;quot;src&amp;quot; 
directory, which is the root of the application. From this point it is best to 
divide up your application into packages based on sub-systems, presentation tier 
components, and classes used to represents data. It should also be noted that 
for larger applications you may want to separately group classes related to HTTP 
and other web services. For example if you had an application with several 
detailed panels, you may want to break each detailed panel into a separate 
class. The following is an example directory structure a flex 
application that divides it components by the following groups: Core Components 
(core), User Management Components (user), and Example (example)&lt;/p&gt;
&lt;pre&gt;
- &lt;b&gt;src&lt;/b&gt;: This is the source code directory
 - &lt;b&gt;core&lt;/b&gt;: custom components used by all packages
  * MyFancyButton.mxml
 - &lt;b&gt;user&lt;/b&gt;: components related for managing user accounts
  - &lt;b&gt;data&lt;/b&gt;: data structures related to user components
   * UserRecord.as
  - &lt;b&gt;interfaces&lt;/b&gt;: interfaces used for communicating with the user components
   * LoginInterface.as
   * ManageAccountInterface.as
  * LoginPanel.mxml
  * ManageAccountPanel.mxml
 - &lt;b&gt;example&lt;/b&gt;: general components used for demonstrating Flex abilities
  - &lt;b&gt;data&lt;/b&gt;: data structures used for the example components
   * CDRecord.as
  * WelcomePanel.mxml
 * MyProject.mxml
&lt;/pre&gt;
&lt;p&gt;For example consider layout our a basic application that will display only 
the welcome screen as a custom component. First you would layout the entire GUI 
minus the welcome panel, which may look something like the following:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/layout.PNG" width="617" height="179"&gt;&lt;/p&gt;
&lt;p&gt;Next make a simple component named &amp;quot;WelcomePanel.mxml&amp;quot; in the &amp;quot;example&amp;quot; 
directory that inherits from &amp;quot;Panel.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/welcome_panel.PNG" width="370" height="389"&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Using State Transitions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Now that the application is laid out and there is a custom component that can 
be used, a state transition can be used to add the custom component to the 
application. In the &amp;quot;MyProject.mxml&amp;quot; component there is a &amp;quot;States&amp;quot; box that has 
a single state listed, which is the base state.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/state_panel.PNG" width="288" height="231"&gt;&lt;/p&gt;
&lt;p&gt;If you right-click on the base state and select the option to create a &amp;quot;New 
State,&amp;quot; you can create a state called &amp;quot;WelcomeState&amp;quot; which can be used to 
display the welcome panel.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/welcome_state.PNG" width="282" height="82"&gt;&lt;/p&gt;
&lt;p&gt;With the &amp;quot;WelcomeState&amp;quot; selected you can then drag and drop the &amp;quot;WelcomePanel&amp;quot; 
onto the &amp;quot;MyProject&amp;quot; component:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/welcome_view_state.PNG" width="615" height="426"&gt;&lt;/p&gt;
&lt;p&gt;If you then reselect the base state the welcome panel will disappear, because 
the application goes back to its original state. If in the base state you select 
the welcome button from the menu panel and specify the &amp;quot;click&amp;quot; attribute to be &amp;quot;currentState='WelcomeState&amp;quot;, 
when the welcome button is pressed the application will move from the base state 
to the &amp;quot;WelcomeState.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/flex_enterprise/welcome_button.PNG" width="280" height="233"&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-2895056894425840264?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/2895056894425840264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=2895056894425840264' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2895056894425840264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/2895056894425840264'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2008/01/flex-tutorial-part-i.html' title='The Flex Tutorial: Part I - Setup and Organization'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-3806753607846640563</id><published>2007-10-25T20:37:00.001-06:00</published><updated>2007-10-25T20:53:40.296-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Flex-Based Message Board</title><content type='html'>&lt;p&gt;A while ago I finally got fed up with a hosting service I was using for a particular product's web registration service, so I moved everything to a new host and decided to make some needed changes. One change in particular was the message board.

I was using phpbb and was spending too much time battling spammers. I originally had it to where anyone could post, because most people with legit questions prefer not to have to create accounts. This of course was fine until the spammers found it, so I turned on the all the validation stuff and people just stopped using the board entirely (and emailing me questions). With the new host I was in need of a new message board, so I decided to make one myself using Flex (and PHP5). This is the current board: &lt;a href="http://www.vdrillpro.net/flexboard/" class="postlink"&gt;http://www.vdrillpro.net/flexboard/&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;My concept is to allow people to post semi-anonymously by allowing users to use any name they want, and all they have to do it leave a valid email address that no one can see (but admins). Users then have to enter a validation code, and are then sent an email in which they have to click on the provided link to move their message out of the queue and on to the board to be seen by others. I am hoping that the anonymous posting will encourage more legit posters, and that with the email validation it will slow down the spam but not be too much of a pain. I also built in the ability to ban email addresses by regular expression, which allows me to use keywords and do stuff like ban all .info, .biz, .cn, and .ru addresses.&lt;/p&gt;
&lt;p&gt;The layout is also different, displaying topics and comments in grid form to give it more of a desktop application feel:
&lt;img src="http://www.vdrillpro.net/blogs/flexboard/topics.PNG" /&gt;

&lt;/p&gt;
&lt;p&gt;Topic view allows the user to see the full content of the post, and all of the replies in grid form:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://www.vdrillpro.net/blogs/flexboard/view.PNG" /&gt;

&lt;/p&gt;
&lt;p&gt;Replies also allow rich text with links:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.vdrillpro.net/blogs/flexboard/reply.PNG" /&gt;

&lt;/p&gt;
&lt;p&gt;An validation code must also be entered before a post is queued:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://www.vdrillpro.net/blogs/flexboard/validate.PNG" /&gt;

&lt;/p&gt;
&lt;p&gt;An email is then sent to the address that was entered containing a link. When the user clicks on that link the post is out of the queue and can then be seen on the message board.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-3806753607846640563?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/3806753607846640563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=3806753607846640563' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3806753607846640563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/3806753607846640563'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2007/10/flex-based-message-board.html' title='Flex-Based Message Board'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-4392980915828064856</id><published>2007-10-21T16:37:00.000-06:00</published><updated>2007-10-21T16:38:13.067-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Introduction to the Spring Framework</title><content type='html'>&lt;p&gt;&lt;b&gt;What is the Spring Framework?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;According to SpringFramework.org:&lt;/p&gt;
&lt;blockquote&gt;
 &lt;p&gt;&lt;i&gt;Spring provides a light-weight solution for building enterprise-ready 
 applications, while still supporting the possibility of using declarative 
 transaction management, remote access to your logic using RMI or web 
 services, and various options for persisting your data to a database &lt;/i&gt;[&lt;a href="#1"&gt;1&lt;/a&gt;].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;More specifically Spring is a way of using regular &lt;i&gt;Java Beans &lt;/i&gt;as &lt;i&gt;
Enterprise JavaBeans&lt;/i&gt; without involving the complexity of &lt;i&gt;J2EE&lt;/i&gt;. &lt;i&gt;
JavaBeans &lt;/i&gt;encapsulate many objects into a single object (the bean), so that 
the bean can be passed around rather than the individual objects [&lt;a href="#2"&gt;2&lt;/a&gt;]. 
The &lt;i&gt;Enterprise JavaBean &lt;/i&gt;(EJB) is a managed, server-side component 
architecture for modular construction of enterprise applications [&lt;a href="#3"&gt;3&lt;/a&gt;], 
which requires a &lt;i&gt;J2EE&lt;/i&gt; container/application server. &lt;i&gt;Java 2 Enterprise 
Edition&lt;/i&gt; (&lt;i&gt;J2EE&lt;/i&gt;) is a combination of libraries and useful technologies 
for the Java programming language, that are used to develop and deploy 
enterprise applications using modular components using a Java application 
server.&lt;/p&gt;
&lt;p&gt;Spring is more than just JavaBeans though, it is a framework that contains 
other frameworks, which are designed to independently work well with other 
frameworks. These frameworks or modules are typically divided into the following:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Inversion of Control Container (Core Container)&lt;/li&gt;
 &lt;li&gt;Context Module&lt;/li&gt;
 &lt;li&gt;Aspect Oriented Programming (AOP) Module&lt;/li&gt;
 &lt;li&gt;Data Access Object (DAO) Module&lt;/li&gt;
 &lt;li&gt;Object-Relational Mapping (ORM) Module&lt;/li&gt;
 &lt;li&gt;Web Module&lt;/li&gt;
 &lt;li&gt;Model-View-Controller (MVC) Framework&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the purposes of introduction though, it is best to start with the basics 
of the &lt;i&gt;Inversion Control Container&lt;/i&gt;. Central in the Spring Framework is 
its &lt;i&gt;Inversion of Control Container&lt;/i&gt; that provides a consistent means of 
configuring and managing Java objects. This container is also known as &lt;i&gt;
BeanFactory&lt;/i&gt;, &lt;i&gt;ApplicationContext&lt;/i&gt; or &lt;i&gt;Core container &lt;/i&gt;[&lt;a href="#4"&gt;4&lt;/a&gt;].
&lt;i&gt;Inversion of Control&lt;/i&gt; is a concept in which the control flow is inverted 
compared to the traditional interaction model expressed in imperative style by a 
series of procedure calls. Thus, instead of the programmer specifying, by the 
means of function calls, a series of events to happen during the lifetime of a 
programme, they would rather register desired &lt;i&gt;responses&lt;/i&gt; to particular 
happenings, and then let some external entities take over the control over the 
precise order and set of events to happen [&lt;a href="#5"&gt;5&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Where do I get the Spring Framework and how do I install it?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The framework is a series of JAR files, which can be downloaded from
&lt;a href="http://www.springframework.org/download"&gt;
http://www.springframework.org/download&lt;/a&gt; for fee. To install it all you 
really have to do is extract the downloaded compressed file to some location on 
your computer, and then reference the appropriate JARs in a Java project. If you 
download the full distribution you will get the following directories, which are 
specified &amp;quot;RELEASE INFO&amp;quot; section of the &amp;quot;readme.txt&amp;quot; included with the 
distribution:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;dist -&amp;nbsp; contains the Spring distribution jar files, as well as a 
 zip of all Java source files&lt;/li&gt;
 &lt;li&gt;docs -&amp;nbsp; contains the Spring reference documentation in PDF and HTML 
 format, as well as the complete API javadocs&lt;/li&gt;
 &lt;li&gt;lib -&amp;nbsp; contains all third-party libraries needed for building the 
 framework and/or running the samples&lt;/li&gt;
 &lt;li&gt;src -&amp;nbsp; contains the general Java source files for the framework&lt;/li&gt;
 &lt;li&gt;mock -&amp;nbsp; contains the general Java source files for Spring's mock 
 and test classes&lt;/li&gt;
 &lt;li&gt;test -&amp;nbsp; contains the general Java source files for Spring's test 
 suite&lt;/li&gt;
 &lt;li&gt;tiger/src - contains the JDK-1.5-specific Java source files for the 
 framework&lt;/li&gt;
 &lt;li&gt;tiger/test -&amp;nbsp; contains the JDK-1.5-specific Java source files for 
 Spring's test suite&lt;/li&gt;
 &lt;li&gt;aspectj/src -&amp;nbsp; contains the AspectJ-specific source files for the 
 framework&lt;/li&gt;
 &lt;li&gt;aspectj/test - contains the AspectJ-specific source files for Spring's 
 test suite&lt;/li&gt;
 &lt;li&gt;samples - contains various demo applications and showcases&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;How do I use the Spring Framework?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Considering that there are many sub-frameworks in Spring, it is easiest to 
start with an example that demonstrates the core basics of the &lt;i&gt;Inversion of 
Control Container&lt;/i&gt;. There are many available Spring Tutorials that can be 
found in books and on the internet. So far the best example that I have been 
able to find is the &lt;i&gt;Inversion of Control &lt;/i&gt;example from DevelopersBook.com, 
in which y&lt;span class="queIndex"&gt;ou don't directly connect your components and 
services together in code but describe which services are needed by which 
components in a configuration file [&lt;a href="#6"&gt;6&lt;/a&gt;]. I have taken the basic 
example and modified it to include comments and a few other properties, with the 
intention for later use in an &lt;i&gt;Aspect Oriented Programming&lt;/i&gt; example. &lt;/span&gt;Consider a simple application framework that provides JavaBean that is used to greet as specified person using a &amp;quot;Greeting Service,&amp;quot; 
and say good-bye to that person using a &amp;quot;Leaving Service.&amp;quot; This requires the 
following classes, interfaces, and XML configuration:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;b&gt;HelloBean.java &lt;/b&gt;- This is the bean that is used to encapsulate the 
 &amp;quot;Greeting Service&amp;quot; and &amp;quot;Leaving Service.&amp;quot;&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;HelloBean.xml&lt;/b&gt; - This is the Spring XML configuration file that is 
 used to specify the instance and relationships of the involved object.&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;GreetingService.java &lt;/b&gt;(implementing &lt;b&gt;GreetingInterface.java&lt;/b&gt;) 
 - This is the service that is used to generate the greeting message.&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;LeavingService.java&lt;/b&gt; (implementing &lt;b&gt;LeavingInterface.java&lt;/b&gt;) - 
 This is the service that is used to generate the leaving message.&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;HelloClient.java &lt;/b&gt;- This is the main class that uses the &lt;i&gt;
 Inversion of Control Container&lt;/i&gt; with the Spring XML configuration file to 
 get the specified instance of the HelloBean.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following is the project directory structure, which shows the location of 
the Java source code files, the related class files, and the Spring XML 
configuration file:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;b&gt;bin&lt;/b&gt;&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;springapp&lt;/b&gt;&lt;ul&gt;
   &lt;li&gt;&lt;b&gt;service&lt;/b&gt;&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;interfaces&lt;/b&gt;&lt;ul&gt;
     &lt;li&gt;GreetingInterface.class&lt;/li&gt;
     &lt;li&gt;LeavingInterface.class&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;GreetingService.class&lt;/li&gt;
    &lt;li&gt;LeavingService.class&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
   &lt;li&gt;&lt;b&gt;bean&lt;/b&gt;&lt;ul&gt;
    &lt;li&gt;HelloBean.class&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
   &lt;li&gt;HelloClient.class&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;HelloBean.xml&lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;b&gt;src&lt;/b&gt;&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;springapp&lt;/b&gt;&lt;ul&gt;
   &lt;li&gt;&lt;b&gt;service&lt;/b&gt;&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;interfaces&lt;/b&gt;&lt;ul&gt;
     &lt;li&gt;GreetingInterface.java&lt;/li&gt;
     &lt;li&gt;LeavingInterface.java&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;GreetingService.java&lt;/li&gt;
    &lt;li&gt;LeavingService.java&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
   &lt;li&gt;&lt;b&gt;bean&lt;/b&gt;&lt;ul&gt;
    &lt;li&gt;HelloBean.java&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
   &lt;li&gt;HelloClient.java&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Architecturally the following class diagram shows how all of the objects 
relate to one another within the &amp;quot;springapp&amp;quot; package:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.net/blogs/spring/class_diagram.png" width="429" height="330"&gt;&lt;/p&gt;
&lt;p&gt;The &amp;quot;HelloClient&amp;quot; uses the Spring XML configuration file &amp;quot;HelloBean.xml&amp;quot; with&amp;nbsp; 
the &lt;i&gt;Inversion of Control Container&lt;/i&gt; to create the specified instance of 
the &amp;quot;HelloBean.&amp;quot; The &amp;quot;HelloBean&amp;quot; encapsulates the objects and functionality of 
the &amp;quot;GreetingService&amp;quot; and &amp;quot;LeavingService.&amp;quot; &lt;/p&gt;
&lt;p&gt;For this particular application, the following libraries from the Spring 
Framework are required:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&amp;lt;spring-install&amp;gt;\lib\jakarta-commons\*.jar&lt;/li&gt;
 &lt;li&gt;&amp;lt;spring-install&amp;gt;\lib\log4j\lg4j-1.2.14.jar&lt;/li&gt;
 &lt;li&gt;&amp;lt;spring-install&amp;gt;\dist\spring.jar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;GreetingService.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is an object that is instantiated by the &amp;quot;HelloBean&amp;quot; in order to 
generate the greeting message. The actual instantiation though is specified in 
the &amp;quot;HelloBean.xml&amp;quot; file, which is handled by the &lt;i&gt;Inversion of Control 
Container&lt;/i&gt; or &lt;i&gt;BeanFactory&lt;/i&gt;. This class only has one property, which is 
the variable &amp;quot;greetingMessage.&amp;quot; In order for the &lt;i&gt;BeanFactory&lt;/i&gt; to be able 
to allow the setting of the value of this variable the class must provide a 
&amp;quot;setter&amp;quot; method. In the case of the &amp;quot;GreetingService,&amp;quot; it has a &amp;quot;setGreetingMessage&amp;quot; 
method that can used by the &lt;i&gt;BeanFactory&lt;/i&gt; to set the value of the &amp;quot;greetingMessage&amp;quot; 
variable.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp.service;

&lt;font color="#0000FF"&gt;import&lt;/font&gt; springapp.service.interfaces.GreetingInterface;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Greeting Service&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Description: This is the service that is used to generate
 * the greeting message.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 1:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 *
 * @author John Valentino II
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public class&lt;/font&gt; GreetingService &lt;font color="#0000FF"&gt;implements&lt;/font&gt; GreetingInterface {

 &lt;font color="#008000"&gt;/** This is greeting message that is displayed.*/&lt;/font&gt;
 &lt;font color="#0000FF"&gt;private&lt;/font&gt; String greetingMessage;

 &lt;font color="#008000"&gt;/**
  * Returns the &amp;quot;Hello&amp;quot; message for the person of the given name.
  * @param name
  * @return String
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String sayHello(String name) {
  &lt;font color="#0000FF"&gt;return&lt;/font&gt; greetingMessage + &amp;quot; &amp;quot; + name + &amp;quot;.&amp;quot;;
 }

 &lt;font color="#008000"&gt;/**
  * Sets the greeting message
  * @param message
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public void&lt;/font&gt; setGreetingMessage(String message) {
  &lt;font color="#0000FF"&gt;this&lt;/font&gt;.greetingMessage = message;
 }

}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;GreetingInterface.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The methods required to be implemented by the &amp;quot;GreetingService&amp;quot; that are 
public and are not &amp;quot;getter&amp;quot; or &amp;quot;setter&amp;quot; methods are specified in this interface. 
This is because it is considered good practice to separately specify those 
methods in an implemented interface.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp.service.interfaces;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Greeting Interface&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Description: Representing the methods of the Greeting Service.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 1:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 *
 * @author John Valentino II
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public interface &lt;/font&gt;GreetingInterface {

 &lt;font color="#008000"&gt;/**
  * Returns the &amp;quot;Hello&amp;quot; message for the person of the given name.
  * @param name
  * @return String
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String sayHello(String name);
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;LeavingService.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is an object that is instantiated by the &amp;quot;HelloBean&amp;quot; in order to 
generate the leaving message. The actual instantiation though is specified in 
the &amp;quot;HelloBean.xml&amp;quot; file, which is handled by the &lt;i&gt;Inversion of Control 
Container&lt;/i&gt; or &lt;i&gt;BeanFactory&lt;/i&gt;. This class only has one property, which is 
the variable &amp;quot;leavingMessage.&amp;quot; In order for the &lt;i&gt;BeanFactory&lt;/i&gt; to be able to 
allow the setting of the value of this variable the class must provide a 
&amp;quot;setter&amp;quot; method. In the case of the &amp;quot;LeavingService,&amp;quot; it has a &amp;quot;setLeavingMessage&amp;quot; 
method that can used by the &lt;i&gt;BeanFactory&lt;/i&gt; to set the value of the 
&amp;quot;leavingMessage&amp;quot; variable.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp.service;

&lt;font color="#0000FF"&gt;import&lt;/font&gt; springapp.service.interfaces.LeavingInterface;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Leaving Service&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Description: This is the service that is used to generate
 * the leaving message.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 2:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 *
 * @author John Valentino II
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public class&lt;/font&gt; LeavingService &lt;font color="#0000FF"&gt;implements&lt;/font&gt; LeavingInterface {

 &lt;font color="#008000"&gt;/** The good-bye message to be displayed. */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;private&lt;/font&gt; String leavingMessage;

 &lt;font color="#008000"&gt;/**
  * Returns the &amp;quot;Good-Bye&amp;quot; message for the person of the given name
  * @param name
  * @return String
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String sayGoodBye(String name) {
  &lt;font color="#0000FF"&gt;return&lt;/font&gt; leavingMessage + &amp;quot; &amp;quot; + name + &amp;quot;.&amp;quot;;
 }

 &lt;font color="#008000"&gt;/**
  * Sets the good-bye message
  * @param message
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public void&lt;/font&gt; setLeavingMessage(String message) {
  &lt;font color="#0000FF"&gt;this&lt;/font&gt;.leavingMessage = message;
 }

}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;LeavingInterface.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The methods required to be implemented by the &amp;quot;LeavingService&amp;quot; that are 
public and are not &amp;quot;getter&amp;quot; or &amp;quot;setter&amp;quot; methods are specified in this interface. &lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp.service.interfaces;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Leaving Interface&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Required methods for the Leaving Service.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 2:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 * 
 * @author John Valentino II
 *
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public interface&lt;/font&gt; LeavingInterface {

 &lt;font color="#008000"&gt;/**
  * Returns the &amp;quot;Good-Bye&amp;quot; message for the person of the given name
  * @param name
  * @return String
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String sayGoodBye(String name);

}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;HelloBean.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is the &lt;i&gt;JavaBean&lt;/i&gt; that is used to encapsulate the services of this 
example application. Since this class has three properties, it specifies three 
&amp;quot;setter&amp;quot; methods to allow the setting of instances or values by the &lt;i&gt;
BeanFactory &lt;/i&gt;or other parent classes.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp.bean;

&lt;font color="#0000FF"&gt;import&lt;/font&gt; springapp.service.GreetingService;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; springapp.service.LeavingService;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Hello Bean&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Description: Represents the Hello Bean.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 4:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 *
 * @author John Valentino II
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public class&lt;/font&gt; HelloBean {

 &lt;font color="#008000"&gt;/** Represents the service used to generate a greeting */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;private&lt;/font&gt; GreetingService greetingService;
 &lt;font color="#008000"&gt;/** Represents the service used to generate a good-bye message */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;private&lt;/font&gt; LeavingService leavingService;
 &lt;font color="#008000"&gt;/** Represents the name of the person to meet or leave */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;private&lt;/font&gt; String personName;

 &lt;font color="#008000"&gt;/**
  * Sets the name of the person
  * @param name
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public void &lt;/font&gt;setPersonName(String name) {
  &lt;font color="#0000FF"&gt;this&lt;/font&gt;.personName = name;
 }

 &lt;font color="#008000"&gt;/**
  * Sets the instance of the greeting service
  * @param service
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public void&lt;/font&gt; setGreetingService(GreetingService service) {
  &lt;font color="#0000FF"&gt;this&lt;/font&gt;.greetingService = service;
 }

 &lt;font color="#008000"&gt;/**
  * Set the instance of the leaving service
  * @param service
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public void&lt;/font&gt; setLeavingService(LeavingService service) {
  &lt;font color="#0000FF"&gt;this&lt;/font&gt;.leavingService = service;
 }

 &lt;font color="#008000"&gt;/**
  * Generates the greeting message
  * @return
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String greet() {
  &lt;font color="#0000FF"&gt;return&lt;/font&gt; greetingService.sayHello(personName);
 }

 &lt;font color="#008000"&gt;/**
  * Generates the leaving message
  * @return
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public&lt;/font&gt; String leave() {
  &lt;font color="#0000FF"&gt;return&lt;/font&gt; leavingService.sayGoodBye(personName);
 }

}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;HelloClient.java&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is the main class of the application that uses the &amp;quot;HelloBean.xml&amp;quot; with 
the &lt;i&gt;Inversion of Control Container&lt;/i&gt; to create the instance of the &amp;quot;HelloBean&amp;quot; 
and call is available methods.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#0000FF"&gt;package&lt;/font&gt; springapp;

&lt;font color="#0000FF"&gt;import&lt;/font&gt; springapp.bean.HelloBean;
&lt;font color="#0000FF"&gt;import&lt;/font&gt; org.springframework.context.support.ClassPathXmlApplicationContext;

&lt;font color="#008000"&gt;/**
 * &amp;lt;p&amp;gt;Title: Hello Client&amp;lt;/p&amp;gt;
 * 
 * &amp;lt;p&amp;gt;Description: Represents a program that uses the HelloBean.&amp;lt;/p&amp;gt;
 * &amp;lt;p&amp;gt;Taken and modified from Code Listing 5:
 * http://www.developersbook.com/spring/spring-tutorials/&amp;lt;/p&amp;gt;
 *
 * @author John Valentino II
 */&lt;/font&gt;
&lt;font color="#0000FF"&gt;public class&lt;/font&gt; HelloClient {

 &lt;font color="#008000"&gt;/**
  * @param args
  */&lt;/font&gt;
 &lt;font color="#0000FF"&gt;public static void&lt;/font&gt; main(String[] args) {

  &lt;font color="#008000"&gt;//Get the instance of the HelloBean as specified in HelloBean.xml&lt;/font&gt;
  ClassPathXmlApplicationContext appContext = 
   &lt;font color="#0000FF"&gt;new&lt;/font&gt; ClassPathXmlApplicationContext(&lt;font color="#0000FF"&gt;new&lt;/font&gt; String[] { &lt;font color="#800080"&gt;&amp;quot;HelloBean.xml&amp;quot;&lt;/font&gt; });
  HelloBean helloBean = (HelloBean) appContext.getBean(&lt;font color="#800080"&gt;&amp;quot;helloBean&amp;quot;&lt;/font&gt;);

  System.out.println(helloBean.greet());
  System.out.println(helloBean.leave());

 }

}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;HelloBean.xml&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is the Spring XML configuration file that is used to specify the 
instances and properties of the bean classes within the application.&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;&lt;font color="#800080"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;!DOCTYPE beans PUBLIC &amp;quot;-//SPRING//DTD BEAN//EN&amp;quot; 
&amp;quot;http://www.springframework.org/dtd/spring-beans.dtd&amp;quot;&amp;gt;&lt;/font&gt;

&amp;lt;&lt;font color="#0000FF"&gt;beans&lt;/font&gt;&amp;gt;
 &lt;font color="#008000"&gt;&amp;lt;!-- Creates an instance of the &amp;quot;HelloBean&amp;quot; class --&amp;gt;&lt;/font&gt;
 &amp;lt;&lt;font color="#0000FF"&gt;bean&lt;/font&gt; &lt;font color="#0000FF"&gt;id&lt;/font&gt;=&amp;quot;helloBean&amp;quot; &lt;font color="#0000FF"&gt;class&lt;/font&gt;=&amp;quot;springapp.bean.HelloBean&amp;quot;&amp;gt;
  &lt;font color="#008000"&gt;&amp;lt;!-- Sets the value of &amp;quot;personName&amp;quot; by
       calling &amp;quot;setPersonName&amp;quot; --&amp;gt;&lt;/font&gt;
  &amp;lt;&lt;font color="#0000FF"&gt;property name&lt;/font&gt;=&amp;quot;personName&amp;quot;&amp;gt;
   &amp;lt;&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;Sarah&amp;lt;/&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;
  &amp;lt;/&lt;font color="#0000FF"&gt;property&lt;/font&gt;&amp;gt;
  &lt;font color="#008000"&gt;&amp;lt;!-- Sets the instance of &amp;quot;greetingService&amp;quot; by
       calling &amp;quot;setGreetingService&amp;quot; --&amp;gt;&lt;/font&gt;
  &amp;lt;&lt;font color="#0000FF"&gt;property name&lt;/font&gt;=&amp;quot;greetingService&amp;quot;&amp;gt; 
   &amp;lt;&lt;font color="#0000FF"&gt;ref bean&lt;/font&gt;=&amp;quot;greetingService&amp;quot; /&amp;gt;
  &amp;lt;/&lt;font color="#0000FF"&gt;property&lt;/font&gt;&amp;gt;
  &lt;font color="#008000"&gt;&amp;lt;!-- Sets the instance of &amp;quot;leavingService&amp;quot; by
       calling &amp;quot;setLeavingService&amp;quot; --&amp;gt;&lt;/font&gt;
  &amp;lt;&lt;font color="#0000FF"&gt;property name&lt;/font&gt;=&amp;quot;leavingService&amp;quot;&amp;gt;
   &amp;lt;&lt;font color="#0000FF"&gt;ref bean&lt;/font&gt;=&amp;quot;leavingService&amp;quot; /&amp;gt; 
  &amp;lt;/&lt;font color="#0000FF"&gt;property&lt;/font&gt;&amp;gt; 
 &amp;lt;/&lt;font color="#0000FF"&gt;bean&lt;/font&gt;&amp;gt;
 &lt;font color="#008000"&gt;&amp;lt;!-- Creates an instance of the &amp;quot;GreetingService&amp;quot; --&amp;gt;&lt;/font&gt;
 &amp;lt;&lt;font color="#0000FF"&gt;bean id&lt;/font&gt;=&amp;quot;greetingService&amp;quot; &lt;font color="#0000FF"&gt;class&lt;/font&gt;=&amp;quot;springapp.service.GreetingService&amp;quot;&amp;gt;
  &lt;font color="#008000"&gt;&amp;lt;!-- Sets the value of &amp;quot;greetingMessage&amp;quot; by 
         calling &amp;quot;setGreetingMessage&amp;quot; --&amp;gt;&lt;/font&gt;
  &amp;lt;&lt;font color="#0000FF"&gt;property name&lt;/font&gt;=&amp;quot;greetingMessage&amp;quot;&amp;gt;
   &amp;lt;&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;Hello&amp;lt;/&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;
  &amp;lt;/&lt;font color="#0000FF"&gt;property&lt;/font&gt;&amp;gt;
 &amp;lt;/&lt;font color="#0000FF"&gt;bean&lt;/font&gt;&amp;gt;
 &lt;font color="#008000"&gt;&amp;lt;!-- Creates an instance of the &amp;quot;LeavingService&amp;quot; --&amp;gt;&lt;/font&gt;
 &amp;lt;&lt;font color="#0000FF"&gt;bean id&lt;/font&gt;=&amp;quot;leavingService&amp;quot; &lt;font color="#0000FF"&gt;class&lt;/font&gt;=&amp;quot;springapp.service.LeavingService&amp;quot;&amp;gt;
  &lt;font color="#008000"&gt;&amp;lt;!-- Sets the value of &amp;quot;leavingMessage&amp;quot; by
       calling &amp;quot;setLeavingMessage&amp;quot; --&amp;gt;&lt;/font&gt;
  &amp;lt;&lt;font color="#0000FF"&gt;property name&lt;/font&gt;=&amp;quot;leavingMessage&amp;quot;&amp;gt;
   &amp;lt;&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;Good-bye&amp;lt;/&lt;font color="#0000FF"&gt;value&lt;/font&gt;&amp;gt;
  &amp;lt;/&lt;font color="#0000FF"&gt;property&lt;/font&gt;&amp;gt;
 &amp;lt;/&lt;font color="#0000FF"&gt;bean&lt;/font&gt;&amp;gt;
&amp;lt;/&lt;font color="#0000FF"&gt;beans&lt;/font&gt;&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Output&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The program runs and generates the following output:&lt;/p&gt;
&lt;div style="border-style: solid; border-width: 1px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px"&gt;
&lt;pre&gt;Hello Sarah.
Good-bye Sarah.&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This output is to be expected as the Spring XML configuration file specifies 
that the &amp;quot;HelloBean&amp;quot; instance has the specified &amp;quot;personName,&amp;quot; an instance of the 
&amp;quot;GreetingService,&amp;quot; and an instance of the &amp;quot;LeavingService.&amp;quot; Both service 
instances are also given specified &amp;quot;greetingMessage&amp;quot; and &amp;quot;leavingMessage&amp;quot; 
values.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Links&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Spring Framework IoC Tutorial:
 &lt;a href="http://www.developersbook.com/spring/spring-tutorials"&gt;
 http://www.developersbook.com/spring/spring-tutorials&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Spring Framework MVC Application Step by Step:
 &lt;a href="http://www.springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step-Part-1.html"&gt;
 http://www.springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step-Part-1.html&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Spring Framework Application Tutorial:
 &lt;a href="http://www.roseindia.net/spring/springpart2.shtml"&gt;
 http://www.roseindia.net/spring/springpart2.shtml&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Spring Framework Documentation:
 &lt;a href="http://static.springframework.org/spring/docs/2.0.x/reference/index.html"&gt;
 http://static.springframework.org/spring/docs/2.0.x/reference/index.html&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;How to create a bean descriptor XML file:
 &lt;a href="http://www.visualbuilder.com/java/spring/tutorial/pageorder/8/"&gt;
 http://www.visualbuilder.com/java/spring/tutorial/pageorder/8/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Inversion of Control:
 &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_control"&gt;
 http://en.wikipedia.org/wiki/Inversion_of_control&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Aspect-Oriented Programming:
 &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;
 http://en.wikipedia.org/wiki/Aspect-oriented_programming&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Factory Method Pattern:
 &lt;a href="http://en.wikipedia.org/wiki/Factory_design_pattern"&gt;
 http://en.wikipedia.org/wiki/Factory_design_pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;a name="1"&gt;SpringFramework.org, Documentation Preface,&lt;/a&gt;
 &lt;a href="http://static.springframework.org/spring/docs/2.0.x/reference/preface.html"&gt;
 http://static.springframework.org/spring/docs/2.0.x/reference/preface.html&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a name="2"&gt;Wikipedia&lt;/a&gt;, JavaBean,
 &lt;a href="http://en.wikipedia.org/wiki/JavaBeans"&gt;
 http://en.wikipedia.org/wiki/JavaBeans&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a name="3"&gt;Wikipedia&lt;/a&gt;, Enterprise JavaBean,
 &lt;a href="http://en.wikipedia.org/wiki/Ejb"&gt;http://en.wikipedia.org/wiki/Ejb&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a name="4"&gt;Wikipedia&lt;/a&gt;, Spring Framework,
 &lt;a href="http://en.wikipedia.org/wiki/Spring_framework"&gt;
 http://en.wikipedia.org/wiki/Spring_framework&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a name="5"&gt;Wikipedia&lt;/a&gt;, Inversion of Control,
 &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_Control"&gt;
 http://en.wikipedia.org/wiki/Inversion_of_Control&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a name="6"&gt;DevlopersBook&lt;/a&gt;.com, Spring Framework Tutorial,
 &lt;a href="http://www.developersbook.com/spring/spring-tutorials/spring-tutorials.php"&gt;
 http://www.developersbook.com/spring/spring-tutorials/spring-tutorials.php&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-4392980915828064856?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/4392980915828064856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=4392980915828064856' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4392980915828064856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4392980915828064856'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2007/10/introduction-to-spring-framework.html' title='Introduction to the Spring Framework'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-4144941512093496776</id><published>2007-05-11T15:31:00.000-06:00</published><updated>2007-05-11T15:33:57.174-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Instant Bach goes Open Source</title><content type='html'>&lt;p&gt;&lt;u&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The program &amp;quot;Instant Bach&amp;quot; was made as a project for an unnamed
computer science class,
which was when I was a sophomore computer science major, and a senior music
performance and music composition double-major. Needless to say at the time of
this program's creation I knew far more about musical theory than I did computer
science. When I approached the professor of this class with my project idea his
response was that &amp;quot;other people have tried stuff similar for this class and failed, and the
same will happen to you.&amp;quot; Despite this opinion I remained confident that a
four-part harmony writing program could be made using the skills I currently had
available, so I went ahead and made the program for my project. I have recently
decided to resurrect this program to expand its capabilities as
an open source project (&lt;a href="http://sourceforge.net/projects/instantbach"&gt;http://sourceforge.net/projects/instantbach&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The original program was based of of static rules which limits it to a
particular number of possible progressions:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/old_interface.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;My most immediate goal for this project is to move all of the rules of voice
leading, doubling, chord structure, and progression to an external rules file,
so that the program can be adjusted to work beyond just being able to voice
major key progressions.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/new_interface.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Purpose&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The first two years of undergraduate music theory are spent learning and
doing mostly one thing: four-part harmony writing. The purpose of this program
is to be able to do four part harmony writing, with or without a user specified
progression, according to all the rules of four part harmony writing, and have
the ability to transpose the result into any key.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Musical Intervals&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The distance between any two musical notes is referred to as an interval, and
is represented by a two-character symbol. The first character denotes the
quality, being &lt;i&gt;P&lt;/i&gt; for perfect, &lt;i&gt;A&lt;/i&gt; for augmented, &lt;i&gt;D&lt;/i&gt; for
diminished, &lt;i&gt;m&lt;/i&gt; for minor, and &lt;i&gt;M&lt;/i&gt; for major. The second character
denotes the melodic distance with a number of how many lines and spaces exist
between the two notes of the interval. &lt;i&gt;Major&lt;/i&gt; and &lt;i&gt;minor&lt;/i&gt; refer to
whether an interval occurs within a natural minor scale or within a major scale.
&lt;i&gt;Augmented&lt;/i&gt; and &lt;i&gt;diminished&lt;/i&gt; are used for intervals that do not exist
in the major or natural minor scales, augmented being greater than, and
diminished being less than. The following is a chart of the most common musical
intervals:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/intervals.PNG" width="428" height="310" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Tertian Harmony&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;Tertian Harmony refers to simultaneously sounding pitches in which each of
the pitches are separated by the distance of major or minor third, in at least
one permutation of the order of notes. Tertian harmonies consisting of three
distinct notes are referred to as &lt;i&gt;triads&lt;/i&gt;, and harmonies consisting of
four distinct notes are referred to as &lt;i&gt;seventh chords&lt;/i&gt;. A triad can have
four different classifications depending on the interval relationship between
the notes in the triad. These different types of triads are called major, minor,
augmented, and diminished. Seventh chords can be major-major, dominant, minor,
half-diminished, or fully diminished. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/harmonies.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Progression&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;For any given scale, for example a &lt;i&gt;C Major scale&lt;/i&gt; (C, D, E, F, G, A,
B), each of the pitches in that scale represent the root note of a tertian chord
of some type. Each of these harmonies are referred to as chords and are
represented by a roman numeral. The roman numeral indicates the quality of a
chord (major, minor, augmented, diminished), the position of the chord inside
the key, and which note is on the bottom, (the root), of that chord. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/chords.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;The first note of a chord is known as the root, the second is the third, the
third is the fifth, and if there is a fourth note it is called the seventh.
Whenever a chord cannot be spelled in thirds, it is in an inversion, meaning
that a note other then the root is on the bottom of the chord. An inversion is
denoted by one number on top of another and is written to the right of the chord
symbol, but I will write them as fractions for simplicity. In a triad, when the
third is on the bottom of the chord it is in first inversion and the symbol that
is used is 6. When the fifth is on the bottom of a triad it is in second
inversion and is written as 6/4. Seventh chords can have three inversions, with
the third, fifth, and seventh on the bottom, denoted 6/5, 4/3, and 2.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Rules of Progression &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The order in which chords can occur have multiple rules, the easiest rule
being that I can move to anything, but rather than explain the progression
behavior with words, I will use a picture of the progression graph, where each
chord symbol is a vertex, and all edges are un-weighted.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/progression.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Other Chord Symbols&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;As shown in the graph, there are other chord symbols that have not yet been
described. They are the Neopolitan Sixth Chord (N6), the French Augmented Sixth
Chord (Fr+6), and the secondary dominant (V/x). These chords incorporate notes
that are outside of the given key, and have strict rules for which chord they
can lead to. The N6 and Fr+6 must go to V, and secondary dominants must lead to
chord symbol on the bottom of the fraction. Secondary dominants are considered
to be a borrowed V from another key, and therefore must progress to the I of the
key from which they were borrowed. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www.vdrillpro.com/blog/instant_bach/other_chords.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Four part Harmony Writing&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;Four-part harmony writing is when a progression is developed and the notes in
the chords of that progression are assigned to four voices, the bass, tenor,
alto, and soprano. Each voice has to stay within a particular range and is
limited to the distance which the voice can move between chords. Each note has
rules for motion and each chord has rules for its resolution. Because most of
the progression consists of triads, and there are four voices, a member of the
chord has to be doubled, which there are also rules for.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Rules of Doubling&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;I, ii, IV, iii, and vi : The root and third can be doubled.&lt;/li&gt;
    &lt;li&gt;V and V/x : The root can be doubled.&lt;/li&gt;
    &lt;li&gt;V7 and V7/x : no doubling is needed or the root can be doubled and the
    fifth omitted.&lt;/li&gt;
    &lt;li&gt;viio : The third can be doubled.&lt;/li&gt;
    &lt;li&gt;vii07 : No doubling is needed.&lt;/li&gt;
    &lt;li&gt;N6 : The third can be doubled.&lt;/li&gt;
    &lt;li&gt;Fr+6 : No doubling is needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Rules of Resolution&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;I, ii, IV, and vi : None.&lt;/li&gt;
    &lt;li&gt;iii : If the fifth is in the soprano or bass it must resolve up by a m2.
    If the fifth is in the tenor or alto it must either resolve up a m2 or move
    down a M3.&lt;/li&gt;
    &lt;li&gt;V and V/x : If the third is in the soprano or bass it must resolve up by
    a m2. If the third is in the tenor or alto it must either resolve up a m2 or
    move down a M3.&lt;/li&gt;
    &lt;li&gt;V7 and V7/x : The third must resolve as the same as in the V and V/x and
    the seventh must move down by a m2.&lt;/li&gt;
    &lt;li&gt;viio : If the root is in the soprano or bass it must resolve up by a m2.
    If the root is in the tenor or alto it must either resolve up a m2 or move
    down a M3. If the chord which the viio is going to is a V, then the leading
    tone (the seventh degree of the scale) is already present and there are no
    rules of resolution.&lt;/li&gt;
    &lt;li&gt;vii07 : The root must resolve the same as in the viio, and even if the
    next chord is V, the seventh must move down by a M2.&lt;/li&gt;
    &lt;li&gt;N6 : The root must move down by a D3.&lt;/li&gt;
    &lt;li&gt;Fr+6 : The A6 (or its inversion d3) interval in the chord must resolve
    to P8 or P1.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Rules of Individual Voice Motion&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Bass: The bass generally skips around more than all of the other voices
    and does not have any specific restrictions.&lt;/li&gt;
    &lt;li&gt;Tenor and Alto: Both these voices generally move very little and rarely
    move more then the interval of a third.&lt;/li&gt;
    &lt;li&gt;Soprano: This voice moves more then the tenor and alto but is usually
    limited to skips of less then a P4.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Range of Voices in Relation to Each Other&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The distance between the tenor and the bass can never exceed a P8+ M3, while
the distance between all other voices must remain within a P8.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Cross-Voicing&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;All voices must always be in order from lowest to highest: bass, tenor, alto,
and soprano. If a voice is ever out of that order it is considered
cross-voicing, which is not allowed. Cross-voicing can also occur in the motion
between two chords.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Illegal Parallel Motion&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;If two voices move the same interval in the same direction they are in
parallel motion. The parallel motions of a P8, P5, or P1 are illegal parallel
motions. These are called parallel octaves, fifths, and unisons.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Programming the Progression &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The progression for the program can be created two ways, either the user can
select the individual chords, or the computer can generate the progression
itself. Harmonic progression can be represented as an unweighted graph, in order
to determine whether a specified progression is valid. The main problem with
this approach is that if the computer were to generate its own progression, it
would have to end at a specific point with a cadence. (A cadence is a series of
chords which end a musical idea or statement). The computer is able to do two of
the most common cadences, an imperfect authentic cadence (IAC), and a perfect
authentic cadence (PAC). Each of the cadences consists of a V then I, but in the
PAC the soprano shares the root with the bass. The problem is that if you have n
chords and start with a random chord, and randomly move through the graph until
n-2, then cadence, there is a good chance that the chord at n-3 will not be able
to go to the chord at n-2. This would mean that the progression would have to be
re-done. To prevent this problem, I built the graph backwards, and the
progression is formed backwards as well. This way the progression never runs
itself into a dead-end because it always starts with I, V, and then the random
chords, so when the progression reaches n, the chord at n will always exist
because there are no verticies in the graph that do not have at least one
adjacent vertex.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Turning the Progression into Musical Notes &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;After the progression has been created, the computer needs a way to assign
notes of all chords in the progression to the four voices. To assign notes to
the four voices the computer must first generate all possible notes each voice
can have. This is done by using a recursive method that when given the starting
pitch of a chord, and the symbol of that chord, builds a chord consisting of
every possible note in that chord. Because rules of voice leading depend on
individual chords and the position of individual notes within that chord, each
note in a chord maintains whether a given note is a root, third, fifth, or
seventh.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;The Chord as a Data Structure &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The main object of this program is the chord, which consists of four voices
and a chord symbol, so the obvious main data structure for the program is a
Chord object, consisting of four voices and a chord symbol. A Chord object also
contains methods which allow the individual voices to be viewed as either the
note or the position of that note within the chord, as well as a method to
obtain the chord symbol. This allows other methods to deal with notes
arithmetically and as the position of that note within the chord for voice
leading purposes.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Creating All The Chords &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;Because of all the rules associated with four-part harmony writing, sometimes
the voicing of a progression leads to a dead-end where the progression is
correct, but because of the way a chord is voiced, it may not be able to
correctly move to the next chord. This is why for the computer to be able to
voice a progression, it must have available all the possible combinations of
four note chords. The combinations have restrictions though, for each voice the
note must be within that voice’s range, and may not overlap that of another
voice.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Checking the Motion Between Chords &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;To check the motion between chords, the motion itself becomes a Motion object
and contains methods to compare the motion with other Motion objects, thus being
able to check for all the rules of motion. A Motion object is created with the
same voice in two adjacent chords, for all four voices. The object basically
takes the two notes, calculates the distance between the two notes, and
determined the direction that they are moving. Besides the Motion object, which
checks for invalid parallel motion, the program also checks for cross-voicing
within chords, cross-voicing between chords, and invalid interval skips. Within
the same method which checks for all the previous mentioned motions, there are a
series of nested Boolean statements which check for proper resolutions of chords
based on chord symbols. Each chord is unique in its resolution, with the
exception of when a member of a chord has to resolve in the same direction and
distance as another. In this case a method was developed to be used for checking
the resolution on chords that resolve using only step-wise motion. Otherwise if
there is resolution, it directly involves the leading tone or has a completely
unique resolution, and must be dealt with individually (Fr+6 and N6 chords).&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Choosing the Most Correct Chord &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;After all the chords have been created and checked for doubling and motion,
the chords that remain are all correct, but there is always a most optimal chord
to choose. This is done by first looking at the inversion of the chord because
chords are generally preferred to be in root position, with the exception of
chords which cannot exist in root position. If there is more than one chord in
root position, the chord which has the least motion to its already created
adjacent chord is chosen. In the case where a chord does not exist in root
position, the chord with the least motion to its already created adjacent chord
is chosen.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8852543472291091913-4144941512093496776?l=jvalentino.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvalentino.blogspot.com/feeds/4144941512093496776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8852543472291091913&amp;postID=4144941512093496776' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4144941512093496776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8852543472291091913/posts/default/4144941512093496776'/><link rel='alternate' type='text/html' href='http://jvalentino.blogspot.com/2007/05/instant-bach-goes-open-source.html' title='Instant Bach goes Open Source'/><author><name>John Valentino</name><uri>http://www.blogger.com/profile/15025531615679576013</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8852543472291091913.post-8528711291074827839</id><published>2007-04-29T21:23:00.000-06:00</published><updated>2007-04-29T21:25:03.05
