HTRACE-132. Trace#startSpan(String, TraceInfo) must not create spans with spanId == 0 (cmccabe)
diff --git a/htrace-core/src/main/java/org/apache/htrace/Trace.java b/htrace-core/src/main/java/org/apache/htrace/Trace.java
index 08e215a..c7147ae 100644
--- a/htrace-core/src/main/java/org/apache/htrace/Trace.java
+++ b/htrace-core/src/main/java/org/apache/htrace/Trace.java
@@ -82,6 +82,7 @@
         end(0).
         description(description).
         traceId(tinfo.traceId).
+        spanId(Tracer.nonZeroRandom64()).
         parents(new long[] { tinfo.spanId }).
         processId(Tracer.getProcessId()).
         build();
diff --git a/htrace-core/src/main/java/org/apache/htrace/Tracer.java b/htrace-core/src/main/java/org/apache/htrace/Tracer.java
index ddfd25c..af2d20e 100644
--- a/htrace-core/src/main/java/org/apache/htrace/Tracer.java
+++ b/htrace-core/src/main/java/org/apache/htrace/Tracer.java
@@ -32,7 +32,7 @@
   public static final Log LOG = LogFactory.getLog(Tracer.class);
   private final static Random random = new Random();
 
-  private static long random64() {
+  static long nonZeroRandom64() {
     long id;
     do {
       id = random.nextLong();
@@ -81,9 +81,9 @@
           begin(System.currentTimeMillis()).
           end(0).
           description(description).
-          traceId(random64()).
+          traceId(nonZeroRandom64()).
           parents(EMPTY_PARENT_ARRAY).
-          spanId(random64()).
+          spanId(nonZeroRandom64()).
           processId(getProcessId()).
           build();
     } else {
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java b/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
index 9956ddb..afd0202 100644
--- a/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
@@ -61,7 +61,7 @@
   private List<TimelineAnnotation> timeline = null;
   private final static Random random = new Random();
 
-  private static long random64() {
+  private static long nonZeroRandom64() {
     long id;
     do {
       id = random.nextLong();
@@ -77,7 +77,7 @@
       description(childDescription).
       traceId(traceId).
       parents(new long[] {spanId}).
-      spanId(random64()).
+      spanId(nonZeroRandom64()).
       processId(processId).
       build();
   }
diff --git a/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java b/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java
index cd4eb28..0ab8f35 100644
--- a/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java
+++ b/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java
@@ -115,4 +115,14 @@
     tc.createSimpleTrace();
     tc.createSampleRpcTrace();
   }
+
+  @Test(timeout=60000)
+  public void testRootSpansHaveNonZeroSpanId() throws Exception {
+    TraceInfo traceInfo = new TraceInfo(100L, 200L);
+    TraceScope scope = Trace.startSpan("myRootSpan", traceInfo);
+    Assert.assertNotNull(scope);
+    Assert.assertEquals("myRootSpan", scope.getSpan().getDescription());
+    Assert.assertEquals(100L, scope.getSpan().getTraceId());
+    Assert.assertTrue(0 != scope.getSpan().getSpanId());
+  }
 }