Thursday, December 27, 2007

This Blog Will Continue on TechPer.net

I have decided to stop blogging on this Blogger hosted service. My blog will continue on my own domain, www.techper.net. If you have subscribed to my feed through my TechPer FeedBurner URL, there will be no changes for you. In a short while, I will simply switch the feedburner datasource to that of the new domain, and you will get to read posts of the new blog.

I have decided not to try and copy or move any content from this blog onto the new domain. It stays here, where it is already indexed, bookmarked and discussed. Also, I will keep comments open and participate in any interesting discussions on old posts here.

The new site: www.techper.net

Thursday, November 29, 2007

10 Tips on JPA Domain Modelling

This post is a collection of tips on what I think is good advice, when domain modelling in Java with JPA as ORM mapping technology. Do you agree? Do you have extra advice? Please let me know!

Here they come, in no particular order.

1. Put Annotation on Methods, not Attributes
If using annotations on attributes, JPA engine will set directly in the attributes using reflection, hereby by-passing any code in setters and getters. This makes it hard to do extra work in setters and getters, if the need arises.

In addition, if you add a getter for some calculated value which has no corresponding attribute, you can mark it @Transient on the method. Had you been putting it on the attributes, you would have no attribute to put the annotation on.

Whatever you do: Try not to mix, using with annotations both on fields and methods. Some JPA providers cannot handle this!

2. Implement Serializable
The specification says you have to, but some JPA providers does not enforce this. Hibernate as JPA provider does not enforce this, but it can fail somewhere deep in its stomach with ClassCastException, if Serializable has not been implemented.

3. Use The Fine Grained Domain Modelling and Mapping Possibilities in JPA
If coming from EJBs (before EJB3), you are not used to be able to do fine grained modelling. EJB2.x was very entity centric. In JPA, you have @Embeddable and @Embedded. Doing more fine grained domain modelling can help make your domain model more expressive.

An @Embeddable is a value object, and as such, it shall be immutable. You do this by only putting getters and no (public) setters on its class. The identity of a value object is based on its state rather than its object id. This means, that the @Embeddable will have no @Id annotation.

As an example, given the domain class Person:
@Entity
public class Person implements Serializable {
...
private String address;

@Basic
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
We could express Address better, by giving it a class of its own. Not because it should be mapped to some other table, but because it makes sense in this particular model. Like this:
@Embeddable
public class Address implements Serializable {
...
private String houseNumber;
private String street;

@Transient
public String getHouseNumber() { return houseNumber; }

@Transient
public String getStreet() { return street; }

@Basic
public String getAddress() { return street + " " + houseNumber; }

// setter needed by JPA, but protected as value object is immutable to domain
protected void setAddress(String address) {
// do all the parsing and rule enforcement here
}
}

@Entity
public class Person implements Serializable {
...
private Address address;

@Embedded
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
}
The better expressiveness comes from: a) Putting a named class on a concept in the model and, b) having a place (the value object class) where to put domain logic and enforce domain rules.

4. Implement Equality using Real Domain Attribute Values
Classes marked @Entity will always have an id attribute. Often, this is a long sequence. It can be tempting to use this value when implementing equals and hashCode (which is also a requirement), but I recommend against it. I can find two good reasons: One based on modelling rules and one based on technical terms.
  • Modelling rule: A class modelled as an entity should be uniquely distinguishable from other instances, solely based on a combination of some of its domain attributes. A long sequence, used solely to obtain relational identification, does not constitute a domain attribute. If you are unable to find a unique combination, it might very well be a sign of a problem with the model.
  • Technical term: If equality is based on a database generated and assigned value, you will not be able to use equals and hashCode before an instance has been persisted. That includes putting the instance into container classes, as they rely on equals and hashCode.
5. Protect the Default Constructor
The JPA specification mandates a default constructor on mapped classes, but a default constructor seldom makes sense in modelling terms. With it, you would be able to construct an entity instance with no state. A constructor should always leave the instance created in a sane state. The requirement for the default constructor is only to make dynamic instantiation of instances of the class possible by the JPA provider.

Luckily, you can, and are allowed to, mark the default constructor as protected. Hibernate will even accept it as private, but that is not by the spec.

6. Protect Setter Method on Id Attribute
Basically the same story as above. In this case, it is just because it makes no sense for the application to assign an id.

NOTE: This is only for when the id attribute is marked as assignable by the provider.

7. Avoid Primitives when Mapping Id Attribute
Simply use Long and not long. This makes it possible to detect a not yet set value by testing for null. If using Java5 or above, auto-boxing should take away the pain.

8. Use the Basic Annotation to Override Defaults
By all means, use @Basic to override the default true value of optional to false, for those fields that are not actually optional (I often find that to be most of my attributes).

9. Go Ahead and Use the Column Annotation
Even if you are not interested in generating a schema or DDL from it, you should not hold back on using the @Column annotation. It tells the reader of the code about important information related to the attribute. This is stuff like nullability, length, scale and precision.

10. Do Not Use java.sql.Date/java.sql.Timestamp in Domain Model
Instead, use java.util.Date or java.util.Calendar. Using the types from the java.sql package is a leakage of concerns into the domain model, that we do not want, nor need.

Just remember to put @Temporal on date and calendar attributes.


Wednesday, November 28, 2007

Now You Can "Click" on a Newspaper Article

When google introduced printed ads in newspapers as part of the AdWords product some time ago, my first response was something in the lines of "what the f...". How can that be a good idea. I didn't give it much thought, and have also been unable to see the big idea there.

Well, until today, when I noticed googles Print Ads 2D Barcodes technology. The idea is to put a small 2D barcode next to the printed ad, in which a URL to a website is encoded. You can then take a snapshot of the barcode with your mobile phone, have software on the phone automatically decode the 2D barcode into the URL, and lastly open a web browser, again on the phone, taking you to the URL.

That is kind of cool, I think :-)

Of course, google has software to decode 2D barcodes, which runs on J2ME and of course Android.

But there are others too. Take a look at Nokia mobile codes, where you can create 2D codes and get scanner software for your phone. To the right is a 2D barcode of the URL to this blog. Sadly, I did not find any barcode scanner software ready for download to my Sony Ericsson W810i. Guess I will have to build zxing and run is on J2ME then.

Thursday, November 22, 2007

Why Override Annotation is Cool

Since Java5 which brought us annotations, Java has had the @Override annotation. But I don't see it used very often, so here I will try and explain why I find it valuable.

When you write a POJO like this:
public class Person {
private String name;

...

public String tostring() {
return "Person[" + name + "]";
}
}
Where the intention of the tostring() method was to override the Object#toString() method, you might be surprised when your method is not called. In this example, it was due to a simple case error ("tostring()" and not "toString()"), but in other scenarios, the error can be hidden somewhere else in a more complex method signature.

