Jun 14

I recently got a request from my one client: “Please add logging of the time it takes to do remote service calls, with minimal impact on the existing code.”

Now I immediately thought of the Proxy design pattern.

The existing code had quite a large number of business interfaces defined, with an implementation for each one that made use of RMI to call the remote objects. I’ll spare you the unnecessary details (JAAS, etc). It boiled down to basically every public method in each business interface implementation making use of an anonymous inner class with a simple public Object run() method to make the actual call to the remote object. A lot of code to change by hand, if logging and measurement of the time it took for remote calls were to be added.

A drastically reduced business interface might look like:

package com.richclientgui.blog.delegate;

public interface SoccerScoreService {
    public int getTeamScore(String teamName);
}

In order to re-enact the work of the JAAS Subject.doAs(…) code that is involved with the actual code, I created a MockSubject class for this example, which just calls the run() method of whatever Runnable gets passed to it:

import java.util.concurrent.Callable;

public class MockSubject {
    public static <T> T doAs(Callable<T> action) throws Exception {
        return action.call();
    }
}

We add a very basic mock implementation (no real remote calls happening here…):

import java.util.concurrent.Callable;

public class MockSoccerScoreServiceImpl implements SoccerScoreService {

    @Override
    public int getTeamScore(String teamName) {
        try {
                
            Integer result = MockSubject.doAs(
                                    new Callable<Integer>() {
                public Integer call() throws Exception {
                    System.out.print("Doing some work...");
                    try {
                         Thread.sleep(1000);
                    } catch (InterruptedException e) {
                         e.printStackTrace();
                    }
                    System.out.println("completed.");
                    return new Integer(50);
                }
             });
             return result.intValue();
                        
        } catch (Exception e) {
             //for this blog, I don't care about the
             //exception handling...
             e.printStackTrace();
             return -1;
        }
    }
}

Now we can just create a simple class with a main method that calls getTeamScore(…) on an instance of MockSoccerScoreServiceImpl.

Now to add the logging…

Approach A: Use a Proxy
We can create a Proxy for the Callable, since all our calls to the server are done using Callable instances. This proxy class measures the time it takes to perform the call() method of the real Callable, and logs it to sysout.

import java.util.concurrent.Callable;

public class LoggingCallableProxy <T> implements Callable<T> {
        private final Callable<T> realCallable;
        
        public LoggingCallableProxy(Callable<T> realCallable){
                this.realCallable = realCallable;
        }
        
        @Override
        public T call() throws Exception {
                long time = System.currentTimeMillis();
                T result = realCallable.call();
                time = System.currentTimeMillis()-time;
                //find calling method, using call level of 3
                //for this example
                final StackTraceElement stackTrace
                        = Thread.currentThread().getStackTrace()[3];
                //using sysout for example, but of course
                //use proper logging in real life
                System.out.println(
                                stackTrace.getClassName()+"."
                                +stackTrace.getMethodName()
                                +" took "+time+"ms to execute.");
                return result;
        }
}

Now comes the disadvantage of using a Proxy: we now have to change all the existing code to now create the instance of LoggingCallableProxy where the Callable was used up to now. This is not so bad if you have the source code, it is just a simple find&replace, so we can be pragmatic and live with it (I’ve always wanted to use the word “pragmatic” in a blog). Our MockSoccerScoreServiceImpl class changes to look like:

import java.util.concurrent.Callable;
import com.richclientgui.blog.proxy.LoggingCallableProxy;

public class MockSoccerScoreServiceImpl implements SoccerScoreService {

        @Override
        public int getTeamScore(String teamName) {
                try {
                
                    Integer result = MockSubject.doAs(
                           new LoggingCallableProxy<Integer>(
                               new Callable<Integer>() {
                         public Integer call() throws Exception {
                             System.out.print("Doing some work...");
                             try {
                                     Thread.sleep(1000);
                             } catch (InterruptedException e) {
                                     e.printStackTrace();
                             }
                             System.out.println("completed.");
                                     return new Integer(50);
                         }
                     }));
                     return result.intValue();
                        
                } catch (Exception e) {
                     //for this blog, I don't care about the
                     //exception handling...
                     e.printStackTrace();
                     return -1;
                }
        }
}

