Using Guice with Flex remoting for BlazeDS

I just finished putting a server together that uses Google’s Guice and Adobe’s BlazeDS.  Here’s how you can quickly get a project working using the same configuration.

* Update: A new post describes using Guice’s ServletModule to configure the MessageBrokerServlet.

Download the libraries

Download Guice and BlazeDS.  Use the project configured in the BlazeDS war to get started.

Create the Guice factory

Since BlazeDS provides the servlet, you won’t be able to configure your classes using Guice unless you have a Flex factory.  This code will inject itself with Guice to get instances of Flex services.

package com.connorgarvey.guiceblazeds.servlet;
 
import java.util.HashMap;
import java.util.Map;
import com.google.inject.Injector;
import flex.messaging.FactoryInstance;
import flex.messaging.FlexContext;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;
 
/**
 * <p>A Flex factory that retrieves instances of Flex services from Guice</p>
 * <p>This is based on a similar factory built for Spring by Jeff Vroom</p>
 * @author Connor Garvey
 * @created May 27, 2009 1:09:49 PM
 * @version 1.0.0
 * @since 1.0.0
 */
public class GuiceFactory implements FlexFactory {
  private static final String SOURCE = "source";
 
  /**
   * @see flex.messaging.FlexFactory#createFactoryInstance(java.lang.String, flex.messaging.config.ConfigMap)
   */
  public FactoryInstance createFactoryInstance(final String id, final ConfigMap properties) {
    final GuiceFactoryInstance instance = new GuiceFactoryInstance(this, id, properties);
    instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
    return instance;
  }
 
  /**
   * @see flex.messaging.FlexConfigurable#initialize(java.lang.String, flex.messaging.config.ConfigMap)
   */
  public void initialize(final String id, final ConfigMap configMap) {
  }
 
  /**
   * @see flex.messaging.FlexFactory#lookup(flex.messaging.FactoryInstance)
   */
  public Object lookup(final FactoryInstance inst) {
    return inst.lookup();
  }
 
  static class GuiceFactoryInstance extends FactoryInstance {
    private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
    GuiceFactoryInstance(final GuiceFactory factory, final String id, final ConfigMap properties) {
      super(factory, id, properties);
    }
 
    @Override
    public Object lookup() {
      final Injector injector = (Injector)FlexContext.getServletContext().getAttribute(
          GuiceServletContextListener.KEY);
      injector.injectMembers(this);
      String className = this.getSource();
      Class<?> clazz = this.classes.get(className);
      if (clazz == null) {
        try {
          clazz = Class.forName(this.getSource());
          this.classes.put(className, clazz);
        }
        catch (ClassNotFoundException ex) {
          ServiceException throwing = new ServiceException();
          throwing.setMessage("Could not find remote service class '" + this.getSource() + "'");
          throwing.setRootCause(ex);
          throwing.setCode("Server.Processing");
          throw throwing;
        }
      }
      return injector.getInstance(clazz);
    }
 
    @Override
    public String toString() {
      return "Guice factory <id='" + this.getId() + "',source='" + this.getSource() +
          "',scope='" + this.getScope() + "'>";
    }
  }
}

Create a context listener

The Guice servlet jar contains a ServletContextListener, but I haven’t taken the time to integrate it into this solution.  For simplicity, you can use this one, which works with the factory above.

package com.connorgarvey.guiceblazeds.servlet;
 
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
 
/**
 * Prepares Guice on application startup
 * @author Connor Garvey
 * @created May 27, 2009 8:37:26 AM
 * @version 1.0.0
 * @since 1.0.0
 */
public abstract class GuiceServletContextListener implements ServletContextListener {
  /**
   * The key of the servlet context attribute holding the injector
   */
  public static final String KEY = Injector.class.getName();
 
  /**
   * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
   */
  public void contextDestroyed(final ServletContextEvent servletContextEvent) {
    servletContextEvent.getServletContext().removeAttribute(KEY);
  }
 