Had you been putting a @Override annotation on top of the method signature, you would have gotten a compiler error (or quite possibly already in the IDE). So the @Override annotation says that the annotated method must fulfill the contract of a method up in the class hierarchy. That is the valuable part of the override annotation :-)

Eclipse and IDEA
Last time I tried Eclipse, it played nice and automatically put the annotation on methods, when I used Eclipse keyboard shortcuts to introduce an override. This was on by default. It is not in IDEA :-( But is is very simple to add. Notice the little checkmark "Insert @Override" in the dialog that Ctrl-O opens? Check it, and it will be checked by default from here on.

C# Has It Built-In
The C# language of .Net has a override keyword as a part of language itself. In the C# language you are forced to use the keyword, which is okay by me, as I like it. What I really do not like then, is the virtual keyword of C#. I much better like that all methods are virtual in Java. But that is another story...

Speedlinking About Flex Libraries and Tools

Here is some collected information about the flex/as3 libraries I have seen out there:

Component Libraries
These are either AS3 utility libraries or flex UI component libraries.
  • as3corelib: Contains a bunch of useful stuff like MD5 and SHA hashing, VCard parsing, jpeg and png encoding, JSON support and utilities for working with arrays, dates, numbers, strings and xml. Seems to be Adobe contributed code.
  • flexlib: A lot of nice UI components and stuff, like the TreeGrid. Also with some Adobe contributions.
  • alivepdf: A way to produce pdf output via as3 code. Not sure where I would use that. Maybe if someone needed to off-load the server from the task. Maybe it is most useful in AIR applications and not so much in the more constrained flex sandbox.
  • actionscript3libraries: A nice list of others over at http://riaforge.org/.
  • tweener: Doing animations using code to move things instead of being forced into the flash timeline model.
  • flexvizgraphlib: A really interesting library with which you can do data visualization in flex

Frameworks
These are not simply libraries of functionality, but whole frameworks that tries to help you structure your complete flex application into something manageable. Mostly helpful when your flex application gets really large, I think. These are about application architecture.
  • Cairngorm: A MVC based framework. Done by Adobe themselves.
  • PureMVC: Another MVC based framework
  • Model-Glue: Well, yet another MVC based framework :-)
  • ARP: A pattern based framework.
  • Flest: Hmm, a MVC looking framework which claims not to be an MVC implementation
  • Foundry: Interesting in that in includes a Java/server-side part, which claims to aid in FDS server development. Not important for dudes like me, which try to avoid FDS, though.
Testing
Some libraries that aid in automatic testing of your flex applications.
  • flexunit: JUnit based API. Not dependent on payware.
  • funfx: Write your tests in the nice ruby language. Uses the automation package of FDS to remote control the application when doing automatic testing, which leads to the need of a license on FDS (payware).
Tools
Do you know of other tools, libs or the like, please let me know. I would like to know!

Wednesday, November 21, 2007

How Nicely Decoupled a Web Client Flex Is

Flex got to be the most decoupled web client I have ever worked with!

Back half a year ago, I blogged about choosing a RIA framework, which I found hard. At that time, we ended up with Flex2 as our choice, and the next couple of months it would have to prove its value. And I most certainly must say that it has! I just wanted to share what our experience have been so far.

Editing and Building
It has proved to be real nice to work with. We are simply using the free SDK, combined with the maven israfil plugin for building and IDEA for editing. With IDEA7, there is pretty good JavaScript (and hereby ActionScript) support combined with some (not much, yet) Flex support.

Flex Framework
The framework itself has shown to be powerful enough for our needs, and I suspect it also will be for the needs of most people. There are quite a few UI components available, including a powerful DataGrid. And the upcoming Flex3 will have even more. Also, the extension possibilities have proved to be good.

The documentation is quite good, and where it lacks or in situations of bugs in the framework, it has come in handy to have the open source code at hand. Sadly, not all of it is open. Missing are stuff like the remote stack (web service calls) and of course all in the flash.* packages.

And there are already flex/as3 component libraries out there, like flexlib on google code and a bunch here, linked to from riaforge.

Sooo Decoupled
Propably, the thing that have stricken me the most about working with flex (or flash) as a platform for applications on the net, has been how decoupled from the server development it can be. And I find that a good thing.

As an example, take the whole build, assemble, deploy and test cycle.

With a technology stack where the web front is using a server-side html/js generation framework, you most often build, assemble and deploy that together with all of the other parts and layers of the application. First then, you test.

With flex, you can compile and try out the UI web front completely by itself. When I work on UI related stuff, I simply compile the flex part and launch the standalone player to try it out. That is a 15 sec. build cycle at most. At the same time, I have my web services up and running in the back all the time, so the standalone player is actually playing up against the server side, as it will be when the flash is being served from a web application to a browser.

