Functional Test and Integration Test Targets in Gradle

* Update February 13th, 2012: Thanks to Ben Ripkens for updates to match the new Gradle API.

While searching online, I found many suggestions for how to add a new test target to a Gradle script. Most of them were wrong and others didn’t properly separate the integration test target from standard targets. After not finding a solution, I came up with one on my own.

This example sets up integration tests for Groovy .

Create a source set

This will separate the integration test code from other code, allowing it to be built separately.

  • The classpath in the example gives integration tests access to all application and test classes
  • The source location will be src/integrationTest/groovy
sourceSets {
  integrationTest {
    compileClasspath = sourceSets.main.output + configurations.testRuntime
    runtimeClasspath = output + sourceSets.main.output + configurations.testRuntime
    groovy {
      srcDir 'src/integrationTest/groovy'
    }
  }
}

Add the target

 

task integrationTest(type: Test) {
  testClassesDir = sourceSets.integrationTest.output.classesDir
  classpath = sourceSets.integrationTest.runtimeClasspath
}

 

Posted in Java at January 11th, 2011. 3 Comments.

Antcall vs Depends

Occasionally, I see issues pop up on Java projects about builds not working properly.  They usually look like, “The build worked yesterday, but it doesn’t work today.  I was working on it, but I didn’t change anything related to the part that is failing.” or “I can’t figure out why, when I run this by itself, it passes.  When I run it as a part of a full build, it fails.”  Build errors are almost always caused by a misunderstanding of the function of “depends”.

How Not to Use Depends

This probably works, but only by chance.

<target name="test" depends="clean,compile,compile-test,test,service-test" />

Depends is not a list of tasks to be executed.  It’s a list of dependencies that must be satisfied before a target can be completed.  Execution is not guaranteed and side effects are common.  Take a close look at what each of the tasks in the following script is doing.

<target name="functional-test" depends="start-server,run-tests,stop-server" />
<target name="service-test" depends="start-server,run-service-tests,stop-server" />
<target name="test" depends="clean,compile,compile-test,functional-test,service-test" />

To a human, the intent is obvious.

  1. Clean and compile
  2. Start server
  3. Run functional tests
  4. Stop server
  5. Start server
  6. Run service tests
  7. Stop server

But Ant will not execute those tasks.  Since they were declared as dependencies, Ant evaluates them as such.  The functional tests will run as you would expect.  When it runs the service-test target, though, it will see the start and stop server tasks again.  As far as it’s concerned, those dependencies have already been satisfied, so it will skip start-server and stop-server.  Ant is evaluating the script correctly, but the script is wrong.

Dependencies are not tasks to be executed.  They are dependencies.  Once a dependency has been satisfied, it will not be executed again.

Antcall Is Not Evil

It exists for a reason.  Use it when it is useful.  Dependencies are dependencies, not task lists.  In this case, it would be impractical to try to write the script to use depends attributes to cause events to happen correctly.  It can be fixed very easily by using antcall.  Each antcall is evaluated separately, so you don’t have to worry about side effects like the script above.  It’s also easier to read.  You can see what’s intended to happen before this target and you can see what this target is intended to do.

<target name="functional-test" depends="start-server,run-tests,stop-server" />
<target name="service-test" depends="start-server,run-service-tests,stop-server" />
<target name="test" depends="clean,compile,compile-test">
  <antcall target="functional-test" />
  <antcall target="service-test" />
</target>

Use Your Own Judgement

Obviously, antcall should not be used instead of depends.  Depends is far more useful.  But don’t throw a tool like antcall away just because it doesn’t seem as cool or concise or elegant.

Posted in Java at September 17th, 2010. 4 Comments.

Guice BlazeDS’ MessageBroker