  /**
   * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
   */
  public void contextInitialized(final ServletContextEvent servletContextEvent) {
    servletContextEvent.getServletContext().setAttribute(KEY,
        this.getInjector(servletContextEvent.getServletContext()));
  }
 
  private Injector getInjector(final ServletContext servletContext) {
    return Guice.createInjector(this.getModules());
  }
 
  /**
   * Gets the modules used by the application
   * @return the modules
   */
  protected abstract List<? extends Module> getModules();
}

Extend GuiceContextListener

Create a concret version of the class above.  It should return all modules needed for the application.

Modify web.xml

Now, prepare web.xml with the normal BlazeDS settings plus some extras for Guice.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <display-name>Guice BlazeDS</display-name>
  <description>Guice BlazeDS</description>
  <listener>
    <listener-class>flex.messaging.HttpFlexSession</listener-class>
  </listener>
  <listener>
    <listener-class>com.connorgarvey.guiceblazeds.servlet.MyCustomGuiceServletContextListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <display-name>MessageBrokerServlet</display-name>
    <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
    <init-param>
      <param-name>services.configuration.file</param-name>
      <param-value>/WEB-INF/config/flex/services-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <url-pattern>/messagebroker/*</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
  </welcome-file-list>
</web-app>

This way, BlazeDS will start at server startup, followed by Guice.

Modify BlazeDS config

Open services-config.xml and add this at the top of the file.  Point it to the Guice factory.

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
  <factories>
    <factory id="guice" class="com.connorgarvey.guiceblazeds.servlet.GuiceFactory" />
  </factories>

Set the factory of all remoting destinations

In remoting-config.xml, be sure to set the factory of all destinations to the name specified in services-config.xml above.

<destination id="SomeService">
  <properties>
    <factory>guice</factory>
    <source>com.connorgarvey.guiceblazeds.service.flex.SomeFlexService</source>
  </properties>
</destination>

How this all works

  1. When the server starts, BlazeDS and Guice are initialized by the servlet listeners.
  2. When BlazeDS receives a request, to a service, it’ll see that it’s supposed to retrieve it from the “guice” factory.
  3. The Guice factory will return an instance of the class specified in the source of the service configuration from Guice to BlazeDS for use in completing the request.
Posted in Guice at June 19th, 2009. 1 Comment.

Android application Green Mileage open sourced

Green Mileage is now an open source application at Google Code.  You can find the full source for most of the Android posts on this site in it at http://code.google.com/p/greenmileage/.  Just click the Source tab, then the Browse link.

The code needs a lot of cleanup, but is still probably worth a look if you’re new to Android.

Posted in Android at April 27th, 2009. 4 Comments.

Creating JavaFX sequences from Java code

Scroll down for the full source.  Today, to execute code asynchronously in JavaFX, the background code must be written in Java.  Ideally, your Java code will return JavaFX data types, keeping your FX code clean and helping you be prepared for the day when you won’t need Java.

This is how you can create and return JavaFX sequences from your Java code.

Set the return type of your method to com.sun.javafx.runtime.sequence.Sequence.  Many of the com.sun.javafx classes seem to have been created for use in Java code.

@Override
public Sequence<String> call() throws Exception {

In your code, use any type of collection class you like.  It’s easiest to use List classes, though, because they can be directly converted.

List<String> names = Arrays.asList("Arthur", "Trillian", "Zaphod");

Then, convert the list to a sequence using com.sun.javafx.runtime.sequence.Sequences and return it.

return Sequences.make(TypeInfo.getTypeInfo(String.class), names);

Here it is all together for impatient people like me.

@Override
public Sequence<String> call() {
  List names = Arrays.asList("Arthur", "Trillian", "Zaphod");
  return Sequences.make(TypeInfo.getTypeInfo(String.class), names);
}
Posted in JavaFX at March 21st, 2009. No Comments.

Simple JavaFX Spinner Using a Timeline

I’ve been working on a demonstration JavaFX application.  It was originaly written for the prerelease candidate.  I just updated it to work with JavaFX version 1.1 and thought I’d share it.  This is a simple spinner that can be stopped and started.  Here’s the full source.  A description of how it works is below.

package org.mediabrowser;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.Node;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;

/**
 * A spinning icon, indicating the application is working
 * @author Connor Garvey
 * @created Oct 22, 2008, 8:12:48 PM
 * @version 0.0.2
 * @since 0.0.1
 */