Testability
At the time where we chose flex, we had an open issue on how to test it. I regret to say, that this is still an open issue :-( The best bet right now seems to be flexunit, but we have postponed it a bit, as it seems hard to integrate nicely into a headless, continuous integration build. For a short while I thought I was going to use funfx and write my tests in Ruby, but that was only until I found out it required a FDS license.

Bottom Line
Bottom line is, that it is simply nice to work with, and I am loving it!
Recommendable!

Forcing Error Pop-Up on a Flex Control without a Validator

In my previous post about ToolTipManager and its delays, I showed how error pop-ups from ToolTipManager looks like. I'll repeat the image here:


This pop-up is normally a result of a validator. But actually, you can, in a very simple way, force such a pop-up to appear quite easily. You simply assign the errorString property on a flex component to a non-empty string. Like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
<![CDATA[
private function setError() : void {
data.errorString = "this is an error popup";
}

private function clearError() : void {
data.errorString = "";
}
]]>
</mx:Script>

<mx:TextInput id="data" text="Enter data here"/>

<mx:Button label="Set error" click="setError()"/>
<mx:Button label="Clear error" click="clearError()"/>
</mx:Application>

That was easy! The errorString property is defined on UIComponent, so it is quite universally available on the UI components of the flex framework.

ToolTipManager.scrubDelay and Hanging ToolTips in Flex

When I use validators on input controls in flex, the flex framework marks fields in error with a red border and a nice little red pop-up with a message when the mouse is moved over the component. Like this:


But sometimes, I experience that the pop-up with the error keeps hanging, even though I move the mouse out of the field in error. This led me to look for the code that performs the pop-up, and found it in ToolTipManager. This interface has three delay values that you can control:
The showDelay is simply millis from the mouse enters the field until the tooltip pop-up comes up. The hideDelay, is how long time the pop-up stays open, while the mouse is in the field. The default is 10 seconds, so if you keep the mouse over a field in error in more than 10 seconds, the pop-up will dissappear. Okay, sane enough.

Now we come to scrubDelay. From the documentation, it was a bit hard to understand (at least for me):

The amount of time, in milliseconds, that a user can take when moving the mouse between controls before Flex again waits for the duration of showDelay to display a ToolTip.

This setting is useful if the user moves quickly from one control to another; after displaying the first ToolTip, Flex will display the others immediately rather than waiting. The shorter the setting for scrubDelay, the more likely that the user must wait for an amount of time specified by showDelay in order to see the next ToolTip. A good use of this property is if you have several buttons on a toolbar, and the user will quickly scan across them to see brief descriptions of their functionality.

The first paragraph, I did not get! The second paragraph though, made me think this could be the source of my trouble. So I grabbed the source, and found out what it did. Here is my explanation:
  • When mouseOverIn or mouseOverOut handlers are called in ToolTipManagerImpl, it is checked if the mouse is over a new target component.
  • If so, the targetChangedMethod is called. This method erases any existing pop-up from another component and pop-ups a new tool-tip for the new target component.
  • BUT: If the scrubTimer is NOT running, there will be a showDelay pause. If the scrubTimer IS running, it will pop-up the new tool-tip immidiately.
I tried setting the scrubDelay larger, and it seemed to make my problem with hanging pop-ups disappear. Great, ... though I am not quite sure exactly why :-(

Sunday, November 18, 2007

Maven and Excluding Transitive Dependencies

Warning, this is just another maven rant...

Why has someone concluded, that we do not need to exclude all transitive dependencies of some dependency?

More than once have I had the need to grab a dependency, but then exclude all or a lot by wildcard, of the incoming transitive dependencies. I cannot even exclude all artifacts from a group of transitive dependencies, without explicitly mentioning each and every of the transitive dependencies that I wont need.

If I do:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security</artifactId>
<version>1.0.4</version>
</dependency>
And I do not want all the spring stuff, it comes with, I cannot write:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security</artifactId>
<version>1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
or something like it. No no, I will have to do:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security</artifactId>
<version>1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-remoting</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
</exclusion>
</exclusions>
</dependency>
Or am I missing how to do this? Please correct me if I am wrong!

IDEA Seems to have Built-In Knowledge about JUnit API

Hmm, I have always liked IDEAs all-time present analysis of my AST when typing, which for instance can give me a warning, if some variable could be null when referenced. I think IDEA analyzes the possible execution paths of the code, and then determines if some variable might be null in a place where it is referenced. The other day I noticed, that IDEA must have built-in knowledge about JUnit, because it seems to use the contract of assertNotNull, in its analysis of nullable variables.

In this little example (JUnit) testcase:
public class TestBlahBlah extends TestCase {
public void testBlah() {
String s = null;
System.out.println("s.length() = " + s.length());
}
}
IDEA promptly warns me about the expression s.length() might produce NullPointerException, and indeed, it will. But, if I add an assertNotNull(s), so that the test looks like this instead:
    ...
public void testBlah() {
String s = null;
assertNotNull(s);
System.out.println("s.length() = " + s.length());
}
The warnings goes away. Nice! And it is not just because the variable has been used to something else in between. If I add assertEquals(s, s) in place of assertNotNull, the warning pops up again.

Just one of the little niceties of a great IDE!

Getting started with Pattern and Matcher from java.util.regex

Since Java 1.4, we have had pattern matching in the java.util.regex package. This package has lots of power as a consequence of the power of regular expressions, but it does not have the most intuitive interface (in my opinion). In addition, the javadocs are very formal, with little overall "how to use it" examples on the class docs. So, here is a small "getting started with java.util.regex package".

Example: Matching and Looping over Result
     import java.util.regex.Matcher;
import java.util.regex.Pattern;

...

String regex = "Foo";
String input = "FooBarFooBar";

Pattern compiledPattern = Pattern.compile(regex);
Matcher matcher = compiledPattern.matcher(input);

while (matcher.find()) {
String matchedSubString = input.substring(matcher.start(), matcher.end());
System.out.println(String.format("Matched '%s'", matchedSubString));
}
First, we compile the regular expression with this line "Pattern compiledPattern = Pattern.compile(regex)". Then, we match it against an input string, to get a Matcher object, with this line "Matcher matcher = compiledPattern.matcher(input)". The matcher can then be used to go matching against the input, match by match. This is what we do in the loop:
     while (matcher.find()) {
String matchedSubString = input.substring(matcher.start(), matcher.end());
System.out.println(String.format("Matched '%s'", matchedSubString));
}

the find() method on the matcher instance goes looking for the next matched substring in the input and returns true, if found. After a find() call which returned true, you can use matcher.start() and matcher.end(), as substring indices into the input string, to get the string, that was matched.

There is more in the regex package, amongst other is regular expression grouping and replacement functionality. But this should get you easily started.

Monday, November 12, 2007

How To Access Session from a JAX-WS Web Service Implementation

Today, I had the need to take a peek into the HttpSession from inside a JAX-WS webservice implementation class. Normally, such an implementation has no access to the servlet API, and generally, I believe that is how it should be.

Anyway, I had the need, so this is how to do it:
import javax.annotation.Resource;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.jws.WebService;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;

@WebService(serviceName = "FooService")
public class FooImpl implements Foo {

@Resource
private WebServiceContext wsContext;

public void wsOperation() {
MessageContext msgContext = wsContext.getMessageContext();
HttpServletRequest request = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
HttpSession session = request.getSession();
// work with the session here ...
}
}
When the JAX-WS stack implementation you are running your web services on is deploying your web service endpoint, it will inject an instance of WebServiceContext into the impl instance. You can then ask it for a MessageContext, and from this get the request, session, response etc.

Beware though. By doing this, you are binding your implementation to knowledge about which transport mechanism, it is deployed on and accessed through. It could be something else than HTTP. On the other hand, I guess 99.9999% of all web service implementations are deployed on HTTP :-)

I have this working with CXF in version 2.0.1-incubator. The WebServiceContext class is only since JAX-WS 2.0 and the @Resource annotation is only from JEE5 and on.

Thursday, November 08, 2007

AVM2 vs JVM and ActionScript3 Performance

AVM2 is Adobes virtual machine in Flash Player 9, that executes ActionScript3 (AS3) bytecode. If you are accustomed to writing code for the great JVM and are starting to write Flex or AIR applications, there are things you should be aware of.

In this blog, I present information on how the AVM2 works, and also show some tips on how to make your code perform better on AVM2.

Most of the information in this blog should be credited to Gary Grossman from Adobe. I found a (great) presentation with his name on it, entitled "ActionScript 3.0 and AVM2: Performance Tuning". I was mostly interested in the AVM2 part, and luckily, the 74 pages of the presentation had quite a bit of information on that subject.

Types and Type Information
Prior to AS3, all type information was stripped out of the code when compiled. At runtime, everything was just dynamically typed atoms. Starting with AS3, when can get the type information all the way down to the runtime.

Another point in the introduction of the native int and uint types, which can make code perform better.

Here is how to take advantage of this great new stuff:

First of all, start working with typed variable. That is, do this:
var document : XML = ....;
and not this:
var document = ...;
var document : Object = ...;
var document : * = ...;
Using explicitly typed variables can improve performance and reduce memory consumption. As a little side note, going from untyped, or dynamically typed to the explicit type information, enables the compiler to catch more errors early on in the development cycle, but that is another story :-)