In a previous post (http://www.connorgarvey.com/blog/?p=132), I wrote about how to use Guice injection for Flex services.  I used web.xml to configure the MessageBrokerServlet and configured each Flex service to use Guice as a factory.  Since then, on this project, we’ve had to introduce new servlets.  Rather than continue to use web.xml’s verbose and fully-qualified-path based configuration, we moved to using Guice’s ServletModule class.  Here are the steps we followed.

  1. Ensure the guice-servlet.jar is included in your project and is deployed with your build.
  2. Add the Guice filter to web.xml.
    <filter>
      <filter-name>guiceFilter</filter-name>
      <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>guiceFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
  3. Create a servlet module, a class extending com.google.inject.servlet.ServletModule.
  4. Override the configureServlets() method of ServletModule and add the message broker servlet configuration.
    this.bind(MessageBrokerServlet.class).in(Scopes.SINGLETON);
    final Map<String, String> params = new TreeMap<String, String>();
    params.put("services.configuration.file", this.context
        .getRealPath("WEB-INF/config/flex/services-config.xml"));
    this.serve("/messagebroker/*").with(MessageBrokerServlet.class, params);

    1. Normally, servlets configured in Guice are tagged with @Singleton.  Since the MessageBrokerServlet is third party, it’s marked as a singleton here, in the module.
  5. Add the new module to the Guice servlet context listener, which should already be configured in web.xml.
  6. Remove the servlet and servlet-mapping from web.xml.
Posted in Guice at October 20th, 2009. 4 Comments.

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.

Testing in Android with mock UI components

As described in an earlier post, Android is not friendly to mocking frameworks or mock-style testing.  If you want to test any class in your application that deals with the Android API, it’s best to run your tests through the emulator, accessing real Android classes.  It’s unfortunate because you’re not just testing your application.  You’re also testing Android.  Anyway, here’s a way to mock a UI component.

If you’re just starting, here are a couple notes to keep you on the right track.

  • Android is bundled with JUnit 3.  Don’t try using an updated JUnit library or another testing framework.  The Android jar doesn’t contain any functional code, so all test cases have to be run in the emulator, which uses JUnit 3.  The test framework that will work best is in the Android API.
  • If you need basic implementations of Android classes, try to avoid mocking them.

“Mock”ing

In my latest test, I needed a TextView so that I could call the simplest method, setText(String).  I’ll describe how I got one.

Don’t bother with the android.test.mock package.  It just contains implementations of classes that throw UnsupportedOperationExceptions.  There isn’t anything there that I have yet found useful.

  1. In the test case, instead of extending TestCase, extend at InstrumentationTestCase or, if necessary, one of its subclasses.  It’ll set up most of the stuff that’s available in an Activity and make it available to your test case.
    public class AnAndroidTest extends InstrumentationTestCase {
  2. Create a mock implementation of TextView or the class you need.
    public class MockTextView extends TextView {
      public MockTextView(final Context context) {
        super(context);
      }
    }
  3. The TextView constructor needs a real Context object because it will call methods on it.  The context is difficult to mock because parts of it are private to Android.  Since the Android JAR is just an API and doesn’t have any functional code, you couldn’t even see the methods if you tried.  They only exist in the VM in the emulator.  AFAIK, if you can’t see a method, you can’t mock it.  That’s why your test case extends InstrumentationTestCase.  Put this in it.
    final TextView textView = new MockTextView(this.getInstrumentation().getContext());

Now write the test case.  The text view is real and has a fully functional context, so the emulator will have everything it needs to support your test case.

Posted in Android at June 1st, 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.

Spring annotations static injection tutorial

Spring’s architecture isn’t very friendly to static classes and methods.  It doesn’t have any way of injecting static properties of classes because it doesn’t have any way to discover them.  Spring’s designers have acknowledged that it’s a shortcoming of the framework and suggest the use of this solution.

  1. Create the static property of the class without any annotations
  2. Mark the class to have static properties injected with @Component so that the properties will be injected on Spring startup
  3. Create a non-static setter method that sets the static property
  4. Mark the setter method with @Autowired(required = true)
@Component
public class UserUtils
{
  private static UserAccessor userAccessor;
 
  /**
   * Sets the user DAO. This method should never be called except by Spring
   * @param userAccessor The user accessor to set
   */
  @Autowired(required = true)
  public void setUserAccessor(userAccessor UserAccessor) {
    UserUtils.userAccessor = userAccessor;
  }
}

Using this technique, you can have all of the advantages of Spring injection without the headaches of Spring injection!  Avoid using this technique whenever possible.  It should only be used to support legacy applications.  With a lot of statically stored values, your application will not scale well.

Posted in Spring at February 11th, 2009. 12 Comments.

Android button tutorial

A lot of people have found this site by searching for an Android button tutorial, so here it is.

  1. This tutorial assumes that you already have an activity and are using an XML layout.
  2. Open the layout XML and add the button element.  Assign an ID with the “@+id” operator.  The + tells Android to generate an ID for this element so that you can reference it in your Java files.
    1. This is an example. Your layout and text elements will probably be very different. In this example case, the ID of the button is “close”.
      <Button android:id="@+id/close"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:text="@string/title_close" />
  3. Open the activity class.  Add a class property to hold a reference to the button.
    private Button closeButton;
  4. If you haven’t already, override the onCreate method.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    }

    1. For this example, we don’t need the saved instance state, so ignore it.
  5. Now, in the onCreate method, attach a listener to the click event for the button.  This example will call “finish()” on the activity, the Android analog of clicking the close button on a window.
protected void onCreate(Bundle savedInstanceState) {
  this.setContentView(R.layout.layoutxml);
  this.closeButton = (Button)this.findViewById(R.id.close);
  this.closeButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
      finish();
    }
  });
}
  1. Here’s a short description of what’s happening.
    1. First, get the button ID.  The ID created earlier in the layout, “close”, is compiled by Android and assigned a unique integer ID which is available to the application through the “R” class, which I assume is short for “Resources”.
    2. Request a reference to the button from the activity by calling “findViewById”.  The button has to be retrieved from the activity because while an ID is unique in an activity, it is not unique among all activities.
    3. Assign the retrieved button to an instance variable so that if you need it later, you can easily find it without having to query for it again.
    4. Create a class implementing “OnClickListener” and set it as the on click listener for the button.

