Friday, October 11, 2013

CSS Custom Cursor that works in IE and Chrome

Frustration with CSS cursor.

This works in Chrome, Firefox and IE (8) (although I can't seem to get this snippet working in IE 8 on my blog)

<P style="cursor: url(/path/to/grab.png), url(/path/to/grab.cur),auto;">
   Text.
</P>

Problems I faced getting this to work.

  1. PNG file works fine on Chrome, not in IE.
  2. CUR file works find in IE, but not in Chrome.
  3. Had to download a program to make CUR files. RealWorld Cursor Editor worked.
  4. But Windows always re-sizes cursor files to 32 pixels x 32 pixels. So I had to resize the image in cur format to fit within the top left quadrant of a 32 pixels x 32 pixels image.
  5. Have to put reference to both file formats in the CSS property, and it wouldn't work in Chroms until I put the auto at the end. cursor: url(/path/to/grab.png), url(/path/to/grab.cur),auto;.

Page that helped me with this:

  1. W3Schools demo page for cursors.

Wednesday, September 04, 2013

Load Java Properties file from relative or absolute path

/**
 * Load properties.
 *
 * @param propertiesFile
 *            path to properties file
 * @return filled in properties object
 * @throws IOException
 *             if something goes wrong
 */
private Properties loadProperties(final String propertiesFile)
      throws IOException {
   // Properties object we are going to fill up.
   Properties properties = new Properties();
   // If file exists as an absolute path, load as input stream.
   final Path path = Paths.get(propertiesFile);
   if (Files.exists(path, LinkOption.NOFOLLOW_LINKS)) {
      properties.load(new FileInputStream(propertiesFile));
   } else {
      // Otherwise, use resource as stream.
      properties.load(getClass().getClassLoader().getResourceAsStream(
            propertiesFile));
   }
   return properties;
}

Sunday, March 31, 2013

Nulls and varargs

I needed to work out how you can invoke methods that have varargs when you don't actually have anything to send for that parameter. Below are the lessons I have learned and below that is the JUnit test that proves it. I am using JDK 7.

  1. When a method has a varargs argument, you can completely ignore it and not put anything at all in that place.
  2. A varargs parameter always has a type, and you can send a single value of that type - or an array of that type.
  3. The array can be empty - but your code should be able to deal with that.
  4. The parameter can be null, although Eclipse wants you cast the null - and your code must be prepared to deal with nulls (or you will throw a NullPointerException).
  5. When using mockit.Deencapsulation to invoke a method that accepts varargs, you cannot ignore the parameter; it has to have something there or JMockit will throw an IllegalArgumentException.
  6. mockit.Deencapsulation throws an IllegalArgumentException if you send null (cast or not) in place of the varargs because null isn't enough information for JMockit to work out what type of argument it is.
  7. You can tell mockit.Deencapsulation to send null in place of the varargs by using a X[].class as the parameter (where X is the type expected by varargs) - and your code must be prepared to deal with nulls (or you will throw a NullPointerException). See http://bit.ly/ZMYZuR.

Here is the test.

import static org.junit.Assert.assertNotNull;

import java.nio.file.Paths;

import mockit.Deencapsulation;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test var args. What calling a method with varargs, you can totally leave out
 * the vararg parameter, but you cannot use null - unless you cast it. But you
 * also can't use a null (even a casted one) when you are using JMockit
 * {@link Deencapsulation#invoke(Class, String, Object...)}.
 *
 * @author RobertMarkBram
 */
@RunWith(JUnit4.class)
public final class TestVarArgs {

  /**
   * A method with var args.
   *
   * @param first
   *           first path
   * @param more
   *           the rest - may be null
   */
  public void readFiles(final String first, final String... more) {
    if (more == null || more.length == 0 || more[0] == null) {
      assertNotNull(Paths.get(first).toString());
    } else {
      assertNotNull(Paths.get(first, more).toString());
    }
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg should
   * work. Completely ignoring the vararg.
   */
  @Test
  public void callMethodWithOneArg() {
    readFiles("C:/Temp");
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and an
   * empty string should work.
   */
  @Test
  public void callMethodWithOneArgAndEmptyString() {
    readFiles("C:/Temp", "");
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and an
   * empty array should work.
   */
  @Test
  public void callMethodWithOneArgAndEmptyArray() {
    String[] empty = {};
    readFiles("C:/Temp", empty);
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and an
   * array with a blank string should work.
   */
  @Test
  public void callMethodWithOneArgAndArrayWithEmptyString() {
    String[] empty = { "" };
    readFiles("C:/Temp", empty);
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and a null
   * works, but you have to do a null check on the varargs in case it is null.
   * Plus, Eclipse gives you a warning for not casting null as vararg.
   */
  @Test
  @SuppressWarnings("all")
  public void callMethodWithOneArgAndNull() {
    readFiles("C:/Temp", null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and a null
   * cast to the expected type works, but you have to do a null check on the
   * varargs in case it is null.
   */
  @Test
  public void callMethodWithOneArgAndStringCastNull() {
    readFiles("C:/Temp", (String) null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} with just one arg and a null
   * cast to the expected type works, but you have to do a null check on the
   * varargs in case it is null.
   */
  @Test
  public void callMethodWithOneArgAndCastNull() {
    readFiles("C:/Temp", (String[]) null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg fails with an {@link IllegalArgumentException} because JMockit
   * requires a valid varargs argument, i.e., not null.
   *
   * @see http://bit.ly/ZMYZuR
   */
  @Test(expected = IllegalArgumentException.class)
  public void callMethodWithOneArgJmockit() {
    Deencapsulation.invoke(this, "readFiles", "C:/Temp");
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg fails with an {@link IllegalArgumentException} because JMockit
   * requires a valid varargs argument, i.e., not a single element of the
   * array.
   *
   * @see http://bit.ly/ZMYZuR
   */
  @Test(expected = IllegalArgumentException.class)
  public void callMethodWithOneArgAndEmptyStringJmockit() {
    Deencapsulation.invoke(this, "readFiles", "");
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and an empty array should work.
   */
  @Test
  public void callMethodWithOneArgAndEmptyArrayJmockit() {
    String[] empty = {};
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", empty);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and an array with a blank string should work.
   */
  @Test
  public void callMethodWithOneArgAndArrayWithEmptyStringJmockit() {
    String[] empty = { "" };
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", empty);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and a null fails with an {@link IllegalArgumentException} because
   * JMockit requires a valid varargs argument, i.e., not null.
   *
   * @see http://bit.ly/ZMYZuR
   */
  @Test(expected = IllegalArgumentException.class)
  public void callMethodWithOneArgAndNullJmockit() {
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and a null cast to the expected type fails with an
   * {@link IllegalArgumentException} because JMockit requires a valid varargs
   * argument, i.e., not null.
   *
   * @see http://bit.ly/ZMYZuR
   */
  @Test(expected = IllegalArgumentException.class)
  public void callMethodWithOneArgAndCastNullJmockit() {
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", (String[]) null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and a null cast to the expected type fails with an
   * {@link IllegalArgumentException} because JMockit requires a valid varargs
   * argument, i.e., not null.
   *
   * @see http://bit.ly/ZMYZuR
   */
  @Test(expected = IllegalArgumentException.class)
  public void callMethodWithOneArgAndStringCastNullJmockit() {
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", (String) null);
  }

  /**
   * Calling {@link #readFiles(String, String...)} via JMockit with just one
   * arg and a null cast to the expected type fails with an
   * {@link IllegalArgumentException} because JMockit requires a valid varargs
   * argument, i.e., not null.
   *
   * @see http://bit.ly/ZMYZuR
   */
  public void callMethodWithOneArgAndNullArrayJmockit() {
    Deencapsulation.invoke(this, "readFiles", "C:/Temp", String[].class);
  }
}

Further reading.

Saturday, March 30, 2013

Use ThreadLocal for shared objects that are not thread-safe

In my last post, Just date, no time: comparing java.util.Date with org.joda.time.DateMidnight, I outlined one reason for using Joda Time over java.util date/time classes (like java.util.Date and java.util.GregorianCalendar) was thread safety.

To be honest, thread safety with java.util.Date isn't likely to be a problem - because most of the time a date will be an instance field in a mutable data object rather than a shared utility object that multiple threads will use at the same time. What you should look out for are objects that are likely to be shared (like GregorianCalendar, DecimalFormat and SimpleDateFormat). Any time you think "I should really make this a static constant so that multiple methods can share it", check the Javadocs for that object to see if it is mutable. Mutable objects that are shared may cause race conditions if they are accessed by multiple threads at the same time. For example, the below objects are mutable and commonly used as shared utility objects in a single class or entire application.

  • GregorianCalendar: it has setter/mutator methods that change it's state.
  • DecimalFormat: Javadocs say if multiple threads access a format concurrently, it must be synchronized.
  • SimpleDateFormat: Javadocs say if multiple threads access a format concurrently, it must be synchronized externally.

The easiest way to make the above objects thread-safe is to use java.lang.ThreadLocal. This means that every thread may have one copy of the object. Below is an example of this.

/** Each thread may have once copy of DATE_FORMAT. */
public static final ThreadLocal<SimpleDateFormat> DATE_FORMAT =
      new ThreadLocal<SimpleDateFormat>() {
         @Override
         protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy/MM/dd HH:mm:s:S");
         }
      };

/** This method uses a thread local version of the formatter. */
public void outputDate() {
   Date date1 = new Date();
   System.out.println(DATE_FORMAT.get().format(date1));
}

Each thread that executes outputDate() will create its own copy of SimpleDateFormat. It solves synchronization issues because no two threads will ever access the same copy of the object at the same time. If your application has 20 threads, then you will have up to 20 copies of SimpleDateFormat: a thread that never executes outputDate() - or any method that uses DATE_FORMAT.get() - will never create its own SimpleDateFormat.

Use this technique for GregorianCalendar, DecimalFormat and SimpleDateFormat. It is safe for most applications because the cost of one of these objects per thread is not high. It is safe for web applications too. In web apps, you are not meant to create your own threads - and you are not doing that here: the web container is the one creating and managing threads, not you.

When not to use this technique:

  • Don't use this technique for objects that must be singletons within an application.
  • Don't use this technique where you must not have multiple threads accessing the same instance (this should be a singleton or have synchronization).
  • Don't use this technique for objects that are heavy enough to break an application if you have multiple copies in memory at the same time.

Other Ways To Solve Thread Safety Issues

There are many ways to solve issues that arise from sharing the same instance of an object. Below is a brief discussion of the most common techniques I know about.

  1. Avoid sharing altogether by keeping the object local. This means every time you need a Calendar, DecimalFormat or SimpleDateFormat etc, declare and initialise the object within each method that uses it.
    private void outputDate(Date date) {
       SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:s:S");
       System.out.println("Date is [" + formatter.format(date) + "]");
    }
    No other method or thread will ever share the same instance so you will never have a synchronization problem. But you will have other problems.
    • DRY: Don't Repeat Yourself. If you have more than one method that needs to input or output dates in the same format, they should use the same formatter. If each method has their own formatter (using the same format string) subtle errors may arise when you need to change the format, but forget to make the change to each formatter.
    • Object creation overhead. Let's say your application has to call outputDate() a few million times. Your application will be slower because it is creating a SimpleDateFormat X million times when it should be creating it just once.
  2. Use a single shared object, but synchronize each use of it. For example, see below.
    synchronized (FORMATTER) {
       System.out.println("Date is [" + FORMATTER.format(date) + "]");
    }
    
    For a singleton that has state, you will most likely need to use synchronization. No other method or thread will ever get to use the same object at the same time. But you may have other problems.
    • Choke points. synchronization can make applications slower in two ways: the overhead of maintaining locks and the cost of having multiple threads waiting on the currently locked thread. The first isn't much of a problem, but the second may be. If the actions performed in the synchronized block take a long time, then all the other threads that are waiting on the synchronized resource must wait. Sometimes this is necessary, but it is still worth considering if there are other ways of solving the problem (can you have multiple copies of the synchronized resource?).
    • Deadlocks. This type of error can be very hard to debug. A deadlock arises where two or more threads are each waiting for the other to finish, and therefore neither thread can ever finish.
  3. Having multiple copies of the shared resource. If the problem allows you to have multiple copies of the same resource, this can help you avoid synchronization issues. There a couple of ways to do this.
    • Object pooling. This technique involves having a group (or pool) of shared objects. Whoever needs one of the objects takes it from a the pool and releases it when finished. Multi-threaded applications use thread pools. Databases uses connection pools. Web servers use HTTP connection pools. Apache Commons has a Pool Component. This is a good way to control the number of shared objects you wish to have in use, but will often need tuning to make sure that your application has enough objects in the pool to satisfy demand but not so many objects that they take up too much of your finite resources at once.
    • Thread local storage (the subject of this post) is similar to object pooling in that you have multiple objects. However, instead of having a common pool of objects that a limited number of threads can share at once, under thread local storage, every thread can potentially have it's own copy of the object. A pool may have 4 objects to be shared among 10 threads; with thread local storage, you will have up to 10 objects - once for each thread.

ThreadLocal vs synchronization

One more issue that needs discussion here is when to use ThreadLocal vs synchronization. Either technique will work for GregorianCalendar, DecimalFormat and SimpleDateFormat - but only the former (ThreadLocal) is appropriate. Below is one question you should ask yourself when determining which technique is most appropriate for your situation.

Is it necessary for multiple threads to access the same instance of the share object?

If you must have only one copy of an object, use synchronization. For example, consider a bank account in a banking application that has two transactions occurring at the same time. The account has $20 in it and two people are attempting to withdraw $15 at the same time: only one of these transactions can succeed. Logically speaking, there is only one instance of the $20 balance, so you can only have one copy of the account in your application at once. Use synchronization so that only one transaction occurs at a time; the second will fail because there are insufficient funds.

Just date, no time: comparing java.util.Date with org.joda.time.DateMidnight

In my current application I am dealing with date input; no times are involved. Therefore it is important that in my code, every date has the same time so that they compare correctly. All java.util.Date objects have a time attached, and if you use the default constructor, they will reflect the time at which they were created, down to the millisecond. It means that two dates constructed at different times are not the same, as you can see from the below code.

Date date1 = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:s:S");
Date date1 = new Date();
try {
   Thread.sleep(1000);
} catch (InterruptedException e) {
   e.printStackTrace();
}
Date date2 = new Date();
System.out.println("date1.compareTo(date2) [" + date1.compareTo(date2) + "]");
System.out.println("date 1: " + formatter.format(date1));
System.out.println("date 2: " + formatter.format(date2));

The output of this code is below.

date1.compareTo(date2) [-1]
date 1: 2013/03/30 19:59:58:470
date 2: 2013/03/30 19:59:59:470

So when dealing with dates in Java, I need to make sure all my dates have the same time. I will show below how you can do this with java.util.Date and compare it with a convenience class in Joda Time called org.joda.time.DateMidnight.

Why Joda Time?

  1. Joda Time is more concise and easier to use than Java's in-built time classes. For example, java.util.Date.getHours() is deprecated and says you should use java.util.Calendar.get(Calendar.HOUR_OF_DAY). Joda Time's base time class - org.joda.time.base.AbstractDateTime - has getHourOfDay().
  2. java.util.Date and java.util.Calendar are not thread-safe. Joda time has org.joda.time.DateMidnight and org.joda.time.DateTime which are thread-safe (or org.joda.time.MutableDateTime if you need a version that can be modified - and thus not thread-safe).
    • What makes them not thread-safe? java.util.Date and java.util.Calendar objects can be changed after they are created: they are mutable; they have setter/mutator methods. Even though these methods are deprecated, they are still there and can still introduce subtle bugs in your code if used.
    • java.util.Date's javadoc says to use java.util.Calendar (which usually means java.util.GregorianCalendar) when you need to change the date/time (and then call getTime() to get a new date object with the modified data). To convert dates to strings or vice versa, use java.text.SimpleDateFormat. Unfortunately, none of these are thread-safe: java.util.Date, java.util.Calendar, java.util.GregorianCalendar and java.text.SimpleDateFormat.
    • So what? For single threaded applications this is not important. But for any application that uses multiple threads, it is very important. If logic from more than one thread changes the state of a single object they each rely on, it may make the results un-predictable. For example: thread 1 is changing a calendar object to be some date in 2000 while thread 2 is changing the same calendar object to be some date in 2013. If those instructions happen to execute at the same time, both threads might end up with a date different to what they are expecting. Any web application is multi-threaded. This means that instance variables of these may have their state changed in unpredictable ways in a web-app. There are still ways around this.
      • Use them as local variables that live and die within one single methods's scope.
      • Take steps to make them thread-safe, such as using synchronised blocks or (much better) embedding them in a java.lang.ThreadLocal instance).

Here is my code comparing uses of Java's time with Joda Time.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.DurationFieldType;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public final class TestDates {

   public static void main(String[] args) {
      gregorian();
      joda();
   }

   public static void gregorian() {
      System.out.format("%34s%n", "--- java.util ---");
      SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:s:S");

      // Default date.
      GregorianCalendar calendar1 = new GregorianCalendar();
      Date date1 = calendar1.getTime();
      System.out.format("%34s %s%n", "Default date", formatter.format(date1));

      // Set date through constructor.
      GregorianCalendar calendar2 =
            new GregorianCalendar(2013, Calendar.APRIL, 30);
      Date date2 = calendar2.getTime();
      System.out.format("%34s %s%n", "Set date through constructor",
            formatter.format(date2));

      // Set date through modifier methods.
      GregorianCalendar calendar3 = new GregorianCalendar();
      calendar3.set(Calendar.YEAR, 2013);
      calendar3.set(Calendar.MONTH, Calendar.APRIL);
      calendar3.set(Calendar.DAY_OF_MONTH, 29);
      calendar3.set(Calendar.HOUR_OF_DAY, 0);
      calendar3.set(Calendar.MINUTE, 0);
      calendar3.set(Calendar.SECOND, 0);
      calendar3.set(Calendar.MILLISECOND, 0);
      Date date3 = calendar3.getTime();
      System.out.format("%34s %s%n", "Set date through modifier methods",
            formatter.format(date3));

      // Parsing a date from a string.
      try {
         Date date4 = formatter.parse("2013/04/29 00:00:0:0");
         System.out.format("%34s %s%n", "Parsing a date from a string",
               formatter.format(date4));
      } catch (ParseException e) {
         System.err.println("Unable to parse date");
         e.printStackTrace();
      }
   }

   public static void joda() {
      System.out.format("%34s%n", "--- org.joda.time ---");
      DateTimeFormatter DATE_FORMAT =
            DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:s:S");

      // Default date.
      DateMidnight date1 = new DateMidnight();
      System.out.format("%34s %s%n", "Default date", DATE_FORMAT.print(date1));

      // Set date through constructor.
      DateMidnight date2 = new DateMidnight(2013, DateTimeConstants.APRIL, 30);
      System.out.format("%34s %s%n", "Set date through constructor",
            DATE_FORMAT.print(date2));

      // Set date based on another date (DateMidnight is immutable, so you
      // cannot change it's state, but it has convenience methods to let you
      // easily make a new date from an existing date.
      DateMidnight date3 = date2.withFieldAdded(DurationFieldType.days(), -1);
      System.out.format("%34s %s%n", "Set date based on another date",
            DATE_FORMAT.print(date3));

      // Parsing a date from a string.
      DateTime date4 = DATE_FORMAT.parseDateTime("2013/04/29 00:00:0:0");
      System.out.format("%34s %s%n", "Parsing a date from a string",
            DATE_FORMAT.print(date4));
   }
}

The output from the code above is here.

                 --- java.util ---
                      Default date 2013/03/30 19:16:56:685
      Set date through constructor 2013/04/30 00:00:0:0
 Set date through modifier methods 2013/04/29 00:00:0:0
      Parsing a date from a string 2013/04/29 00:00:0:0
             --- org.joda.time ---
                      Default date 2013/03/30 00:00:0:0
      Set date through constructor 2013/04/30 00:00:0:0
    Set date based on another date 2013/04/29 00:00:0:0
      Parsing a date from a string 2013/04/29 00:00:0:0

Conclusions

For dealing with just dates (no times), org.joda.time.DateMidnight is less verbose than using a combination of java.util.Calendar and java.util.Date. You can see from the code examples above, that using java.util involves using a calendar to set the date and then using getTime() to get a java.util.Date. With Joda Time, I can work directly with a DateMidnight object. Although I can change the date on a calendar to get a new java.util.Date, with DateMidnight I can use convenience methods on it to get a new DateMidnight with different state.

Further reading.

Tuesday, March 26, 2013

Testing a private method through Reflection of JMockit

I came across a private method that I wanted to unit test. It was a lynch-pin in the algorithm and needed to be tested independently of its callers to resolve an issue I was experiencing with it. Usually you will test private methods indirectly by thoroughly testing the public methods with enough variation in the parameters to make you reasonably sure that you have tested all states the private method can be put through. But sometimes you just want to test the private method directly.

One way is to make it public or protected. However, I don't think changing the visibility of a method just to enable testing is a good design choice.

Or you could use Java Reflection. Or you could use JMockit De-encapsulation (which uses reflection). JMockit's de-encapsulation is intended to allow mocking of private methods, but it can be used to invoke them directly as well.

Below I will give examples of how to invoke a method using both reflection and JMockit de-encapsulation.

First is the example class with a private method, ripe for the testing.

public class StringParser {
   private String[] parseString(final String listOfNames) {
      return listOfNames.split(",");
   }
}

And here is my test code.

import static org.junit.Assert.assertArrayEquals;
import java.lang.reflect.Method;
import mockit.Deencapsulation;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public final class TestStringParser {

   /** Test a private method with JMockit. */
   @Test
   public void testStringParsingJmockit() {
      // Create the object containing the private method I will test.
      StringParser tested = new StringParser();
      // This is the result I expect to receive from the method being tested.
      String[] expected = { "one", "two", "three" };
      // Invoke the private method, getting the actual results.
      // tested: the object containing the private method.
      // "parseString": name of the private method.
      // "one,two,three": the argument I want to send to the private method.
      String[] actual =
            Deencapsulation.invoke(tested, "parseString", "one,two,three");
      // Test that the expected results match the actual results.
      assertArrayEquals("Parsed list not as expected.", expected, actual);
   }

   /** Test a private method with Java Reflection.
    * @throws Exception
    *            if there are issues with Reflection such as method not existing
    */
   @Test
   public void testParsingForCommas() throws Exception {
      // Create the object containing the private method I will test.
      StringParser tested = new StringParser();
      // This is the result I expect to receive from the method being tested.
      String[] expected = { "one", "two", "three" };
      // Create a "Method" object representing the private method I will test.
      // "parseString": name of the private method.
      // String.class: the TYPE of argument I want to send to the private method.
      Method declaredMethod =
            tested.getClass().getDeclaredMethod("parseString", String.class);
      // Tell Java to make the private method callable by outside code.
      declaredMethod.setAccessible(true);
      // Invoke the private method, getting the actual results.
      // tested: the object containing the private method.
      // "one,two,three": the argument I want to send to the private method.
      String[] actual =
            (String[]) declaredMethod.invoke(tested, "one,two,three");
      // Test that the expected results match the actual results.
      assertArrayEquals("Parsed list not as expected.", expected, actual);
   }

}

I received help on how to do the JMockit code from a couple of very useful forums.

Thursday, March 21, 2013

Eclipse and JMockit: Method should have no parameters

I am testing out JMockit in Eclipse and I find an error I didn't expect with my very first test. I am using jmockit-1.1, JUnit 4, Java SE 1.7, Juno Service Release 1.

I have the following code as a jUnit test in Eclipse.

package rmb.budget.reader;

import mockit.Mocked;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class TestReader {
  @Test
  public void testReader(
      @Mocked MyReader reader) {
  }
}
When I run this, I get the below error.
java.lang.Exception: Method testReader should have no parameters
  at org.junit.runners.model.FrameworkMethod.validatePublicVoidNoArg(FrameworkMethod.java:69)
  at org.junit.runners.ParentRunner.validatePublicVoidNoArgMethods(ParentRunner.java:131)
  at org.junit.runners.BlockJUnit4ClassRunner.validateTestMethods(BlockJUnit4ClassRunner.java:178)
  at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:163)
  at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:102)
  at org.junit.runners.ParentRunner.validate(ParentRunner.java:344)
  at org.junit.runners.ParentRunner.(ParentRunner.java:74)
  at org.junit.runners.BlockJUnit4ClassRunner.(BlockJUnit4ClassRunner.java:55)
  at org.junit.runners.JUnit4.(JUnit4.java:20)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
  at java.lang.reflect.Constructor.newInstance(Unknown Source)
  at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
  at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
  at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
  at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
  at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
  at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

My understanding from the JMockit Getting Started page is that it very definitely should be possible to use (mocked) parameters in @Test methods.

import org.junit.*;
import mockit.*;

public class MyFirstJMockitTest {
   @Test
   public void testMethodWithMockParameter(
         @Mocked YetAnotherDependency testSpecificMock) {
   }
}

I raised a bug report but was soon put right by the JMockit developer, Rogerio Liesenfeld. I had two things wrong.

  • In your .classpath file, the JMockit jar must appear before JUnit. For example.
    <classpathentry kind="lib" path="lib/jmockit-1.1.jar"/>
    <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
    
  • I was using the vanilla JRE in my project, which fails if you don't use the -javaagent JVM parameter. I found it easier to swap over to a JDK version of Java SE instead (which you can get from the Oracle Java SE download page). I already had it installed - what Java developer wouldn't? (This resulted from having just made my Eclise Java project with default options selected in a newly created workspace.) So now I was using a proper JDK in my project.
    Use a JDK for development in Eclipse, not a vanilla JRE.

Friday, March 15, 2013

Implementing a Generics Based Java Factory Method

Beyond adding a type to a Collection, I still need a reminder about how to do more complicated things with generics! So, primarily for my own reference, here is an example of implementing a generics-based Java factory method.

public abstract class PrintingDelegate {
   public static PrintingDelegate getInstance(
         final Class<? extends PrintingDelegate> delegateClass) {
      try {
         return delegateClass.newInstance();
      } catch (Exception e) {
         throw new IllegalArgumentException(e);
      }
   }
}
public final class PrintingDelegateXxx extends PrintingDelegate { ... }
public final class PrintingDelegateYyy extends PrintingDelegate { ... }

I got this from Roland Illig's answer to this StackOverflow post: Am I implementing a generics-based Java factory correctly?

Tuesday, March 12, 2013

Nested Data Sets with Input Parameters in BIRT

Update: Monday 23 June 2014, 12:58:32 PM - added missing documentation about Data Set Parameter Binding.

Earlier, I was having trouble with nested data sets in a BIRT report (Juno Service Release 1, BIRT 4.2.1)

I created a sample report where each row in the outer data set contained a list - the values for the inner data set. I was trying to use a Report Variable to hold that list and it wasn't working. You can see the code for that example in this pastebin post. It seems as though the outer data set is being completely evaluated before the inner data set - so that the inner data set is always left with the last value stored in the report variable.

The solution I found was to abandon report variables, and instead use Data Set Parameters whereby the outer data set will directly pass values to the inner data set. In this post, I will show how to do that.

Firstly, here is the complete source for the working report using Data Set Parameters to pass data from the outer data set to the inner: http://pastebin.com/3ehAahDj. It is a completely self contained example: the data is set up in the Scripted Data Set portion.

Next, here are instructions on how to set up data set parameters.

  1. In the Outer Data Set, create a column to represent the data that you will send to the Inner Data Set.
    1. Right click on the Outer Data Set and select Edit. It doesn't matter if the Outer Data Set will not directly use this data. In this situation, the Outer Data Set will not display this data - just pass it to the Inner Data Set.
    2. Click on Output Columns.
    3. Click Add and give the column a name and data type. The column, valuesForInner, is a Java Object in this case because it will be a list of values (java.util.ArrayList).
      Create Output Column in Outer Data Set for the data you will send to the Inner Data Set.
  2. In the Outer Data Set's fetch method, retrieve the data that you will send to the Inner Data Set.
    row["valuesForInner"] = value;
  3. In the Inner Data Set, create a parameter to represent the data being passed to it from the Outer Data Set.
    1. Right click on the Inner Data Set and select Edit.
    2. Click on Parameters.
    3. Click Add and give the parameter a name, data type and default value. The column, valuesFromOuter, is a Java Object (it will be a java.util.ArrayList) and its default value is null.
      Setting a parameter for the Inner Data Set - which will be passed to it from the Outer Data Set
  4. In the Inner Data Set, create a column to represent individual elements from data (a list) sent from the Outer Data Set through the parameter you just created.
    1. Right click on the Inner Data Set and select Edit.
    2. Click on Output Columns.
    3. Click Add and give the column a name and data type. The column, value, is a string - one element from the java.util.ArrayList input parameter above.
      Create Output Column in Inner Data Set for the data sent from the Outer Data Set.
  5. In the Inner Data Set's open method, retrieve the data from the parameter (which is a list - so I am getting an iterator() from it.
    values = inputParams["valuesFromOuter"].iterator();
  6. In the Inner Data Set's fetch method, populate the Output Column from list passed in through the input parameter.
    if (!values.hasNext() ) {
       return false;
    }
    row["value"] = values.next();
    return true;
          

Lastly, on the List that is making use of the Inner Data Set, go to the Property Editor, Binding tab and click on the "Data Set Parameter Binding" button.

When you click on the "Data Set Parameter Binding" button, make sure that it has a row binding the output column of your Outer Data Set to the correct Input Parameter of your Inner Data set for that usage of the List.

Here is the result. Pretty huh? :)

Preview of the report showing that data sent to the inner data set updates correctly

I asked about how to fix the original report in a few different places that you may find helpful when troubleshooting BIRT issues.

Friday, March 01, 2013

Template toString(), hasCode() and equals() in Eclipse

I am using the following template in Eclipse to output a standard pattern for toString(), hashCode() and equals(). By default I use Apache commons lang.

   @Override
   public String toString() {
      return new org.apache.commons.lang.builder.ToStringBuilder${cursor}(this).append("some field", someField)
            .append("some field", someField).toString();
   }

   @Override
   public int hashCode() {
      return new org.apache.commons.lang.builder.HashCodeBuilder()
            .append(someField).append(someField).toHashCode();
   }

   @Override
   public boolean equals(final Object obj) {
      if (obj == this) {
         return true;  // test for reference equality
      }
      if (obj == null) {
         return false; // test for null
      }
      if (obj instanceof ${enclosing_type}) {
         final ${enclosing_type} other =
               (${enclosing_type}) obj;
         return org.apache.commons.lang.ObjectUtils.equals(someField, other.someField)
               && ObjectUtils.equals(someField, other.someField);
      } else {
         return false;
      }
   }

In Eclipse, I enter this through Window > Preferences > Java > Editor > Templates > click New, and enter details as below.

Template I use in Eclipse for toString(), hashCode() and equals() - click to expand

Note that I include the fully qualified name of the utility classes (such as org.apache.commons.lang.builder.HashCodeBuilder) just once so that I can easily import them through Eclipse by clicking on the fully qualified name and pressing control+shift+m.

As mentioned above, I am using Apache commons lang by default. However as explained by Sean Patrick Floyd in this StackOverflow post, guava-libraries are also a good choice. Java 7's Objects class has an equals(Object a, Object b) utility method that will serve for part of this too.

Although toString(), hashCode() and equals() may seem simple enough, there are many pitfalls to be aware of when implementing these methods. I recommend reading Effective Java (2nd Edition) by Joshua Bloch to learn more (available as an Amazon Kindle eBook).

JUnit Tests can still be run from a main method

I encountered a happy coincidence today: a JUnit test can just as easily be run from a main method. (Feel free to whisper sarcastically at this point. It was new to me!) I had begun with an old school main method test, when I realised I wanted to get more serious and write JUnit tests instead. I dutifully added my @Test methods and in an absent minded fashion ran the class as a Java application instead of a JUnit test (from within Eclipse). Lo and behold, whatever @Test method I called from main still works fine and gives meaningful error information if it fails.

package test;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class Tester {

 public static void main(String[] args) {
  Tester tester = new Tester();
  tester.testSomething();
  System.out.println("Test complete.");
 }

 @Test
 public void testSomething() {
  Assert.assertEquals(true, false);
 }
}

And the output when this test fails.

Exception in thread "main" junit.framework.AssertionFailedError: expected:<true> but was:<false>
   at junit.framework.Assert.fail(Assert.java:50)
   at junit.framework.Assert.failNotEquals(Assert.java:287)
   at junit.framework.Assert.assertEquals(Assert.java:67)
   at junit.framework.Assert.assertEquals(Assert.java:147)
   at junit.framework.Assert.assertEquals(Assert.java:153)
   at test.Tester.testSomething(Tester.java:20)
   at test.Tester.main(Tester.java:14)

Wednesday, February 27, 2013

Enums in an Eclipse Scrapbook page

I was trying to do some quick testing of enums in an Eclipse Scrapbook (a jpage file). I am using JDK 1.7.0_02, Win XP 64-bit, Eclipse Juno.

class A {
    enum Month {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}
}
A a = new A();

When I execute the above snippet I get this error:

The member enum Month can only be defined inside a top-level class or interface

I tried moving the enum out of the class definition with the following code.

enum Month {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}
Month.valueOf("JAN");

And I still get the error, plus being unable to resolve Month:

The member enum Month can only be defined inside a top-level class or interface
Month cannot be resolved

Perhaps Eclipse just puts the code into a main method and runs it, in which case this error is understandable (you cannot define a local enum, even though you can define a local type). I believe the only way to do this is to move the enum itself out of the jpage into a new class. So I make the class like so:

package test;
public class Test {
   public enum Month {
      JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
   };
}

Then in the jpage, import the test package.

  1. Right click and select "Set Imports".
  2. Click "Add Packages" and enter/select the test package.

Finally, the jpage will only need the below code.

Test.Month.valueOf("JAN");

Which is all very unfortunate, because this completely defeats the purpose of using an Eclipse Scrapbook file. If I have to create a new class for the enum, I might as well forget the jpage, add a main method to Test.java and put the rest of testing code there!

I asked this question in a few other places because it was driving me mad.

Setting Cell Widths in BIRT Grid

I had a problem with setting cell widths in a BIRT 4.2.1 Grid (using Eclipse Juno). I had a grid with two rows and five columns. I had merged all the cells in the top row and found that after that point, setting cell widths on the bottom row made no difference whatsoever - all the cells remained the same width.

The solution was to delete the top row, leaving me with a grid of just one row and five columns. Fix up the cell widths and then add another row at the top and merge those cells.