Another advice is to use the native int and uint types where possible, instead of using the Number object type. But beware, as compliance with ECMAScript requires the VM to promote basic int types to Number sometimes. For example in this code:
var i:int=1;
methodCall(i + 42); // will promote to Number
If you know, that it will be within an int type, you can help the compiler by introducing a coercion like this: methodCall(int(i+42)).

Also, array index with int and uint types have fast paths when compared to Number, so consider coercion of array indexing too.

Common Subexpression Elimination (CSE)
When writing Java code, I am accustomed to not thinking that much about common subexpressions in loops etc. I let the compiler and the VM handle all that optimization. It is pretty good at it, and me trying to help it might very well destroy its possibilities of doing it well.

AVM2 can do CSE too, but not as good. For instance, in this simple code:
for (var i:int=0; i < arr.length; i++) {
callMethod(arr[i]);
}
the arr.length expression is evaluated on each iteration of the loop. This is due to the fact, that it might have sideeffects or be dynamically overridden. So, do this:
var len:int=arr.length;
for (var i:int=0; i<len;i++) {
callMethod(arr[i]);
}

Method Closures
In AS3, we got method closures, which also mean we can create variables that are functions, and pass them around, while the function still retains the environment, it was created within ("this" is still what "this" was, when defined).

If you write code like this, with inner, anonymous function closures:
function foo() : void {
var handler : Function = function(event:Event) : void {
// blah blah
}

addEventListener("someEvent", handler);
}
The definition of the handler variable, will force a creation of an "Activation" object, that is to hold the environment state, at time of creation. You can get better performance and memory utilization by doing it this way:
function handler(event:Event) : void {
// blah blah
}

function foo() : void {
addEventListener("someEvent", handler);
}
as this will utilize the method closure functionality of the AVM2, but without an activation object.

JIT Compilation and Constructors
Now that flash player is a stackbased, byte-code oriented virtual machine, it is natural for it to have JIT compilation. And so it has. I think it is far from the JVM hotspot and compiler, but we must also recognize, that flash player clearly has another target. But the objectives of the JIT compiler are good, I think. They are:
  • Fast compile times
  • Limited passes
  • Cautious with memory
The fact that AVM2 does JIT compilation might also be why there is no 64bit version of the player as of yet. Doing JIT requires extra work for each CPU to target. AVM2 does have a MIR format (Macromedia Intermediate Representation), which is uses on its way from byte-code to JIT'ed machine code. The responsibility of the MIR is to abstract commonalities between CPUs, but it must still be extra work again and again for each architecture, when doing JIT.

There is one thing to take notice of with JIT in AVM2. Constructors are not JIT'ed, so if you have performance intensive code in a class, take it out of the constructor.

Garbage Collection
The memory management and garbage collector is to be found in the separate MMgc project. This is a Deferred Reference Counting (DRC) mechanism combined with an incremental, conservative mark/sweep collector. Of course, the garbage collector implementation has been tuned for best client performance, with small (30ms) time slices.

Overall, I find the new flashplayer architecture much nicer, than I have previously thought of it. I guess it has also come a long way, suddenly growing up to serve us real, complex applications on the web. This all actually gives me more peace in mind, with respect to the flex applications we are building. Large applications on the flex platform will have a hard time succeeding, if their executing runtime (the AVM2) is not up for the task of running real applications.

I am confident that it is!

Monday, November 05, 2007

Comparator or Comparable and more than one Ordering Implementation

To impose ordering on Java objects, you can either implement Comparable or Comparator. Which one to choose? Well, here is my five cents on the issue. When comparing the two approaches, I will use this little simple Java class:
public class Task {
private Integer priority;
private String description;

public Task(Integer priority, String description) {
this.priority = priority;
this.description = description;
}

public String toString() {
return String.format("Task[%d,%s]", priority, description);
}
}

Comparable
Is implemented to express what the docs mention as the implementing class' natural ordering. It is implemented on the class, that is to be ordered, and as such, it can only provide one single ordering implementation. In the example above, I will have to choose, if I want to order on priority or on description. A sample implementation could be like this:
public class Task implements Comparable<Task> {
...

public int compareTo(Task o) {
return priority.compareTo(o.priority);
}

...
}

which compares on priority and only on priority. I can then sort instances in a List like this:
        List<Task> listOfTasks = new ArrayList<Task>() {{
add(new Task(1, "Shop For Christmas Gifts"));
add(new Task(2, "Bring World Peace"));
add(new Task(3, "Make Love, Not War"));
}};

Collections.sort(listOfTasks);

Nice and easy, but I often go with the other implementation (Comparator), as it gives me the freedom to provide more than one implementation. Here is how:

Comparator
Where Comparable was for one single, natural ordering, an implementation of Comparator represents a total ordering of instances of a class. You can provide more than one implementation of Comparator, and then choose when sorting, which one you want to sort on.

I often go for a design, where I put the Comparator implementations as public static classes on the class, that they are implemented to sort on. Like this:
public class Task {
...

public static class ByPriorityComparator implements Comparator<Task> {
public int compare(Task t1, Task t2) {
return t1.priority.compareTo(t2.priority);
}
}

public static class ByDescriptionComparator implements Comparator<Task> {
public int compare(Task t1, Task t2) {
return t1.description.compareTo(t2.description);
}
}

...
}

I can then sort instances in a List like this:
        List<Task> listOfTasks = new ArrayList<Task>() {{
add(new Task(1, "Shop For Christmas Gifts"));
add(new Task(2, "Bring World Peace"));
add(new Task(3, "Make Love, Not War"));
}};

Collections.sort(listOfTasks, new ByPriorityComparator());

// or...

Collections.sort(listOfTasks, new ByDescriptionComparator());

Using SQL Templates in IDEA SQL Query Plugin

If you are like me, a regular user of IDEA, you might also have the excellent SQL Query Plugin installed and use it daily. But you might not have noticed the little neat templates feature, that it has. It can save you a great deal of typing.