Now we have logging of the time measurements, with minimal code impact.

However, that simple yet far-reaching find&replace operation one potentially hundreds of methods in a huge number of classes still worries me…

Approach B: use Aspects

Aspect-oriented programming (AOP) has been around for a while, and it allows us to weave in functionality without changing existing java classes. That is an extremely brief and potentially inaccurate summary, but it will suffice for this blog. Go read more about aspects and AspectJ.

First, we need to enable aspects on our project. Do this, you must:

  1. Download the AspectJ Development Tools (AJDT) if you are using the Eclipse IDE (AspectJ also integrates with other IDEs).
  2. Convert the project to an AspectJ project: Right-click on project, choose Configure -> Convert to AspectJ project
  3. Now you are ready to start implementing aspects.

Second: change back the MockSoccerScoreServiceImpl class to now make use of the LoggingCallableProxy anymore.

Then we can implement our aspect:

import com.richclientgui.blog.delegate.MockSubject;

/**
 * This aspect will find all occurrences of the MockSubject.doAs(...)
 * method being called, and wrap that in code to log the time
 * measurements.
 */
public aspect TimeLoggerAspect  {

        // the pointcut defines what method calls to intercept
        // All calls to the MockSubject.doAs(...) method
        // (wildcards for return and param types)
        pointcut doingRemoteCalls() :
                call(* MockSubject.doAs(..));

        /* around() defines an advise that will be executed whenever
         * the doingRemoteCalls() pointcut is matched.
         * It measures the time that it takes to execute the actual
         * doAs(...)method at that point, and prints out the time,
         * class and method calling the MockSubject.doAs(..) method
         */
        Object around() : doingRemoteCalls() {
                long time = System.currentTimeMillis();
                Object result = proceed();
                time = System.currentTimeMillis()-time;
                //find calling method
                final StackTraceElement stackTrace
                        = Thread.currentThread().getStackTrace()[2];
                System.out.println(
                                stackTrace.getClassName()+"."
                                +stackTrace.getMethodName()+" took "
                                +time+"ms to execute.");
                return result;
        }
}

Now you can run your main/test class as an AspectJ application, by using the Run As -> AspectJ/Java Application menu option in Eclipse.
(Visit the AspectJ website to see how to run it from commandline or other IDEs.)

We added logging to the remote calls, without changing any existing code, by just adding one simple aspect. This is only the tip of the iceberg of what you can do with AOP.

Eclipse RCP tip:
For Eclipse RCP applications, you will need to add a dependency to the org.aspectj.runtime plug-in to your plug-in project in order to use AspectJ.

Tagged with:
Jun 10

I recently blogged (on my blogger site) about my quest to find a more effective way of coding Java GUI applications. This resulted in the creation of a one-day workshop that I am very excited about.

The details from the JTraining website are:

Fast-tracking Java GUI Development
This is a great one-day workshop that discusses a number of concerns with developing Graphical User Interfaces applications with Java, and explore various ways to improve the speed and efficiency of development.

  • Do you sometimes think that coding in Java is perhaps not the best way of constructing GUIs?
  • Do you feel that your team should be able to develop GUI applications much faster?
  • Are you frustrated with the amount of “donkey code” you are writing to implement some basic GUI features?
  • Are the new team members struggling with the high learning curve of the Java GUI framework you are using?
  • Are you spending more time on coding GUI behaviour than you spend on coding domain behaviour?
  • Do your team find it difficult to add or modify existing features of a GUI application?

The above questions highlight some of the issues typically found when doing GUI application development. We have been specialising in Java GUI development for more than a decade, and in this time we have investigated and used a wide range of frameworks, tools and techniques to help us build GUI applications more effectively. This workshop explores a number of these options, in a highly interactive and hands-on way.

Visual GUI builder tools, code generators, UI DSLs: these are some of the topics we will investigate.

However, none of these have any meaning if a good foundation of UI development principles and practices is not embraced in a project. The workshop also aims to instil a number of important principles and practices that is a must for any good GUI development team.

