You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2017/07/04 10:24:22 UTC

[1/2] zeppelin git commit: ZEPPELIN-2397. Add toJson and fromJson method for serializable objects

Repository: zeppelin
Updated Branches:
  refs/heads/master f3f24f300 -> f36b1a157


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java
index 9d32212..80d5356 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java
@@ -16,12 +16,21 @@
  */
 package org.apache.zeppelin.helium;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.*;
 
 /**
  * Helium config. This object will be persisted to conf/helium.conf
  */
-public class HeliumConf {
+public class HeliumConf implements JsonSerializable {
+  private static final Gson gson =  new GsonBuilder()
+    .setPrettyPrinting()
+    .registerTypeAdapter(HeliumRegistry.class, new HeliumRegistrySerializer())
+    .create();
+
   // enabled packages {name, version}
   private Map<String, String> enabled = Collections.synchronizedMap(new HashMap<String, String>());
 
@@ -91,4 +100,12 @@ public class HeliumConf {
   public void setBundleDisplayOrder(List<String> orderedPackageList) {
     bundleDisplayOrder = Collections.synchronizedList(orderedPackageList);
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static HeliumConf fromJson(String json) {
+    return gson.fromJson(json, HeliumConf.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java
index 271f73f..c2234c6 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java
@@ -16,13 +16,26 @@
  */
 package org.apache.zeppelin.helium;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.Map;
 
 /**
  * To read package.json
  */
-public class NpmPackage {
+public class NpmPackage implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   public String name;
   public String version;
   public Map<String, String> dependencies;
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NpmPackage fromJson(String json) {
+    return gson.fromJson(json, NpmPackage.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java
index 3414209..4175cad 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java
@@ -16,10 +16,23 @@
  */
 package org.apache.zeppelin.helium;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 /**
  * Represetns webpack json format result
  */
-public class WebpackResult {
+public class WebpackResult implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   public final String [] errors = new String[0];
   public final String [] warnings = new String[0];
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static WebpackResult fromJson(String json) {
+    return gson.fromJson(json, WebpackResult.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
index 0df8f67..bbc2b3b 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
@@ -18,70 +18,35 @@
 package org.apache.zeppelin.interpreter;
 
 import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import org.apache.commons.lang.NullArgumentException;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
+import org.apache.zeppelin.dep.DependencyResolver;
+import org.apache.zeppelin.display.AngularObjectRegistry;
+import org.apache.zeppelin.display.AngularObjectRegistryListener;
+import org.apache.zeppelin.helium.ApplicationEventListener;
+import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.aether.RepositoryException;
+
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFilePermission;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.internal.StringMap;
-import com.google.gson.reflect.TypeToken;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.NullArgumentException;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.repository.Authentication;
-import org.sonatype.aether.repository.Proxy;
-import org.sonatype.aether.repository.RemoteRepository;
-
-import org.apache.zeppelin.conf.ZeppelinConfiguration;
-import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
-import org.apache.zeppelin.dep.Dependency;
-import org.apache.zeppelin.dep.DependencyResolver;
-import org.apache.zeppelin.display.AngularObjectRegistry;
-import org.apache.zeppelin.display.AngularObjectRegistryListener;
-import org.apache.zeppelin.helium.ApplicationEventListener;
-import org.apache.zeppelin.interpreter.Interpreter.RegisteredInterpreter;
-import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
-import org.apache.zeppelin.scheduler.Job;
-import org.apache.zeppelin.scheduler.Job.Status;
 
 /**
  * Manage interpreters.
@@ -95,9 +60,6 @@ public class InterpreterFactory implements InterpreterGroupFactory {
   private ZeppelinConfiguration conf;
 
   private final InterpreterSettingManager interpreterSettingManager;
-
-  private Gson gson;
-
   private AngularObjectRegistryListener angularObjectRegistryListener;
   private final RemoteInterpreterProcessListener remoteInterpreterProcessListener;
   private final ApplicationEventListener appEventListener;
@@ -120,10 +82,6 @@ public class InterpreterFactory implements InterpreterGroupFactory {
     this.appEventListener = appEventListener;
     this.shiroEnabled = shiroEnabled;
 
-    GsonBuilder builder = new GsonBuilder();
-    builder.setPrettyPrinting();
-    gson = builder.create();
-
     this.interpreterSettingManager = interpreterSettingManager;
     //TODO(jl): Fix it not to use InterpreterGroupFactory
     interpreterSettingManager.setInterpreterGroupFactory(this);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
index 786a723..ca688dc 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
@@ -17,6 +17,9 @@
 
 package org.apache.zeppelin.interpreter;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.sonatype.aether.repository.RemoteRepository;
 
 import java.util.List;
@@ -25,8 +28,19 @@ import java.util.Map;
 /**
  *
  */
-public class InterpreterInfoSaving {
+public class InterpreterInfoSaving implements JsonSerializable {
+
+  private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
   public Map<String, InterpreterSetting> interpreterSettings;
   public Map<String, List<String>> interpreterBindings;
   public List<RemoteRepository> interpreterRepositories;
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static InterpreterInfoSaving fromJson(String json) {
+    return gson.fromJson(json, InterpreterInfoSaving.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
index 8270aba..1327e09 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
@@ -63,6 +63,7 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
@@ -162,11 +163,12 @@ public class InterpreterSettingManager {
       return;
     }
     InterpreterInfoSaving infoSaving;
-    try (BufferedReader json =
+    try (BufferedReader jsonReader =
         Files.newBufferedReader(interpreterBindingPath, StandardCharsets.UTF_8)) {
       JsonParser jsonParser = new JsonParser();
-      JsonObject jsonObject = jsonParser.parse(json).getAsJsonObject();
+      JsonObject jsonObject = jsonParser.parse(jsonReader).getAsJsonObject();
       infoSaving = gson.fromJson(jsonObject.toString(), InterpreterInfoSaving.class);
+
       for (String k : infoSaving.interpreterSettings.keySet()) {
         InterpreterSetting setting = infoSaving.interpreterSettings.get(k);
         List<InterpreterInfo> infos = setting.getInterpreterInfos();
@@ -236,7 +238,7 @@ public class InterpreterSettingManager {
       info.interpreterSettings = interpreterSettings;
       info.interpreterRepositories = interpreterRepositories;
 
-      jsonString = gson.toJson(info);
+      jsonString = info.toJson();
     }
 
     if (!Files.exists(interpreterBindingPath)) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
index ed8982b..9cea693 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
@@ -515,8 +515,8 @@ public class RemoteInterpreter extends Interpreter {
 
   private RemoteInterpreterContext convert(InterpreterContext ic) {
     return new RemoteInterpreterContext(ic.getNoteId(), ic.getParagraphId(), ic.getReplName(),
-        ic.getParagraphTitle(), ic.getParagraphText(), gson.toJson(ic.getAuthenticationInfo()),
-        gson.toJson(ic.getConfig()), gson.toJson(ic.getGui()), gson.toJson(ic.getRunners()));
+        ic.getParagraphTitle(), ic.getParagraphText(), ic.getAuthenticationInfo().toJson(),
+        gson.toJson(ic.getConfig()), ic.getGui().toJson(), gson.toJson(ic.getRunners()));
   }
 
   private InterpreterResult convert(RemoteInterpreterResult result) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
index b3cb6c3..ff915a3 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
@@ -26,8 +26,12 @@ import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectRegistry;
@@ -35,6 +39,7 @@ import org.apache.zeppelin.display.Input;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+import org.apache.zeppelin.notebook.json.NotebookTypeAdapterFactory;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.utility.IdHashes;
 import org.apache.zeppelin.resource.ResourcePoolUtils;
@@ -52,12 +57,26 @@ import com.google.gson.Gson;
 /**
  * Binded interpreters for a note
  */
-public class Note implements Serializable, ParagraphJobListener {
+public class Note implements ParagraphJobListener, JsonSerializable {
   private static final Logger logger = LoggerFactory.getLogger(Note.class);
   private static final long serialVersionUID = 7920699076577612429L;
-  private static final Gson gson = new GsonBuilder()
-      .registerTypeAdapterFactory(Input.TypeAdapterFactory)
-      .create();
+  private static Gson gson = new GsonBuilder()
+      .setPrettyPrinting()
+      .registerTypeAdapterFactory(new NotebookTypeAdapterFactory<Paragraph>(Paragraph.class) {
+        @Override
+        protected void beforeWrite(Paragraph source, JsonElement toSerialize) {
+          Map<String, ParagraphRuntimeInfo> runtimeInfos = source.getRuntimeInfos();
+          if (runtimeInfos != null) {
+            JsonElement jsonTree = gson.toJsonTree(runtimeInfos);
+            if (toSerialize instanceof JsonObject) {
+              JsonObject jsonObj = (JsonObject) toSerialize;
+              jsonObj.add("runtimeInfos", jsonTree);
+            }
+          }
+        }
+      }).setDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
+      .registerTypeAdapter(Date.class, new NotebookImportDeserializer())
+      .registerTypeAdapterFactory(Input.TypeAdapterFactory).create();
 
   // threadpool for delayed persist of note
   private static final ScheduledThreadPoolExecutor delayedPersistThreadPool =
@@ -323,7 +342,7 @@ public class Note implements Serializable, ParagraphJobListener {
     try {
       Gson gson = new Gson();
       String resultJson = gson.toJson(srcParagraph.getReturn());
-      InterpreterResult result = gson.fromJson(resultJson, InterpreterResult.class);
+      InterpreterResult result = InterpreterResult.fromJson(resultJson);
       newParagraph.setReturn(result, null);
     } catch (Exception e) {
       // 'result' part of Note consists of exception, instead of actual interpreter results
@@ -898,11 +917,6 @@ public class Note implements Serializable, ParagraphJobListener {
   }
 
   public static Note fromJson(String json) {
-    GsonBuilder gsonBuilder = 
-            new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer())
-        .create();
     Note note = gson.fromJson(json, Note.class);
     convertOldInput(note);
     return note;
@@ -913,4 +927,50 @@ public class Note implements Serializable, ParagraphJobListener {
       p.settings.convertOldInput();
     }
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Note note = (Note) o;
+
+    if (paragraphs != null ? !paragraphs.equals(note.paragraphs) : note.paragraphs != null) {
+      return false;
+    }
+    //TODO(zjffdu) exclude name because FolderView.index use Note as key and consider different name
+    //as same note
+    //    if (name != null ? !name.equals(note.name) : note.name != null) return false;
+    if (id != null ? !id.equals(note.id) : note.id != null) {
+      return false;
+    }
+    if (angularObjects != null ?
+        !angularObjects.equals(note.angularObjects) : note.angularObjects != null) {
+      return false;
+    }
+    if (config != null ? !config.equals(note.config) : note.config != null) {
+      return false;
+    }
+    return info != null ? info.equals(note.info) : note.info == null;
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result = paragraphs != null ? paragraphs.hashCode() : 0;
+    //    result = 31 * result + (name != null ? name.hashCode() : 0);
+    result = 31 * result + (id != null ? id.hashCode() : 0);
+    result = 31 * result + (angularObjects != null ? angularObjects.hashCode() : 0);
+    result = 31 * result + (config != null ? config.hashCode() : 0);
+    result = 31 * result + (info != null ? info.hashCode() : 0);
+    return result;
+  }
+
+  @VisibleForTesting
+  public static Gson getGson() {
+    return gson;
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index 720a3be..07febf1 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -182,14 +182,11 @@ public class Notebook implements NoteEventListener {
    * @throws IOException, IllegalArgumentException
    */
   public String exportNote(String noteId) throws IOException, IllegalArgumentException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
     Note note = getNote(noteId);
     if (note == null) {
       throw new IllegalArgumentException(noteId + " not found");
     }
-    return gson.toJson(note);
+    return note.toJson();
   }
 
   /**
@@ -202,16 +199,9 @@ public class Notebook implements NoteEventListener {
    */
   public Note importNote(String sourceJson, String noteName, AuthenticationInfo subject)
       throws IOException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-
-    Gson gson =
-        gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()).create();
-    JsonReader reader = new JsonReader(new StringReader(sourceJson));
-    reader.setLenient(true);
     Note newNote;
     try {
-      Note oldNote = gson.fromJson(reader, Note.class);
+      Note oldNote = Note.fromJson(sourceJson);
       convertFromSingleResultToMultipleResultsFormat(oldNote);
       newNote = createNote(subject);
       if (noteName != null)

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java
index 8fcecf4..500f068 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java
@@ -110,8 +110,7 @@ public class NotebookAuthorization {
     fis.close();
 
     String json = sb.toString();
-    NotebookAuthorizationInfoSaving info = gson.fromJson(json,
-            NotebookAuthorizationInfoSaving.class);
+    NotebookAuthorizationInfoSaving info = NotebookAuthorizationInfoSaving.fromJson(json);
     authInfo = info.authInfo;
   }
   

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java
index 38cd0b6..629e400 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java
@@ -17,12 +17,26 @@
 
 package org.apache.zeppelin.notebook;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.Map;
 import java.util.Set;
 
 /**
  * Only used for saving NotebookAuthorization info
  */
-public class NotebookAuthorizationInfoSaving {
+public class NotebookAuthorizationInfoSaving implements JsonSerializable {
+
+  private static final Gson gson = new Gson();
+
   public Map<String, Map<String, Set<String>>> authInfo;
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NotebookAuthorizationInfoSaving fromJson(String json) {
+    return gson.fromJson(json, NotebookAuthorizationInfoSaving.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java
index 86e0f0b..0b8eed8 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java
@@ -36,7 +36,8 @@ public class NotebookImportDeserializer implements JsonDeserializer<Date> {
   private static final String[] DATE_FORMATS = new String[] {
     "yyyy-MM-dd'T'HH:mm:ssZ",
     "MMM d, yyyy h:mm:ss a",
-    "MMM dd, yyyy HH:mm:ss"
+    "MMM dd, yyyy HH:mm:ss",
+    "yyyy-MM-dd HH:mm:ss.SSS"
   };
 
   @Override

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
index 9bb5d21..be88a1b 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
@@ -20,6 +20,7 @@ package org.apache.zeppelin.notebook;
 import com.google.common.collect.Maps;
 import com.google.common.base.Strings;
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.completer.CompletionType;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectRegistry;
@@ -49,7 +50,7 @@ import com.google.common.annotations.VisibleForTesting;
 /**
  * Paragraph is a representation of an execution unit.
  */
-public class Paragraph extends Job implements Serializable, Cloneable {
+public class Paragraph extends Job implements Cloneable, JsonSerializable {
 
   private static final long serialVersionUID = -6328572073497992016L;
 
@@ -755,4 +756,72 @@ public class Paragraph extends Job implements Serializable, Cloneable {
   public Map<String, ParagraphRuntimeInfo> getRuntimeInfos() {
     return runtimeInfos;
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    if (!super.equals(o)) {
+      return false;
+    }
+
+    Paragraph paragraph = (Paragraph) o;
+
+    if (title != null ? !title.equals(paragraph.title) : paragraph.title != null) {
+      return false;
+    }
+    if (text != null ? !text.equals(paragraph.text) : paragraph.text != null) {
+      return false;
+    }
+    if (user != null ? !user.equals(paragraph.user) : paragraph.user != null) {
+      return false;
+    }
+    if (dateUpdated != null ?
+        !dateUpdated.equals(paragraph.dateUpdated) : paragraph.dateUpdated != null) {
+      return false;
+    }
+    if (config != null ? !config.equals(paragraph.config) : paragraph.config != null) {
+      return false;
+    }
+    if (settings != null ? !settings.equals(paragraph.settings) : paragraph.settings != null) {
+      return false;
+    }
+    if (results != null ? !results.equals(paragraph.results) : paragraph.results != null) {
+      return false;
+    }
+    if (result != null ? !result.equals(paragraph.result) : paragraph.result != null) {
+      return false;
+    }
+    return runtimeInfos != null ?
+        runtimeInfos.equals(paragraph.runtimeInfos) : paragraph.runtimeInfos == null;
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result1 = super.hashCode();
+    result1 = 31 * result1 + (title != null ? title.hashCode() : 0);
+    result1 = 31 * result1 + (text != null ? text.hashCode() : 0);
+    result1 = 31 * result1 + (user != null ? user.hashCode() : 0);
+    result1 = 31 * result1 + (dateUpdated != null ? dateUpdated.hashCode() : 0);
+    result1 = 31 * result1 + (config != null ? config.hashCode() : 0);
+    result1 = 31 * result1 + (settings != null ? settings.hashCode() : 0);
+    result1 = 31 * result1 + (results != null ? results.hashCode() : 0);
+    result1 = 31 * result1 + (result != null ? result.hashCode() : 0);
+    result1 = 31 * result1 + (runtimeInfos != null ? runtimeInfos.hashCode() : 0);
+    return result1;
+  }
+
+  public String toJson() {
+    return Note.getGson().toJson(this);
+  }
+
+  public static Paragraph fromJson(String json) {
+    return Note.getGson().fromJson(json, Paragraph.class);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java
new file mode 100644
index 0000000..2ed7df0
--- /dev/null
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.notebook.json;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+
+/**
+ * Custom adapter type factory
+ * Modify the jsonObject before serailaization/deserialization
+ * @param <C> the type whose json is to be customized for serialization/deserialization
+ */
+public class NotebookTypeAdapterFactory<C> implements TypeAdapterFactory {
+  private final Class<C> customizedClass;
+
+  public NotebookTypeAdapterFactory(Class<C> customizedClass) {
+    this.customizedClass = customizedClass;
+  }
+
+  @SuppressWarnings("unchecked")
+  // we use a runtime check to guarantee that 'C' and 'T' are equal
+  public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+    return type.getRawType() == customizedClass ? (TypeAdapter<T>) customizeTypeAdapter(gson,
+        (TypeToken<C>) type) : null;
+  }
+
+  private TypeAdapter<C> customizeTypeAdapter(Gson gson, TypeToken<C> type) {
+    final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
+    final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
+    return new TypeAdapter<C>() {
+      @Override
+      public void write(JsonWriter out, C value) throws IOException {
+        JsonElement tree = delegate.toJsonTree(value);
+        beforeWrite(value, tree);
+        elementAdapter.write(out, tree);
+      }
+
+      @Override
+      public C read(JsonReader in) throws IOException {
+        JsonElement tree = elementAdapter.read(in);
+        afterRead(tree);
+        return delegate.fromJsonTree(tree);
+      }
+    };
+  }
+
+  /**
+   * Override this to change {@code toSerialize} before it is written to the
+   * outgoing JSON stream.
+   */
+  protected void beforeWrite(C source, JsonElement toSerialize) {
+  }
+
+  /**
+   * Override this to change {@code deserialized} before it parsed into the
+   * application type.
+   */
+  protected void afterRead(JsonElement deserialized) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
index 5ef3c16..de337fa 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
@@ -25,7 +25,6 @@ import java.io.Writer;
 import java.net.URISyntaxException;
 import java.security.InvalidKeyException;
 import java.util.Collections;
-import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -35,15 +34,12 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
-import org.apache.zeppelin.notebook.NotebookImportDeserializer;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.Job;
 import org.apache.zeppelin.user.AuthenticationInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import com.microsoft.azure.storage.CloudStorageAccount;
 import com.microsoft.azure.storage.StorageException;
 import com.microsoft.azure.storage.file.CloudFile;
@@ -132,12 +128,6 @@ public class AzureNotebookRepo implements NotebookRepo {
     String json = IOUtils.toString(ins,
         conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_ENCODING));
     ins.close();
-
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer())
-        .create();
-
     Note note = Note.fromJson(json);
 
     for (Paragraph p : note.getParagraphs()) {
@@ -156,10 +146,7 @@ public class AzureNotebookRepo implements NotebookRepo {
 
   @Override
   public void save(Note note, AuthenticationInfo subject) throws IOException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
-    String json = gson.toJson(note);
+    String json = note.toJson();
 
     ByteArrayOutputStream output = new ByteArrayOutputStream();
     Writer writer = new OutputStreamWriter(output);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
index 9502cf3..273d75d 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
@@ -1,7 +1,5 @@
 package org.apache.zeppelin.notebook.repo;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import com.mongodb.MongoBulkWriteException;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientURI;
@@ -18,7 +16,6 @@ import com.mongodb.client.model.UpdateOptions;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
-import org.apache.zeppelin.notebook.NotebookImportDeserializer;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.notebook.ApplicationState;
 import org.apache.zeppelin.scheduler.Job;
@@ -164,10 +161,7 @@ public class MongoNotebookRepo implements NotebookRepo {
     // document to JSON
     String json = doc.toJson();
     // JSON to note
-    Gson gson = new GsonBuilder()
-            .registerTypeAdapter(Date.class, new NotebookImportDeserializer())
-            .create();
-    Note note = gson.fromJson(json, Note.class);
+    Note note = Note.fromJson(json);
 
     for (Paragraph p : note.getParagraphs()) {
       if (p.getStatus() == Job.Status.PENDING || p.getStatus() == Job.Status.RUNNING) {
@@ -192,8 +186,7 @@ public class MongoNotebookRepo implements NotebookRepo {
    */
   private Document noteToDocument(Note note) {
     // note to JSON
-    Gson gson = new GsonBuilder().create();
-    String json = gson.toJson(note);
+    String json = note.toJson();
     // JSON to document
     Document doc = Document.parse(json);
     // set object id as note id

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
index 71fa19f..16b270c 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
@@ -24,7 +24,6 @@ import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.Collections;
-import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -36,7 +35,6 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
-import org.apache.zeppelin.notebook.NotebookImportDeserializer;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.Job.Status;
 import org.apache.zeppelin.user.AuthenticationInfo;
@@ -61,8 +59,6 @@ import com.amazonaws.regions.Region;
 import com.amazonaws.regions.Regions;
 import com.amazonaws.services.s3.model.S3Object;
 import com.amazonaws.services.s3.model.S3ObjectSummary;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 
 /**
  * Backend for storing Notebooks on S3
@@ -186,11 +182,6 @@ public class S3NotebookRepo implements NotebookRepo {
   }
 
   private Note getNote(String key) throws IOException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer())
-        .create();
-
     S3Object s3object;
     try {
       s3object = s3client.getObject(new GetObjectRequest(bucketName, key));
@@ -226,10 +217,7 @@ public class S3NotebookRepo implements NotebookRepo {
 
   @Override
   public void save(Note note, AuthenticationInfo subject) throws IOException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
-    String json = gson.toJson(note);
+    String json = note.toJson();
     String key = user + "/" + "notebook" + "/" + note.getId() + "/" + "note.json";
 
     File file = File.createTempFile("note", "json");

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
index c30f20f..4006d13 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
@@ -43,7 +43,6 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.notebook.ApplicationState;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
-import org.apache.zeppelin.notebook.NotebookImportDeserializer;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.Job.Status;
 import org.apache.zeppelin.user.AuthenticationInfo;
@@ -51,8 +50,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 
 /**
 *
@@ -164,8 +161,7 @@ public class VFSNotebookRepo implements NotebookRepo {
     if (!noteJson.exists()) {
       throw new IOException(noteJson.getName().toString() + " not found");
     }
-
-
+    
     FileContent content = noteJson.getContent();
     InputStream ins = content.getInputStream();
     String json = IOUtils.toString(ins, conf.getString(ConfVars.ZEPPELIN_ENCODING));
@@ -222,10 +218,7 @@ public class VFSNotebookRepo implements NotebookRepo {
 
   @Override
   public synchronized void save(Note note, AuthenticationInfo subject) throws IOException {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
-    String json = gson.toJson(note);
+    String json = note.toJson();
 
     FileObject rootDir = getRootDir();
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java
index b072251..0257b8c 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java
@@ -48,8 +48,6 @@ import org.eclipse.jetty.websocket.client.WebSocketClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
 
 /**
  * Zeppelin websocket client.
@@ -59,7 +57,6 @@ public class ZeppelinClient {
   private static final Logger LOG = LoggerFactory.getLogger(ZeppelinClient.class);
   private final URI zeppelinWebsocketUrl;
   private final WebSocketClient wsClient;
-  private static Gson gson;
   // Keep track of current open connection per notebook.
   private ConcurrentHashMap<String, Session> notesConnection;
   // Listen to every note actions.
@@ -99,7 +96,6 @@ public class ZeppelinClient {
   private ZeppelinClient(String zeppelinUrl, String token, ZeppelinConfiguration conf) {
     zeppelinWebsocketUrl = URI.create(zeppelinUrl);
     wsClient = createNewWebsocketClient();
-    gson = new Gson();
     notesConnection = new ConcurrentHashMap<>();
     schedulerService = SchedulerService.getInstance();
     authModule = Authentication.initialize(token, conf);
@@ -177,7 +173,7 @@ public class ZeppelinClient {
       zeppelinMsg.ticket = authModule.getTicket();
       zeppelinMsg.roles = authModule.getRoles();
     }
-    String msg = gson.toJson(zeppelinMsg);
+    String msg = zeppelinMsg.toJson();
     return msg;
   }
 
@@ -189,14 +185,12 @@ public class ZeppelinClient {
     if (StringUtils.isBlank(zeppelinMessage)) {
       return null;
     }
-    Message msg;
     try {
-      msg = gson.fromJson(zeppelinMessage, Message.class);
-    } catch (JsonSyntaxException ex) {
-      LOG.error("Cannot deserialize zeppelin message", ex);
-      msg = null;
+      return Message.fromJson(zeppelinMessage);
+    } catch (Exception e) {
+      LOG.error("Fail to parse zeppelinMessage", e);
+      return null;
     }
-    return msg;
   }
   
   private Session openWatcherSession() {
@@ -316,7 +310,7 @@ public class ZeppelinClient {
     if (StringUtils.isEmpty(token)) {
       relayToAllZeppelinHub(hubMsg, noteId);
     } else {
-      client.relayToZeppelinHub(hubMsg.serialize(), token);
+      client.relayToZeppelinHub(hubMsg.toJson(), token);
     }
 
   }
@@ -336,7 +330,7 @@ public class ZeppelinClient {
       if (noteAuth.isReader(noteId, userAndRoles)) {
         token = userTokens.get(user);
         hubMsg.meta.put("token", token);
-        client.relayToZeppelinHub(hubMsg.serialize(), token);
+        client.relayToZeppelinHub(hubMsg.toJson(), token);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java
index 4eb00df..bc34324 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java
@@ -195,7 +195,7 @@ public class ZeppelinhubClient {
   }
 
   public void handleMsgFromZeppelinHub(String message) {
-    ZeppelinhubMessage hubMsg = ZeppelinhubMessage.deserialize(message);
+    ZeppelinhubMessage hubMsg = ZeppelinhubMessage.fromJson(message);
     if (hubMsg.equals(ZeppelinhubMessage.EMPTY)) {
       LOG.error("Cannot handle ZeppelinHub message is empty");
       return;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java
index 95a1e77..43adf4a 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java
@@ -27,15 +27,12 @@ import org.eclipse.jetty.websocket.api.WebSocketListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-
 /**
  * Zeppelin Watcher that will forward user note to ZeppelinHub.
  *
  */
 public class WatcherWebsocket implements WebSocketListener {
   private static final Logger LOG = LoggerFactory.getLogger(ZeppelinWebsocket.class);
-  private static final Gson GSON = new Gson();
   private static final String watcherPrincipal = "watcher";
   public Session connection;
   
@@ -59,7 +56,7 @@ public class WatcherWebsocket implements WebSocketListener {
     Message watcherMsg = new Message(OP.WATCHER);
     watcherMsg.principal = watcherPrincipal;
     watcherMsg.ticket = TicketContainer.instance.getTicket(watcherPrincipal);
-    session.getRemote().sendStringByFuture(GSON.toJson(watcherMsg));
+    session.getRemote().sendStringByFuture(watcherMsg.toJson());
   }
 
   @Override
@@ -69,7 +66,7 @@ public class WatcherWebsocket implements WebSocketListener {
 
   @Override
   public void onWebSocketText(String message) {
-    WatcherMessage watcherMsg = GSON.fromJson(message, WatcherMessage.class);
+    WatcherMessage watcherMsg = WatcherMessage.fromJson(message);
     if (StringUtils.isBlank(watcherMsg.noteId)) {
       return;
     }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java
index aa1ce21..4f7c652 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java
@@ -19,6 +19,7 @@ package org.apache.zeppelin.notebook.repo.zeppelinhub.websocket.protocol;
 import java.util.Map;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.notebook.repo.zeppelinhub.websocket.Client;
 import org.apache.zeppelin.notebook.socket.Message;
 import org.apache.zeppelin.notebook.socket.Message.OP;
@@ -33,7 +34,7 @@ import com.google.gson.JsonSyntaxException;
  * Zeppelinhub message class.
  *
  */
-public class ZeppelinhubMessage {
+public class ZeppelinhubMessage implements JsonSerializable {
   private static final Gson gson = new Gson();
   private static final Logger LOG = LoggerFactory.getLogger(Client.class);
   public static final ZeppelinhubMessage EMPTY = new ZeppelinhubMessage();
@@ -64,11 +65,11 @@ public class ZeppelinhubMessage {
     return new ZeppelinhubMessage(zeppelinMsg.op, zeppelinMsg.data, meta);
   }
 
-  public String serialize() {
+  public String toJson() {
     return gson.toJson(this, ZeppelinhubMessage.class);
   }
 
-  public static ZeppelinhubMessage deserialize(String zeppelinhubMessage) {
+  public static ZeppelinhubMessage fromJson(String zeppelinhubMessage) {
     if (StringUtils.isBlank(zeppelinhubMessage)) {
       return EMPTY;
     }
@@ -76,7 +77,7 @@ public class ZeppelinhubMessage {
     try {
       msg = gson.fromJson(zeppelinhubMessage, ZeppelinhubMessage.class);
     } catch (JsonSyntaxException ex) {
-      LOG.error("Cannot deserialize zeppelinhub message", ex);
+      LOG.error("Cannot fromJson zeppelinhub message", ex);
       msg = EMPTY;
     }
     return msg;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java
index b88fd72..50da343 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java
@@ -37,37 +37,37 @@ public class ZeppelinhubUtils {
   public static String liveMessage(String token) {
     if (StringUtils.isBlank(token)) {
       LOG.error("Cannot create Live message: token is null or empty");
-      return ZeppelinhubMessage.EMPTY.serialize();
+      return ZeppelinhubMessage.EMPTY.toJson();
     }
     HashMap<String, Object> data = new HashMap<>();
     data.put("token", token);
     return ZeppelinhubMessage
              .newMessage(ZeppelinHubOp.LIVE, data, new HashMap<String, String>())
-             .serialize();
+             .toJson();
   }
   
   public static String deadMessage(String token) {
     if (StringUtils.isBlank(token)) {
       LOG.error("Cannot create Dead message: token is null or empty");
-      return ZeppelinhubMessage.EMPTY.serialize();
+      return ZeppelinhubMessage.EMPTY.toJson();
     }
     HashMap<String, Object> data = new HashMap<>();
     data.put("token", token);
     return ZeppelinhubMessage
              .newMessage(ZeppelinHubOp.DEAD, data, new HashMap<String, String>())
-             .serialize();
+             .toJson();
   }
   
   public static String pingMessage(String token) {
     if (StringUtils.isBlank(token)) {
       LOG.error("Cannot create Ping message: token is null or empty");
-      return ZeppelinhubMessage.EMPTY.serialize();
+      return ZeppelinhubMessage.EMPTY.toJson();
     }
     HashMap<String, Object> data = new HashMap<>();
     data.put("token", token);
     return ZeppelinhubMessage
              .newMessage(ZeppelinHubOp.PING, data, new HashMap<String, String>())
-             .serialize();
+             .toJson();
   }
 
   public static ZeppelinHubOp toZeppelinHubOp(String text) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
index 3784f5e..06c83e1 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
@@ -17,13 +17,16 @@
 
 package org.apache.zeppelin.notebook.socket;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.HashMap;
 import java.util.Map;
 
 /**
  * Zeppelin websocket massage template class.
  */
-public class Message {
+public class Message implements JsonSerializable {
   /**
    * Representation of event type.
    */
@@ -179,6 +182,7 @@ public class Message {
     PARAS_INFO                    // [s-c] paragraph runtime infos
   }
 
+  private static final Gson gson = new Gson();
   public static final Message EMPTY = new Message(null);
   
   public OP op;
@@ -212,4 +216,12 @@ public class Message {
     sb.append('}');
     return sb.toString();
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static Message fromJson(String json) {
+    return gson.fromJson(json, Message.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java
index 0fb28cc..c982ca7 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java
@@ -17,11 +17,12 @@
 package org.apache.zeppelin.notebook.socket;
 
 import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 
 /**
  * Zeppelin websocket massage template class for watcher socket.
  */
-public class WatcherMessage {
+public class WatcherMessage implements JsonSerializable {
 
   public String message;
   public String noteId;
@@ -39,10 +40,14 @@ public class WatcherMessage {
     this.subject = builder.subject;
   }
   
-  public String serialize() {
+  public String toJson() {
     return gson.toJson(this);
   }
-  
+
+  public static WatcherMessage fromJson(String json) {
+    return gson.fromJson(json, WatcherMessage.class);
+  }
+
   /**
    * Simple builder.
    */

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
index 3d0fe1a..2e3812c 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
@@ -19,19 +19,6 @@ package org.apache.zeppelin.interpreter;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Properties;
-
-import com.google.common.collect.Maps;
-import com.google.gson.Gson;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.NullArgumentException;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
@@ -40,7 +27,6 @@ import org.apache.zeppelin.dep.Dependency;
 import org.apache.zeppelin.dep.DependencyResolver;
 import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
 import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
-import org.apache.zeppelin.user.AuthenticationInfo;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
 import org.apache.zeppelin.notebook.JobListenerFactory;
 import org.apache.zeppelin.notebook.Note;
@@ -50,21 +36,22 @@ import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.repo.VFSNotebookRepo;
 import org.apache.zeppelin.scheduler.SchedulerFactory;
 import org.apache.zeppelin.search.SearchService;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 import org.quartz.SchedulerException;
 import org.sonatype.aether.RepositoryException;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.*;
 
-import org.mockito.Mock;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
 
 public class InterpreterFactoryTest {
 
@@ -341,8 +328,7 @@ public class InterpreterFactoryTest {
     byte[] encoded = Files.readAllBytes(Paths.get(confFilePath));
     String json = new String(encoded, "UTF-8");
 
-    Gson gson = new Gson();
-    InterpreterInfoSaving infoSaving = gson.fromJson(json, InterpreterInfoSaving.class);
+    InterpreterInfoSaving infoSaving = InterpreterInfoSaving.fromJson(json);
     Map<String, InterpreterSetting> interpreterSettings = infoSaving.interpreterSettings;
     for (String key : interpreterSettings.keySet()) {
       InterpreterSetting setting = interpreterSettings.get(key);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java
index 0eb37df..69c1f86 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java
@@ -17,6 +17,10 @@
 
 package org.apache.zeppelin.notebook;
 
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import org.apache.zeppelin.display.AngularObject;
+import org.apache.zeppelin.display.ui.TextBox;
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.interpreter.InterpreterResult;
@@ -32,6 +36,8 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 
+import java.util.Date;
+
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
@@ -233,4 +239,28 @@ public class NoteTest {
     assertNotEquals(System.identityHashCode(baseParagraph), System.identityHashCode(user2Paragraph));
     assertNotEquals(System.identityHashCode(user1Paragraph), System.identityHashCode(user2Paragraph));
   }
+
+  public void testNoteJson() {
+    Note note = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    note.setName("/test_note");
+    note.getConfig().put("config_1", "value_1");
+    note.getInfo().put("info_1", "value_1");
+    String pText = "%spark sc.version";
+    Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
+    p.dateUpdated = new Date();
+    p.setText(pText);
+    p.setResult("1.6.2");
+    p.settings.getForms().put("textbox_1", new TextBox("name", "default_name"));
+    p.settings.getParams().put("textbox_1", "my_name");
+    note.getAngularObjects().put("ao_1", Lists.newArrayList(new AngularObject("name_1", "value_1", note.getId(), p.getId(), null)));
+
+    // test Paragraph Json
+    Paragraph p2 = Paragraph.fromJson(p.toJson());
+    assertEquals(p2.settings, p.settings);
+    assertEquals(p2, p);
+
+    // test Note Json
+    Note note2 = Note.fromJson(note.toJson());
+    assertEquals(note2, note);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
index ed329b6..495e17b 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
@@ -195,7 +195,15 @@ public class NotebookTest implements JobListenerFactory{
     assertEquals(notes.size(), 2);
     assertEquals(notes.get(1).getId(), copiedNote.getId());
     assertEquals(notes.get(1).getName(), copiedNote.getName());
-    assertEquals(notes.get(1).getParagraphs(), copiedNote.getParagraphs());
+    // format has make some changes due to
+    // Notebook.convertFromSingleResultToMultipleResultsFormat
+    assertEquals(notes.get(1).getParagraphs().size(), copiedNote.getParagraphs().size());
+    assertEquals(notes.get(1).getParagraphs().get(0).getText(),
+        copiedNote.getParagraphs().get(0).getText());
+    assertEquals(notes.get(1).getParagraphs().get(0).settings,
+        copiedNote.getParagraphs().get(0).settings);
+    assertEquals(notes.get(1).getParagraphs().get(0).title,
+        copiedNote.getParagraphs().get(0).title);
 
     // delete the notebook
     for (String note : noteNames) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java
index 4cce203..1f07f4f 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java
@@ -17,7 +17,7 @@ public class ZeppelinhubMessageTest {
   public void testThatCanSerializeZeppelinHubMessage() {
     Map<String,String> meta = Maps.newHashMap();
     meta.put("key1", "val1");
-    String zeppelinHubMsg = ZeppelinhubMessage.newMessage(OP.LIST_NOTES, "my data", meta).serialize();
+    String zeppelinHubMsg = ZeppelinhubMessage.newMessage(OP.LIST_NOTES, "my data", meta).toJson();
 
     assertEquals(msg, zeppelinHubMsg);
   }
@@ -27,7 +27,7 @@ public class ZeppelinhubMessageTest {
     Map<String,String> meta = Maps.newHashMap();
     meta.put("key1", "val1");
     ZeppelinhubMessage expected = ZeppelinhubMessage.newMessage(OP.LIST_NOTES.toString(), "my data", meta);
-    ZeppelinhubMessage zeppelinHubMsg = ZeppelinhubMessage.deserialize(msg);
+    ZeppelinhubMessage zeppelinHubMsg = ZeppelinhubMessage.fromJson(msg);
 
     assertEquals(expected.op, zeppelinHubMsg.op);
     assertEquals(expected.data, zeppelinHubMsg.data);
@@ -36,8 +36,8 @@ public class ZeppelinhubMessageTest {
   
   @Test
   public void testThatInvalidStringReturnEmptyZeppelinhubMessage() {
-    assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.deserialize(""));
-    assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.deserialize("dwfewewrewr"));
+    assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.fromJson(""));
+    assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.fromJson("dwfewewrewr"));
   }
 
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
index 363ccf6..46134e5 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
@@ -147,10 +147,10 @@ public class DistributedResourcePoolTest {
     intp2.interpret("put key2 value2", context);
 
     ret = intp1.interpret("getAll", context);
-    assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size());
+    assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size());
 
     ret = intp2.interpret("getAll", context);
-    assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size());
+    assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size());
 
     ret = intp1.interpret("get key1", context);
     assertEquals("value1", gson.fromJson(ret.message().get(0).getData(), String.class));
@@ -173,7 +173,7 @@ public class DistributedResourcePoolTest {
         ResourceSet remoteSet = new ResourceSet();
         Gson gson = new Gson();
         for (Resource s : set) {
-          RemoteResource remoteResource = gson.fromJson(gson.toJson(s), RemoteResource.class);
+          RemoteResource remoteResource = RemoteResource.fromJson(s.toJson());
           remoteResource.setResourcePoolConnector(this);
           remoteSet.add(remoteResource);
         }
@@ -278,14 +278,14 @@ public class DistributedResourcePoolTest {
 
     // make sure no resources are automatically created
     ret = intp1.interpret("getAll", context);
-    assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size());
+    assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size());
 
     // invoke method in local resource pool and save result
     ret = intp1.interpret("invoke key1 length ret1", context);
     assertEquals("3", ret.message().get(0).getData());
 
     ret = intp1.interpret("getAll", context);
-    assertEquals(3, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size());
+    assertEquals(3, ResourceSet.fromJson(ret.message().get(0).getData()).size());
 
     ret = intp1.interpret("get ret1", context);
     assertEquals("3", gson.fromJson(ret.message().get(0).getData(), String.class));
@@ -295,7 +295,7 @@ public class DistributedResourcePoolTest {
     assertEquals("5", ret.message().get(0).getData());
 
     ret = intp1.interpret("getAll", context);
-    assertEquals(4, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size());
+    assertEquals(4, ResourceSet.fromJson(ret.message().get(0).getData()).size());
 
     ret = intp1.interpret("get ret2", context);
     assertEquals("5", gson.fromJson(ret.message().get(0).getData(), String.class));


[2/2] zeppelin git commit: ZEPPELIN-2397. Add toJson and fromJson method for serializable objects

Posted by zj...@apache.org.
ZEPPELIN-2397. Add toJson and fromJson method for serializable objects

### What is this PR for?
Add toJson and fromJson method for all the objects that need ser/der in zeppelin.

### What type of PR is it?
[Refactoring]

### Todos
* [ ] - Task

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-2397?filter=-2

### How should this be tested?
Outline the steps to test the PR here.

### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Author: Jeff Zhang <zj...@apache.org>

Closes #2272 from zjffdu/ZEPPELIN-2397 and squashes the following commits:

4fb12fe [Jeff Zhang] ZEPPELIN-2397. Add toJson and fromJson method for serializable objects


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/f36b1a15
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/f36b1a15
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/f36b1a15

Branch: refs/heads/master
Commit: f36b1a1577ccd7dce438cf834985c9d72abca1e3
Parents: f3f24f3
Author: Jeff Zhang <zj...@apache.org>
Authored: Wed Apr 12 18:43:34 2017 +0800
Committer: Jeff Zhang <zj...@apache.org>
Committed: Tue Jul 4 18:24:16 2017 +0800

----------------------------------------------------------------------
 .../zeppelin/common/JsonSerializable.java       | 26 +++++++
 .../org/apache/zeppelin/dep/Repository.java     | 14 +++-
 .../apache/zeppelin/display/AngularObject.java  | 15 +++-
 .../java/org/apache/zeppelin/display/GUI.java   | 35 ++++++++-
 .../java/org/apache/zeppelin/display/Input.java | 67 ++++++++++++----
 .../apache/zeppelin/helium/HeliumPackage.java   | 15 +++-
 .../zeppelin/interpreter/InterpreterResult.java | 14 +++-
 .../RemoteZeppelinServerResource.java           | 15 +++-
 .../InvokeResourceMethodEventMessage.java       | 14 +++-
 .../remote/RemoteInterpreterEventClient.java    | 19 ++---
 .../remote/RemoteInterpreterEventPoller.java    | 19 +++--
 .../remote/RemoteInterpreterServer.java         | 17 ++--
 .../zeppelin/resource/RemoteResource.java       | 15 +++-
 .../org/apache/zeppelin/resource/Resource.java  | 14 +++-
 .../apache/zeppelin/resource/ResourceId.java    | 15 +++-
 .../zeppelin/resource/ResourcePoolUtils.java    |  7 +-
 .../apache/zeppelin/resource/ResourceSet.java   | 15 +++-
 .../zeppelin/user/AuthenticationInfo.java       | 16 +++-
 .../org/apache/zeppelin/user/Credentials.java   |  3 +-
 .../zeppelin/user/CredentialsInfoSaving.java    | 15 +++-
 .../org/apache/zeppelin/display/GUITest.java    | 49 ++++++++++++
 .../zeppelin/helium/HeliumPackageTest.java      |  4 +-
 .../apache/zeppelin/realm/ZeppelinHubRealm.java | 20 +++--
 .../org/apache/zeppelin/rest/HeliumRestApi.java |  2 +-
 .../zeppelin/rest/InterpreterRestApi.java       | 12 +--
 .../zeppelin/rest/NotebookRepoRestApi.java      |  7 +-
 .../apache/zeppelin/rest/NotebookRestApi.java   | 10 +--
 .../zeppelin/rest/message/CronRequest.java      | 14 +++-
 .../message/NewInterpreterSettingRequest.java   | 13 +++-
 .../zeppelin/rest/message/NewNoteRequest.java   | 14 +++-
 .../rest/message/NewParagraphRequest.java       | 15 +++-
 .../message/NotebookRepoSettingsRequest.java    | 13 +++-
 .../rest/message/RestartInterpreterRequest.java | 15 +++-
 .../RunParagraphWithParametersRequest.java      | 15 +++-
 .../UpdateInterpreterSettingRequest.java        | 14 +++-
 .../apache/zeppelin/socket/NotebookServer.java  |  4 +-
 .../zeppelin/rest/AbstractTestRestApi.java      |  2 -
 .../zeppelin/rest/ZeppelinSparkClusterTest.java |  3 -
 .../zeppelin/socket/NotebookServerTest.java     | 12 +--
 .../java/org/apache/zeppelin/helium/Helium.java | 13 +---
 .../helium/HeliumApplicationFactory.java        |  4 +-
 .../zeppelin/helium/HeliumBundleFactory.java    |  9 +--
 .../org/apache/zeppelin/helium/HeliumConf.java  | 19 ++++-
 .../org/apache/zeppelin/helium/NpmPackage.java  | 15 +++-
 .../apache/zeppelin/helium/WebpackResult.java   | 15 +++-
 .../interpreter/InterpreterFactory.java         | 72 ++++-------------
 .../interpreter/InterpreterInfoSaving.java      | 16 +++-
 .../interpreter/InterpreterSettingManager.java  |  8 +-
 .../interpreter/remote/RemoteInterpreter.java   |  4 +-
 .../java/org/apache/zeppelin/notebook/Note.java | 80 ++++++++++++++++---
 .../org/apache/zeppelin/notebook/Notebook.java  | 14 +---
 .../notebook/NotebookAuthorization.java         |  3 +-
 .../NotebookAuthorizationInfoSaving.java        | 16 +++-
 .../notebook/NotebookImportDeserializer.java    |  3 +-
 .../org/apache/zeppelin/notebook/Paragraph.java | 71 ++++++++++++++++-
 .../json/NotebookTypeAdapterFactory.java        | 82 ++++++++++++++++++++
 .../notebook/repo/AzureNotebookRepo.java        | 15 +---
 .../notebook/repo/MongoNotebookRepo.java        | 11 +--
 .../zeppelin/notebook/repo/S3NotebookRepo.java  | 14 +---
 .../zeppelin/notebook/repo/VFSNotebookRepo.java | 11 +--
 .../zeppelinhub/websocket/ZeppelinClient.java   | 20 ++---
 .../websocket/ZeppelinhubClient.java            |  2 +-
 .../websocket/listener/WatcherWebsocket.java    |  7 +-
 .../websocket/protocol/ZeppelinhubMessage.java  |  9 ++-
 .../websocket/utils/ZeppelinhubUtils.java       | 12 +--
 .../zeppelin/notebook/socket/Message.java       | 14 +++-
 .../notebook/socket/WatcherMessage.java         | 11 ++-
 .../interpreter/InterpreterFactoryTest.java     | 34 +++-----
 .../org/apache/zeppelin/notebook/NoteTest.java  | 30 +++++++
 .../apache/zeppelin/notebook/NotebookTest.java  | 10 ++-
 .../protocol/ZeppelinhubMessageTest.java        |  8 +-
 .../resource/DistributedResourcePoolTest.java   | 12 +--
 72 files changed, 929 insertions(+), 343 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/common/JsonSerializable.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/common/JsonSerializable.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/common/JsonSerializable.java
new file mode 100644
index 0000000..7764138
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/common/JsonSerializable.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.common;
+
+/**
+ * Interface for class that can be serialized to json
+ */
+public interface JsonSerializable {
+
+  String toJson();
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/Repository.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/Repository.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/Repository.java
index 86f39bd..74adce8 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/Repository.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/Repository.java
@@ -18,6 +18,8 @@
 package org.apache.zeppelin.dep;
 import static org.apache.commons.lang.StringUtils.isNotBlank;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.sonatype.aether.repository.Authentication;
 import org.sonatype.aether.repository.Proxy;
 
@@ -25,7 +27,9 @@ import org.sonatype.aether.repository.Proxy;
  *
  *
  */
-public class Repository {
+public class Repository implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   private boolean snapshot = false;
   private String id;
   private String url;
@@ -98,4 +102,12 @@ public class Repository {
     }
     return null;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static Repository fromJson(String json) {
+    return gson.fromJson(json, Repository.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java
index 84ee67e..2187705 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java
@@ -22,6 +22,8 @@ import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.ExecutorService;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.scheduler.ExecutorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,8 +35,9 @@ import org.slf4j.LoggerFactory;
  *
  * @param <T>
  */
-public class AngularObject<T> {
+public class AngularObject<T> implements JsonSerializable {
   private static final Logger LOGGER = LoggerFactory.getLogger(AngularObject.class);
+  private static final Gson gson = new Gson();
 
   private String name;
   private T object;
@@ -63,7 +66,7 @@ public class AngularObject<T> {
    * @param paragraphId paragraphId belongs to. can be null
    * @param listener event listener
    */
-  protected AngularObject(String name, T o, String noteId, String paragraphId,
+  public AngularObject(String name, T o, String noteId, String paragraphId,
       AngularObjectListener listener) {
     this.name = name;
     this.noteId = noteId;
@@ -253,4 +256,12 @@ public class AngularObject<T> {
     sb.append('}');
     return sb.toString();
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static AngularObject fromJson(String json) {
+    return gson.fromJson(json, AngularObject.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java
index 66b21c6..086f805 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java
@@ -25,8 +25,12 @@ import org.apache.zeppelin.display.ui.Select;
 import org.apache.zeppelin.display.ui.TextBox;
 
 import java.io.Serializable;
-
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -96,7 +100,7 @@ public class GUI implements Serializable {
   }
 
   public List<Object> checkbox(String id, Collection<Object> defaultChecked,
-                                     ParamOption[] options) {
+                               ParamOption[] options) {
     Collection<Object> checked = (Collection<Object>) params.get(id);
     if (checked == null) {
       checked = defaultChecked;
@@ -124,6 +128,31 @@ public class GUI implements Serializable {
     this.forms = new LinkedHashMap<>();
   }
 
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    GUI gui = (GUI) o;
+
+    if (params != null ? !params.equals(gui.params) : gui.params != null) {
+      return false;
+    }
+    return forms != null ? forms.equals(gui.forms) : gui.forms == null;
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result = params != null ? params.hashCode() : 0;
+    result = 31 * result + (forms != null ? forms.hashCode() : 0);
+    return result;
+  }
+
   public String toJson() {
     return gson.toJson(this);
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/Input.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/Input.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/Input.java
index 12fa782..f713f4a 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/Input.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/Input.java
@@ -18,6 +18,7 @@
 package org.apache.zeppelin.display;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.display.ui.*;
 import org.apache.zeppelin.display.ui.OptionInput.ParamOption;
 
@@ -37,13 +38,13 @@ public class Input<T> implements Serializable {
   // in future.
   public static final RuntimeTypeAdapterFactory TypeAdapterFactory =
       RuntimeTypeAdapterFactory.of(Input.class, "type")
-        .registerSubtype(TextBox.class, "TextBox")
-        .registerSubtype(Select.class, "Select")
-        .registerSubtype(CheckBox.class, "CheckBox")
-        .registerSubtype(OldInput.OldTextBox.class, "input")
-        .registerSubtype(OldInput.OldSelect.class, "select")
-        .registerSubtype(OldInput.OldCheckBox.class, "checkbox")
-        .registerSubtype(OldInput.class, null);
+          .registerSubtype(TextBox.class, "TextBox")
+          .registerSubtype(Select.class, "Select")
+          .registerSubtype(CheckBox.class, "CheckBox")
+          .registerSubtype(OldInput.OldTextBox.class, "input")
+          .registerSubtype(OldInput.OldSelect.class, "select")
+          .registerSubtype(OldInput.OldCheckBox.class, "checkbox")
+          .registerSubtype(OldInput.class, null);
 
   protected String name;
   protected String displayName;
@@ -86,6 +87,44 @@ public class Input<T> implements Serializable {
     return argument;
   }
 
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    Input<?> input = (Input<?>) o;
+
+    if (hidden != input.hidden) {
+      return false;
+    }
+    if (name != null ? !name.equals(input.name) : input.name != null) {
+      return false;
+    }
+    if (displayName != null ? !displayName.equals(input.displayName) : input.displayName != null) {
+      return false;
+    }
+    if (defaultValue != null ?
+        !defaultValue.equals(input.defaultValue) : input.defaultValue != null) {
+      return false;
+    }
+    return argument != null ? argument.equals(input.argument) : input.argument == null;
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result = name != null ? name.hashCode() : 0;
+    result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+    result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0);
+    result = 31 * result + (hidden ? 1 : 0);
+    result = 31 * result + (argument != null ? argument.hashCode() : 0);
+    return result;
+  }
+
   public static TextBox textbox(String name, String defaultValue) {
     return new TextBox(name, defaultValue);
   }
@@ -276,7 +315,7 @@ public class Input<T> implements Serializable {
           delimiter = DEFAULT_DELIMITER;
         }
         Collection<Object> checked = value instanceof Collection ? (Collection<Object>) value
-                : Arrays.asList((Object[]) value);
+            : Arrays.asList((Object[]) value);
         List<Object> validChecked = new LinkedList<>();
         for (Object o : checked) {  // filter out obsolete checked values
           for (ParamOption option : optionInput.getOptions()) {
@@ -316,22 +355,22 @@ public class Input<T> implements Serializable {
   }
 
   public static String[] split(String str, char split) {
-    return split(str, new String[] {String.valueOf(split)}, false);
+    return split(str, new String[]{String.valueOf(split)}, false);
   }
 
   public static String[] split(String str, String[] splitters, boolean includeSplitter) {
     String escapeSeq = "\"',;${}";
     char escapeChar = '\\';
 
-    String[] blockStart = new String[] {"\"", "'", "${", "N_(", "N_<"};
-    String[] blockEnd = new String[] {"\"", "'", "}", "N_)", "N_>"};
+    String[] blockStart = new String[]{"\"", "'", "${", "N_(", "N_<"};
+    String[] blockEnd = new String[]{"\"", "'", "}", "N_)", "N_>"};
 
     return split(str, escapeSeq, escapeChar, blockStart, blockEnd, splitters, includeSplitter);
 
   }
 
   public static String[] split(String str, String escapeSeq, char escapeChar, String[] blockStart,
-      String[] blockEnd, String[] splitters, boolean includeSplitter) {
+                               String[] blockEnd, String[] splitters, boolean includeSplitter) {
 
     List<String> splits = new ArrayList<>();
 
@@ -442,7 +481,7 @@ public class Input<T> implements Serializable {
         // check if block is started
         for (int b = 0; b < blockStart.length; b++) {
           if (curString.substring(lastEscapeOffset + 1)
-                       .endsWith(getBlockStr(blockStart[b])) == true) {
+              .endsWith(getBlockStr(blockStart[b])) == true) {
             blockStack.add(0, b); // block is started
             blockStartPos = i;
             break;
@@ -453,7 +492,7 @@ public class Input<T> implements Serializable {
     if (curString.length() > 0) {
       splits.add(curString.toString().trim());
     }
-    return splits.toArray(new String[] {});
+    return splits.toArray(new String[]{});
 
   }
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java
index c1af75f..759b991 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java
@@ -16,7 +16,10 @@
  */
 package org.apache.zeppelin.helium;
 
+import com.google.gson.Gson;
 import org.apache.zeppelin.annotation.Experimental;
+import org.apache.zeppelin.common.JsonSerializable;
+import org.apache.zeppelin.dep.Repository;
 
 import java.util.Map;
 
@@ -24,7 +27,9 @@ import java.util.Map;
  * Helium package definition
  */
 @Experimental
-public class HeliumPackage {
+public class HeliumPackage implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   private HeliumType type;
   private String name;           // user friendly name of this application
   private String description;    // description
@@ -129,4 +134,12 @@ public class HeliumPackage {
   }
 
   public Map<String, Object> getConfig() { return config; }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static HeliumPackage fromJson(String json) {
+    return gson.fromJson(json, HeliumPackage.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java
index 7aab8a3..b08a97e 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java
@@ -20,6 +20,8 @@ package org.apache.zeppelin.interpreter;
 import java.io.IOException;
 import java.io.Serializable;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,8 +30,10 @@ import java.util.*;
 /**
  * Interpreter result template.
  */
-public class InterpreterResult implements Serializable {
+public class InterpreterResult implements Serializable, JsonSerializable {
   transient Logger logger = LoggerFactory.getLogger(InterpreterResult.class);
+  private static final Gson gson = new Gson();
+
   /**
    *  Type of result after code execution.
    */
@@ -109,6 +113,14 @@ public class InterpreterResult implements Serializable {
     return msg;
   }
 
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static InterpreterResult fromJson(String json) {
+    return gson.fromJson(json, InterpreterResult.class);
+  }
+
   public String toString() {
     StringBuilder sb = new StringBuilder();
     Type prevType = null;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/RemoteZeppelinServerResource.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/RemoteZeppelinServerResource.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/RemoteZeppelinServerResource.java
index b2a87aa..bf96a09 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/RemoteZeppelinServerResource.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/RemoteZeppelinServerResource.java
@@ -17,10 +17,15 @@
 
 package org.apache.zeppelin.interpreter;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 /**
  * Remote Zeppelin Server Resource
  */
-public class RemoteZeppelinServerResource {
+public class RemoteZeppelinServerResource implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   /**
    * Resource Type for Zeppelin Server
    */
@@ -55,4 +60,12 @@ public class RemoteZeppelinServerResource {
   public void setData(Object data) {
     this.data = data;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static RemoteZeppelinServerResource fromJson(String json) {
+    return gson.fromJson(json, RemoteZeppelinServerResource.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/InvokeResourceMethodEventMessage.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/InvokeResourceMethodEventMessage.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/InvokeResourceMethodEventMessage.java
index a2b0690..aaf3d7b 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/InvokeResourceMethodEventMessage.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/InvokeResourceMethodEventMessage.java
@@ -16,12 +16,16 @@
  */
 package org.apache.zeppelin.interpreter.remote;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.resource.ResourceId;
 
 /**
  * message payload to invoke method of resource in the resourcepool
  */
-public class InvokeResourceMethodEventMessage {
+public class InvokeResourceMethodEventMessage implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   public final ResourceId resourceId;
   public final String methodName;
   public final String[] paramClassnames;
@@ -91,4 +95,12 @@ public class InvokeResourceMethodEventMessage {
       return false;
     }
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static InvokeResourceMethodEventMessage fromJson(String json) {
+    return gson.fromJson(json, InvokeResourceMethodEventMessage.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
index 2cdbf39..5f8ccb7 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
@@ -85,7 +85,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
    */
   public void angularObjectAdd(AngularObject object) {
     sendEvent(new RemoteInterpreterEvent(
-        RemoteInterpreterEventType.ANGULAR_OBJECT_ADD, gson.toJson(object)));
+        RemoteInterpreterEventType.ANGULAR_OBJECT_ADD, object.toJson()));
   }
 
   /**
@@ -93,7 +93,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
    */
   public void angularObjectUpdate(AngularObject object) {
     sendEvent(new RemoteInterpreterEvent(
-        RemoteInterpreterEventType.ANGULAR_OBJECT_UPDATE, gson.toJson(object)));
+        RemoteInterpreterEventType.ANGULAR_OBJECT_UPDATE, object.toJson()));
   }
 
   /**
@@ -146,10 +146,9 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
       }
 
       // send request
-      Gson gson = new Gson();
       sendEvent(new RemoteInterpreterEvent(
           RemoteInterpreterEventType.RESOURCE_GET,
-          gson.toJson(resourceId)));
+          resourceId.toJson()));
 
       // wait for response
       while (!getResourceResponse.containsKey(resourceId)) {
@@ -198,11 +197,9 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
         }
       }
       // send request
-      Gson gson = new Gson();
-
       sendEvent(new RemoteInterpreterEvent(
           RemoteInterpreterEventType.RESOURCE_INVOKE_METHOD,
-          gson.toJson(invokeMethod)));
+          invokeMethod.toJson()));
       // wait for response
       while (!getInvokeResponse.containsKey(invokeMethod)) {
         try {
@@ -252,11 +249,9 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
         }
       }
       // send request
-      Gson gson = new Gson();
-
       sendEvent(new RemoteInterpreterEvent(
           RemoteInterpreterEventType.RESOURCE_INVOKE_METHOD,
-          gson.toJson(invokeMethod)));
+          invokeMethod.toJson()));
       // wait for response
       while (!getInvokeResponse.containsKey(invokeMethod)) {
         try {
@@ -279,7 +274,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
     ResourceSet resourceSet = new ResourceSet();
 
     for (String res : resources) {
-      RemoteResource resource = gson.fromJson(res, RemoteResource.class);
+      RemoteResource resource = RemoteResource.fromJson(res);
       resource.setResourcePoolConnector(this);
       resourceSet.add(resource);
     }
@@ -296,7 +291,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
    * @param object java serialized of the object
    */
   public void putResponseGetResource(String resourceId, ByteBuffer object) {
-    ResourceId rid = gson.fromJson(resourceId, ResourceId.class);
+    ResourceId rid = ResourceId.fromJson(resourceId);
 
     logger.debug("Response resource {} from RemoteInterpreter", rid.getName());
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
index 126a46f..6927b3b 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
@@ -130,12 +130,11 @@ public class RemoteInterpreterEventPoller extends Thread {
         if (event.getType() == RemoteInterpreterEventType.NO_OP) {
           continue;
         } else if (event.getType() == RemoteInterpreterEventType.ANGULAR_OBJECT_ADD) {
-          AngularObject angularObject = gson.fromJson(event.getData(), AngularObject.class);
+          AngularObject angularObject = AngularObject.fromJson(event.getData());
           angularObjectRegistry.add(angularObject.getName(),
               angularObject.get(), angularObject.getNoteId(), angularObject.getParagraphId());
         } else if (event.getType() == RemoteInterpreterEventType.ANGULAR_OBJECT_UPDATE) {
-          AngularObject angularObject = gson.fromJson(event.getData(),
-              AngularObject.class);
+          AngularObject angularObject = AngularObject.fromJson(event.getData());
           AngularObject localAngularObject = angularObjectRegistry.get(
               angularObject.getName(), angularObject.getNoteId(), angularObject.getParagraphId());
           if (localAngularObject instanceof RemoteAngularObject) {
@@ -146,7 +145,7 @@ public class RemoteInterpreterEventPoller extends Thread {
             localAngularObject.set(angularObject.get());
           }
         } else if (event.getType() == RemoteInterpreterEventType.ANGULAR_OBJECT_REMOVE) {
-          AngularObject angularObject = gson.fromJson(event.getData(), AngularObject.class);
+          AngularObject angularObject = AngularObject.fromJson(event.getData());
           angularObjectRegistry.remove(angularObject.getName(), angularObject.getNoteId(),
                   angularObject.getParagraphId());
         } else if (event.getType() == RemoteInterpreterEventType.RUN_INTERPRETER_CONTEXT_RUNNER) {
@@ -161,14 +160,14 @@ public class RemoteInterpreterEventPoller extends Thread {
           sendResourcePoolResponseGetAll(resourceSet);
         } else if (event.getType() == RemoteInterpreterEventType.RESOURCE_GET) {
           String resourceIdString = event.getData();
-          ResourceId resourceId = gson.fromJson(resourceIdString, ResourceId.class);
+          ResourceId resourceId = ResourceId.fromJson(resourceIdString);
           logger.debug("RESOURCE_GET {} {}", resourceId.getResourcePoolId(), resourceId.getName());
           Object o = getResource(resourceId);
           sendResourceResponseGet(resourceId, o);
         } else if (event.getType() == RemoteInterpreterEventType.RESOURCE_INVOKE_METHOD) {
           String message = event.getData();
           InvokeResourceMethodEventMessage invokeMethodMessage =
-              gson.fromJson(message, InvokeResourceMethodEventMessage.class);
+              InvokeResourceMethodEventMessage.fromJson(message);
           Object ret = invokeResourceMethod(invokeMethodMessage);
           sendInvokeMethodResult(invokeMethodMessage, ret);
         } else if (event.getType() == RemoteInterpreterEventType.OUTPUT_APPEND) {
@@ -237,8 +236,8 @@ public class RemoteInterpreterEventPoller extends Thread {
 
           appListener.onStatusChange(noteId, paragraphId, appId, status);
         } else if (event.getType() == RemoteInterpreterEventType.REMOTE_ZEPPELIN_SERVER_RESOURCE) {
-          RemoteZeppelinServerResource reqResourceBody = gson.fromJson(
-              event.getData(), RemoteZeppelinServerResource.class);
+          RemoteZeppelinServerResource reqResourceBody = RemoteZeppelinServerResource.fromJson(
+              event.getData());
           progressRemoteZeppelinControlEvent(
               reqResourceBody.getResourceType(), listener, reqResourceBody);
 
@@ -326,7 +325,7 @@ public class RemoteInterpreterEventPoller extends Thread {
                   resResource.setData(remoteRunners);
 
                   try {
-                    eventClient.onReceivedZeppelinResource(gson.toJson(resResource));
+                    eventClient.onReceivedZeppelinResource(resResource.toJson());
                   } catch (Exception e) {
                     clientBroken = true;
                     logger.error("Can't get RemoteInterpreterEvent", e);
@@ -398,7 +397,7 @@ public class RemoteInterpreterEventPoller extends Thread {
           List<String> resourceList = client.resourcePoolGetAll();
           Gson gson = new Gson();
           for (String res : resourceList) {
-            resourceSet.add(gson.fromJson(res, Resource.class));
+            resourceSet.add(Resource.fromJson(res));
           }
         } catch (Exception e) {
           logger.error(e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
index 4df3088..f501014 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
@@ -355,9 +355,7 @@ public class RemoteInterpreterServer
 
   @Override
   public void onReceivedZeppelinResource(String responseJson) throws TException {
-    RemoteZeppelinServerResource response = gson.fromJson(
-        responseJson, RemoteZeppelinServerResource.class);
-
+    RemoteZeppelinServerResource response = RemoteZeppelinServerResource.fromJson(responseJson);
     if (response == null) {
       throw new TException("Bad response for remote resource");
     }
@@ -609,7 +607,7 @@ public class RemoteInterpreterServer
         ric.getReplName(),
         ric.getParagraphTitle(),
         ric.getParagraphText(),
-        gson.fromJson(ric.getAuthenticationInfo(), AuthenticationInfo.class),
+        AuthenticationInfo.fromJson(ric.getAuthenticationInfo()),
         (Map<String, Object>) gson.fromJson(ric.getConfig(),
             new TypeToken<Map<String, Object>>() {}.getType()),
         GUI.fromJson(ric.getGui()),
@@ -942,11 +940,8 @@ public class RemoteInterpreterServer
     }
 
     ResourceSet resourceSet = resourcePool.getAll(false);
-
-    Gson gson = new Gson();
-
     for (Resource r : resourceSet) {
-      result.add(gson.toJson(r));
+      result.add(r.toJson());
     }
 
     return result;
@@ -981,7 +976,7 @@ public class RemoteInterpreterServer
   public ByteBuffer resourceInvokeMethod(
       String noteId, String paragraphId, String resourceName, String invokeMessage) {
     InvokeResourceMethodEventMessage message =
-        gson.fromJson(invokeMessage, InvokeResourceMethodEventMessage.class);
+        InvokeResourceMethodEventMessage.fromJson(invokeMessage);
 
     Resource resource = resourcePool.get(noteId, paragraphId, resourceName, false);
     if (resource == null || resource.get() == null) {
@@ -1030,7 +1025,7 @@ public class RemoteInterpreterServer
   public void resourceResponseInvokeMethod(
       String invokeResourceMethodEventMessage, ByteBuffer object) throws TException {
     InvokeResourceMethodEventMessage message =
-        gson.fromJson(invokeResourceMethodEventMessage, InvokeResourceMethodEventMessage.class);
+        InvokeResourceMethodEventMessage.fromJson(invokeResourceMethodEventMessage);
 
     if (message.shouldPutResultIntoResourcePool()) {
       Resource resource = resourcePool.get(
@@ -1102,7 +1097,7 @@ public class RemoteInterpreterServer
       logger.warn("Application instance {} is already running");
       return new RemoteApplicationResult(true, "");
     }
-    HeliumPackage pkgInfo = gson.fromJson(packageInfo, HeliumPackage.class);
+    HeliumPackage pkgInfo = HeliumPackage.fromJson(packageInfo);
     ApplicationContext context = getApplicationContext(
         pkgInfo, noteId, paragraphId, applicationInstanceId);
     try {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/RemoteResource.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/RemoteResource.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/RemoteResource.java
index 6342231..874c1cb 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/RemoteResource.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/RemoteResource.java
@@ -16,10 +16,15 @@
  */
 package org.apache.zeppelin.resource;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 /**
  * Resource that can retrieve data from remote
  */
-public class RemoteResource extends Resource {
+public class RemoteResource extends Resource implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   ResourcePoolConnector resourcePoolConnector;
 
   RemoteResource(ResourceId resourceId, Object r) {
@@ -91,4 +96,12 @@ public class RemoteResource extends Resource {
         returnResourceName);
     return resource;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static RemoteResource fromJson(String json) {
+    return gson.fromJson(json, RemoteResource.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/Resource.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/Resource.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/Resource.java
index 098e7ba..b57d46b 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/Resource.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/Resource.java
@@ -16,6 +16,8 @@
  */
 package org.apache.zeppelin.resource;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -26,7 +28,9 @@ import java.nio.ByteBuffer;
 /**
  * Information and reference to the resource
  */
-public class Resource {
+public class Resource implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   private final transient Object r;
   private final transient LocalResourcePool pool;
   private final boolean serializable;
@@ -203,4 +207,12 @@ public class Resource {
     Logger logger = LoggerFactory.getLogger(Resource.class);
     logger.error(e.getMessage(), e);
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static Resource fromJson(String json) {
+    return gson.fromJson(json, Resource.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceId.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceId.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceId.java
index 3fb3102..bef9e3f 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceId.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceId.java
@@ -16,10 +16,15 @@
  */
 package org.apache.zeppelin.resource;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 /**
  * Identifying resource
  */
-public class ResourceId {
+public class ResourceId implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   private final String resourcePoolId;
   private final String name;
   private final String noteId;
@@ -80,4 +85,12 @@ public class ResourceId {
       return false;
     }
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static ResourceId fromJson(String json) {
+    return gson.fromJson(json, ResourceId.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourcePoolUtils.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourcePoolUtils.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourcePoolUtils.java
index a55cdf9..b26995a 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourcePoolUtils.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourcePoolUtils.java
@@ -17,7 +17,6 @@
 
 package org.apache.zeppelin.resource;
 
-import com.google.gson.Gson;
 import org.apache.zeppelin.interpreter.InterpreterGroup;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
@@ -59,9 +58,8 @@ public class ResourcePoolUtils {
             continue;
           }
           List<String> resourceList = client.resourcePoolGetAll();
-          Gson gson = new Gson();
           for (String res : resourceList) {
-            resourceSet.add(gson.fromJson(res, Resource.class));
+            resourceSet.add(Resource.fromJson(res));
           }
         } catch (Exception e) {
           logger.error(e.getMessage(), e);
@@ -108,9 +106,8 @@ public class ResourcePoolUtils {
         try {
           client = remoteInterpreterProcess.getClient();
           List<String> resourceList = client.resourcePoolGetAll();
-          Gson gson = new Gson();
           for (String res : resourceList) {
-            resourceSet.add(gson.fromJson(res, Resource.class));
+            resourceSet.add(Resource.fromJson(res));
           }
 
           if (noteId != null) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceSet.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceSet.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceSet.java
index bbc3f06..01d3c70 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceSet.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/resource/ResourceSet.java
@@ -16,6 +16,9 @@
  */
 package org.apache.zeppelin.resource;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.regex.Pattern;
@@ -23,7 +26,9 @@ import java.util.regex.Pattern;
 /**
  * List of resources
  */
-public class ResourceSet extends LinkedList<Resource> {
+public class ResourceSet extends LinkedList<Resource> implements JsonSerializable {
+
+  private static final Gson gson = new Gson();
 
   public ResourceSet(Collection<Resource> resources) {
     super(resources);
@@ -102,4 +107,12 @@ public class ResourceSet extends LinkedList<Resource> {
       return false;
     }
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static ResourceSet fromJson(String json) {
+    return gson.fromJson(json, ResourceSet.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java
index 766418a..d00d160 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java
@@ -18,19 +18,23 @@
 
 package org.apache.zeppelin.user;
 
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-
+import com.google.gson.Gson;
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /***
  *
  */
-public class AuthenticationInfo {
+public class AuthenticationInfo implements JsonSerializable {
   private static final Logger LOG = LoggerFactory.getLogger(AuthenticationInfo.class);
+  private static final Gson gson = new Gson();
+
   String user;
   List<String> roles;
   String ticket;
@@ -115,4 +119,12 @@ public class AuthenticationInfo {
     return ANONYMOUS.equals(this) || "anonymous".equalsIgnoreCase(this.getUser())
         || StringUtils.isEmpty(this.getUser());
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static AuthenticationInfo fromJson(String json) {
+    return gson.fromJson(json, AuthenticationInfo.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
index 6a2fae3..e80a89f 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
@@ -20,6 +20,7 @@ package org.apache.zeppelin.user;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -118,7 +119,7 @@ public class Credentials {
       fis.close();
 
       String json = sb.toString();
-      CredentialsInfoSaving info = gson.fromJson(json, CredentialsInfoSaving.class);
+      CredentialsInfoSaving info = CredentialsInfoSaving.fromJson(json);
       this.credentialsMap = info.credentialsMap;
     } catch (IOException e) {
       LOG.error("Error loading credentials file", e);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/CredentialsInfoSaving.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/CredentialsInfoSaving.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/CredentialsInfoSaving.java
index 20b586c..48bb24d 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/CredentialsInfoSaving.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/CredentialsInfoSaving.java
@@ -17,11 +17,24 @@
 
 package org.apache.zeppelin.user;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.Map;
 
 /**
  * Helper class to save credentials
  */
-public class CredentialsInfoSaving {
+public class CredentialsInfoSaving implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   public Map<String, UserCredentials> credentialsMap;
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static CredentialsInfoSaving fromJson(String json) {
+    return gson.fromJson(json, CredentialsInfoSaving.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/GUITest.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/GUITest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/GUITest.java
index 6def2e7..15af2e6 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/GUITest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/GUITest.java
@@ -117,4 +117,53 @@ public class GUITest {
     assertTrue(gui2.forms.get("checkbox_1") instanceof CheckBox);
     assertEquals(options, ((CheckBox) gui2.forms.get("checkbox_1")).getOptions());
   }
+
+  // load old json file and will convert it into new forms of Input
+  @Test
+  public void testOldGson_3() throws IOException {
+    String oldJson = "{\n" +
+        "        \"params\": {\n" +
+        "          \"maxAge\": \"35\"\n" +
+        "        },\n" +
+        "        \"forms\": {\n" +
+        "          \"maxAge\": {\n" +
+        "            \"name\": \"maxAge\",\n" +
+        "            \"defaultValue\": \"30\",\n" +
+        "            \"hidden\": false\n" +
+        "          }\n" +
+        "        }\n" +
+        "      }";
+    GUI gui = GUI.fromJson(oldJson);
+    assertEquals(1, gui.forms.size());
+    assertTrue(gui.forms.get("maxAge") instanceof TextBox);
+    assertEquals("30", gui.forms.get("maxAge").getDefaultValue());
+
+    oldJson = "{\n" +
+        "        \"params\": {\n" +
+        "          \"marital\": \"single\"\n" +
+        "        },\n" +
+        "        \"forms\": {\n" +
+        "          \"marital\": {\n" +
+        "            \"name\": \"marital\",\n" +
+        "            \"defaultValue\": \"single\",\n" +
+        "            \"options\": [\n" +
+        "              {\n" +
+        "                \"value\": \"single\"\n" +
+        "              },\n" +
+        "              {\n" +
+        "                \"value\": \"divorced\"\n" +
+        "              },\n" +
+        "              {\n" +
+        "                \"value\": \"married\"\n" +
+        "              }\n" +
+        "            ],\n" +
+        "            \"hidden\": false\n" +
+        "          }\n" +
+        "        }\n" +
+        "      }";
+    gui = GUI.fromJson(oldJson);
+    assertEquals(1, gui.forms.size());
+    assertTrue(gui.forms.get("marital") instanceof Select);
+    assertEquals("single", gui.forms.get("marital").getDefaultValue());
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java
index a697fbd..4b91c82 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java
@@ -43,7 +43,7 @@ public class HeliumPackageTest {
         "  }\n" +
         "}";
 
-    HeliumPackage p = gson.fromJson(examplePackage, HeliumPackage.class);
+    HeliumPackage p = HeliumPackage.fromJson(examplePackage);
     assertEquals(p.getSpellInfo().getMagic(), "%echo");
     assertEquals(p.getSpellInfo().getUsage(), "%echo <TEXT>");
   }
@@ -70,7 +70,7 @@ public class HeliumPackageTest {
         "  }\n" +
         "}";
 
-    HeliumPackage p = gson.fromJson(examplePackage, HeliumPackage.class);
+    HeliumPackage p = HeliumPackage.fromJson(examplePackage);
     Map<String, Object> config = p.getConfig();
     Map<String, Object> accessToken = (Map<String, Object>) config.get("access-token");
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ZeppelinHubRealm.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ZeppelinHubRealm.java b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ZeppelinHubRealm.java
index d84207d..113469f 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ZeppelinHubRealm.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ZeppelinHubRealm.java
@@ -37,6 +37,7 @@ import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.notebook.repo.zeppelinhub.model.UserSessionContainer;
 import org.apache.zeppelin.notebook.repo.zeppelinhub.websocket.utils.ZeppelinhubUtils;
 import org.apache.zeppelin.server.ZeppelinServer;
@@ -62,7 +63,6 @@ public class ZeppelinHubRealm extends AuthorizingRealm {
   private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
 
   private final HttpClient httpClient;
-  private final Gson gson;
 
   private String zeppelinhubUrl;
   private String name;
@@ -73,7 +73,6 @@ public class ZeppelinHubRealm extends AuthorizingRealm {
     //TODO(anthonyc): think about more setting for this HTTP client.
     //                eg: if user uses proxy etcetc...
     httpClient = new HttpClient();
-    gson = new Gson();
     name = getClass().getName() + "_" + INSTANCE_COUNT.getAndIncrement();
   }
 
@@ -150,9 +149,9 @@ public class ZeppelinHubRealm extends AuthorizingRealm {
     
     User account = null;
     try {
-      account = gson.fromJson(responseBody, User.class);
+      account = User.fromJson(responseBody);
     } catch (JsonParseException e) {
-      LOG.error("Cannot deserialize ZeppelinHub response to User instance", e);
+      LOG.error("Cannot fromJson ZeppelinHub response to User instance", e);
       throw new AuthenticationException("Cannot login to ZeppelinHub");
     }
 
@@ -200,12 +199,21 @@ public class ZeppelinHubRealm extends AuthorizingRealm {
   }
 
   /**
-   * Helper class that will be use to deserialize ZeppelinHub response.
+   * Helper class that will be use to fromJson ZeppelinHub response.
    */
-  protected class User {
+  protected static class User implements JsonSerializable {
+    private static final Gson gson = new Gson();
     public String login;
     public String email;
     public String name;
+
+    public String toJson() {
+      return gson.toJson(this);
+    }
+
+    public static User fromJson(String json) {
+      return gson.fromJson(json, User.class);
+    }
   }
   
   public void onLoginSuccess(String username, String session) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java
index 1342f42..c8cd79a 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java
@@ -134,7 +134,7 @@ public class HeliumRestApi {
       return new JsonResponse(Response.Status.NOT_FOUND, "Paragraph " + paragraphId + " not found")
           .build();
     }
-    HeliumPackage pkg = gson.fromJson(heliumPackage, HeliumPackage.class);
+    HeliumPackage pkg = HeliumPackage.fromJson(heliumPackage);
 
     String appId = helium.getApplicationFactory().loadAndRun(pkg, paragraph);
     return new JsonResponse(Response.Status.OK, "", appId).build();

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
index a324e57..8824d90 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
@@ -35,7 +35,6 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import com.google.gson.Gson;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
 import org.apache.zeppelin.rest.message.RestartInterpreterRequest;
@@ -47,7 +46,6 @@ import org.sonatype.aether.repository.RemoteRepository;
 import org.apache.zeppelin.annotation.ZeppelinApi;
 import org.apache.zeppelin.dep.Repository;
 import org.apache.zeppelin.interpreter.InterpreterException;
-import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.rest.message.NewInterpreterSettingRequest;
 import org.apache.zeppelin.rest.message.UpdateInterpreterSettingRequest;
@@ -65,8 +63,6 @@ public class InterpreterRestApi {
   private InterpreterSettingManager interpreterSettingManager;
   private NotebookServer notebookServer;
 
-  Gson gson = new Gson();
-
   public InterpreterRestApi() {
   }
 
@@ -118,7 +114,7 @@ public class InterpreterRestApi {
   public Response newSettings(String message) {
     try {
       NewInterpreterSettingRequest request =
-          gson.fromJson(message, NewInterpreterSettingRequest.class);
+          NewInterpreterSettingRequest.fromJson(message);
       if (request == null) {
         return new JsonResponse<>(Status.BAD_REQUEST).build();
       }
@@ -144,7 +140,7 @@ public class InterpreterRestApi {
 
     try {
       UpdateInterpreterSettingRequest request =
-          gson.fromJson(message, UpdateInterpreterSettingRequest.class);
+          UpdateInterpreterSettingRequest.fromJson(message);
       interpreterSettingManager
           .setPropertyAndRestart(settingId, request.getOption(), request.getProperties(),
               request.getDependencies());
@@ -187,7 +183,7 @@ public class InterpreterRestApi {
 
     InterpreterSetting setting = interpreterSettingManager.get(settingId);
     try {
-      RestartInterpreterRequest request = gson.fromJson(message, RestartInterpreterRequest.class);
+      RestartInterpreterRequest request = RestartInterpreterRequest.fromJson(message);
 
       String noteId = request == null ? null : request.getNoteId();
       if (null == noteId) {
@@ -239,7 +235,7 @@ public class InterpreterRestApi {
   @ZeppelinApi
   public Response addRepository(String message) {
     try {
-      Repository request = gson.fromJson(message, Repository.class);
+      Repository request = Repository.fromJson(message);
       interpreterSettingManager.addRepository(request.getId(), request.getUrl(),
           request.isSnapshot(), request.getAuthentication(), request.getProxy());
       logger.info("New repository {} added", request.getId());

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRepoRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRepoRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRepoRestApi.java
index 5a66334..a8bcbef 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRepoRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRepoRestApi.java
@@ -39,7 +39,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.gson.Gson;
 import com.google.gson.JsonSyntaxException;
 
 /**
@@ -52,7 +51,6 @@ public class NotebookRepoRestApi {
 
   private static final Logger LOG = LoggerFactory.getLogger(NotebookRepoRestApi.class);
 
-  private Gson gson = new Gson();
   private NotebookRepoSync noteRepos;
   private NotebookServer notebookWsServer;
 
@@ -91,8 +89,7 @@ public class NotebookRepoRestApi {
   /**
    * Update a specific note repo.
    *
-   * @param message
-   * @param settingId
+   * @param payload
    * @return
    */
   @PUT
@@ -104,7 +101,7 @@ public class NotebookRepoRestApi {
     AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
     NotebookRepoSettingsRequest newSettings = NotebookRepoSettingsRequest.EMPTY;
     try {
-      newSettings = gson.fromJson(payload, NotebookRepoSettingsRequest.class);
+      newSettings = NotebookRepoSettingsRequest.fromJson(payload);
     } catch (JsonSyntaxException e) {
       LOG.error("Cannot update notebook repo settings", e);
       return new JsonResponse<>(Status.NOT_ACCEPTABLE, "",

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
index e18a2e7..a343879 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
@@ -332,9 +332,9 @@ public class NotebookRestApi {
   public Response createNote(String message) throws IOException {
     String user = SecurityUtils.getPrincipal();
     LOG.info("Create new note by JSON {}", message);
+    NewNoteRequest request = NewNoteRequest.fromJson(message);
     AuthenticationInfo subject = new AuthenticationInfo(user);
     Note note = notebook.createNote(subject);
-    NewNoteRequest request = gson.fromJson(message, NewNoteRequest.class);
     if (request != null) {
       List<NewParagraphRequest> initialParagraphs = request.getParagraphs();
       if (initialParagraphs != null) {
@@ -396,7 +396,7 @@ public class NotebookRestApi {
       throws IOException, CloneNotSupportedException, IllegalArgumentException {
     LOG.info("clone note by JSON {}", message);
     checkIfUserCanWrite(noteId, "Insufficient privileges you cannot clone this note");
-    NewNoteRequest request = gson.fromJson(message, NewNoteRequest.class);
+    NewNoteRequest request = NewNoteRequest.fromJson(message);
     String newNoteName = null;
     if (request != null) {
       newNoteName = request.getName();
@@ -427,7 +427,7 @@ public class NotebookRestApi {
     checkIfNoteIsNotNull(note);
     checkIfUserCanWrite(noteId, "Insufficient privileges you cannot add paragraph to this note");
 
-    NewParagraphRequest request = gson.fromJson(message, NewParagraphRequest.class);
+    NewParagraphRequest request = NewParagraphRequest.fromJson(message);
     AuthenticationInfo subject = new AuthenticationInfo(user);
     Paragraph p;
     Double indexDouble = request.getIndex();
@@ -787,7 +787,7 @@ public class NotebookRestApi {
       throws IOException, IllegalArgumentException {
     LOG.info("Register cron job note={} request cron msg={}", noteId, message);
 
-    CronRequest request = gson.fromJson(message, CronRequest.class);
+    CronRequest request = CronRequest.fromJson(message);
 
     Note note = notebook.getNote(noteId);
     checkIfNoteIsNotNull(note);
@@ -937,7 +937,7 @@ public class NotebookRestApi {
     // handle params if presented
     if (!StringUtils.isEmpty(message)) {
       RunParagraphWithParametersRequest request =
-          gson.fromJson(message, RunParagraphWithParametersRequest.class);
+          RunParagraphWithParametersRequest.fromJson(message);
       Map<String, Object> paramsForUpdating = request.getParams();
       if (paramsForUpdating != null) {
         paragraph.settings.getParams().putAll(paramsForUpdating);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/CronRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/CronRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/CronRequest.java
index 5a33931..0cd1b63 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/CronRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/CronRequest.java
@@ -19,13 +19,17 @@ package org.apache.zeppelin.rest.message;
 
 import java.util.Map;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.interpreter.InterpreterOption;
 
 /**
  *  CronRequest rest api request message
  *
  */
-public class CronRequest {
+public class CronRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   String cron;
 
   public CronRequest (){
@@ -35,4 +39,12 @@ public class CronRequest {
   public String getCronString() {
     return cron;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static CronRequest fromJson(String json) {
+    return gson.fromJson(json, CronRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewInterpreterSettingRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewInterpreterSettingRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewInterpreterSettingRequest.java
index 7e3a414..feaa303 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewInterpreterSettingRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewInterpreterSettingRequest.java
@@ -20,13 +20,16 @@ package org.apache.zeppelin.rest.message;
 import java.util.List;
 import java.util.Map;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.dep.Dependency;
 import org.apache.zeppelin.interpreter.InterpreterOption;
 
 /**
  * NewInterpreterSetting rest api request message
  */
-public class NewInterpreterSettingRequest {
+public class NewInterpreterSettingRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
   private String name;
   private String group;
 
@@ -57,4 +60,12 @@ public class NewInterpreterSettingRequest {
   public InterpreterOption getOption() {
     return option;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NewInterpreterSettingRequest fromJson(String json) {
+    return gson.fromJson(json, NewInterpreterSettingRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNoteRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNoteRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNoteRequest.java
index 67c1b67..42477e4 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNoteRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNoteRequest.java
@@ -20,13 +20,17 @@ package org.apache.zeppelin.rest.message;
 import java.util.List;
 import java.util.Map;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.interpreter.InterpreterOption;
 
 /**
  *  NewNoteRequest rest api request message
  *
  */
-public class NewNoteRequest {
+public class NewNoteRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   String name;
   List<NewParagraphRequest> paragraphs;
 
@@ -41,4 +45,12 @@ public class NewNoteRequest {
   public List<NewParagraphRequest> getParagraphs() {
     return paragraphs;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NewNoteRequest fromJson(String json) {
+    return gson.fromJson(json, NewNoteRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewParagraphRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewParagraphRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewParagraphRequest.java
index 5be732f..b7182e9 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewParagraphRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewParagraphRequest.java
@@ -17,6 +17,9 @@
 
 package org.apache.zeppelin.rest.message;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.HashMap;
 
 /**
@@ -27,7 +30,9 @@ import java.util.HashMap;
  * table,pieChart,multibarChart,stackedAreaChart,lineChart,scatterChart
  * colWidth (optional), e.g. 12.0
  */
-public class NewParagraphRequest {
+public class NewParagraphRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   String title;
   String text;
   Double index;
@@ -50,4 +55,12 @@ public class NewParagraphRequest {
   }
 
   public HashMap< String, Object > getConfig() { return config; }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NewParagraphRequest fromJson(String json) {
+    return gson.fromJson(json, NewParagraphRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NotebookRepoSettingsRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NotebookRepoSettingsRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NotebookRepoSettingsRequest.java
index 9884476..84b3794 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NotebookRepoSettingsRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NotebookRepoSettingsRequest.java
@@ -19,12 +19,15 @@ package org.apache.zeppelin.rest.message;
 import java.util.Collections;
 import java.util.Map;
 
+import com.google.gson.Gson;
 import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 
 /**
  * Represent payload of a notebook repo settings.
  */
-public class NotebookRepoSettingsRequest {
+public class NotebookRepoSettingsRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
 
   public static final NotebookRepoSettingsRequest EMPTY = new NotebookRepoSettingsRequest();
 
@@ -46,4 +49,12 @@ public class NotebookRepoSettingsRequest {
     }
     return repoSetting.isEmpty();
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static NotebookRepoSettingsRequest fromJson(String json) {
+    return gson.fromJson(json, NotebookRepoSettingsRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RestartInterpreterRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RestartInterpreterRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RestartInterpreterRequest.java
index f28be61..4a8fa44 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RestartInterpreterRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RestartInterpreterRequest.java
@@ -17,10 +17,15 @@
 
 package org.apache.zeppelin.rest.message;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 /**
  * RestartInterpreter rest api request message
  */
-public class RestartInterpreterRequest {
+public class RestartInterpreterRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   String noteId;
 
   public RestartInterpreterRequest() {
@@ -30,4 +35,12 @@ public class RestartInterpreterRequest {
   public String getNoteId() {
     return noteId;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static RestartInterpreterRequest fromJson(String json) {
+    return gson.fromJson(json, RestartInterpreterRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
index 7d8095f..ff6d314 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
@@ -17,12 +17,17 @@
 
 package org.apache.zeppelin.rest.message;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
+
 import java.util.Map;
 
 /**
  * RunParagraphWithParametersRequest rest api request message
  */
-public class RunParagraphWithParametersRequest {
+public class RunParagraphWithParametersRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   Map<String, Object> params;
 
   public RunParagraphWithParametersRequest() {
@@ -32,4 +37,12 @@ public class RunParagraphWithParametersRequest {
   public Map<String, Object> getParams() {
     return params;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static RunParagraphWithParametersRequest fromJson(String json) {
+    return gson.fromJson(json, RunParagraphWithParametersRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateInterpreterSettingRequest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateInterpreterSettingRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateInterpreterSettingRequest.java
index c2deeff..8764e8b 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateInterpreterSettingRequest.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateInterpreterSettingRequest.java
@@ -20,13 +20,17 @@ package org.apache.zeppelin.rest.message;
 import java.util.List;
 import java.util.Properties;
 
+import com.google.gson.Gson;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.dep.Dependency;
 import org.apache.zeppelin.interpreter.InterpreterOption;
 
 /**
  * UpdateInterpreterSetting rest api request message
  */
-public class UpdateInterpreterSettingRequest {
+public class UpdateInterpreterSettingRequest implements JsonSerializable {
+  private static final Gson gson = new Gson();
+
   Properties properties;
   List<Dependency> dependencies;
   InterpreterOption option;
@@ -49,4 +53,12 @@ public class UpdateInterpreterSettingRequest {
   public InterpreterOption getOption() {
     return option;
   }
+
+  public String toJson() {
+    return gson.toJson(this);
+  }
+
+  public static UpdateInterpreterSettingRequest fromJson(String json) {
+    return gson.fromJson(json, UpdateInterpreterSettingRequest.class);
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
index 667daa9..9a4ed7a 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
@@ -115,7 +115,7 @@ public class NotebookServer extends WebSocketServlet
 
 
   private static final Logger LOG = LoggerFactory.getLogger(NotebookServer.class);
-  Gson gson = new GsonBuilder()
+  private static Gson gson = new GsonBuilder()
       .registerTypeAdapterFactory(new NotebookTypeAdapterFactory<Paragraph>(Paragraph.class) {
         @Override
         protected void beforeWrite(Paragraph source, JsonElement toSerialize) {
@@ -2432,7 +2432,7 @@ public class NotebookServer extends WebSocketServlet
         try {
           watcher.send(
               WatcherMessage.builder(noteId).subject(subject).message(serializeMessage(message))
-                  .build().serialize());
+                  .build().toJson());
         } catch (IOException e) {
           LOG.error("Cannot broadcast message to watcher", e);
         }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
index 00b82fd..ac991f5 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
@@ -52,7 +52,6 @@ import org.hamcrest.TypeSafeMatcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonParser;
@@ -66,7 +65,6 @@ public abstract class AbstractTestRestApi {
   protected static final boolean wasRunning = checkIfServerIsRunning();
   static boolean pySpark = false;
   static boolean sparkR = false;
-  static Gson gson = new Gson();
   static boolean isRunningWithAuth = false;
 
   private static File shiroIni = null;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
index 2714352..e1700b2 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
@@ -39,14 +39,11 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.google.gson.Gson;
-
 /**
  * Test against spark cluster.
  * Spark cluster is started by CI server using testing/startSparkCluster.sh
  */
 public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
-    Gson gson = new Gson();
     AuthenticationInfo anonymous;
 
     @BeforeClass

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
index f905227..3a0749f 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
@@ -129,19 +129,19 @@ public class NotebookServerTest extends AbstractTestRestApi {
     notebookServer.onOpen(sock2);
     verify(sock1, times(0)).send(anyString()); // getNote, getAngularObject
     // open the same notebook from sockets
-    notebookServer.onMessage(sock1, gson.toJson(new Message(OP.GET_NOTE).put("id", note1.getId())));
-    notebookServer.onMessage(sock2, gson.toJson(new Message(OP.GET_NOTE).put("id", note1.getId())));
+    notebookServer.onMessage(sock1, new Message(OP.GET_NOTE).put("id", note1.getId()).toJson());
+    notebookServer.onMessage(sock2, new Message(OP.GET_NOTE).put("id", note1.getId()).toJson());
 
     reset(sock1);
     reset(sock2);
 
     // update object from sock1
-    notebookServer.onMessage(sock1, gson.toJson(
+    notebookServer.onMessage(sock1,
         new Message(OP.ANGULAR_OBJECT_UPDATED)
         .put("noteId", note1.getId())
         .put("name", "object1")
         .put("value", "value1")
-        .put("interpreterGroupId", interpreterGroup.getId())));
+        .put("interpreterGroupId", interpreterGroup.getId()).toJson());
 
 
     // expect object is broadcasted except for where the update is created
@@ -379,10 +379,10 @@ public class NotebookServerTest extends AbstractTestRestApi {
       defaultInterpreterId = settings.get(1).getId();
     }
     // create note from sock1
-    notebookServer.onMessage(sock1, gson.toJson(
+    notebookServer.onMessage(sock1,
         new Message(OP.NEW_NOTE)
         .put("name", noteName)
-        .put("defaultInterpreterId", defaultInterpreterId)));
+        .put("defaultInterpreterId", defaultInterpreterId).toJson());
 
     // expect the events are broadcasted properly
     verify(sock1, times(2)).send(anyString());

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/Helium.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/Helium.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/Helium.java
index 08014c4..2b9e320 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/Helium.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/Helium.java
@@ -20,6 +20,7 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.common.JsonSerializable;
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.resource.DistributedResourcePool;
@@ -45,7 +46,6 @@ public class Helium {
   private final String registryPaths;
   private final File registryCacheDir;
 
-  private final Gson gson;
   private final HeliumBundleFactory bundleFactory;
   private final HeliumApplicationFactory applicationFactory;
 
@@ -63,13 +63,6 @@ public class Helium {
     this.registryCacheDir = registryCacheDir;
     this.bundleFactory = bundleFactory;
     this.applicationFactory = applicationFactory;
-
-    GsonBuilder builder = new GsonBuilder();
-    builder.setPrettyPrinting();
-    builder.registerTypeAdapter(
-        HeliumRegistry.class, new HeliumRegistrySerializer());
-    gson = builder.create();
-
     heliumConf = loadConf(heliumConfPath);
   }
 
@@ -124,7 +117,7 @@ public class Helium {
       return conf;
     } else {
       String jsonString = FileUtils.readFileToString(heliumConfFile);
-      HeliumConf conf = gson.fromJson(jsonString, HeliumConf.class);
+      HeliumConf conf = HeliumConf.fromJson(jsonString);
       return conf;
     }
   }
@@ -133,7 +126,7 @@ public class Helium {
     String jsonString;
     synchronized (registry) {
       clearNotExistsPackages();
-      jsonString = gson.toJson(heliumConf);
+      jsonString = heliumConf.toJson();
     }
 
     File heliumConfFile = new File(heliumConfPath);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumApplicationFactory.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumApplicationFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumApplicationFactory.java
index bfebdf0..84368a7 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumApplicationFactory.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumApplicationFactory.java
@@ -16,7 +16,6 @@
  */
 package org.apache.zeppelin.helium;
 
-import com.google.gson.Gson;
 import org.apache.thrift.TException;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
@@ -38,7 +37,6 @@ import java.util.concurrent.ExecutorService;
 public class HeliumApplicationFactory implements ApplicationEventListener, NotebookEventListener {
   private final Logger logger = LoggerFactory.getLogger(HeliumApplicationFactory.class);
   private final ExecutorService executor;
-  private final Gson gson = new Gson();
   private Notebook notebook;
   private ApplicationEventListener applicationEventListener;
 
@@ -117,7 +115,7 @@ public class HeliumApplicationFactory implements ApplicationEventListener, Noteb
 
         try {
           appStatusChange(paragraph, appState.getId(), ApplicationState.Status.LOADING);
-          String pkgInfo = gson.toJson(pkg);
+          String pkgInfo = pkg.toJson();
           String appId = appState.getId();
 
           client = intpProcess.getClient();

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumBundleFactory.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumBundleFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumBundleFactory.java
index 2bf19d1..1ab14ba 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumBundleFactory.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumBundleFactory.java
@@ -589,8 +589,7 @@ public class HeliumBundleFactory {
           }
         }
       }
-      Gson gson = new Gson();
-      return gson.fromJson(sb.toString(), WebpackResult.class);
+      return WebpackResult.fromJson(sb.toString());
     } catch (IOException e) {
       logger.error(e.getMessage(), e);
       return new WebpackResult();
@@ -609,11 +608,9 @@ public class HeliumBundleFactory {
       if (!packageJson.isFile()) {
         return null;
       }
-      Gson gson = new Gson();
       try {
-        NpmPackage npmPackage = gson.fromJson(
-            FileUtils.readFileToString(packageJson),
-            NpmPackage.class);
+        NpmPackage npmPackage = NpmPackage.fromJson(
+            FileUtils.readFileToString(packageJson));
 
         String[] nameVersion = new String[2];
         nameVersion[0] = npmPackage.name;