views:

335

answers:

2

I have been debugging some existing code for which unit tests are failing on my system, but not on colleagues' systems. The root cause is that SimpleDateFormat is throwing ParseExceptions when parsing dates that should be parseable. I created a unit test that demonstrates the code that is failing on my system:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import junit.framework.TestCase;

public class FormatsTest extends TestCase {

    public void testParse() throws ParseException {
        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
        formatter.setTimeZone(TimeZone.getDefault());
        formatter.setLenient(false);

        formatter.parse(formatter.format(new Date()));
    }
}

This test throws a ParseException on my system, but runs successfully on other systems.

java.text.ParseException: Unparseable date: "20100603100243.118 -0600"
    at java.text.DateFormat.parse(DateFormat.java:352)
    at FormatsTest.testParse(FormatsTest.java:16)

I have found that I can setLenient(true) and the test will succeed. The setLenient(false) is what is used in the production code that this test mimics, so I don't want to change it.

+4  A: 

--- Edited after response indicating that the developer is using IBM's J9 1.5.0 Java Virtual Machine ---

IBM's J9 JVM seems to have a few bugs and incompatibilities in the parse routine of DateFormat, which SimpleDateFormat likely inherits because it is a subclass of DateFormat. Some evidence to support that IBM's J9 isn't functioning quite the way you might expect other JVMs (like Sun's HotSpot JVM) can be seen here.

Note that these bugs and incompatibilites are not even consistent within the J9 JVM, in other words, the IBM J9 formatting logic might actually generate formatted times that are not compatible with the IBM J9 parsing logic.

It seems that people who are tied to IBM's J9 JVM tend to work around the bug in the JVM by not using DateFormat.parse(...) (or SimpleDateFormat.parse(...)). Instead they tend to use java.util.regex.Matcher to parse the fields out manually.

Perhaps a later release of the J9 JVM fixes the issue, perhaps not.

--- Original post follows ---

Funny, the same code modified to:

import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;

public class FormatsTest {

 public void testParse() throws ParseException {
  DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
  formatter.setTimeZone(TimeZone.getDefault());
  formatter.setLenient(false);
  System.out.println(formatter.format(new Date()));

  formatter.parse(formatter.format(new Date()));
 }

 public static void main(String[] args) throws Exception {
   FormatsTest test = new FormatsTest();
   test.testParse();
 }

}

runs fine on my system. I would wager that it is something in your environment. Either you are compiling the code on one JVM major release and running it on another (which can cause some issues as the libraries could be out of date) or the system you are running it on might be reporting the time zone information oddly.

Finally, you might want to consider if you are using a very early point release of the JVM. Sometimes bugs do creep into the various versions, and they are fixed in later point releases. Could you please modify your question to include the "java -version" information for you system?

Either way, both of these are just educated guesses. The code should work as written.

Edwin Buck
java version "1.6.0_17"OpenJDK Runtime Environment (IcedTea 1.7.1) (fedora-37.b17.fc12-x86_64)OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode)
Edwin Buck
I get:20100603101026.294 -0600Exception in thread "main" java.text.ParseException: Unparseable date: "20100603101026.294 -0600" at java.text.DateFormat.parse(DateFormat.java:352) at FormatsTest.testParse(FormatsTest.java:15) at FormatsTest.main(FormatsTest.java:20)</code>Using:java version "1.5.0"Java(TM) 2 Runtime Environment, Standard Edition (build pwi32dev-20060511 (SR2))IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223-20060504 (JIT enabled)J9VM - 20060501_06428_lHdSMRJIT - 20060428_1800_r8GC - 20060501_AA)JCL - 20060511a
GregInYEG
I assume that's the same configuration your production environment has?
OscarRyz
original post edited, the issue is likely not on the compiler side of things, but in the java.util.DateFormat class in the IBM J9 version of the standard java library.
Edwin Buck
BTW, I agree that the code should work as written, and in fact is working as written on other computers that I have run it on.
GregInYEG
@Greg Glad to hear it. It's pretty rare for the Java platform to have a bug like this in it, but it's all written by humans, and eventually mistakes are made. Welcome to your first Java platform bug. Raise an issue with IBM, they might have a fix already. If not then perhaps you can meet your goals by temporarily disabling the unit test while you determine if it is worthwhile to get the affected systems migrated to an unaffected JVM.
Edwin Buck
+1  A: 

That should probably be a bug in IBM's J9 VM about the SimpleDateFormat class.

This post show a similar problem, and says it should be fixed on v6.

You may find the list of changes for several releases here.

I see there's a number related to DateFormat. So, you should probably raise a bug report or something with IBM for them to give you a patch.

OscarRyz
BTW, about those other computers, are they using the same configuration as yours? ( probably somebody installed Sun's JDK in their computer and that's why it's running well )
OscarRyz
I checked around, and some people have a newer IBM JVM than I do, but they all are using the IBM JVM. I will try upgrading to see if it fixes the problem.
GregInYEG