When the SQL Query Plugin pane is open, click its settings icon and choose the templates tab. See the picture below:

Say you have a table called "user", which have a column "username". If you find yourself querying this table on "username" again and again, you might create this template:

SELECT * FROM user WHERE username='$param1'

And name it something short, like "seluser" (short for "select user"). In the query editor area, where you normally write your queries, you simply type:

@seluser admin

And hit execute query (Ctrl-Enter), and it will execute your template, but with "admin" replaced into $param1. Of course, templates can have many parameters, and they are given as a comma-separated list when executing it.

Simple and easy. The example query above is very simple, and the queries you create templates for should be more complex for any real benefit to be harvested. I have one in my current project, where I need to join two tables on four (4) different columns, two get an equi-join. A template can safe me typing there.

One idea that just popped into my head, was if SQL Query Plugin could come with some pre-written templates, that matched the JDBC driver of the current connection. Like a bunch of queries to query into the valuable v$xxx data dictionary of Oracle bases. Just a thought.

Friday, November 02, 2007

Coping with Flex Asynchronous Remote Calls - Part III

The fact that flex web service calls are asynchronous have implications on how you design your code. This part III of my series of posts on the subject, which shows how to handle concurrent, asynchronous calls to the same web service method.

In part II of this post series, I showed how to use callbacks to handle the asynchronity of the calls. But the solution presented there, does not handle concurrent calls to the same web service method. To handle concurrent calls, you need to use the call object itself, and assign tokens on it. In the solution I show here, I set the callback as the token.
package com.blogspot.techpolesen {

import mx.rpc.soap.WebService;
import mx.rpc.events.ResultEvent;

public class RemoteService {
private var remoteService : WebService = new WebService();

function RemoteService() : void {
remoteService = new WebService();
remoteService.wsdl = "/services/RemoteService?wsdl";
remoteService.loadWSDL();
remoteService.addEventListener(ResultEvent.RESULT, handleNextInSequenceResult);
}

public function callNextInSequence(parameterPassedToServer : String, callback : Function) : void {
var call : Object = remoteService.nextInSequence.send(parameterPassedToServer);
call.callbackFunction = callback;
}

private function handleNextInSequenceResult(event : ResultEvent) : void {
var token : Object = event.token;
token.callbackFunction(event.result);
}
}
}
Heres is a bit of explanation on the above code:
  • The as3 class above is a wrapper around the remote web service calls.
  • The constructor instantiates the web service client object, parses the wsdl and adds a listener for the result event
  • The callNextInSequence method is the one, that can call my remote web service method (called nextInSequence, which accepts a string and appends a sequence number after it and returns it)
  • IMPORTANT: Note how the callNextInSequence method, uses the send() method of the operation instance to call the web service. The return value of send() is a call object, on which you can put tokens.
  • Tokens, which are put on a call, will appear on the result event, when the result of that particular remote call returns with a result.
  • In this implementation, I use the token to remember who I need to callback on, with the result of the call.
  • Left is only to explain the handleNextInSequenceResult listener, which is quite simple. It simply obtains the token from the event (which is the function callback) and calls it with the result of the remote call.
Here is Main.mxml content, which uses this class:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import com.blogspot.techpolesen.RemoteService;

private var remoteServiceProxy : RemoteService = new RemoteService();

private function callItConcurrently() : void {
results.text = ""; // clear result area

// do some concurrent, asynchronous calls
remoteServiceProxy.callNextInSequence("value 1", handleResult);
remoteServiceProxy.callNextInSequence("value 2", handleResult);
remoteServiceProxy.callNextInSequence("value 3", handleResult);
}

private function handleResult(result : String) : void {
results.text += "Result: result = " + result + "\n";
}
]]>
</mx:Script>

<mx:Button label="Do concurrent, asynchronous remote calls" click="callItConcurrently()"/>
<mx:TextArea id="results" width="80%" height="50%"/>
</mx:Application>

Downloading the source
I have zipped up the sources for you. It can be downloaded from here. Ready to be build with maven.

This is a multi-module maven build. There are two directories:
  • client : Contains the flex source and a pom to build it
  • server : Contains the web service and a pom to build it
The war artifact output from the server module have in it the flash output from the client module and a index.html which loads it.

To start the server after a build, you simply jump into the server directory and do a "mvn jetty:run-exploded".

Other Small Flex Tutorials
This was lesson 9 in my series of posts on what I learn about developing filthy rich flash apps using flex2. If you want to read more, the previous lessons can be found here:

Wednesday, October 31, 2007

Logging WebService Methods Called in Axis using a Handler

When you look in the access log of a server hosting web services, you are unable to see which web service methods, that are actually called. This is due to the fact that SOAP requests are HTTP POST requests, where the method called is a function of the SOAP message posted.

If you are using axis, there is a simple way to log which methods that are called. This can be done by implementing a handler and configure it into the chain of handlers, that axis executes on each request.

Here is the handler:
package com.blogspot.techpolesen.webservice.util;

import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.log4j.Logger;

public class LogMethodCalledAxisHandler extends BasicHandler {
private static final Logger LOG = Logger.getLogger("com.blogspot.techpolesen.webservice.util.LogMethodCalledAxisHandler");

public void invoke(MessageContext msgContext) throws AxisFault {
Handler serviceHandler = msgContext.getService();
String serviceName = serviceHandler == null ? null : serviceHandler.getName();
String methodName = msgContext.getOperation().getMethod().getName();
LOG.info("SOAP Method called: [" + methodName + "] in [" + serviceName + "]");
}
}
You then package this class in your war and put this into your axis deployment wsdd file:
<requestFlow>
<handler type="java:com.blogspot.techpolesen.webservice.util.LogMethodCalledAxisHandler"/>
</requestFlow>
This will make axis call this handler as part of the chain of handlers called for each SOAP request. In my implementation I simply log service name and method called using log4j.

BTW: This post was done with axis1 as the basis. In axis2, the handler concept has shifted a bit into modules and deployment is also done differently than the wsdd.

Project Planning with OpenProj

Some time ago I stumpled upon OpenProj, an open source, free project planning tool like Microsoft Project. Recently, I took it for a ride, just to see what it can do. And I must say, that it looks really complete and nice. So, if you are into gantt chart control and like to avoid M$, I think you should give OpenProj a try.

Monday, October 29, 2007

Flex Trace and Logging

Here is a bit of collected information about how to trace and log in flex.

Flex Tracing
This is easy. There is a global trace() function, which you can call from anywhere. The output from trace calls only appears when the flash applikation in run on either the debugger version of the flash player or the debugger version of the standalone player.

There are two options for getting at the output: Either through the flex debugger or by having it go into a file. Of the two, I have found the latter the most useful.