As UI elements go, buttons are some of the simplest.  Later, I’ll write about menus and dialogs, which aren’t so easy.

Posted in Android at January 31st, 2009. 96 Comments.

A recursive toString method for trees

While working on a project that uses Hibernate, my team was getting a little frustrated while trying to interrogate a tree structure in our data model since all collections are mapped as java.util.HashSets.  We wanted a simple function that could print the tree to the log, so I took a free hour and wrote this.  It was a little more complicated than I anticipated because it had to handle situations like these.

root
   |
   |- child
   |
   |- child

root
   |
   |- child
      |
      |- child

and the infamous (to me) …

root
   |
   |- child
   |   |
   |   |- child
   |       |
   |       |- child
   |
   |- child

There’s a subtle difference.  Notice that in the middle one, the line for the first child stops because there aren’t any more children, but in the last one, the line continues?  I could have created some kind of 2D text buffer and gone back to draw the line, but that would be boring.  Here’s what I came up with. I don’t know whether it’s pretty, but it works!

/**
 * Creates a tree representation of the node
 * @param node The node, which may not be null
 * @return A string containing the formatted tree
 */
public static String toStringTree(Node node) {
  final StringBuilder buffer = new StringBuilder();
  return toStringTreeHelper(node, buffer, new LinkedList<Iterator<Node>>()).toString();
}
 
private static void toStringTreeDrawLines(List<Iterator<Node>> parentIterators, boolean amLast) {
  StringBuilder result = new StringBuilder();
  Iterator<Iterator<Node>> it = parentIterators.iterator();
  while (it.hasNext()) {
    Iterator<Node> anIt = it.next();
    if (anIt.hasNext() || (!it.hasNext() && amLast)) {
      result.append("   |");
    }
    else {
      result.append("    ");
    }
  }
  return result.toString();
}
 
private static StringBuilder toStringTreeHelper(Node node, StringBuilder buffer, List<Iterator<Node>>
    parentIterators) {
  if (!parentIterators.isEmpty()) {
    boolean amLast = !parentIterators.get(parentIterators.size() - 1).hasNext();
    buffer.append("\n");
    String lines = toStringTreeDrawLines(parentIterators, amLast);
    buffer.append(lines);
    buffer.append("\n");
    buffer.append(lines);
    buffer.append("- ");
  }
  buffer.append(node.toString());
  if (node.hasChildren()) {
    Iterator<Node> it = node.getChildNodes().iterator();
    parentIterators.add(it);
    while (it.hasNext()) {
      Node child = it.next();
      toStringTreeHelper(child, buffer, parentIterators);
    }
    parentIterators.remove(it);
  }
  return buffer;
}
Posted in Java at January 30th, 2009. No Comments.