I’m also giving away more detail here (I still have to finalize the content and outline, will add that to our website later):
A) discussion of frustrations & issues with “traditional” approach to GUI development using something like RCP/Swing
[interactive discussion]
B) exploration of alternatives:
* Tools (e.g. SWT Designer, Eclipse e4, etc)
* UI DSLs (e.g. Glimmer, Gryphon, XScalaWT)
* Code Generation (e.g. XText, ANTler)
[I want to demo some of the options, and allow for practical hands-on use of at least one. My current idea is that we divide in groups, and each develop a UI DSL, using something like XText, or a more dynamic language like Scala]
C) Discussion of Practices and Principles when doing GUI development, including:
- UI Design
- UI Testing
- Tool (in)dependency
- Domain Driven UIs
[This discussion will also involve a whiteboard/interactive design session (also done in groups).]

And all this will be taking place on 1 July 2010 at my new training and agile office venue in Worcester (or if the group gets to big, we’ll move to an extremely nice country lodge nearby).

Please see our training website for more details.

Tagged with:
Jan 14

If you:

  • are a fast and willing learner
  • are passionate about developing quality software
  • are self-disciplined and self-motivating
  • tired of the typical city and office life
  • need more flexibility in your working day
  • have experience in Object-oriented development
  • have experience in Java (acronyms optional)
  • are willing to either move to Worcester or work remotely with regular visits to Worcester

Then we:

  • want to talk to you about contracting or permanent employee options
  • want to provide training and mentoring
  • want to make you part of a newly founded team that has the goal of becoming the leading Southern Africa Eclipse RCP/RAP and OSGi development team
  • want to expose you not only to exciting new software projects, prototyping, and technology research, but also to interesting consultation opportunities, and unfortunately a bit of less interesting maintenance work

Email us at: jobs@richclientgui.com

Tagged with:
May 27

This is my second blog about the Eclipse Commands framework, but actually the first one containing useful (I hope) information. I’m going to focus on the topic from a practical “using it in development” point of view, trying to keep the examples as simple as possible and the theory limited. For an updated outline please refer to the first blog in the series: Eclipse RCP Commands Part One.

Short history: the Commands framework has been around partially since Eclipse 3.0, maturing over the versions until it became quite useful in Eclipse 3.3. Some refinements in Eclipse 3.4 makes it even more appealing. I must admit, before Eclipse 3.3 I saw no reason for using Commands, and I stuck to using IActions and IActionDelegates, trying to work around their issues as much as possible (and falling into the rythm of the copy-and-paste anti-pattern in order to contribute an IActionDelegate to multiple places in a UI). No I’m trying to convince all my clients to “renew” their code to use Commands…

What are Commands

A command is neither the presentation nor a particular behavior implementation; it is an abstract representation of some semantical behavior.” – Marc R. Hoffmann (see Article on Eclipse Commands Framework)

That’s the best quote I could find as to what a Command is. What does it boil down to? I assume (hope?) you are all familiar with the Model-View-Controller pattern, used especially when developing UI applications. By abstracting a particular piece of functionality into separate Model, View and Controller objects, the code is must less coupled, allowing more (and easier) reuse, flexibility and extensibility.

Well, the Command design is not exactly MVC, but it has the same goals in mind. It abstracts the actual business or application semantics (i.e. what is actually meant to happen from business or application functionality perspective) into this thing called a Command. Worries about how it should appear in the UI (menu contributions), or what exactly must happen on a code implementation level to execute the command (handlers) is left for later. In this way we get the same decoupling of presentation and implementation as with MVC, and thus the gain in reusability of Commands and their handlers, and increase in the flexibility and extensibility of the code, thus leading overall to code that is much easier to maintain.

Add to the above paragraph that code that is easier to maintain leads to huge development cost savings, and you’ll have a convincing argument to offer to your boss for allowing you to refactor away all the old IActionDelegates.

Ok, but what to we do with Commands?

Plain and simple: we use it to implement functions that our application can perform and make it available as menu or toolbar items so the user can invoke it.

On a more practical level

That is about enough theory for one day. Let’s get down to the bits and the bytes.

The Example

Firstly, I want to introduce my patent-pending idea for an application. Image this: you have this cross-platform application (obviously implemented using Eclipse RCP) that can actually read electronic versions of books, that we can call “e-books”. “Wow!” you say. “Amazing”. “What a novel idea”.

Let us call our bleeding edge application MyReader. You can download the source code for this blog’s version of the example.