public class Spinner extends CustomNode {
  var rotation: Number = 0;
  var timeline: Timeline = Timeline {
    repeatCount: Timeline.INDEFINITE;
    keyFrames: [
      KeyFrame {
        time: 50ms
        action: tick
      }
    ]
  };

  public override function create(): Node {
    return Group {
      content: [
        ImageView {
          image: Image {
            url: "{__DIR__}resources/color_wheel.png"
          }
          transforms: Rotate {
            pivotX: 8
            pivotY: 8
            angle: bind this.rotation
          }
          translateX: 3
          translateY: 3
        },
        Rectangle {
          width: 22
          height: 22
        }
      ]
    };
  }

  public function start() {
    this.timeline.play();
  }

  public function stop() {
    this.timeline.stop();
  }

  function tick() {
    this.rotation += 20;
    if (this.rotation == 360) {
      this.rotation = 0;
    }
  }
}
  • First, the spinner extends CustomNode. That way, it can be placed anywhere in a UI.
  • The timeline is used to rotate the spinner
    • Since the application will be starting and stopping the spinner, set it to run forever, Timeline.INDEFINITE
    • The spinner only does one thing, turn, so it only needs one key frame.  It’s set to turn 20 degrees every 50ms.
  • JavaFX will call create() to create instances of the spinner
    • The __DIR__ makes the spinner image relative to the current class
    • Since the image is 16×16, set the rotation pivot point to 8×8, the center of the image
    • The angle of rotation is bound to a property of the class so that it can be easily modified
    • When an image starts to rotate, it appears to shake because it’s not round.  To smooth the rotation out, it’s transformed down and to the right and placed inside of a rectangle.
Posted in JavaFX at March 14th, 2009. No Comments.

Tutorial for creating an icon for an Android button: Part 2 of 2

This is part 2 of this tutorial.  Click here to see part 1.

  1. You should have two shapes in Inkscape.
    offsetshadowarrowarrowmask
  2. Now, you have to get these into the GIMP.  The easiest way is to take a screen shot.  To do that, in GIMP, go to File -> Acquire -> Screen Shot.  Take two shots.  Crop one to the shadowed image and the other to the black and white.
  3. Pick the shadowed image and add an opaque layer mask.  View the Layers dialog.  Right click the “Background” layer and click Add Layer Mask…
  4. Pick the black and white image.  Select the entire image and copy it.
  5. Pick the shadowed image and in the layers dialog, click on the mask, to the right of the image.
  6. Pick the shadowed image and paste.  You should see something like the image below.  Pick the move tool and drag the mask around until it exactly matches the shadowed arrow.
    alphaarrow
  7. Now, crop the image to the arrow shape.
  8. Right click on the floating layer and anchor it.
  9. Right click on the mask layer and apply it.
  10. Now, just save it!  Remember to save it as a PNG so that the empty parts are transparent.
    finalarrow1

I hope this helps anyone else who needs more than the standard Android icons.

More updates:

Will S. created a wireless icon.

Great tutorial, and very easy to follow, thanks.
I made a wifi icon, which can be found here:
http://digitalsquid.co.uk/files/2009/08/wifiicon.png
(you can use it if you want)

Posted in Android at January 25th, 2009. 12 Comments.

Tutorial for creating an icon for an Android button: Part 1 of 2

Update

The Android developer site has some great icon guidelines now.  I recommend taking a look.  If you have Photoshop or another program that supports vector shapes and drop-shadows, you can see the proper settings there.

Nick says

… you can do the whole thing in Inkscape without having to go into GIMP, by using a clip mask.

Duplicate your arrow, then select both this and the inverse arrow and do Object > Clip > Set. The inverse arrow will be clipped to only show the content contained within the arrow shape.

Introduction

