views:

489

answers:

3

I have a JUnit test that is checking to make sure that a customized xml serialization is working properly. The customized xml serialization is just a few custom converters for Xstream. The deserializers work, but for some reason in Eclipse 3.x, JUnit fails the serialization. In Ant on the command line, it works just fine. It also works just fine in Eclipse if I debug and step through the test case, but if put a break point after the failing testcase executes it fails still.

What gives? Am I having a class path issue?

Some additional information:

Expected:

<site>
  <name>origin</name>
  <version>0.6.0</version>
  <description>Stuff</description>
  <source>./fake-file.xml</source>
  <location>
    <latitude deg="44" min="26" sec="37.640"/>
    <longitude deg="-57" min="-38" sec="-6.877"/>
    <ellipsoid-height value="-79.256" units="meters"/>
    <geoid-height value="0.000" units="meters"/>
  </location>
</site>

Actual:

<site>
  <name>origin</name>
  <version>0.6.0</version>
  <description>Stuff</description>
  <source>./fake-file.xml</source>
  <location>
    <latitude deg="44" min="26" sec="37.640"/>
    <longitude deg="-57" min="-38" sec="-6.877"/>
    <ellipsoid-height value="-79.256" units="meters"/>
    <geoid-height value="-79.256" units="meters"/>
  </location>
</site>

The code that writes the location fields:

public void marshal(Object source, 
                    HierarchicalStreamWriter writer,
                    MarshallingContext context)
{
   ILatLonEllipsoidHeightPoint aLoc = (ILatLonEllipsoidHeightPoint) source;
   synchronized(aLoc)
   {
      writer.startNode(LATITUDE);
      writer.addAttribute(DEGREES,
         Integer.toString(
           PointUnitConversions.getLatitudeHours(aLoc.getLatitude())));
      writer.addAttribute(MINUTES,
         Integer.toString(
           PointUnitConversions.getLatitudeMinutes(aLoc.getLatitude())));
      writer.addAttribute(SECONDS,
         String.format("%.3f", 
           PointUnitConversions.getLatitudeSeconds(aLoc.getLatitude())));
      writer.endNode();

      writer.startNode(LONGITUDE);
      writer.addAttribute(DEGREES, 
         Integer.toString(
           PointUnitConversions.getLongitudeHours(aLoc.getLongitude())));
      writer.addAttribute(MINUTES,
         Integer.toString(
           PointUnitConversions.getLongitudeMinutes(aLoc.getLongitude())));
      writer.addAttribute(SECONDS,
         String.format("%.3f", 
           PointUnitConversions.getLongitudeSeconds(aLoc.getLongitude())));      
      writer.endNode();

      writer.startNode(ELLIPSOID_HEIGHT);
      writer.addAttribute(VALUE, 
         String.format("%.3f", aLoc.getEllipsoidHeight()));
      writer.addAttribute(UNITS, METERS);
      writer.endNode();      

      writer.startNode(GEOID_HEIGHT);
      writer.addAttribute(VALUE, 
         String.format("%.3f", aLoc.getGeoidHeight()));
      writer.addAttribute(UNITS, METERS);
      writer.endNode();
   }
}

The PointUnitConversions calls do the obvious math to take a decimal degrees and convert to corresponding integer or double values for the component parts.

Its just that last attribute of location that is causing the failure.

+2  A: 

It works fine if you debug it? Sounds like a timing issue; and debugging it slows it down enough to work. Can you post some code?

Edit:
Thanks for adding the info. It seems that if its NOT failing when you step through it, but it fails if you just run it normally, I would bet its a timing/Threading issues. Are you doing this in a Thread somewhere? Is there some contention? Or a race condition?

OTisler
There absolutely is a race condition. The call to aLoc.getGeoidHeight() does much more than I realized. The issue is caused by the order of tests executing. Eclipse is executing the entire test suite in apparently random order, but in Ant order is defined.
Jay R.
Glad I was able to help. You should look into using the JUnit setup() and teardown() to try and reset the initial conditions before each test is run. That would make sure every test is independent of previous conditions
OTisler
Thanks!. I'm on my way through all of the tests case to find the one causing the problem. The issue is in the setup(), things are changed on static members, and then not reset in the teardown() methods.
Jay R.
+1  A: 

Something's different.

Can't tell based on what you posted, but my guesses might be:

  1. Different JVM used by Ant, command shell, and Eclipse,
  2. Different JARs in the CLASSPATH for Ant and Eclipse,
  3. Different XML encodings.
duffymo
A: 

Probably not the same XML lib used. Find out which is used using for example this small code piece:

import org.w3c.dom.Text;
public class TextTest {
    public static void main(String[] args) {
        System.out.println(Text.class.getResource("Text.class"));
    }
}
Philipp