Thursday, December 24, 2009

Mocking Objects To Unit Test Android OS Applications

First Things First
Testing applications for Android OS can be done in two ways:
  • test on the Android platform using android.test and android.test.mock classes, or
  • testing on the development machine using the regular Java VM and standard Java unit testing and object mocking frameworks.
The good discussion as to pros and cons of each is presented in this article by a Google developer (although not an Android developer). The conclusion was to use the second option, due to valid limitations ofTo the first approach.

Mocking

What are mock objects? They are fake objects that can pretend to the callers to be an object they pretend to be, but are under full control of the test. Full control means two things here:
  • The test can monitor what methods of a mock object are called during the test and what parameters are provided, and
  • The test can dictate what results a mock class should return, without having to actually use, or even implement the class that is mocked.
Why mock objects? Without mocking objects, unit testing is limited to cases where the class under test doesn't use any other classes, or may be just some basic classes. The fuller answer is to why, can be given the following answers. To simplify explaining these answers, let's assume that we want to test class A which uses class B:
  • If some of the class A results depend on class B results. Without using mocking, the test would include the testing of class B. Often, we want to be able to write a test that tests just a single class. Smaller tests can be less brittle, that is they don't break as often with the changes done to the code after the test has been written.
  • If using class B in the test environment is not practical. For example, if the class B is a database, a web service or a GPS module, both of which are tightly coupled to the real world.
  • If we want to test class A before class B is implemented, so it doesn't exists, yet.
  • In general, mocking allows us to test not only an internal code of class A, but also if it uses class B correctly. So, it tests the class collaboration.
For more info on this topic see wikipedia article or this.

What Tools Are Available for Mocking?
The least of tools is quite long. In last couple years, I used probably the following ones:
  • JMock
  • Easy Mock
  • Mockito
  • PowerMock
The reasons I moved from one framework to another are new features (PowerMock can mock even static and final methods) and simpler syntax/tests (esp. Mockito). Also, PowerMock is in a way a conglomerate of Mockito and EasyMock. Although, that means that sometimes, when you use PowerMock you have to use the Mockito, and sometimes the EasyMock like API's. The good part is, that onces you know what mocking is about, using different API's is not that different.

Monday, December 14, 2009

Using JSON RESTfull Web Services in A Flex Application

Choice of JSON Library for Flex
After a few hours of googling, I have decided that the strongest candidate is the corelib library, which for ActionScript 3 is called as3corelib. It's hosted on Google code, although there are multiple references to it on Adobe website. However, none of these references pointed me to any trace of corelib on Adobe website. I wasn't able to figure out why. Leave a comment if you know the story behind.

It seems, that Flash Builder 4 comes with a HTTPService Wizard, which can import a JSON webservice, among other formats.

Limitations of Flash HttpService for RESTfull Webservices
The problem is that because FlashPlayer uses the browser for all networking operations, and Safari browser supports only Post and Get operations, HttpService doesn't support Put, Delete, Headers and Options operations. As a workaround, there is a library hosted on Google Code called RestHttpService, that can be used.