For my Android application, Green Mileage, I created a number input dialog box.  One of the buttons in the dialog is a backspace key.  Right now, it’s just a button that says, “Back”.  When typing, it’s function is not immediately intuitive, so I wanted to replace it with an ImageButton.  To skip to the example, scroll down. Unfortunately, none of the Android icons look quite right.  I found an image of a red X and a trash can.  Neither would look like a backspace, so I decided to create my own.

Since Android is open source, I assumed that Google would have created some kind of template for button images.  I thought I would find a PSD, but after much searching, could not.  Rather than pay $1,000 for Photoshop, I decided to use open source applications to create the image.  Here’s how I did it.

Step 1: Get Inkscape and GIMP

Since this drawing will be made with vector graphics, it’s best to use a vector graphics program, so head on over to Inkscape’s web site and download it if you don’t already have it.  The post-processing will be done in GIMP, so grab a copy of that too.  Both have versions for Linux and Windows.

Step 2: Create the Inkscape drawing

The points on the arrow should be evenly spaced, so they shouldn’t be drawn by hand.  The arrow is really just a triangle with a rectangle dangling from its side.

  1. This tutorial is about drawing an arrow shape, but you can use most of these steps for any icon.
  2. First, let’s draw the arrow.  Pick the polygon tool: Polygon tool
  3. In the toolbar at the top of the screen, set these values.
    1. Corners: 3
    2. Spoke ratio: 0.5
    3. Rounded: 0
    4. Randomized: 0
  4. In the drawing canvas click and hold.  While holding the left mouse button, press and hold the control key.  That will help you draw the triangle so that the right side is vertical.
    triangle
  5. Select the rectangle tool and draw a rectangle for the right side of the arrow.  Make it overlap with the triangle.  Then, select both objects.  In the menu bar, click Object -> Align and Distribute.  Click the “Center on horizontal axis” button.
    trianglerectangle
  6. Now, with both objects selected, in the menu bar, click Path -> Union.
    arrow
  7. Android menu buttons have rounded corners and gradient fills.  Let’s apply those next.  With the arrow selected, in the menu bar, click Object -> Fill and Stroke.  Click the Stroke Style tab.  Select the round join and set the width to a high enough value that the corners look rounded.
  8. Select the Stroke Paint tab and pick the linear gradient.  The gradient will appear sideways, but we’ll fix it later.  Click Duplicate to create an Android button gradient.  Click Edit… Select the first stop at the top of the window, then at the bottom of the window, set its RGBA value to 666b66ff.  Set the second stop to b2afb2ff.
  9. Select the Fill tab, create a linear gradient and set it to the one you just created for the stroke.
  10. Close the Fill and Stroke dialog.
    horizontalgradientarrow
  11. To rotate the gradient, click the gradient tool, gradienttool.
  12. You’ll see two handles.  Drag the lighter side to the top of the arrow and the darker side to the bottom.  The handles will snap in to place.
    gradientarrow
  13. Android menu buttons also have an inner shadow.  Make a copy of the arrow away from the original arrow and draw a rectangle around it.  Make it a good amount larger.  Align the rectangle and the arrow the same way the triangle and rectangle were aligned before.  Then, select both the rectangle and the arrow and in the menu bar, select Path -> Exclusion.  Set the fill of the new shape to black and the path to the same gradient as the arrow, ensuring that the gradient minimum and maximum are aligned to the arrow, not the box.  Make a duplicate of the new shape and set it aside for use later.
    inversearrow1
  14. Select both the original and the new, inverse arrow and align them horizontally and vertically.
  15. Select the larger, inverse arrow and open its Fill and Stroke options,  move the blur slider to the right until it looks like a shadow.  Also adjust the alpha of the fill option until the arrow looks like it has an inner shadow.  Don’t worry if the space outside of the arrow doesn’t look right.  Then, since Android’s shadows are offset, move the inverse arrow down and to the right a bit.  The arrow keys are good for this.
    offsetshadowarrow
  16. Now, in the copy of the inverse arrow you made, set the stroke to white and the fill color to black.

Go to part 2

Posted in Android at January 24th, 2009. 12 Comments.