Step 1: Create a RCP application using Eclipse 3.4 (I’m using 3.4.1) and the New Plug-in Project wizard.

  • Name the project MyReader
  • On the next wizard page fill in the details you want, but make sure “Would you like to create a rich client application” is set to “Yes“.
  • On the third wizard page, select the “RCP application with a view” as the template to use.
  • Run the resulting RCP application to make sure it runs, so you don’t blame my examples later for messing up your pristine code.

    Now we have the example application that we are going to enable with Commands. Exciting, isn’t it?

    How to define a Command

    To have a command that is actually accessible in the UI, and able to do something, we need 3 “components”:

  • The Intent: the Command declaration
  • The Presentation: the menu contribution declaration(s)
  • The Behaviour: the Handler that implements the behaviour of the Command

    Declaring the Command (Intent)

    We declare the Command using the org.eclipse.ui.commands extension point. I’m sure you remember this command we declare indicates the meaning or intent of the functionality we want to add to our application or plugin.

    Let us explore this Command declaration in our example, and then I’ll discuss what is going on.
    We need to open an ebook file with our application, so we will define a command to do this.

    Step 2: Add the org.eclipse.ui.commands extension to our plugin.xml

  • Open the PDE-Editor (Plugin Editor), if it is not open already, and select the Extensions tab. (You double-click the plugin.xml or MANIFEST.MF files in the project. However, if you did not know that, you must maybe first implement a “Hello RCP World” application before jumping to Commands…)
  • If, due to random bit-changes caused by unexplained solar activity, you already have the org.eclipse.ui.commands extension in your list of extensions, then do not follow the rest of this step.
  • Click on the “Add…” button.
  • Start typing in “org.eclipse.ui.commands“, and select it from the filtered list when you see it. If it is not available uncheck the “Show only extension points from required plug-ins” option.
  • Select the Finish button. This will add the org.eclipse.ui.commands entry to your plugin.xml file.

    Step 3: Declare the Open File command

  • right-click the org.eclipse.ui.commands extension, and select New -> Command from the context menu.
  • change the id to something like “mydomain.myreader.commands.OpenEBook
  • change the name to “Open eBook
  • change description to “Opens an eBook file for reading
  • for now, ignore the rest

    Steps 2 and 3 updates the plugin.xml file of the plugin project by adding the necessary extension point and declaring a basic command. The plugin.xml file now contains:






       <extension
             point="org.eclipse.ui.commands">
          <command
                description="Open an eBook file for reading"
                id="com.richclientgui.myreader.commands.OpenEBook"
                name="Open eBook">
          </command>
       </extension>


    Congratulations! Your first command.

    “But if I run my app, I don’t see this command. What’s wrong?” Nothing. We still need to define how this command will be visible in the UI, and what the behavior should be when this command is invoked. As mentioned earlier, these are decoupled from the Command declaration.

    However, let us first examine the declaration in the plugin.xml. The org.eclipse.ui.commands extension allows us to declare, among other things, a Command. The Command definition needs the following attributes:

    id a unique id that will be used for referring to this command when declaring the UI contributions and Handlers
    name a user-readable name that will be used for the label in the menu contribution(s), if the menu contribution does not define its own label
    description a user-readable name that will be used for the tooltip in the menu contribution(s), if the contribution does not define its own description

    We are still going to have a look at some of the other attributes available. If you can’t wait, go and see org.eclipse.ui.commands for more detailed information about the extension point definition. Go on, don’t mind me.

    Note: here we had a look at how to declare commands using the extension point in the plugin.xml file. In a later blog I plan to discuss how to do it programmatically. I will update this section with a link to that blog as soon as it is available.

    Basic menu contribution (Presentation)

    It is time to get his command to be presented in the UI of the application. I assume you have already done some nice UI design work sessions with your potential end-users and you are ready to build the ultimate user friendly intuitive graphical user interface for your application. For our example we are just going to use the UI-design-by-coincidence approach and just add our stuff and see how it looks.

    In order to contribute an item that will invoke a Command to the UI, we need to add the org.eclipse.ui.menus extension to our plugin.xml, and declare a MenuContribution element followed by a Command element.

    We first declare where (i.e. the main menubar or toolbar, or a view or editor specific menu and/or toolbar, or a context menu) the command should be added via the MenuContribution. Then we declare the visual representation of our Command using the MenuContribution’s Command element.

    Step 4:Add the org.eclipse.ui.menus extension to plugin.xml

  • Click on the Add… button in the Plugin Editor.
  • Select the org.eclipse.ui.menus extension from the list of available extensions. If it is not available uncheck the “Show only extension points from required plug-ins” option.
  • Select the Finish button. This will add the org.eclipse.ui.menus extension to the plugin.xml file.

    Step 5: Add the MenuContribution element

  • Right-click the org.eclipse.ui.menus extension, and select New -> menuContribution from the context menu
  • Change the locationURI to menu:file?after=additions (don’t worry, we’ll discuss it just now)

    Step 6: Add the Command to the MenuContribution

  • Right-click on the menuContribution created in step 5, and select New -> command from the context menu.
  • Change commandId to the id you provided to your Command definition in step 3.
  • Change mnemonic to “O” to underline the first letter of the “Open” as your shortcut mnemonic for your command in the menu.

    I’m sure you are eager to run your MyReader app now. Go ahead, please. Do you see it? A grayed-out Open eBook menu-item just underneath Exit in the File menu.
    First Menu Contribution with grayed-out Open eBook Command

    That is not quite what we intended. We’ll get there, though. First a discussion on what we actually did.

    We first needed to add the org.eclipse.ui.menus extension to our plugin, and then we declared that we want to contribute an item to a menu via the MenuContribution element. We only had to specify one attribute: the locationURI. More on that in the next section.

    We then declared that we are actually contributing a Command item as part of our MenuContribution. This is not the actual definition of a Command, but just an element indicating that we wish to represent the command with the identifier specified in commandId as an item in the menu or toolbar that we are declaring this MenuContribution for. Thus by specifying the locationURI “menu:file?after=additions” and the commandId “com.richclientgui.myreader.commands.OpenEBook” we are saying that we want the OpenEBook command to display in the standard File menu after the additions placeholder.

    The mnemonic attribute indicates what character should be underlined and act as a shortcut key for selecting the menu item, if that menu is currently open. Other additional attributes can be specified to manage the presentation of the Command in the menu, e.g. the icon, label (overriding the value set in the Command’s name attribute), tooltip (overriding the value set in the Command’s description attribute), etc. This gives us the flexibility to present the same Command slightly different depending on where it gets contributed, something that is not possible with IActions and IActionDelegates.

    LocationURI

    The locationURI is an interesting attribute: it allows the developer to use a URI string to specify where a specific contribution (whether it is a command item, a submenu or some other widget that can be contributed) must be added. It is of the form:
    [scheme]:[id]?[placement arguments]

    scheme The scheme indicates the type of the target component of the contribution, and can be one of:

  • menu : either main menu or view menu
  • toolbar : either main toolbar or view toolbar
  • popup : context menu
  • id The unique identifier of the menu, toolbar or context (popup) menu where the contribution must be added. See the list below for standard platform identifiers that can be used.
    placement The arguments helps to define the placement of the contribution items in relation to another item or placeholder (i.e. GroupMarker) in the target menu. It consists of either the word “before” or “after” followed by an equal sign (=) and then the identifier of a menu contribution item. The word “additions” can also be used in place of an identifier. Contributions added to “additions” will typically be placed last in a menu.

    Talking in detail about the locationURI and menu contribution placement can be a long blog entry on its own, so I want to come to this subject in more detail later in the series.

    Note: I usually declare my view’s identifier as the same as the fully qualified Java class name of the ViewPart implementation class, and then use the convention viewID.menu, viewID.toolbar and viewID.popup as identifiers for its various menus. E.g. a View implemented in the class com.richclientgui.myreader.BookView will have the Id com.richclientgui.myreader.BookView and the menu IDs com.richclientgui.myreader.BookView.menu, com.richclientgui.myreader.BookView.toolbar and com.richclientgui.myreader.BookView.popup.

    Platform Menu IDs

    Some standard identifiers are available for commonly used menus and toolbars:

    ID Description
    org.eclipse.ui.main.menu the main Eclipse application menubar
    org.eclipse.ui.main.toolbar the main Eclipse application toolbar
    org.eclipse.ui.popup.any contributions using this identifier will be visible in all context menus of the application (well, that’s not the full truth, but that is a topic for another blog)
    menu:file three guesses what menu this one point to…
    menu:help I’m not even going to say its a menu, and you only get one guess
    menu:window Ok, you start to get the picture
    helpEnd name of group-marker at end of Help menu
    quit id of Exit action

    See IIDEActionConstants and IWorkbenchActionConstants for more useful identifiers.

    I can’t wait to move that Open eBook item to the top of the menu…

    Step 7: Change Command menu-item placement

  • Select the menuContribution element we specified in step 6.
  • Change the locationURI to be menu:file?before=quit

    Running our latest version gives us a still grayed-out item, but at least where we want it.

    Open eBook Command in right place

    And our plugin.xml has grown a bit:






       <extension
             point="org.eclipse.ui.commands">
          <command
                description="Open an eBook file for reading"
                id="com.richclientgui.myreader.commands.OpenEBook"
                name="Open eBook">
          </command>
       </extension>
       <extension
             point="org.eclipse.ui.menus">
          <menuContribution
                locationURI="menu:file?before=quit">
             <command
                   commandId="com.richclientgui.myreader.commands.OpenEBook"
                   mnemonic="O"
                   style="push">
             </command>
          </menuContribution>
       </extension>


    Now to implement the behaviour.

    Simple Handler (Behaviour)

    After all this build-up, it is quite simple to actually add behaviour to a Command. You need to

  • implement a class that extends org.eclipse.core.commands.AbstractHandler,
  • and update your Command’s defaultHandler attribute that you left empty in step 3.

    Step 8: Implement a default Handler

  • Implement a class called DefaultOpenEBookHandler that extends AbstractHandler, and only override the execute(…) method. I just added a call to the JFace MessageDialog class to show some information. I will discuss these Handler classes more in a future blog in the series.
  • Select the OpenEBookCommand definition from step 3 and select the DefaultOpenEBookHandler class as the defaultHandler‘s value.

    Here is my DefaultOpenEBookHandler class:






    package com.richclientgui.myreader.handlers;

    import org.eclipse.core.commands.AbstractHandler;
    import org.eclipse.core.commands.ExecutionEvent;
    import org.eclipse.core.commands.ExecutionException;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.swt.widgets.Display;

    public class DefaultOpenEBookHandler extends AbstractHandler {

      public Object execute(ExecutionEvent eventthrows ExecutionException {
        MessageDialog.openInformation(Display.getDefault().getActiveShell(),
            "O no!""I'm not ready yet. Go read the hardcopy book.");
        return null;
      }

    }


    If you run the application now, you will actually see that the command item in the menu is enabled, and you should see a dialog with a message if you select the item.
    Open eBook Command shows dialog

    The Sum of the Parts

    We saw a basic introduction of how to:

  • declare a Command
  • contribute that command to the main menu-bar
  • define a class that encapsulated the behaviour of the Command

    Each of these components on their own does not add value to an application, but together it forms a powerful yet flexible and very maintainable Commands framework, far superior to using IActions and IActionDelegates because of the separation between the intent, presentation and behaviour.

    Summary of Steps

    Step 1 Create sample RCP application
    Step 2 Add the org.eclipse.ui.commands extension to our plugin.xml
    Step 3 Declare the Open File command
    Step 4 Add the org.eclipse.ui.menus extension to plugin.xml
    Step 5 Add the MenuContribution element
    Step 6 Add the Command to the MenuContribution
    Step 7 Change Command menu-item placement
    Step 8 Implement a default Handler

    You can download the source code for this blog’s version of the example.

    Next Episode

    Do not miss out on the next exciting episode on Eclipse RCP Commands. There I’ll be tackling mind-blowing topics, like

  • how to show commands only when you want to
  • how to disable commands
  • dynamic menu contributions
  • handling the Handlers
    (Time and weather permitting.)

    References

  • Eclipse.org Commands Framework Article in bugzilla
  • Article on Eclipse Commands Framework, by Marc R. Hoffmann
  • Eclipse.org Wiki on Command Framework
  • Eclipse Commands Tutorial, by Lars Vogel

    Enough said for now.

  • Tagged with:
    preload preload preload