Flex trace into a file
In your home directory, you put a file called mm.cfg, which contains the following three lines:
ErrorReportingEnable=1
TraceOutputFileEnable=1
MaxWarnings=1
And when you run your flash application on a debug player, the flash runtime will open and write to a file at this path: "$HOME/.macromedia/Flash_Player/Logs/flashlog.txt". You can then "tail -f" this file and see all the trace.

Flex trace through debugger
Well, you start the fdb debugger binary and type run. After this, you start your flash application in a debugger version of a player and connects to the debugger through the dialog that opens. You then switch back to the fdb console and type continue (twice). Trace will then flow out on the fdb console.

Only problem is, that on linux, the fdb console disconnects at random intervals (or, most often, just before you reach the trace information you are interested in).

Flex trace in the FlashTracer firefox plugin
Firefox has a nice plugin called FlashTracer, which can show the contents of the trace file enabled with the mm.cfg file. This is really nice, as you need not tail the file and can view the output along the application.

If you are running linux, you need a special built version. Alessandro Crugnola has a nice blog entry about how to install the linux built version of FlashTracer.

Flex Logging
While you use tracing mostly for debugging purposes, logging can be done on several levels and hence be used for more sophisticated purposes. There is a complete mx.logging package in flex2, which provides the main logging functionality of flex.

Two central abstractions here are ILogger which abstracts something that you can log to and ILoggingTarget, which abstracts something that can accept logs and do something with them. When logging to an ILogger, you can do it as debug, info, warn, error or fatal. In addition, an ILogger has a category, which is a hierarchic name. A log target can have filters on which categories they "let through", and a level setting, that specifies which of the five debug, info, warn, error and fatal levels that it "let through".

In the mx.logging.targets package, there are two (very) simple logging targets implemented. One which goes to trace output, and one old, deprecated minidebug-based one, which should never have been in the public flex2 api.

Good thing is, that you can implement your own log targets. I have written an example on how to send logs to the server from a flex application using a log target implementation, which might be helpful.

Friday, October 26, 2007

Keeping Mongrel Alive when it Keeps Crashing

For some time, I have had a problem with a rails deployment of mine. It is running apache in front of several mongrel instances. Problem is, the mongrel processes simply disappear, without a trace. Their pid files are still lying around. The log shows nothing. There appears to be no system in it. There can be weeks between and there can be days between. It can happen in the night and it can happen at daytime. Sucks.

Today, I sat down and wrote a simple bash shell script, which performs some basic surveillance and a restart, if mongrel processes disappear. Would be more nice for them not to crash, I know.

If you have the same problem, I here give you my quick and simple script. It even notifies by email when a restart has been performed. Of course, comments on improvements are more than welcome.
#!/bin/bash

SLEEP_INTERVAL=60
PID_DIR=/var/opt/rails/yourapp/log
CLUSTER_CTL_CMD=/etc/init.d/mongrel_cluster_ctl
NOTIFY_EMAIL=youremail@goes.here

if [ $USER != "root" ]; then
echo "I need to be run as root. From here on, I will quickly grow cold."
exit 1
fi

# Act a bit like a daemon, by ignoring HUP and
# being nice and releasing yourself to / in case someone needs to
# unmount where you were started.
#
trap 1
cd /

function restart_mongrels() {
echo "stopping..."
$CLUSTER_CTL_CMD stop
echo "stopped, will sleep 10 secs"
sleep 10
echo "done sleeping, will remove any old pid files and start mongrels"
rm -f $PID_DIR/mongrel.*.pid
$CLUSTER_CTL_CMD start
echo "issued start, will wait 10 secs more, to let it fire up properly"
sleep 10
mail -s "Mongrels restarted" $NOTIFY_EMAIL <<ENDMAIL
At `date` your mongrel instanses were restarted.
Have a blast digging around in the logfiles trying to find out why...
.
ENDMAIL
}

while (true); do
# start by checking, that there are ANY pidfiles around
ls $PID_DIR/mongrel.*.pid > /dev/null 2>&1
ANY_PID_FILES=$?
if [ $ANY_PID_FILES -ne 0 ]; then
echo "`date`: oops, found no pid files at all in $PID_DIR, going for a restart"
restart_mongrels
fi

# if there are pidfiles, check that their processes are running
for pidfile in $PID_DIR/mongrel.*.pid ; do
# check that pidfile is still here (as in, we remove them all deeper in this for-loop, if mongrels are down)
if [ ! -f $pidfile ]; then
echo "skipping missing pid file: $pidfile (can happen after a restart)"
continue
fi

PID=`cat $pidfile`
ps -p$PID > /dev/null
PID_CHECK_RESULT=$?
if [ $PID_CHECK_RESULT -ne 0 ]; then
echo "`date`: Oops, did not find process for pid $PID in pid file $pidfile, will restart mongrels"
restart_mongrels
fi
done
echo "`date`: Checked all mongrel instances are up an running, will sleep for $SLEEP_INTERVAL seconds and check again...Zzzz"
sleep $SLEEP_INTERVAL
done

Wednesday, October 17, 2007

Cool ActiveRecord Completion Support

Previously I have complained about Rails and how the attributes of a model aren't properly visible on the model as such (because they are automatically added at runtime by matching it to its table). The only way for me to get a complete picture of a model, is to look both into the migrations that work on the table of the model and into the model itself, and then combine these views.

Well, seems like others had the same trouble but did something about it. Tor Norbye show some screenshots of the latest new Netbeans support for ActiveRecord completion here, which actually does this. Netbeans is looking into the migrations and into the model, and then supports code completion in the IDE with all the information it collects. Supposedly it does not stop at the migration that creates a table, but also recognizes later migrations that change the schema. Things like rename of columns.

Cool! Simply cool!

Monday, October 15, 2007

Blog Action Day: City Bikes in Copenhagen Denmark

Today is Blog Action Day 2007 about environment, and this is my contribution.

I live in Denmark in the city of Copenhagen, and I would like to put emphazis on something simple that can be done for the environment. Here, we have city bikes, which are bikes you can grab and use to get around, without any expense. It works like a shopping cart. You put in a coin to get the cart out of its holder, and get the coin back, when you replace the bike in another holder somewhere in the city. Nice and easy!

What this can do for the environment is not so much the lesser use of cars to get around, but what else it brings. Like the fact, that there is emphazis on making it more easy to get around in Copenhagen on bikes. Something that is good for all bikers, and which might bring more bikers and less cars around.

So, why not start this up in your city?

Wednesday, October 03, 2007

No Project-Level Encoding in IDEA 7

In short: If you would like to be able to set a charset encoding for your sources at the project level in IDEA, I urge you to vote for this jira issue at JetBrains.

Some time ago I wrote and released the encoding-plugin for IDEA to let you set a project encoding that is then checked against the IDE-level setting.