Using Eclipse IDE: Tips, Facts and Tricks

  • If a value gets stuck in Eclipse caches/preferences that doesn't make sense and you can't find a way to update to the new value using Eclipse GUI:
    • Search the workspace/.metadata folder for the obsolete value and correct it, esp. the .settings files. Don't touch binary files, unless you know what you're doing.
    • clean the Eclipse cache by starting exlipse, just once, with the first command line argument set to -clean
    • export preferences, switch to a new workspace and re-import the saved prefs.
    • reinstall Eclipse
    For more info see this great article.
  • The Project Delete doesn't delete any files from the project directory, not even from the .settings folder, unless you check the Delete files... checkbox. Question: is any information lost if I delete a project and then re-import it?
  • How to add a .jar file to classpath without using absolute paths? Follow these steps:

    • Go to Windows > Prefs > Java > Build Path > Claspath variable. Add a new variable pointing to the jar or to a folder, if there are many jars to add.
    • Go to Java Build Path of your project and click Add Variable. If you have specified a var pointing to a single jar, just select it and click OK. If you have created a var pointing to a folder, select it and click Extend. Then, select the jars you want to add (you can add them all in one step). Click OK.
  • How can I move project to another folder? For me this works:


    • Delete the project
    • Move the folder
    • Re-import the project
     

    Tuesday, December 8, 2009

    RESTfull Webservices Using Java with Introduction to JSON

    Introduction
    What are RESTfull or Rest web services and how can they be implemented in with Java? Also what is JSON and how to make a webservice that returns a JSON object?  This is what this blog is about. Specifically, first, about installing and running a sample RESTfull application available from Jersey project.

    What are RESTfull webservices? See this article. Or any other; there are many.

    Approach 1

    This approach uses one of the samples provided by the Jersey project and uses Maven to install the libraries. It's a bit heavy approach, but it works. Approach 2 below also uses Jersey, but is way lighter and simpler.


    Server Side
    I'm using Eclipse IDE with Glassfish Application Server. The steps for this configuration are:
    • Add Jersey and Jersey Documentation and Examples components to Glassfish using its admin console. Note, use GlassFish v3 Prelude version.  When I used GlassFish v3 Promoted Build, the Examples module was not showing in its Update Tool.
    • Restart the GF server.
    • Find the Jersey samples in GF_Home/glassfish/jersey folder.  Go into helloworld-webapp folder. You should see a .pom file there, that is used by maven. From that folder, run "mvn clean package" command. Install maven if needed.
    • Maven installs many files, and for me it ended with an error saying it can't read the glassfish-embedded-all-3.0-Prelude-Embedded-b10.jar file.  I have located this file in the maven repository (Documents and Settings/user/.m2/...) and found that it was broken.  I had to download it manually from internet (search by the file name).
    • Rerun the mvn command. It finished successfully and created a war file in the target directory.
    • Open GF console, and from Web Applications do a deploy. Point to the above war file and click OK. That did it.
    • Point your browser to http://localhost:8080/helloworld-webapp/helloworld. The string "Hello World" appeared.
    Analyzing the Sample
    After I had the sample running, I have exploded and analyzed the contents of the generated war file. The file had a class file implementing the resource plus two more short config files.

    sun-web.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
    <sun-web-app error-url="">
      <context-root>/helloworld-webapp</context-root>
      <class-loader delegate="true"/>
      <jsp-config>
        <property name="keepgenerated" value="true">
          <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
      </jsp-config>
    </sun-web-app> 

    web.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>com.sun.jersey.samples.helloworld.resources</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    </web-app> 

    Approach 2
    Approach 1 worked OK, but I wasn't able to apply the sample to deploy an application of my own. And so I searched for a tutorial that uses Eclipse and possibly no Maven. I have run into this mini tutorial which worked great. I was able to drop this application into a Tomcat 6.0 and GlassFish 3 Prelude containers and it worked in both fine.
    Also, this example illustrates how the service can be implemented for different response formats, leaving to the requestor to decide which one to use.

    JSON
     JSON is simply a format, in a way an alternative to XML, that is especially useful for (de-)serializing objects, for example in order to send them over internet. The format is derived from JavaScript native format, but it became language neutral.  Here's a sample:
    {"name":"Alfred Alfredo","age":"47"}
    A nice and concise description of JSON syntax is on JSON website. To have your RESTfull webservice return a JSON object, download and add to the project jettison.jar that Jersey uses to create a JSON object. Now, for the sake of the demonstration, say that the webservice need to return a Person object:

    @XmlRootElement
    public class Person {
     public String name;
     public int age;
     
     public Person() {} // required by JAXB
     
     public Person(String name, int age) {
      this.name = name;
      this.age = age;
     }
    }

    Thanks to the annotations in this class, in order to return a JSON object we just need to define a method:

    @Path("/person")
    public class PersonResource {
      @GET  @Produces("application/json")
      public Person get() {
       return new Person("Alfred Alfredo",47);
      }
    }

    The JSON object as specified above, in the first part of this section will be returned. You can test it using a browser by pointing it to http://localhost:8080/jersey1/rest/person, where jersey1 is the context of my web app, rest is my servlet mapping and person is what I defined with @Path in my RESTful resource class.

    Tuesday, December 1, 2009

    Presenting Business Objects Reports in PDF Format Using Web Services

    Suppose you have a web application, whether of an RIA type or Web 1.0 type, that needs to present a report. One of the attractive options, is to have the report show in the browser as a PDF document. It seems an interesting option, because most users already have Adobe Acrobat Reader installed and are familiar with it. They usually know how to navigate through the document, print it or save it for emailing or just for later use.
    If your organization is also one of the many that use Business Objects (BO) as their standard reporting technology, the solution presented below may be for you.

    Since version XII, the Business Object Enterprise server is bundled and by default installs the web services module which allows to access reports via SOAP web services. Here's the solution:
    • The web application requests a report by calling the special reporting servlet, passing to it the report ID and required parameters.
    • The servlet uses web services to login to BO server and request the report, which then is returned to the client and displayed in a new browser tab or window in Acrobat Reader.
    The example below, shows the solution for the case when the client is a Flex application and the servlet is implemented in Java.

    Reporting Servlet
    The servlet consists of the following modules:
    • login module (login to BO server)
    • report parms module (requests a list of the parameters required by the report and prepares them)
    • report viewer module (configures the request to return the report in PDF format)
    • retrieve and deliver module (requests the report from BO server and sends it on its way back to the client)
    Login Module:
    
      SessionSoap session = new SessionSoapProxy("http://crystalbo:8080/dswsbobje/services/session");
      EnterpriseCredential credents = new EnterpriseCredential();
      credents.setLogin(businObjectsLoginName);
      credents.setPassword(businObjectsLoginPwd);
      SessionInfo si = session.login(credents);
      if( si == null ) { login failed... }
      // Instantiate Report Engine
      ReportEngineSoap rptEngine = new ReportEngineSoapProxy();
    

    Monday, November 16, 2009

    FlashPlayer and Flex Security Restrictions When Consuming a Webservice

    Here our system configuration (scenario):
    • Server A: hosts your Flex application
    • Server B: hosts a webservice consumed by your Flex application
     In order for your Flex application to be able to consume the webservice in above scenario, you have two options:
    • Place in the root of the application server on Server B a crossdomain.xml file specifying: allow-access-from-domain: server-A-domain, or
    • Use the Proxy service on Server A, which is part of LCDS and BlazeDS dataservices.

    Tuesday, November 10, 2009

    Google Voice: Can I Make Calls and Receive Them Without Using My Air-time Minutes?

    It's tricky, and I have wasted $55 by not understanding this. You always can make free calls to continental US if you place the call from the GV website. But, how about calling from you cell phone?

    Scenario: GV Account with GV Mobile Application
    If you:
    • open a Google Voice (GV) account and add you cell phone number to it
    • download to your mobile device a GV application (I'm using Android, G1)
    • make a call, or receive, a call selecting Google Voice for this, when asked,  
    The call will use your minutes! I have experienced this and it costed me. I know.

    Scenario: As Above with myFavs
    If you:
    • have myFavs or a similar service on your cell phone plan, and 
    • you add your GV number to your favs
    • receive a call or call you GV voice mail: your minutes won't be used
    • place call: your minutes will be used
    Scenario: As Above with A Twist
    If you add to your favs also the number that GV calls when you initiate a call, no minutes will be charged. However, for some reason, this number changes. So, this is not a robust solution.

    Saturday, October 31, 2009

    Why TDD Rather Than Traditional QA's Writing Tests

    First, I describe what is TDD. Then, I present a story that lead me to writing this article.  But if you don't care about stories, just skip to Conclusion and Resources


    What is TDD?
    I'll describe TDD not with my own words but with a few selected excerpts from this resource:
    • The practice of maintaining automated unit test suites has gained widespread acceptance over the past decade to the point where most developers today either engage in some amount of test writing or at least feel bad for not doing it.
    • To prevent regression, developers must provide a set of tests that exercise an application top-to-bottom and end-to-end (front-end to back-end), but anecdotal evidence suggests that even automated tests covering as little as 50% of the code can effectively guard against regression in many applications.
    • Competent developers either conform to a test-first discipline in which small test harnesses are built to exercise an API before the API itself is even implemented, or else employ a code-a-little-test-a-little (CALTAL) approach in which each unit of code developed is tested immediately after its compiled.
    • Most build systems, such as ant, provide direct support for running test suites as part of the application build process, and continuous integration systems, such as Cruise Control or Hudson, kick off such builds automatically each time code is committed to the team's version control system


    Situation
    Recently, I ran into project OpenSatNav. It's an open-source version of AndNav2, that is navigator application for Android OS based on OpenStreetMap. Great project, still pretty young, but dynamically expanding. I watched a few issues being fixed by the developers involved, and noticed that the process of findind a solution was a bit erratic. There were several attempts to guess a solution, and guesses were not perfect, but then there were a few better guesses.  Some NullPointException bugs cropped out after a few days and were fixed. Still, some issues were reported, but never reproduced, so by the token "it doesn't show the problem anymore, so let's close this issue", the issue has been closed. What was obvious to me, is that the solution is not necessarily correct. The testing was done manually and without even any systematic approach.

    Spring into Action
    It was obvious to me that what was definitely missing, was the automated testing, especially unit testing. I tried to step in and encourage unit testing. The idea of TDD, or any unit testing that I proposed several times was for the project team like a fairy tale about a bad wolf. But the developer team and the project lead were friendly and not exclusive.The lead-developer on this issue, responding to my requests, did include a well defined test-scenario with the fix code. I thought: it's not bad, I'll step in and write a unit or functional test for this fix. I have experience with TDD for Android, Java, GWT and Flex projects.

    Result
    It took me time (I have a full-time job and four children ages 4 - 19, plus, I took this as an opportunity to review the currently best practices for testing for Android OS), but finally I got to writing the test. And here's what I have found, which may be very well what also you experience is in this matter.  While writing a unit or a functional test for your own fix or new feature is a fun and a relatively straightforward activity, writing a test for a code written by someone else, is neither much fun nor simple. You end up reverse engineering the whole part of the system that surrounds the part where the fix was made.

    Conclusion
    Simple. Write your own tests. This, was for me always fun and an enlightening experience. And, I think, my design and coding have improved because of the tests I wrote. Tests for my own fixes.  Tests written immediately after I have written the code (CALTAL), or even just before I have written the code.

    Resources
    The following are useful for getting quickly to speed with TDD, esp. for Android OS development:

    Thursday, October 29, 2009

    Use Eclipse to Build a Starter Java Web Application

    • Create a new eclipse project using the Dynamic Web Project
    • After it's created, you may find an error in web.xml: Cannot find the declaration of element 'web-app'. To fix it, change all occurrences of j2ee to javaee in the attributes of the web-app tag in web.xml.
    • Place all jars required by your app:
      • into yourWebApp/WEB-INF/lib folder if you want just your app to acces it
      • into tomcatHome/shared/lib folder if you want all web apps on the server to share it
      • into tomcatHome/common/lib folder if you want all application and the server to be able to use it

    Using Derby aka JavaDB

    • The database package is included with j2ee package or download.
    • To start the server: go to bin folder and fire-off the startNetworkServer.bat or the like on other OS's.
    • To create a database: connect to the server with the following JDBC URL: jdbc:derby://localhost:1527/fiber1;create=true. Replace fiber1 with the name of the DB you want to be created upon connect.
    • There is a tool called DdlUtils freely available from Apache that allows migration from one DB vendor to another. That means migration of the schema and the data. Can be used via Ant or from a Java program.

    Saturday, October 24, 2009

    System Recovery Using Linux

    Recently, oe of our laptops failed.  It was slowly getting worse and worse.  We had to recover the files, but the installed windows OS wasn't operational any more.  I have run into a SystemRescueCD. It's an open project, that provides a set of rescue-oriented tools, togather with the basic linux system on a bootable CD or USB.

    Here's how I have done the retrieval of the files:
    • Mount the windows harddisk:
      mkdir /mnt/sjb/windows
      ntfs-g3 /dev/sda1 /mnt/sjb/windows
    • Mount the USB to copy the files onto:
      mkdir /mnt/sjb/usb
      mount -t vfat /dev/sdb1 /mnt/sjb/usb (vfat is an extension of fat16)
    I have also used an external harddisk connected via USB to copy a larger amount of data from the laptop's harddisk.  To find which device name I should point to to mount it (like /dev/sda1), I have used the testdisk utility available on the CD.

    Friday, October 23, 2009

    Confluence Wiki Office-Connector Plugin: Problem when Using IE

    We have experienced problems, on some of our computers, when trying to use Office Connector plugin with IE.  Office Connector is a plugin that allows to easily edit an attached office document in its native editor, whether MS Word, Excell or OpenOffice Writer or some other. In Firefox, it works very well, once you install the add-on.  But in IE, it displays a message:

    Unable to create an ActiveX object to open
    the document. This is most likely because
    of the security settings for your browser.

    Notes:
    • The SharePoint.OpenDocuments ActiveX class is installed as part of MS Office, as part of Office Tools. The problem is not related to the IE version (both, IE6 and IE7 sometimes worked and on other computers didn't).
    • If you try to open for edit a document attached to a confluence page, the above class gets loaded into IE, and can be found in the list of loaded IE extensions.
    • To verify that it's installed correctly on your machine, run the script
      WScript.Echo "About to create an new SharePoint.OpenDocuments.1"
      dim obj
      set obj = CreateObject("SharePoint.OpenDocuments.1")
      WScript.Echo "Finished"
    • After tweaking the existing versions of the MS Office on the machine, it started working.

    VBScript, VB, VBA Scripts and The Like: A Few Basic Facts

    First two samples. A VBScript:

    WScript.Echo "About to create an new SharePoint.OpenDocuments.1"

    dim obj
    set obj = CreateObject("SharePoint.OpenDocuments.1")

    WScript.Echo "Finished"


    And a VBA:
    Public Sub myTest()
        Dim spObject As Object
        Dim aaa As String
       
        On Error Resume Next
        Set spObject = CreateObject("SharePoint.OpenDocuments.1")
       
        If Err.Number <> 0 Then
            aaa = "sss"
        End If   
    End Sub

    Notes:
    • In VBScript, the try/catch/finally/end try is available.  Not in VB/VBA.
    • VBA runs in a MS Office App only, while the VBScript is more like JavaScript: can run in the browser or from the command line. Use CScript.exe to run in the latter environment.
    • How to output a line to the console in VB/VBA? Don't know.

    Tuesday, October 20, 2009

    Windows Remote Desktop Connection Issues

    Clipboard Sharing Not Working
    * if the RDPCLIP is not running, start it (Start Menu -> Run -> CMD and type RDPCLIP)
    * if it's running, restart it. 
    That was tested with WinXP. 

    Friday, October 2, 2009

    RedHat Software Installation Utility RPM

    Simple usage:
    • You need: an RPM file downloaded from rpmfind.net website or the like
      • On that website, provide the complete name of the package, but only the name, in main search box.
    • Run: rpm -Uvh name_of_the_rpm.rpm
      • The nice thing: this command will not install anything until all dependencies are satisfied.
      • If any dependencies are unsatisfied, this command will indicate what is needed. Download it and append the name of additional .rpm file(s) to the command and execute again. Continue the loop until all dependencies are satisfied.
    That's it. For today.

    Monday, September 28, 2009

    Start An Application When Linux, RedHat, Starts

    Here you go:
    • Create a control script in /etc/init.d folder that responds to at least start and stop commands.
    • In this script, include a comment line: chkconfig 35 80 20 (there is a meaning to it: for which runlevels the process is to be off or on).
    • Run the chkconfig --add your_control_script command. Run it with --list option to verify that the control script has been added to the list of processes to start at boot time.
    • If there are any problems during boot time, they are recorded in the /var/log/boot.log and/or /var/log/messages files.
    Note:
    Global environ variables are usually defined in the /etc/profile script. This script is automatically run by every interactive shell process (or a shell process with --login argument). The /etc/profile doesn't seem to be executed automatically during the boot process, though. You may need to do:
    . /etc/profile
    in your control script if you need to use any of the global environ variables.

    How to Share Files between Mac and Other Computers

    I mean, other than via a USB disk.

    Share Mac's Files via FTP
    • Go to Settings -> Sharing and enable File Sharing
    • Click the Options button and check the FTP.
    • From a windows machine, point to the mac using ftp://11.123.123.321 (use mac's ip)
    • Provide your mac's user and password.

    Sunday, September 27, 2009

    Android: News Summary

    • In July 2009, a new SDK version was released, called 1.5 release 3. Was it a release corresponding to the Android update that happened 1-2 months after the Cupcake update?
    • There is also Android 1.6 SDK available, that will work only with Android 1.6 to be made available on Oct 2009.

    Friday, September 25, 2009

    Connect To A Remote Windows Workstation To Provide Support

    So, someone from you family, living far away from you, asked you to help him/her with her windows computer and you would like to help, but are not willing to spend $450 for air tickets. Well, sometimes it may be a good idea to spend this money and spend some time with your family. But if there are reasons you can't do it right at this moment, but you would still like to help with the computer problem, what do you do? Especially, if it's your older relative or friend? Not really technical savvy or even scarred of this new and strange technology.

    One simple approach I have found (after trying two other approaches with only partial success), is a product called TeamViewer. The personal/non-profit use is free. The thing works like this:
    • The person that receives the support, downloads and runs the TeamViewerQS, which generates a random ID and password.
    • The supporter downloads the TeamViewer and starts it. It asks for a user and password.
    • The supported needs to obtain these to pieces of information from the other person (phone, email, text message, etc.) and enter.
    • The rest is simple. Just like the MS Remote Desktop or VNC.
    A really cool part of this is, you can actually test the TeamViewer first without getting your relative at all. The company provides a "test" machines you can connect to for testing. Easy, they're probably running just a bunch of windows virtual boxes. But still, it's a good idea.

    Enjoy! And do make at another time a trip to visit your family in person. In my case, the relative I needed to help, lives in Poland. I live in Oregon. TeamVeaver was helpful.

    Friday, September 18, 2009

    Glassfish Enterprise Server: Changing Port

    I couldn't find a straight and good answer easily. So, here's what you to change the port your server is listening on:
    • start the server
    • go to admin console (default: http://localhost:4848)
    • Open: Configuration -> HTTP Service -> Network Config -> Network Listeners
    • The main port is listed as the listener1, I believe.
    That's it. Simple. You don't even need to restart the server for the change to take effect.

    Changing it by editing the domain.xml file is possible, but the server always chokes for a while to accept it. You can also use asadmin get server and asadmin set ... but this is still more messy than just doing it in the console.

    Monday, September 7, 2009

    Parsing a Text on Android Phone

    Introduction
    I have a wiki markup text that I need to parse. My first version, which I use in DroidWiki application for Android, is a wiki custom parsing. I wrote my own parsing, because I haven't found a parsing code on the internet that was light enough to be used on Android phone. That code does a regular expression matching for each wiki tag. So, every line is matched at least Recently, I decided to try my hand at more fancy parsing: just parse into a sequence of tokens. Below, are the results of my research on this topic.

    Using One-Character-At-A-Time Parsing
    One way to solve the problem is to use a one-pass parsing, having the Java code to look at each character (just once) and isolate the tokens this way. Using the character iterator goes like this:
    StringCharacterIterator iter = new StringCharacterIterator(markup);

    for( char c = iter.first(); c != CharacterIterator.DONE; c = iter.next() ) {
    // process the char: is it one of the characters that starts any of the syntax tokens?
    }

    This could be fast, but the code would be complicated. I decided for a different approach.

    Using Interpreter Design Pattern

    The idea:
    1. Parse the text and convert it to a sequence of basic tokens:
      • every continuous piece of a regular text is a token
      • every sequence of syntax is a token (for example, the char less-than if parsing HTML text would be a simgle token by itself)
    2. Process the list of these basic tokens and aggregate them into complete syntactical elements (for example, every complete HTML tag would be a single token).
    If you want, create
    • a SimpleToken class for item 1 above,
    • a base Token class and specialize it for more significant/complex syntactical elements for item 2 above

    Thursday, September 3, 2009

    Compiling a Flex Application with Ant

    Introduction
    This blog summarizes how to compile a Flex application using ant.

    Creating the build.xml File
    The build.xml file:
    <project name="fishbaitTestModule" basedir="." default="compile_flex_project">

    <!-- Properties -->
    <property environment="env" />
    <property name="flexhome_dir" location="${env.FLEX_HOME}" />
    <property name="src_dir" location="${basedir}/../test-src" />
    <property name="libs_dir" location="${basedir}/libs" />
    <property name="deploy_dir" location="${basedir}/deploy" />

    <!-- Define the flex ant task -->
    <taskdef resource="flexTasks.tasks" classpath="${libs_dir}/flexTasks.jar"/>

    <target name="clean">
    <delete dir="${deploy_dir}" />
    </target>

    <target name="init" depends="clean">
    <mkdir dir="${deploy_dir}" />
    </target>

    <!-- Don't touch. Required by flex ant task -->
    <property name="FLEX_HOME" location="${flexhome_dir}" />
    <target name="compile_flex_project" depends="init">
    <mxmlc file="${src_dir}/testSuites/FishBaitTestModule.mxml" output="${deploy_dir}/FishBaitTestModule.swf">
    <load-config filename="${flexhome_dir}/frameworks/flex-config.xml"/>
    <source-path path-element="${flexhome_dir}/frameworks"/>

    <compiler.source-path path-element="${src_dir}"/>

    <compiler.debug>false</compiler.debug>

    <!-- List of SWC files or directories that contain SWC files. -->
    <compiler.library-path dir="${basedir}/libs" append="true">
    <include name="AirMonkeyLibrary.swc" />
    <include name="MonkeyFlexUnitLibrary.swc" />
    <include name="fluint.swc" />
    </compiler.library-path>
    </mxmlc>
    </target>

    </project>


    How To Use The Script
    • create FLEX_HOME environment variable on your system (we tested this on WinXP) and point it to Flex root folder.
    • copy files flexTasks.jar and flexTasks.tasks into libs_dir folder. You can obtain these files from Adobe.
    • Note: the ant FLEX_HOME property just above the compile_flex_project target needs to be there; it seems that the mxmlc task uses and requires it, even if you already have envvar with the same name setup on your system.
    • the src_dir, libs_dir properties point to folders where the Flex source, required SWC files are located, respectively. The deploy_dir is where the SWF files will be created, your compiled application.
    • FYI: If you are running your Ant script from Eclipse, the Ant you're running is installed in ...\eclipse\plugins\org.apache.ant_1.7.0.v200803061910 or similar folder.

    Using FlexUnit to Unit Test Cairngorm Visual Objects

    Introduction
    In a RIA application a typical split of the source code (counted by code size, in bytes) is as follows:
    • 45-60% - client: visual objects like views and their sub-components with their logic
    • 15-20% - client: non-visual objects (primarily Cairngorm worker-to-service piping)
    • 30-35% - server: middle-tier code
    In the couple medium-size business application, I have analyzed, the middle-tier was implemented in Java and the client was implemented in Flex using the Cairngorm architecture. So, I don't have verified numbers for other RIA configurations.

    If we are determined to use TDD or simple just provide automated tests for our application and get the most coverage for the effort required to develop these tests, it seems we could use the following testing methodologies:
    • FlexUnit testing for the client, especially the client's visual objects
    • FlexMonkey tests for whole client's features
    • jUnit tests for the middle-tier code.
    I another blog, I will touch on the FlexMonkey. In this one, I'd like to present how we can unit test the visual layer of the client using the FlexUnit framework. jUnit testing is well described in many other sources.

    Testing Scenario
    In the spirit of Cairngorm, a UI user gesture is directed to a handler which creates a Cairngorm message, attaches a payload to it (any relevant information) and dispatches it (event.dispatch()). Our test will mimic a user gesture (click a button) and will try to catch the dispatched Cairngorm event and verify its payload. We're using Flex 3 (ver. 3.2) and FlexUnit 4 beta 2.

    Sample Application
    To explain the topic, I'll be using the following sample application. The view (Main.mxml adds it to the ViewStack) is (to see the code in a new window, move your mouse pointer over the code and click the left of the icons that appear in upper-right corner):
    <?xml version="1.0" encoding="utf-8"?>
    <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    width="400" height="300">
    
    <mx:Script source="MyViewScript.as" />
    
    <mx:HBox verticalAlign="middle" >
    <mx:Text id="txtValue" text="Entry:" />
    <mx:TextInput id="entryTextInput" />
    <mx:Button id="btnSave" label="Save" click="onBtnSaveClick(event)" />
    </mx:HBox>
    
    </mx:VBox>

    The script used bu the view is:
    import gov.olcc.fishbait.events.SaveEntryEvent;
    import gov.olcc.fishbait.model.ViewModelLocator;
    import gov.olcc.fishbait.vo.EntryVO;
    
    public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();
    
    public function onBtnSaveClick(event):void
    {
    trace("clickHandler detected an event of type: " + event.type);
    
    var entryVO: EntryVO = new EntryVO();
    entryVO.text = entryTextInput.text;
    
    var saveEvent: SaveEntryEvent = new SaveEntryEvent(entryVO);
    
    saveEvent.dispatch();
    }
    
    

    and the TestRunner class to run the test is
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="*"
    xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
    xmlns:business="gov.olcc.fishbait.business.*"
    xmlns:control="gov.olcc.fishbait.control.*"
    xmlns:view="gov.olcc.fishbait.view.*"
    layout="vertical"
    width="100%" height="100%"
    creationComplete="runTests()">
    
    <mx:Script>
    <![CDATA[
    import com.adobe.cairngorm.control.FrontController;
    // import gov.olcc.fishbait.view.TestFishBaitView;
    import gov.olcc.fishbait.view.MyView;
    import org.flexunit.runner.FlexUnitCore;
    import org.flexunit.flexui.TestRunnerBase;
    import gov.olcc.fishbait.view.MainTest;
    // import gov.olcc.fishbait.view.TestFishBait;
    
    //Add an import statement(s) for the class(es) under test
    private var core: FlexUnitCore;
    
    private function runTests():void
    {
    core = new FlexUnitCore();
    core.addListener(testRunner);
    core.run(MainTest);
    }
    
    ]]>
    </mx:Script>
    
    <!-- Cairngorm Controller and Service Locator -->
    <control:FishBaitController id="controller" />
    <business:Services id="services" />
    
    <flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
    </mx:Application>

    The trick is to be able to catch the Cairngorm event. What is not obvious, the event.dispatch() method uses a CairngormEventDispatcher, so we need to add our listener to it. The resulting test code is
    package gov.olcc.fishbait.view {
    import com.adobe.cairngorm.control.CairngormEventDispatcher;
    import flash.events.MouseEvent;
    import gov.olcc.fishbait.events.SaveEntryEvent;
    import gov.olcc.fishbait.model.ViewModelLocator;
    import gov.olcc.fishbait.vo.EntryVO;
    import mx.automation.codec.AssetPropertyCodec;
    import org.flexunit.Assert;
    import org.fluint.uiImpersonation.UIImpersonator;
    import org.flexunit.async.Async;
    
    public class MainTest {
    var myView: MyView;
    public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();
    
    [Before(async,ui)]
    public function setUp():void {
    myView = new MyView();
    UIImpersonator.addChild(myView);
    }
    
    [After(async,ui)]
    public function tearDown():void {
    UIImpersonator.removeChild( myView );
    }   
    
    [Test(async,timeout="3000")]
    public function testOnBtnSaveClick():void {
    CairngormEventDispatcher.getInstance().
    addEventListener(SaveEntryEvent.SAVE_TEXT,
    Async.asyncHandler( this, handleTestOnBtnSaveClick, 3000 ),
    false,0,true);
    
    myView.entryTextInput.text = "Test Text";
    var clickEvent: MouseEvent = new MouseEvent(MouseEvent.CLICK);
    myView.btnSave.dispatchEvent(clickEvent);
    }
    
    private function handleTestOnBtnSaveClick(event:SaveEntryEvent,
    passThroughData:Object):void {
    var entry:EntryVO = event.text;
    Assert.assertEquals("Test Text", entry.text);
    }
    }
    }

    Other points about this test:
    • We use FlexUnit UIImpersonator as a parent to our view. Without adding a view to a parent, the UI controlls are not initialized and can't be used.
    • To get the instance of the CairngormEventDispatcher, we use its static mathod getInstance().
    • Since the actual test happens in the event handler, we need to user an annotation [Test(async,timeout="xxx ms"] to request the Async support for the test.
    • Then, instead of providing just the handler method as an argument to the assEventListener(), we wrap this method in Async.asyncHandler(), which will wait for the handler to be called unless the handler will not be called within specified time, in which case the test will fail.
    And this is it. Enjoy testing Cairngorm visual objects.

    Wednesday, August 26, 2009

    Wikipedia Is Still Free.

    I have recently been sent an article by CNN about changes in Wikipedia. It decided to start to moderate the changes to articles about living people.

    The article is interesting. Although, it's not much of a shift. There were some rules and monitoring in place already. Although, the results of these monitoring processes were only shown as warning/information boxes at the top of the articles. The change the article is talking about will affect only a small portion of the wikipedia articles. So, you're still free to go there and correct any misinformation, if any, about State of Oregon, US or City of Portland. Or extend them, if you know of facts that would be good to be there. It's still in your hands. Sorry, in our hands.

    Go, ahead!

    Tuesday, August 18, 2009

    Using FlexUnit 4 with Flex 3: Sample Application

    Introduction
    We had hard time finding on the internet a sample like this. So, here's ours. Additional steps required for this test to be run:
    • download FlexUnit 4 from their site.
    • add the FlexUnit swc files to the project's classpath
    • copy the sources below into your project and adapt them (use the view source icon in each source code frame below to view/copy the source code).
    • once everything is on place, right click on the TestRunner and select Run Flex Application.
    At the end of the article, we have added some notes about using FlexUnit with FlashBuilder 4 and Flex 4
    Enjoy! It's a great tool!

    File structure

    Tested Object

    package olcc.account
    {
    public class Account
    {
    public function Account(){
    }
    
    private var balance:Number=0;
    
    public function deposit(amount:Number): void {
    balance=balance+amount;
    }
    
    public function withdraw(amount:Number): void {
    balance=balance-amount;
    }
    
    public function getBalance():Number {
    return balance;
    }
    }
    }
    
    Test Suite (Optional)

    package olcc.account
    {
    import org.flexunit.runners.Suite;
    
    [Suite]
    [RunWith("org.flexunit.runners.Suite")]
    public class MyTestSuite
    {
    public var t1: AccountTest;
    
    }
    }
    


    Unit Test

    package olcc.account
    {
    import org.flexunit.Assert;
    
    public class AccountTest
    {
    [Test]
    public function testNew():void {
    var account:Account = new Account();
    Assert.assertEquals("Expecting zero account balance", 0, account.getBalance());
    }
    
    [Test]
    public function testDeposit():void {
    var account:Account=new Account();
    account.deposit(50);
    Assert.assertEquals("Balance on a new account after 50 deposit is 50",50,account.getBalance());
    account.deposit(25);
    Assert.assertEquals("Balance after 50 deposit and another 25 deposit is 75", 75,account.getBalance());
    
    }
    
    [Test]
    public function testWithdraw():void {
    var account:Account = new Account();
    account.deposit(100);
    account.withdraw(50);
    Assert.assertEquals("Balance should be: + $100 - $50 = $50",50,account.getBalance());
    }
    }
    }


    Test Runner
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="*"
    xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
    creationComplete="onCreationComplete()">
    
    <mx:Script>
    <![CDATA[
    import org.flexunit.runner.FlexUnitCore;
    import org.flexunit.flexui.TestRunnerBase;
    //Add an import statement(s) for the class(es) under test
    import olcc.account.MyTestSuite;
    
    private var core: FlexUnitCore;
    
    private function onCreationComplete():void
    {
    core = new FlexUnitCore();
    core.addListener(testRunner);
    core.run(MyTestSuite);
    }
    ]]>
    </mx:Script>
    
    <flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
    </mx:Application>

    Using FlexUnit 4 with Flex 4

    Flex 4 beta2 has support for FlexUnit, and the most recent version of it which is version 4.0. If you go to the New->TestCase menu, FlashBuilder can create for you a whole test class. And add to the flex build path the necessary libraries. This is done pretty well. But when I tried to apply the simple test application presented above to a Flex 4 application, I ran into multiple problems. One critical, as of today, was the issue that the AsDoc for Flex 4 is not available, nor much of the documentation for it. So, some classes from FlexUnit 4 that I needed (like TestRunnerBase), I wasn't able to find. Until these issues are resolved in Flex 4, I decided to use the FlexUnit 4 directly. To do this, I removed the Flex 4 libraries from the build path and added the FlexUnit 4 beta 2 libraries (.swc files). In general, the flex parser is not always stable, which showed up in this exercise and I had a compilation error that shows every other time I compile my TestRunner.mxml (with the same source code), but I can run the tests. Simply, I made sure that the last compilation is a clean one. Also, closing and reopening the project eliminated this issue.

    Tuesday, August 11, 2009

    FlexUnit Plugin for Eclipse

    Since we intend to do unit testing in our Flex+Java development, I have been playing with FlexUnit and have found an eclipse plugin that makes it easier to use (also, in plugin central). Here's a summary and lessons learned on how to start with the plugin

    Installation
    Follow the installation instructions from here. Once installed, open the plugin's help in Eclipse and configure it. A few points:
    • Download FlexUnit and FlexUnit extension for the plugin.
    • You will need to have Flex Builder 3.
    • You will need a debugger version of Flash Player (I used version 10). A standalone player used by the plugin comes with Flex Builder (directory: player)
    • Follows instructions from Adobe on how to enable logging and error output for Flash Player. When you follow them, after you create a mm.cfg file, you will need to restart all instances of Flash Player for the Logs folder to show up.
    Using The Plugin
    To use a plugin:
    • Create a unit test using Flex Builder's wizard. I recommend keeping them in another source folder, so they can be easily skipped when releasing the app. For example, keep the flex source in flex-src and flex tests in flex-test. The server code put in java-src and java-test, or whatever language you use for the middle-tier.
    • Create a harness. Right click in the test file in the project navigator, find FlexUnit menu and select Create Harness. This will create a small mxml file for your test. However, if you use FlexUnit 0.9, the code needs a correction. Replace:
      EclipsePluginTestRunner.runTests( new Array(AccountTest.suite()) );
      with
      EclipsePluginTestRunner.run( AccountTest.suite() );
    • Run the test. Right click on the harness file and select Run from the FlexUnit menu. Observer the test results on the nice eclipse viewer.
    I had the problem that the test launch process never finishes in eclipse. But it doesn't seem to be harmful. Just ignore it.

    Summary
    It's a great plugin. It could do quite a bit more, but it's a great start. It worked for me with a FlexUnit 4, when I used the syntax of FlexUnit 0.9. When I switched to FlexUnit 4 syntax, I didn't have to apply the correction mentioned above to the auto-generated harness to compile. However, I didn't get my tests executed. So, I guess, for now, using the FlexUnit 0.9 is a better option. However, I have heard from the plugin author that he intends to do another release of the plugin.

    Sunday, July 12, 2009

    Graphics - Format Selection

    The Problem
    So, you decided to edit an picture from you camera. Most likely, it came from the camera as a JPG or JPEG file. However, if you edit it and save, and especially repeat this process couple times, your image will look different. Wherever there was a smooth transition from one color, or shade, to another color or shade, you will notice strange lines, like contour lines on a map.

    The Mystery Revealed
    The reason is, each time your editing software saves a file in JPEG format, it compresses the image and introduces small changes to your picture. These changes are small and they are not noticeable. Because JPEG compression algorithm is allowed to perform these small changes, it is able to compress the file so nicely. So, it all works great, unless you save it not once but 3, 4 or 8 times. Then these small changes accumulate and the deformations are very well visible and not really pretty. Your picture is ruined.

    The Solution
    So, what, shall you avoid the JPEG format? Not at all. However, if you decide to edit the picture, save it in a lossless format. You can open it, edit and save as many times as you want, and you picture will not deteriorate. Than, when you are ready to post the picture to your website or print it, save it as a JPEG file. But what is a lossless format? Well, there are two good candidates: TIFF and PNG. TIFF is better, in a way, because it can save more than just the image. It can also save paths and layers (I'm not sure of layers, though). Just make sure, that you don't let the TIFF formatter use JPEG as compression. You would get into the same problem as described above. PNG may be even a bit smaller, but it will not save anything more than the image itself.

    Tool
    GIMP image editor will allow you to open and save in all these formats without problems.

    Sunday, July 5, 2009

    Date, Time, SQLite and Android

    This post summarizes my recent experience (problem, finally solved) with storing and then reading and displaying the date and time in Android application.

    Storing the current time/date in SQLite
    The most common way is to do:
    database.execSQL("update TABLE_NAME set COLUMN_NAME = datetime('now') where ...");
    As a result, SQLite stores a string representing the current time in UTC (GMT), using the ISO8601 date/time format. This format (YYYY-MM-DD HH:MM:SS), is by the way suitable for date/time comparisons. The fact that the value stored is in UTC and not in a local time zone, is actually nice. More about it below.

    Retrieving a time/date and displaying it
    To retrieve the value, follow the recommended Android practice:
    Cursor row = databaseHelper.query(true, TABLE_NAME, new String[] {
    COLUMN_INDEX}, ID_COLUMN_INDEX + "=" + rowId,
    null, null, null, null, null);
    String dateTime = row.getString(row.getColumnIndexOrThrow(COLUMN_INDEX));
    This, returns a string, parse it and reformat to your local format and time zone:
    DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try {
    date = iso8601Format.parse(dateTime);
    } catch (ParseException e) {
    Log.e(TAG, "Parsing ISO8601 datetime failed", e);
    }

    long when = date.getTime();
    int flags = 0;
    flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
    flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
    flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
    flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;

    String finalDateTime = android.text.format.DateUtils.formatDateTime(context,
    when + TimeZone.getDefault().getOffset(when), flags);
    Note the when + TimeZone.getDefault().getOffset(when) above. This does the trick to convert the UTC time/date to local time. The DateUtils.formatDateTime() seem to be supposed to do this, but it doesn't, or I wasn't able to find a way to achieve it.

    And that's it.

    Thursday, June 18, 2009

    Interfaces, Inheritence and Hibernate

    How to choose: Inheritence or Interface?
    • Idea 1: If the relationship is more an "is a", use inheritance. If it is more a "can be", use interface. Examples: TextBox "is-a" Control, ArrayList "can-be" enumerated.
    • Idea 2: If your object is a specialization of another object, use inheritance. But if the feature that distinguishes the derived class from the base class is something that other classes may need to support as well, an interface is a better choice.

    Monday, June 15, 2009

    Flash Builder 4, Hibernate and Eclipse: Working Together

    So, we at OLCC decided to give Flash Builder 4 (beta) a try. So far, we have been working only with a small sample using the JEE for its server tier, but already have learned a few valuable lessons:

    Creating a New Flex Project
    • Accept the folder names flex_src, bin-debug; the FB4 doesn't deal correctly with non-default values.
    • After creating a project, go to .flexProperties and set the serverContextRoot="/YourProjectName". After opening Properties->Flex Server window, reset this value of serverContextRoot.
    • Instead of using mx:Text, there is now s:SimpleText control.
    Error 404, when trying to Debug the application

    When we got this, we saw the URL that FlashBuilder is trying to use to start the HTML wrapper is http://localhost:8080/ProjectNamebin-debug/Main.html. The bin-debug definitely shouldn't be there. We also noticed, that this same URL shows in the project properties on Flex Build Path page as the Server Root URL. It can't be fixed there, but we fixed it in the Debug run configuration. Trying to use Run instead of Debug was even more messy. For some reason, it tried to connect the debugger to the FlashPlayer (yes, in Run mode).

    PermGen Issue

    Also, recently, we had problem with running out of the space in PermGen. The only solution we found, was to reduce its size (yes, reduce!) from the default 256M to 128M.

    The funny thing is, we had eclipse running fine for a long time. Then, when we installed a 2nd instance of eclipse, using a separate workspace, we started experiencing this problem. When we used the 256M, and any serious action crashed the Eclipse, we ran the eclipsec.exe which showed an error message "not able to find enough memory to start jvm with these options" or smth like this. That's why we have reduced the memory. We haven't had the PermGen issue since then. I don't understand this issue really, it's more a trial-and-error solution, but it works.


    Hibernate

    For Hibernate, we use:
    • Database Development perspective provided by eclipse
    • Hibernate installed via GlassFish admin console (we pointed eclipse compiler at it)
    • Hibernate Tools from JBoss Tools (installed just the hibernate tools through the eclipse update site http://download.jboss.org/jbosstools/updates/stable/)
    • JavaDB bundled with GlassFish server
    This configuration seems a good mix. That's it for now.

    Tuesday, June 9, 2009

    GlassFish Application Server: Introduction and More

    This blog summarizes what I have found interesting or not-obvious about the Sun's open source enterprise application server called GlassFish. If you think, any of the info in this blog is not precise or just incorrect, feel free to comment.

    • Version 2.1 of GlassFish is the final version that implements Java EE 5. Version 3.0 of GlassFish is the first one that implements Java EE 6. It's a preview, but ready for production.
    • Server Domain: a new concept introduced into GlassFish that means one or more server instances that can be managed as a whole by an administrator. For developer, domain=server instance. For administrator, it can comprise of multiple, clustered server instances. Each domain, even if all domains are local, runs in its own JVM (there is also one JVM instance associated with the server administration/control, it seems). More info.
    • Virtual Server: to be finished...

    Wednesday, May 20, 2009

    Using Unit Testing to Test GWT RCP Calls

    This is a short note. I'm working on a GWT application and ran into a problem with an RPC call which gets some objects from the database using Hibernate and passes them back to the client. I'm going to solve the problem using Dozer, but I needed to confirm this was the problem and simplify the testing of this in future. So, I decided I want to unit test this service from the client's perspective. Here are my notes from this exercise:
    • The easiest way to create a GWTTestCase is using the GWT's jUnitCreator. Creating it by hand is possible but tricky.
    • The asynchronous test needs to use delayTestFinish(delayMs) and finishTest(). In my case, I had to set 5000 Ms. For some reason, 500Ms, which I thought would be more than enough was timing out.
    • The good news is, that when using Eclipse plugin for GWT, starting initiating Run as JUnit Test on the GWTTestCase test starts for you also the server. And doing the same with Debug as JUnit Test allows to debug the client as well as server code.
    Note: the similar test is supported in Flex application!

    Tuesday, May 12, 2009

    Developing Flex Applications with Java Middle-Tier

    Intro
    In my job we are using Flex with Java to develop web applications that support the activity of the agency I'm working for. It's my first experience with Flex and I'd say, I'm duly impressed. I had experience of developing using GWT and I must say, that Flex is an equally good tool.

    A Simple Way
    Just follow this tutorial.

    Tools Used
    We use the following toolset:

    • eclipse with FlexBuilder plugin (plugin is not free)
    • jBoss
    • Java for back-end
    • LCDS to communicate between Flex and Java (not free, but there are free alternatives: BlazeDS and the LCDS Express is also free, I think).
    • Cairngorm pattern for Flex client structure

    Tips and Gotchas

    • A great intro to Cairngorm (and Flex itself) is one by David Tucker.
    • He is using ColdFusion for the back-end, so switch to this or this for how to do it with Java.
    The Cairngorm pattern for calling a remote service is a bit complex. Here's how it goes:
    • In the main mxml file (the one where you define mx:Application): instantiate the ServiceLocator: . The id "services" is irrelevant, it seems. And instantiate the FrontController.
    • Let say, the command LOGIN is to be handled by the back-end. Dispatch the command by initiating the LoginEvent and calling dispatch() on it.
    • Each event is mapped onto a command in the FrontController. Let say, in this case, onto a LoginCommand.
    • In loginCommand, instantiate a delegate, say LoginDelegate and call the login(event)
    • In LoginDelegate, obtain the service proxy using:
      ServiceLocator.getInstance().getRemoteObject("myRemoteObject");
      and call the login(args) on it.
    • Now, two additional files need to be setup: Services.mxml and remoting-config.xml
    • In the first one, Services.mxml, define a mx:RemoteObject with id="myRemoteObject" and the destination="myRemoteClass".
    • In the second, the remoting-config.xml, define a destination with id="myRemoteClass" and the Java class package+classname in the source tag.
    • In the Flex Server properties (access through project properties), set the Root Context as the /YourProjectName.
    If you need to pass an object between client and the server, create two corresponding value objects (usually named *VO, like LoginVO), one in ActionScript in flex branch and one in Java branch:

    • The ActionScript version, needs to have an annotation above the class definition: [RemoteClass(alias=org.sjb.LoginVO)].
    • The Java version needs to be public and have public setters.
    If you want to debug not only Flex (which is done the usual "eclipse" way), stop the JBoss server and start it in Debug mode. That's all that is needed.

    Conclusion
    Altogether, using Flex with Java is very simple. Enjoy it!

    Wednesday, April 29, 2009

    How to Deploy a GWT Application to Tomcat?

    Intro
    OK, so you have tried the GWT (Google Web Toolkit), decided that it's cool, and you created your first application, precisely a module. You have tried it locally on your development machine, using the hosted mode and, may be, in the web mode by using the Compile/Browse button on the hosted-mode preview window. Now, you can either deploy it to Google App Engine, which is a way to try it online free and easily (make sure that your app doesn't become the IP of Google! I haven't looked at the terms of use myself.) or you decide yo want to go for it, and publish it for real. You purchase a Java hosting plan (google for it; you can find some within $12/mo.), and you're ready to deploy your application to your Tomcat server.

    Deploying It
    I used this re
    source to help me with. Basically, follow the steps ( is the root of your GWT application,):
    • create a staging folder (let's call it deploy)
    • copy contents of /www/com.meography.EntryScreen into /deploy
    • create /WEB-INF with folders classes and lib in it
    • create web.xml file in WEB-INF. See the above resource for how to.
    • copy contents of /bin folder to deploy/WEB-INF/classes
    • copy all needed jars into deploy/WEB-INF/lib (you don't need gwt-user.jar nor gwt-dev-windows.jar, though)
    • compress all of the conents of deploy folder into a zip file and rename the file to .war.
    • upload the file to Tomcat, which can be done via browser using Tomcat manager, which is usually already installed for you by your Java hosting vendor. Once the upload finishes, the manager will show your application with options to Start, Stop, Reload and Undeploy it. The name of the app, is the base URL for your app.
    Point your browser to the main .html file of the module (URL indicated by Tomcat manager + YourMainScreen.html). And, voila, you should be on. Well, if there are any problems, for example with your database setup, you'll find errors in the catalina.log file in the /tomcat/logs folder on your production server.

    Re-Deploying It
    To redeploy, after you have done some changes, simply repeat the steps above, but remember to preserve files you had to tweak or create for your production environment like web.xml and possibly hibernate.cfg.xml, if you happen to use Hibernate and use different database on your development machine and on your production server (Java hosting plan will usually have MySQL and PostgreSQL databases included). And, one more thing. I have found that I have to do Undeploy, upload the new .war file and then Deploy for the changes to post correctly. The reason may be, that GWT application is compiled into JavaScript cache files with random names, so the file names will be different each time you compile it, and so, just copying the new .war file over will not replace all of the old files.

    Any feedback? Feel free to let me know.

    Thursday, April 23, 2009

    Developing for Android Platform

    Why Android?
    I'm a Java developer. Yes, I could enhance my C/C++ skills, get an iPhone and develop for the iDevices. But, I guess, I wasn't motivated enough. Also, I'm a strong supported of open source development. So, first, I noticed OpenMoko platform. But their development slowed down and stopped. Never got to the point when I'd be able to get a phone and develop for it. Finally, I noticed the Google's Android initiative in late 2007. Yes, I'm afraid of humongous corporations like Micstosoft and now Google. Still, I didn't see a more attractive choice. So, I waited for Google to release the Android phone. I could switch to Windows Mobile platform, but this, somehow, didn't attract me. Finally, in Jan 2009, after living with Palm for good 7 years, and I'm a heavy user of the personal organizers (several years ago, I'd create my own notebooks/calendars, so they'd fit my needs; out of paper and cardboard; I did this for good 2-3 years), finally in Jan 2009, I decided it was time to do the move and I purchased a black G1 (for the picture and a story of my other organizers, see this blog).

    Does It Fulfill The Promise?
    In short, yes. Is it perfect? No. I can suggest several improvements of the top of my head, even just for hardware. And for software, too, of course. Would I recommend it? Definitely. Does it have a potential? Oh, yes, sure. This section could be a topic on its own, but, it will have to wait for another time. Let's move.

    So, to Cut To The Chase, How Do I Develop for Android
    Simple. The list of tools I use:
    • Eclipse (3.4.2)
    • JDK (1.6)
    • ADT (0.8.0) - great tool. Can even deploy to the device over USB and monitor the app.
    • Positron aka Autoandroid - for integration testing. Unit testing doesn't work that great for fat clients. This is a great tool except for a few hick-ups.
    • jUnit - for the pieces that can be unit testing without reaching to your left year with your right foot.
    Do you want more details, technical details? Sure. Here they're:

    Where can I find some sample Android applications?
    Well, one good sample is the Android platform itself. For example, to see the source code for the native Android calendar application, you can view it here.

    Deploying onto the Device:
    • an unsigned .apk file installs with a "Application installation unsuccessful"
    • log a application crash,,, where can I find it? The ADT displays LogCat.

    Using Positron aka Autoandroid:
    • If getting an error about Autoandroid "java.net.SocketException: Connection reset" problem, either:
      • rerun the Android Application and run stories again or
      • application crashed on Android
    • If you get error "Internal Error ... ShouldNotReachHere", do
      • go to the jUnit relevant run configuration, //Classpath// and remove the Android Library from Bootstrap.
      • do //Advanced//, //Add Library// and choose JRE System Library
      • add JUnit library the same way

    Tuesday, February 3, 2009

    To Refinance or Not To Refinance

    OK. Mortgage interest rates are falling. Everyone is refinancing or at least trying to do it to benefit from the lower rates. So, I did a research myself as well. There were three distinct ways to do it. I'm describing them below.

    No-Cost Refinancing Offer From My Current Mortgage Bank
    The WaMu offered to reduce my mortgage by 0.25%, for no cost. The savings looked fabulous (down to $500's from almost $1200 a month), but after I looked at it carefully, it was primarily because they calculated as if for a new 15-years loan, while on my current loan I have only 10 years left. The actual savings would be only about $40 a month.

    Best Deal I Was Able To Find on The Internet
    I did a search for the best rates. The website (don't remember which one), took me into a lender search instead of giving me a rate. When I clicked the button that said Get Your Rate, I've got a list of lenders instead, and after 5 minutes (yes! even though it was Saturday night, around 8pm), my phone rang and one of the lenders from the list wanted to talk to me. So, in a way it worked smoothly. The thing is, that the best deal the lender had was a rate lower by 0.75% for a closing cost of some $4500. And, no, it wasn't because of my credit score. Mine is over 800, and it was him who checked and told me the score.

    ING Direct EasyOrange Refinancing Deal
    This deal is about a 5 year loan based on a 30-year period. So, I'd have to payback the whole loan after 5 years. But that wouldn't be a problem in our situation. Anyway, they're giving a rate of 4.75%, which is pretty good right now, for closing costs of $1750 only. Seemed a great deal. Just to make sure it makes even sense to refinance if we don't plan to live in this house more than 2-3 years, I went to timevalue.com website and compared my current mortgage with th EasyOrange deal. The image below shows the results:

    It seems after all, that the EasyOrange doesn't save as any money after all.

    That was it. I guess, the no-cost 0.25% is the best deal after all. But it will lock me for a year at least. What is rates go down a lot within months?

    Tuesday, January 20, 2009

    Brief Visual History of PDA's

    Today, I had to stay home and take care of our youngest one for a couple of hours. He was very busy playing out the story of Joseph being almost killed and then sold by his loving brothers, that I decided to do some cleanup. Since my G1 phone is more or less setup, I decided to trash the older PDA I used to use and which I still kept in my drawer. I had a moment of nostalgia and so I ended up saving for some of my memories for the generations to come.

    Most of my adventure with PDA's is captured by the following picture:


    I have been using all these PDA's, including Treo 90, the most fun one, in addition to the cell phone. Finally, with G1, I have one device instead of two. I didn't stress it: I was actually carrying the two devices always with me, wherever I went. One in my pocket and another in a little holster. I got rid of the holster now, which made my wife happy. She never liked this extra decoration. And, besides the two functions being one fullfilled by a single gadget, I must say I enjoy the G1 a lot. It's appearance doesn't give it justice. Really.

    There is much more to say about this little brief history topic, but my time is limited while I want to have some left to play with extending WikiNotes app into a more fully developed wiki application. Yes, for G1, or I should rather say, for Android.

    Friday, January 2, 2009

    Search Web Services or API for Commercial Use

    Suppose, you need to collect some data based on Internet search for your business. What options are there to use existing web search services? Google? Yahoo? Anyone else? Here's what I have found.

    Google
    Here's what I have found:

    • Google SOAP search web services seem not to be available for new applications any more. In 2006, Google seems to have stopped issuing new API keys.
    • There is another option from Google: API not SOAP based. The terms don't exclude commercial use, but there is a restriction on caching the results of the search. I guess, if we process the results and store the processed data, it wouldn't be considered caching.
    • The API services have exclusivity requirement: you are not supposed to use on the same site any other search provider.
    Yahoo
    Here's what I have found:
    • Y! makes the search available via web services (REST but not SOAP webservices).
    • Each application has to use Application ID, which Y! issues for free. There is a rate limit for each application id.
    • Allowed usage: web search API is available to commercial use, however a form of exclusivity restraint is imposed: you are not supposed to integrate the results with results from other search providers.
    • Storage restrictions: "you may not store any user data collected through the Yahoo! APIs for more than 24 hours". Again, would storing the processed, for example aggregated data, be subject to this restriction? I suppose, not.
    MSDN: Live Search WebServices API
    Terms of use summary:
    • SOAP-based webservices call Silky Road.
    • No restrictions other than an application ID needed. But their license is more complex and I might have missed something.
    Other
    I'm sure there are/may be other search web services available, and some of them may be free. DoubleClick? I didn't analyze other options.