Rename trace exporters that have inconsistent naming. (#942)

* Rename trace exporters [Logging|Stackdriver|Zipkin]Exporter to [Logging|Stackdriver|Zipkin]TraceExporter.

* Add old [Logging|Stackdriver|Zipkin]Exporter back and deprecate them to maintain compatibility.

* Implement old trace exporters using renamed ones.
diff --git a/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingExporter.java b/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingExporter.java
index eada24f..da8f578 100644
--- a/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingExporter.java
+++ b/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingExporter.java
@@ -17,13 +17,7 @@
 package io.opencensus.exporter.trace.logging;
 
 import com.google.common.annotations.VisibleForTesting;
-import io.opencensus.trace.Tracing;
-import io.opencensus.trace.export.SpanData;
 import io.opencensus.trace.export.SpanExporter;
-import io.opencensus.trace.export.SpanExporter.Handler;
-import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javax.annotation.concurrent.ThreadSafe;
 
 /**
@@ -37,18 +31,17 @@
  *   ... // Do work.
  * }
  * }</pre>
+ *
+ * @deprecated Deprecated due to inconsistent naming. Use {@link LoggingTraceExporter}.
  */
 @ThreadSafe
+@Deprecated
 public final class LoggingExporter {
-  private static final Logger logger = Logger.getLogger(LoggingExporter.class.getName());
-  private static final String REGISTER_NAME = LoggingExporter.class.getName();
-  private static final LoggingExporterHandler HANDLER = new LoggingExporterHandler();
-
   private LoggingExporter() {}
 
   /** Registers the Logging exporter to the OpenCensus library. */
   public static void register() {
-    register(Tracing.getExportComponent().getSpanExporter());
+    LoggingTraceExporter.register();
   }
 
   /**
@@ -58,12 +51,12 @@
    */
   @VisibleForTesting
   static void register(SpanExporter spanExporter) {
-    spanExporter.registerHandler(REGISTER_NAME, HANDLER);
+    LoggingTraceExporter.register(spanExporter);
   }
 
   /** Unregisters the Logging exporter from the OpenCensus library. */
   public static void unregister() {
-    unregister(Tracing.getExportComponent().getSpanExporter());
+    LoggingTraceExporter.unregister();
   }
 
   /**
@@ -74,18 +67,6 @@
    */
   @VisibleForTesting
   static void unregister(SpanExporter spanExporter) {
-    spanExporter.unregisterHandler(REGISTER_NAME);
-  }
-
-  @VisibleForTesting
-  static final class LoggingExporterHandler extends Handler {
-    @Override
-    public void export(Collection<SpanData> spanDataList) {
-      // TODO(bdrutu): Use JSON as a standard format for logging SpanData and define this to be
-      // compatible between languages.
-      for (SpanData spanData : spanDataList) {
-        logger.log(Level.INFO, spanData.toString());
-      }
-    }
+    LoggingTraceExporter.unregister(spanExporter);
   }
 }
diff --git a/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingTraceExporter.java b/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingTraceExporter.java
new file mode 100644
index 0000000..65e4091
--- /dev/null
+++ b/exporters/trace/logging/src/main/java/io/opencensus/exporter/trace/logging/LoggingTraceExporter.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.exporter.trace.logging;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.opencensus.trace.Tracing;
+import io.opencensus.trace.export.SpanData;
+import io.opencensus.trace.export.SpanExporter;
+import io.opencensus.trace.export.SpanExporter.Handler;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * An OpenCensus span exporter implementation which logs all data.
+ *
+ * <p>Example of usage:
+ *
+ * <pre>{@code
+ * public static void main(String[] args) {
+ *   LoggingTraceExporter.register();
+ *   ... // Do work.
+ * }
+ * }</pre>
+ */
+@ThreadSafe
+public final class LoggingTraceExporter {
+  private static final Logger logger = Logger.getLogger(LoggingTraceExporter.class.getName());
+  private static final String REGISTER_NAME = LoggingTraceExporter.class.getName();
+  private static final LoggingExporterHandler HANDLER = new LoggingExporterHandler();
+
+  private LoggingTraceExporter() {}
+
+  /** Registers the Logging exporter to the OpenCensus library. */
+  public static void register() {
+    register(Tracing.getExportComponent().getSpanExporter());
+  }
+
+  /**
+   * Registers the {@code LoggingHandler}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} where this service is registered.
+   */
+  @VisibleForTesting
+  static void register(SpanExporter spanExporter) {
+    spanExporter.registerHandler(REGISTER_NAME, HANDLER);
+  }
+
+  /** Unregisters the Logging exporter from the OpenCensus library. */
+  public static void unregister() {
+    unregister(Tracing.getExportComponent().getSpanExporter());
+  }
+
+  /**
+   * Unregisters the {@code LoggingHandler}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} from where this service is
+   *     unregistered.
+   */
+  @VisibleForTesting
+  static void unregister(SpanExporter spanExporter) {
+    spanExporter.unregisterHandler(REGISTER_NAME);
+  }
+
+  @VisibleForTesting
+  static final class LoggingExporterHandler extends Handler {
+    @Override
+    public void export(Collection<SpanData> spanDataList) {
+      // TODO(bdrutu): Use JSON as a standard format for logging SpanData and define this to be
+      // compatible between languages.
+      for (SpanData spanData : spanDataList) {
+        logger.log(Level.INFO, spanData.toString());
+      }
+    }
+  }
+}
diff --git a/exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingExporterTest.java b/exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingTraceExporterTest.java
similarity index 78%
rename from exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingExporterTest.java
rename to exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingTraceExporterTest.java
index ce5e4bd..c2b77e4 100644
--- a/exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingExporterTest.java
+++ b/exporters/trace/logging/src/test/java/io/opencensus/exporter/trace/logging/LoggingTraceExporterTest.java
@@ -20,7 +20,7 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 
-import io.opencensus.exporter.trace.logging.LoggingExporter.LoggingExporterHandler;
+import io.opencensus.exporter.trace.logging.LoggingTraceExporter.LoggingExporterHandler;
 import io.opencensus.trace.export.SpanExporter;
 import org.junit.Before;
 import org.junit.Test;
@@ -29,9 +29,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-/** Unit tests for {@link LoggingExporter}. */
+/** Unit tests for {@link LoggingTraceExporter}. */
 @RunWith(JUnit4.class)
-public class LoggingExporterTest {
+public class LoggingTraceExporterTest {
   @Mock private SpanExporter spanExporter;
 
   @Before
@@ -41,13 +41,13 @@
 
   @Test
   public void registerUnregisterLoggingService() {
-    LoggingExporter.register(spanExporter);
+    LoggingTraceExporter.register(spanExporter);
     verify(spanExporter)
         .registerHandler(
-            eq("io.opencensus.exporter.trace.logging.LoggingExporter"),
+            eq("io.opencensus.exporter.trace.logging.LoggingTraceExporter"),
             any(LoggingExporterHandler.class));
-    LoggingExporter.unregister(spanExporter);
+    LoggingTraceExporter.unregister(spanExporter);
     verify(spanExporter)
-        .unregisterHandler(eq("io.opencensus.exporter.trace.logging.LoggingExporter"));
+        .unregisterHandler(eq("io.opencensus.exporter.trace.logging.LoggingTraceExporter"));
   }
 }
diff --git a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporter.java b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporter.java
index efe1c85..2a77541 100644
--- a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporter.java
+++ b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporter.java
@@ -16,18 +16,13 @@
 
 package io.opencensus.exporter.trace.stackdriver;
 
-import static com.google.common.base.Preconditions.checkState;
-
 import com.google.auth.Credentials;
 import com.google.auth.oauth2.GoogleCredentials;
 import com.google.cloud.ServiceOptions;
 import com.google.common.annotations.VisibleForTesting;
-import io.opencensus.trace.Tracing;
 import io.opencensus.trace.export.SpanExporter;
 import io.opencensus.trace.export.SpanExporter.Handler;
 import java.io.IOException;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
 
 /**
  * An OpenCensus span exporter implementation which exports data to Stackdriver Trace.
@@ -40,16 +35,12 @@
  *   ... // Do work.
  * }
  * }</pre>
+ *
+ * @deprecated Deprecated due to inconsistent naming. Use {@link StackdriverTraceExporter}.
  */
+@Deprecated
 public final class StackdriverExporter {
 
-  private static final String REGISTER_NAME = StackdriverExporter.class.getName();
-  private static final Object monitor = new Object();
-
-  @GuardedBy("monitor")
-  @Nullable
-  private static Handler handler = null;
-
   /**
    * Creates and registers the Stackdriver Trace exporter to the OpenCensus library for an explicit
    * project ID and using explicit credentials. Only one Stackdriver exporter can be registered at
@@ -61,10 +52,7 @@
    */
   public static void createAndRegisterWithCredentialsAndProjectId(
       Credentials credentials, String projectId) throws IOException {
-    synchronized (monitor) {
-      checkState(handler == null, "Stackdriver exporter is already registered.");
-      registerInternal(StackdriverV2ExporterHandler.createWithCredentials(credentials, projectId));
-    }
+    StackdriverTraceExporter.createAndRegisterWithCredentialsAndProjectId(credentials, projectId);
   }
 
   /**
@@ -85,10 +73,7 @@
    * @throws IllegalStateException if a Stackdriver exporter is already registered.
    */
   public static void createAndRegisterWithProjectId(String projectId) throws IOException {
-    synchronized (monitor) {
-      checkState(handler == null, "Stackdriver exporter is already registered.");
-      registerInternal(StackdriverV2ExporterHandler.create(projectId));
-    }
+    StackdriverTraceExporter.createAndRegisterWithProjectId(projectId);
   }
 
   /**
@@ -109,17 +94,7 @@
    * @throws IllegalStateException if a Stackdriver exporter is already registered.
    */
   public static void createAndRegister() throws IOException {
-    synchronized (monitor) {
-      checkState(handler == null, "Stackdriver exporter is already registered.");
-      registerInternal(StackdriverV2ExporterHandler.create(ServiceOptions.getDefaultProjectId()));
-    }
-  }
-
-  private static void registerInternal(Handler newHandler) {
-    synchronized (monitor) {
-      handler = newHandler;
-      register(Tracing.getExportComponent().getSpanExporter(), newHandler);
-    }
+    StackdriverTraceExporter.createAndRegister();
   }
 
   /**
@@ -129,7 +104,7 @@
    */
   @VisibleForTesting
   static void register(SpanExporter spanExporter, Handler handler) {
-    spanExporter.registerHandler(REGISTER_NAME, handler);
+    StackdriverTraceExporter.register(spanExporter, handler);
   }
 
   /**
@@ -138,11 +113,7 @@
    * @throws IllegalStateException if a Stackdriver exporter is not registered.
    */
   public static void unregister() {
-    synchronized (monitor) {
-      checkState(handler != null, "Stackdriver exporter is not registered.");
-      unregister(Tracing.getExportComponent().getSpanExporter());
-      handler = null;
-    }
+    StackdriverTraceExporter.unregister();
   }
 
   /**
@@ -153,7 +124,7 @@
    */
   @VisibleForTesting
   static void unregister(SpanExporter spanExporter) {
-    spanExporter.unregisterHandler(REGISTER_NAME);
+    StackdriverTraceExporter.unregister(spanExporter);
   }
 
   private StackdriverExporter() {}
diff --git a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporter.java b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporter.java
new file mode 100644
index 0000000..6ad17c6
--- /dev/null
+++ b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporter.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.exporter.trace.stackdriver;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.auth.Credentials;
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.cloud.ServiceOptions;
+import com.google.common.annotations.VisibleForTesting;
+import io.opencensus.trace.Tracing;
+import io.opencensus.trace.export.SpanExporter;
+import io.opencensus.trace.export.SpanExporter.Handler;
+import java.io.IOException;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * An OpenCensus span exporter implementation which exports data to Stackdriver Trace.
+ *
+ * <p>Example of usage on Google Cloud VMs:
+ *
+ * <pre>{@code
+ * public static void main(String[] args) {
+ *   StackdriverTraceExporter.createAndRegisterWithProjectId("MyStackdriverProjectId");
+ *   ... // Do work.
+ * }
+ * }</pre>
+ */
+public final class StackdriverTraceExporter {
+
+  private static final String REGISTER_NAME = StackdriverTraceExporter.class.getName();
+  private static final Object monitor = new Object();
+
+  @GuardedBy("monitor")
+  @Nullable
+  private static Handler handler = null;
+
+  /**
+   * Creates and registers the Stackdriver Trace exporter to the OpenCensus library for an explicit
+   * project ID and using explicit credentials. Only one Stackdriver exporter can be registered at
+   * any point.
+   *
+   * @param credentials a credentials used to authenticate API calls.
+   * @param projectId the cloud project id.
+   * @throws IllegalStateException if a Stackdriver exporter is already registered.
+   */
+  public static void createAndRegisterWithCredentialsAndProjectId(
+      Credentials credentials, String projectId) throws IOException {
+    synchronized (monitor) {
+      checkState(handler == null, "Stackdriver exporter is already registered.");
+      registerInternal(StackdriverV2ExporterHandler.createWithCredentials(credentials, projectId));
+    }
+  }
+
+  /**
+   * Creates and registers the Stackdriver Trace exporter to the OpenCensus library for an explicit
+   * project ID. Only one Stackdriver exporter can be registered at any point.
+   *
+   * <p>This uses the default application credentials see {@link
+   * GoogleCredentials#getApplicationDefault}.
+   *
+   * <p>This is equivalent with:
+   *
+   * <pre>{@code
+   * StackdriverExporter.createAndRegisterWithCredentialsAndProjectId(
+   *     GoogleCredentials.getApplicationDefault(), projectId);
+   * }</pre>
+   *
+   * @param projectId the cloud project id.
+   * @throws IllegalStateException if a Stackdriver exporter is already registered.
+   */
+  public static void createAndRegisterWithProjectId(String projectId) throws IOException {
+    synchronized (monitor) {
+      checkState(handler == null, "Stackdriver exporter is already registered.");
+      registerInternal(StackdriverV2ExporterHandler.create(projectId));
+    }
+  }
+
+  /**
+   * Creates and registers the Stackdriver Trace exporter to the OpenCensus library. Only one
+   * Stackdriver exporter can be registered at any point.
+   *
+   * <p>This uses the default application credentials see {@link
+   * GoogleCredentials#getApplicationDefault}.
+   *
+   * <p>This uses the default project ID configured see {@link ServiceOptions#getDefaultProjectId}.
+   *
+   * <p>This is equivalent with:
+   *
+   * <pre>{@code
+   * StackdriverExporter.createAndRegisterWithProjectId(ServiceOptions.getDefaultProjectId());
+   * }</pre>
+   *
+   * @throws IllegalStateException if a Stackdriver exporter is already registered.
+   */
+  public static void createAndRegister() throws IOException {
+    synchronized (monitor) {
+      checkState(handler == null, "Stackdriver exporter is already registered.");
+      registerInternal(StackdriverV2ExporterHandler.create(ServiceOptions.getDefaultProjectId()));
+    }
+  }
+
+  private static void registerInternal(Handler newHandler) {
+    synchronized (monitor) {
+      handler = newHandler;
+      register(Tracing.getExportComponent().getSpanExporter(), newHandler);
+    }
+  }
+
+  /**
+   * Registers the {@code StackdriverExporter}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} where this service is registered.
+   */
+  @VisibleForTesting
+  static void register(SpanExporter spanExporter, Handler handler) {
+    spanExporter.registerHandler(REGISTER_NAME, handler);
+  }
+
+  /**
+   * Unregisters the Stackdriver Trace exporter from the OpenCensus library.
+   *
+   * @throws IllegalStateException if a Stackdriver exporter is not registered.
+   */
+  public static void unregister() {
+    synchronized (monitor) {
+      checkState(handler != null, "Stackdriver exporter is not registered.");
+      unregister(Tracing.getExportComponent().getSpanExporter());
+      handler = null;
+    }
+  }
+
+  /**
+   * Unregisters the {@code StackdriverExporter}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} from where this service is
+   *     unregistered.
+   */
+  @VisibleForTesting
+  static void unregister(SpanExporter spanExporter) {
+    spanExporter.unregisterHandler(REGISTER_NAME);
+  }
+
+  private StackdriverTraceExporter() {}
+}
diff --git a/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporterTest.java b/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporterTest.java
similarity index 83%
rename from exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporterTest.java
rename to exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporterTest.java
index 7179058..6a12a89 100644
--- a/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverExporterTest.java
+++ b/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverTraceExporterTest.java
@@ -29,9 +29,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-/** Unit tests for {@link StackdriverExporter}. */
+/** Unit tests for {@link StackdriverTraceExporter}. */
 @RunWith(JUnit4.class)
-public class StackdriverExporterTest {
+public class StackdriverTraceExporterTest {
   @Mock private SpanExporter spanExporter;
   @Mock private Handler handler;
 
@@ -42,12 +42,12 @@
 
   @Test
   public void registerUnregisterStackdriverExporter() {
-    StackdriverExporter.register(spanExporter, handler);
+    StackdriverTraceExporter.register(spanExporter, handler);
     verify(spanExporter)
         .registerHandler(
-            eq("io.opencensus.exporter.trace.stackdriver.StackdriverExporter"), same(handler));
-    StackdriverExporter.unregister(spanExporter);
+            eq("io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter"), same(handler));
+    StackdriverTraceExporter.unregister(spanExporter);
     verify(spanExporter)
-        .unregisterHandler(eq("io.opencensus.exporter.trace.stackdriver.StackdriverExporter"));
+        .unregisterHandler(eq("io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter"));
   }
 }
diff --git a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java
index 47cfbf1..389e57a 100644
--- a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java
+++ b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java
@@ -16,18 +16,12 @@
 
 package io.opencensus.exporter.trace.zipkin;
 
-import static com.google.common.base.Preconditions.checkState;
-
 import com.google.common.annotations.VisibleForTesting;
-import io.opencensus.trace.Tracing;
 import io.opencensus.trace.export.SpanExporter;
 import io.opencensus.trace.export.SpanExporter.Handler;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
 import zipkin2.Span;
 import zipkin2.codec.SpanBytesEncoder;
 import zipkin2.reporter.Sender;
-import zipkin2.reporter.urlconnection.URLConnectionSender;
 
 /**
  * An OpenCensus span exporter implementation which exports data to Zipkin.
@@ -40,16 +34,12 @@
  *   ... // Do work.
  * }
  * }</pre>
+ *
+ * @deprecated Deprecated due to inconsistent naming. Use {@link ZipkinTraceExporter}.
  */
+@Deprecated
 public final class ZipkinExporter {
 
-  private static final String REGISTER_NAME = ZipkinExporter.class.getName();
-  private static final Object monitor = new Object();
-
-  @GuardedBy("monitor")
-  @Nullable
-  private static Handler handler = null;
-
   private ZipkinExporter() {}
 
   /**
@@ -61,7 +51,7 @@
    * @throws IllegalStateException if a Zipkin exporter is already registered.
    */
   public static void createAndRegister(String v2Url, String serviceName) {
-    createAndRegister(SpanBytesEncoder.JSON_V2, URLConnectionSender.create(v2Url), serviceName);
+    ZipkinTraceExporter.createAndRegister(v2Url, serviceName);
   }
 
   /**
@@ -75,12 +65,7 @@
    */
   public static void createAndRegister(
       SpanBytesEncoder encoder, Sender sender, String serviceName) {
-    synchronized (monitor) {
-      checkState(handler == null, "Zipkin exporter is already registered.");
-      Handler newHandler = new ZipkinExporterHandler(encoder, sender, serviceName);
-      handler = newHandler;
-      register(Tracing.getExportComponent().getSpanExporter(), newHandler);
-    }
+    ZipkinTraceExporter.createAndRegister(encoder, sender, serviceName);
   }
 
   /**
@@ -90,7 +75,7 @@
    */
   @VisibleForTesting
   static void register(SpanExporter spanExporter, Handler handler) {
-    spanExporter.registerHandler(REGISTER_NAME, handler);
+    ZipkinTraceExporter.register(spanExporter, handler);
   }
 
   /**
@@ -99,11 +84,7 @@
    * @throws IllegalStateException if a Zipkin exporter is not registered.
    */
   public static void unregister() {
-    synchronized (monitor) {
-      checkState(handler != null, "Zipkin exporter is not registered.");
-      unregister(Tracing.getExportComponent().getSpanExporter());
-      handler = null;
-    }
+    ZipkinTraceExporter.unregister();
   }
 
   /**
@@ -114,6 +95,6 @@
    */
   @VisibleForTesting
   static void unregister(SpanExporter spanExporter) {
-    spanExporter.unregisterHandler(REGISTER_NAME);
+    ZipkinTraceExporter.unregister(spanExporter);
   }
 }
diff --git a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporter.java b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporter.java
new file mode 100644
index 0000000..45c1e4f
--- /dev/null
+++ b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporter.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.exporter.trace.zipkin;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.opencensus.trace.Tracing;
+import io.opencensus.trace.export.SpanExporter;
+import io.opencensus.trace.export.SpanExporter.Handler;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import zipkin2.Span;
+import zipkin2.codec.SpanBytesEncoder;
+import zipkin2.reporter.Sender;
+import zipkin2.reporter.urlconnection.URLConnectionSender;
+
+/**
+ * An OpenCensus span exporter implementation which exports data to Zipkin.
+ *
+ * <p>Example of usage:
+ *
+ * <pre>{@code
+ * public static void main(String[] args) {
+ *   ZipkinTraceExporter.createAndRegister("http://127.0.0.1:9411/api/v2/spans", "myservicename");
+ *   ... // Do work.
+ * }
+ * }</pre>
+ */
+public final class ZipkinTraceExporter {
+
+  private static final String REGISTER_NAME = ZipkinTraceExporter.class.getName();
+  private static final Object monitor = new Object();
+
+  @GuardedBy("monitor")
+  @Nullable
+  private static Handler handler = null;
+
+  private ZipkinTraceExporter() {}
+
+  /**
+   * Creates and registers the Zipkin Trace exporter to the OpenCensus library. Only one Zipkin
+   * exporter can be registered at any point.
+   *
+   * @param v2Url Ex http://127.0.0.1:9411/api/v2/spans
+   * @param serviceName the {@link Span#localServiceName() local service name} of the process.
+   * @throws IllegalStateException if a Zipkin exporter is already registered.
+   */
+  public static void createAndRegister(String v2Url, String serviceName) {
+    createAndRegister(SpanBytesEncoder.JSON_V2, URLConnectionSender.create(v2Url), serviceName);
+  }
+
+  /**
+   * Creates and registers the Zipkin Trace exporter to the OpenCensus library. Only one Zipkin
+   * exporter can be registered at any point.
+   *
+   * @param encoder Usually {@link SpanBytesEncoder#JSON_V2}
+   * @param sender Often, but not necessarily an http sender. This could be Kafka or SQS.
+   * @param serviceName the {@link Span#localServiceName() local service name} of the process.
+   * @throws IllegalStateException if a Zipkin exporter is already registered.
+   */
+  public static void createAndRegister(
+      SpanBytesEncoder encoder, Sender sender, String serviceName) {
+    synchronized (monitor) {
+      checkState(handler == null, "Zipkin exporter is already registered.");
+      Handler newHandler = new ZipkinExporterHandler(encoder, sender, serviceName);
+      handler = newHandler;
+      register(Tracing.getExportComponent().getSpanExporter(), newHandler);
+    }
+  }
+
+  /**
+   * Registers the {@code ZipkinExporter}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} where this service is registered.
+   */
+  @VisibleForTesting
+  static void register(SpanExporter spanExporter, Handler handler) {
+    spanExporter.registerHandler(REGISTER_NAME, handler);
+  }
+
+  /**
+   * Unregisters the Zipkin Trace exporter from the OpenCensus library.
+   *
+   * @throws IllegalStateException if a Zipkin exporter is not registered.
+   */
+  public static void unregister() {
+    synchronized (monitor) {
+      checkState(handler != null, "Zipkin exporter is not registered.");
+      unregister(Tracing.getExportComponent().getSpanExporter());
+      handler = null;
+    }
+  }
+
+  /**
+   * Unregisters the {@code ZipkinExporter}.
+   *
+   * @param spanExporter the instance of the {@code SpanExporter} from where this service is
+   *     unregistered.
+   */
+  @VisibleForTesting
+  static void unregister(SpanExporter spanExporter) {
+    spanExporter.unregisterHandler(REGISTER_NAME);
+  }
+}
diff --git a/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java b/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporterTest.java
similarity index 80%
rename from exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java
rename to exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporterTest.java
index 5f8a888..2a032d0 100644
--- a/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java
+++ b/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinTraceExporterTest.java
@@ -29,9 +29,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-/** Unit tests for {@link ZipkinExporter}. */
+/** Unit tests for {@link ZipkinTraceExporter}. */
 @RunWith(JUnit4.class)
-public class ZipkinExporterTest {
+public class ZipkinTraceExporterTest {
   @Mock private SpanExporter spanExporter;
   @Mock private Handler handler;
 
@@ -42,11 +42,12 @@
 
   @Test
   public void registerUnregisterZipkinExporter() {
-    ZipkinExporter.register(spanExporter, handler);
+    ZipkinTraceExporter.register(spanExporter, handler);
     verify(spanExporter)
-        .registerHandler(eq("io.opencensus.exporter.trace.zipkin.ZipkinExporter"), same(handler));
-    ZipkinExporter.unregister(spanExporter);
+        .registerHandler(
+            eq("io.opencensus.exporter.trace.zipkin.ZipkinTraceExporter"), same(handler));
+    ZipkinTraceExporter.unregister(spanExporter);
     verify(spanExporter)
-        .unregisterHandler(eq("io.opencensus.exporter.trace.zipkin.ZipkinExporter"));
+        .unregisterHandler(eq("io.opencensus.exporter.trace.zipkin.ZipkinTraceExporter"));
   }
 }