This plugin was a response to the old issue on the need for a real project level charset encoding in IDEA, and with the relese of my plugin, a new debate was spawned on the jira issue at JetBrains. Suddenly, someone discussed it and JetBrains seemed to take notice.

Well, the other day I received a mail notice from the jira instance at JetBrains, telling me, that the issue have been moved to be fixed in "Next IDEA Version" (which is the one after v7). Dammit!

Tuesday, October 02, 2007

10 Areas Where Rails Fails

Having done both some real world Rails development and a lot of real world Java development, I have accumulated some experience, that I would like to share. In particular about where rails fails to deliver for me.

I should start by saying, that I like Rails on a lot of areas. But we also know, that all technologies and tools have a flip side, which we come to know about only by using it for some time.

Let us jump right in...

1. Domain Modelling
A lot of the domain objects (though, by all means not all) of the domain model will come from representations of relational database tables. In Rails, these need to inherit ActiveRecord::Base, which is definitely polluting the domain model.

But what about behaviour only domain objects? One example is reporting queries and how to model them. Say I need to select some of the attributes of two joined tables Foo and Bar. One way to do it is to add a static finder method on one of them, say Foo (which one can be hard to choose). The finder will then return instances of the class chosen, Foo, but with a "nice" collection of attributes from the two different class types. Rails marks the instance as "readonly", but it really sucks. The model instance simple gets the attributes you select, even though they do not belong on the type. These are incomplete instances and not all domain logic will work on the model instance.

Actually, a lot seems to be hooked up on inheriting ActiveRecord::Base. There is no real is-a relation here between ActiveRecord::Base and the domain object.

2. Transaction Demarcation in Code
I knew this before entering Rails and I have come to hate it. You need to demarcate your transactions yourself in code. It is really not that nice.

3. Deployment
This is totally not as easy and clean as with Java. The sole existence (and need of) of a tool like Capistrano says it all. I have previously blogged about Rails deployment compared to Java and I think that post says it all.

4. Tool Support
Aahh, a much debated subject :-) I for one, can and have worked without nice tools, auto-completion and the like. But, I have also come to love what IDEA can do for me, when coding Java. This includes refactoring, auto-completion, documentation popup etc.

Now, this has changed a lot lately with tools like the IDEA Ruby plugin and NetBeans Ruby and Rails support. But still, there are stuff that is next to impossible to do, simply due to the dynamic nature of the Ruby language and the extensive use of these dynamic features in the Rails framework.

What makes NetBeans and IDEA plugins usable for more than syntax highlightning when doing Rails development is the fact, that they are targeting the Rails framework specificly. Not only the Ruby language.

5. Internationalization
It is not there. It is as simple as that. There are hacks and stuff out there, but in practise, it is missing from the framework.

6. Attributes of ActiveRecord models "Invisible"
Due to the dynamic nature of Rails, the attributes of ActiveRecord models are added dynamically by ActiveRecord, using a lookup of attributes on the database table. At first a nice thing with respect to speed in development. In the long term, I have found it irritating at best. I need to combine a view of a migration that created the table together with the model, to get the full picture. And even then, I am missing migrations that have added or changed the table.

And I am violating the DRY principle, when I am writing stuff like max length on a column and not null constraints in the migrations, but also needs to write the same in validations on the model.

7. Validations outside ActiveRecord
All the nice validations like validates_length_of or validates_uniqueness_of are tied to ActiveRecord. There are solutions out there to reuse this code in other classes, but it seems like a design error from the beginning.

8. Migrations Become a Pain
Talking about migrations. It quickly becomes unfeasible to use migrations to add extra columns or change an existing model. Often, migrations use the model classes to change the data as the schema changes. But, when running all migrations on a clean database, it is done using the latest and greatest version of the model. Not the version of the model when the migration was originally written.

9. Polluted APIs
Rails adds helper methods on various API classes which pollutes the APIs. But I suspect the Ruby APIs themselves to be quite polluted themselves. Try doing a "Date.methods" in the rails console: What the f*** are all those doing on Date? :-) If you could do completion in the IDE, you wouldn't be able to find the tree for the forrest

10. Documentation
The Rails framework documentation is spread all over the apidocs, which is not that good with respect to browsing it. I have found some cookbooks, wikis and other stuff, but there is a real lack of a good users manual and/or wiki controlled by some entity that can keep it together and updated.

So What Then?
Despite the above rants, I do like Rails. And I would also recommend it or use it myself, on some specific type of projects. These are the simple, CRUD-like ones with only a small amount of domain logic and complexity.

What I would love to do next time I startup a completely new project, is to base it on Java technologies this time, but choose them for what they have learnt from Rails. One example could be Tapestry5. Another could be Grails with GORM, but that might be too dynamic, hence experiencing the same problems. And then see how productivity is, while still retaining some of the Java goodies, like nice tool support, static checking, refactorings that works, completion, ...

Monday, October 01, 2007

Quicker Maven Builds

A simple tip. Maven builds quickly get slow, as more and more unit tests are added. Often, when developing, I do "maven -Dmaven.test.skip=true", until I think I am ready. I then do a build with tests and if okay, I commit.

Only thing is, typing "-Dmaven.test.skip=true" is long and tiring. But, you can shorten it down a bit. Add this to the profiles section of your settings.xml:

<profile>
<id>quick</id>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>

Then, when you want to build without tests, you simply do "mvn -Pquick".

You can also do a little script or alias for quick building with maven, as I have previously written about.

Wednesday, September 26, 2007

Coping with Flex Asynchronous Remote Calls - Part II

In my previous post about using modal dialogs to give the illusion of synchronous remote calls in flex to the user, I showed one way of coping with flex remote calls being asynchronous.

Another way is to fully accept the asynchronism of the remote calls, and start designing your application using callbacks instead.

Imagine the situation, where some code on the client needs to make this (seemingly simple) call:

var result : String = remoteService.doServerSideCalculations(42);

Where remoteService.doServerSideCalculations() is a call to a remote web service. Looks like a no-brainer when coming from the Java world. It is just a method call with a return value. Well, no. Because the remote call is asynchronous, you will not get the return value of the call into result.

The next thing you try when you do not know actionscript3, is to look for some call in the flex api or actionscript3 language to issue a wait, yield or sleep. This could make it possible to let the client wait for the request to return, and then continue operation from there on. But there exist no such calls or functionality!

What to do then?

Design with Callbacks
What you need to do is start designing with callback methods. What I have done is to wrap the remote service in a proxy class, which takes care of calling the remote service and waiting for results. In the event of remote methods which return a value, the proxy will issue a callback to the caller on the proxy, giving the return value of the remote call as a parameter value.

In the above example, I would create a proxy class in as3 like this:

package com.blogspot.techpolesen {
import mx.rpc.soap.WebService;
import mx.rpc.events.ResultEvent;

public class RemoteService {
private var remoteService : WebService = new WebService();

function RemoteService() : void {
remoteService = new WebService();
remoteService.wsdl = "/services/RemoteService?wsdl";
remoteService.loadWSDL();
}

public function doServerSideCalculation(input : int, callback : Function) : void {
// the listener on the result event will call the callback with the return value
var listener : Function = function(event : ResultEvent) : void {
remoteService.removeEventListener(ResultEvent.RESULT, listener);
callback(remoteService.doServerSideCalculation.lastResult);
};

remoteService.addEventListener(ResultEvent.RESULT, listener);

// do the actual call
remoteService.doServerSideCalculation(input);
}
}
}

Here, the RemoteService as3 class wraps the call to the doServerSideCalculation(int) method in an as3 method, which takes a second argument, the callback function. What the as3 implementation does is to add an event listener, that waits for the ResultEvent. When this event occurs, the return value is ready, and the callback can be made, giving the return value back to the caller of the proxy.

Here is an example on how the above proxy class can be used in the application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import com.blogspot.techpolesen.RemoteService;

private var remoteServiceProxy : RemoteService = new RemoteService();

private function callIt() : void {
lbl.text = "Calling...";
remoteServiceProxy.doServerSideCalculation(42, function(result : int) : void {
lbl.text = "Result: " + result;
});
}
]]>
</mx:Script>

<mx:Button label="Do remote call using callback" click="callIt()"/>
<mx:Label id="lbl"/>
</mx:Application>

And here is a bit of explanation:
  • When the button is clicked, the callIt() method is called
  • The callIt() method invokes doServerSideCalculation on the client-side as3 proxy for the remote service
  • The key is in the parameters to that method. The first parameter is easy, 42, which is simply the parameter to the actual remote call.
  • But the second parameter, callback, is of Function type. It takes a reference to a method. This method is the callback, that will be called when the remote call returns.
  • In the implementation of doServerSideCalculation, an event listener is added on the result event. This listener will be called by flex, when the remote call returns. The listener in turn grabs the return value from the method, and executes a call on the callback method, passing the remote call return value as parameter.
What happens when you click the button, is that callIt calls the doServerSideCalculation, method giving it a callback method. You can view this method as the left-side of the result = doServerSideCalculation(input) call. It simply assigns the result to a label.

You could also combine the above with a modal dialog or a modal dialogs with some progress indication. You would then open the modal dialog in doServerSideCalculation.

Downloading the source
I have zipped up the sources for you. It can be downloaded from here. Ready to be build with maven.

This is a multi-module maven build. There are two directories:
  • client : Contains the flex source and a pom to build it
  • server : Contains the web service and a pom to build it
The war artifact output from the server module have in it the flash output from the client module and a index.html which loads it.

To start the server after a build, you simply jump into the server directory and do a "mvn jetty:run-exploded".

Other Small Flex Tutorials
This was lesson 8 in my series of posts on what I learn about developing filthy rich flash apps using flex2. If you want to read more, the previous lessons can be found here:

Monday, September 17, 2007

Coping with Flex Asynchronous Remote Calls - Part I

This post is showing you, how to easily use a modal dialog popup with a ProgressBar, when calling a Web Service in Flex. This can help make the impression to the user, that the call is synchronous.

UPDATE: This is Part I in a multipart post. You can view part II here, about using callbacks to cope with the asynchronous calls.

Previously, i blogged about how to call a web service from flex code. In that post, I showed the basics of calling web services from actionscript code, but I only briefly mentioned, that remote calls are asynchronous in flex. Actually, the asynchronity of remote calls has a major impact, on how you design the client.

In this post, I show one way to cope with the asynchronity.

When a remote call is issued, and the result of the call is to be known on the client, before it can let the user continue, we need to "wait" for the operation to finish. This can be done by opening a modal dialog. In this example, the modal dialog also contains an indication of progress, showing the user, that some operation is running.

Here is the code for the client:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="loadWebService()">
<mx:Script>
<![CDATA[
import mx.rpc.soap.WebService;
import mx.rpc.events.ResultEvent;
import mx.managers.PopUpManager;

private var longRunningService : WebService = new WebService();

private function loadWebService() : void {
longRunningService = new WebService();
longRunningService.wsdl = "/services/LongRunningService?wsdl";
longRunningService.loadWSDL();
}

private function callWebService() : void {
var popup : ShowProgress = ShowProgress(PopUpManager.createPopUp(this, ShowProgress, true));
PopUpManager.centerPopUp(popup);
longRunningService.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void {
PopUpManager.removePopUp(popup);
});
longRunningService.slowOperation();
}
]]>
</mx:Script>

<mx:Button label="Call a long running remote method" click="callWebService()"/>
</mx:Application>

In the above code, loadWebService() is called at application creation time. It loads and parses the wsdl and adds web service operations to the longRunningService variable.

When the button is clicked, it calls callWebService() which:
  1. Creates a popup window from the ShowProgress type (my progress dialog), marking it modal. After this line of code, the modal popup is showing, and no user input can be made.
  2. It then adds an event listener for the ResultEvent.EVENT event, which is dispatched when the web service call completes. This handler will remove the popup when called.
  3. The web service call is made.
And here is the code for the ShowProgress.mxml dialog:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" title="Talking to server" creationComplete="init()">
<mx:Script>
<![CDATA[
private function init() : void {
progress.setProgress(1, 0); // to start progress indicator when indeterminate
}
]]>
</mx:Script>
<mx:ProgressBar id="progress" mode="manual" indeterminate="true"/>
</mx:TitleWindow>

It contains only a ProgressBar component, which is set into manual mode and set to be indeterminate. In manual mode, we must use setProgress to update progress. When being indeterminate, it does not show progress against an absolute stop value, but simply indicates "some" progress. In the init() method, I call setProgress(1, 0), which starts the indeterminate progress indicator.

It is important to note here, that the call is not actually synchronous now, just because of the modal dialog. It only appears to be, by the user. The application will continue, after the call to the web service.

Downloading the source
I have zipped up the sources for you. It can be downloaded from here. Ready to be build with maven.

This is a multi-module maven build. There are two directories:
  • client : Contains the flex source and a pom to build it
  • server : Contains the web service and a pom to build it
The war artifact output from the server module have in it the flash output from the client module and a index.html which loads it.

To start the server after a build, you simply jump into the server directory and do a "mvn jetty:run-exploded".

Other Small Flex Tutorials
This was lesson 7 in my series of posts on what I learn about developing filthy rich flash apps using flex2. If you want to read more, the previous lessons can be found here: