You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@zeppelin.apache.org by GitBox <gi...@apache.org> on 2018/12/24 14:01:23 UTC

[GitHub] jongyoul closed pull request #3267: [ZEPPELIN-3609] Refactoring `ZeppelinServer` to adopt DI

jongyoul closed pull request #3267: [ZEPPELIN-3609] Refactoring `ZeppelinServer` to adopt DI
URL: https://github.com/apache/zeppelin/pull/3267
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.travis.yml b/.travis.yml
index 8619455253..2d810bf89d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -48,7 +48,7 @@ matrix:
     # Test License compliance using RAT tool
     - jdk: "oraclejdk8"
       dist: trusty
-      env: BUILD_PLUGINS="false" SCALA_VER="2.11" PROFILE="-Prat" BUILD_FLAG="clean" TEST_FLAG="org.apache.rat:apache-rat-plugin:check" TEST_PROJECTS=""
+      env: SCALA_VER="2.11" PROFILE="-Prat" BUILD_FLAG="clean" TEST_FLAG="org.apache.rat:apache-rat-plugin:check" TEST_PROJECTS=""
 
     # Run e2e tests (in zeppelin-web)
     # chrome dropped the support for precise (ubuntu 12.04), so need to use trusty
@@ -57,7 +57,7 @@ matrix:
       sudo: false
       dist: trusty
       jdk: "oraclejdk8"
-      env: BUILD_PLUGINS="false" CI="true" WEB_E2E="true" PYTHON="2" SCALA_VER="2.11" SPARK_VER="2.1.0" HADOOP_VER="2.6" PROFILE="-Phadoop2 -Pscala-2.11" BUILD_FLAG="install -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl ${INTERPRETERS}" TEST_MODULES="-pl zeppelin-web" TEST_PROJECTS="-Pweb-e2e"
+      env: CI="true" WEB_E2E="true" PYTHON="2" SCALA_VER="2.11" SPARK_VER="2.1.0" HADOOP_VER="2.6" PROFILE="-Phadoop2 -Pscala-2.11" BUILD_FLAG="install -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl ${INTERPRETERS}" TEST_MODULES="-pl zeppelin-web" TEST_PROJECTS="-Pweb-e2e"
       addons:
         apt:
           packages:
@@ -70,7 +70,7 @@ matrix:
     - sudo: required
       jdk: "oraclejdk8"
       dist: trusty
-      env: BUILD_PLUGINS="true" PYTHON="3" SPARKR="true" PROFILE="-Pspark-2.2 -Phelium-dev -Pexamples -Pscala-2.11" BUILD_FLAG="install -Pbuild-distr -DskipRat" TEST_FLAG="verify -Pusing-packaged-distr -DskipRat" MODULES="-pl ${INTERPRETERS}" TEST_PROJECTS="-Dtests.to.exclude=**/SparkIntegrationTest.java,**/ZeppelinSparkClusterTest.java,**/org/apache/zeppelin/spark/*,**/HeliumApplicationFactoryTest.java -DfailIfNoTests=false"
+      env: PYTHON="3" SPARKR="true" PROFILE="-Pspark-2.2 -Phelium-dev -Pexamples -Pscala-2.11" BUILD_FLAG="install -Pbuild-distr -DskipRat" TEST_FLAG="verify -Pusing-packaged-distr -DskipRat" MODULES="-pl ${INTERPRETERS}" TEST_PROJECTS="-Dtests.to.exclude=**/SparkIntegrationTest.java,**/ZeppelinSparkClusterTest.java,**/org/apache/zeppelin/spark/*,**/HeliumApplicationFactoryTest.java -DfailIfNoTests=false"
 
     # Test selenium with spark module for 1.6.3
     - jdk: "oraclejdk8"
@@ -82,7 +82,7 @@ matrix:
     # Test interpreter modules
     - jdk: "oraclejdk8"
       dist: trusty
-      env: BUILD_PLUGINS="false" PYTHON="3" SPARKR="true" SCALA_VER="2.10" PROFILE="-Pscala-2.10" BUILD_FLAG="install -DskipTests -DskipRat" TEST_FLAG="test -DskipRat" MODULES="-pl $(echo .,zeppelin-interpreter,zeppelin-interpreter-api,${INTERPRETERS} | sed 's/!//g')" TEST_PROJECTS=""
+      env: PYTHON="3" SPARKR="true" SCALA_VER="2.10" PROFILE="-Pscala-2.10" BUILD_FLAG="install -DskipTests -DskipRat" TEST_FLAG="test -DskipRat" MODULES="-pl $(echo .,zeppelin-interpreter,zeppelin-interpreter-api,${INTERPRETERS} | sed 's/!//g')" TEST_PROJECTS=""
 
     # Run ZeppelinSparkClusterTest & SparkIntegrationTest in one build would exceed the time limitation of travis, so running them separately
 
@@ -101,24 +101,24 @@ matrix:
     # Test spark module for 2.4.0 with scala 2.11
     - jdk: "oraclejdk8"
       dist: trusty
-      env: BUILD_PLUGINS="false" PYTHON="2" SCALA_VER="2.11" PROFILE="-Pspark-2.4 -Phadoop2 -Pscala-2.11" SPARKR="true" BUILD_FLAG="install -DskipTests -DskipRat -am" TEST_FLAG="test -DskipRat -am" MODULES="-pl spark/interpreter,spark/spark-dependencies" TEST_PROJECTS="-Dtest=org.apache.zeppelin.spark.*,org.apache.zeppelin.rinterpreter.*,org.apache.spark.api.r.* -DfailIfNoTests=false"
+      env: PYTHON="2" SCALA_VER="2.11" PROFILE="-Pspark-2.4 -Phadoop2 -Pscala-2.11" SPARKR="true" BUILD_FLAG="install -DskipTests -DskipRat -am" TEST_FLAG="test -DskipRat -am" MODULES="-pl spark/interpreter,spark/spark-dependencies" TEST_PROJECTS="-Dtest=org.apache.zeppelin.spark.*,org.apache.zeppelin.rinterpreter.*,org.apache.spark.api.r.* -DfailIfNoTests=false"
 
     # Test spark module for 2.3.2 with scala 2.11
     - jdk: "oraclejdk8"
       dist: trusty
-      env: BUILD_PLUGINS="false" PYTHON="2" SCALA_VER="2.11" PROFILE="-Pspark-2.3 -Phadoop3 -Pscala-2.11" SPARKR="true" BUILD_FLAG="install -DskipTests -DskipRat -am" TEST_FLAG="test -DskipRat -am" MODULES="-pl spark/interpreter,spark/spark-dependencies" TEST_PROJECTS="-Dtest=org.apache.zeppelin.spark.*,org.apache.zeppelin.rinterpreter.*,org.apache.spark.api.r.* -DfailIfNoTests=false"
+      env: PYTHON="2" SCALA_VER="2.11" PROFILE="-Pspark-2.3 -Phadoop3 -Pscala-2.11" SPARKR="true" BUILD_FLAG="install -DskipTests -DskipRat -am" TEST_FLAG="test -DskipRat -am" MODULES="-pl spark/interpreter,spark/spark-dependencies" TEST_PROJECTS="-Dtest=org.apache.zeppelin.spark.*,org.apache.zeppelin.rinterpreter.*,org.apache.spark.api.r.* -DfailIfNoTests=false"
 
     # Test python/pyspark with python 2, livy 0.5
     - sudo: required
       dist: trusty
       jdk: "oraclejdk8"
-      env: BUILD_PLUGINS="false" PYTHON="2" SCALA_VER="2.10" SPARK_VER="1.6.3" HADOOP_VER="2.6" LIVY_VER="0.5.0-incubating" PROFILE="-Pspark-1.6 -Phadoop2 -Pscala-2.10" BUILD_FLAG="install -am -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl livy" TEST_PROJECTS=""
+      env: PYTHON="2" SCALA_VER="2.10" SPARK_VER="1.6.3" HADOOP_VER="2.6" LIVY_VER="0.5.0-incubating" PROFILE="-Pspark-1.6 -Phadoop2 -Pscala-2.10" BUILD_FLAG="install -am -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl livy" TEST_PROJECTS=""
 
     # Test livy 0.5 with spark 2.2.0 under python3
     - sudo: required
       dist: trusty
       jdk: "openjdk8"
-      env: BUILD_PLUGINS="false" PYTHON="3" SPARK_VER="2.2.0" HADOOP_VER="2.6" LIVY_VER="0.5.0-incubating" PROFILE="" BUILD_FLAG="install -am -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl livy" TEST_PROJECTS=""
+      env: PYTHON="3" SPARK_VER="2.2.0" HADOOP_VER="2.6" LIVY_VER="0.5.0-incubating" PROFILE="" BUILD_FLAG="install -am -DskipTests -DskipRat" TEST_FLAG="verify -DskipRat" MODULES="-pl livy" TEST_PROJECTS=""
 
 before_install:
   # check files included in commit range, clear bower_components if a bower.json file has changed.
@@ -140,7 +140,7 @@ before_install:
 install:
   - echo "mvn $BUILD_FLAG $MODULES $PROFILE -B"
   - mvn $BUILD_FLAG $MODULES $PROFILE -B
-  - if [ $BUILD_PLUGINS == "true" ]; then echo "mvn clean package -pl zeppelin-plugins -amd -B"; mvn clean package -pl zeppelin-plugins -amd -B; fi
+  - if [ x"$BUILD_PLUGINS" == x"true" ]; then echo "mvn clean package -pl zeppelin-plugins -amd -B"; mvn clean package -pl zeppelin-plugins -amd -B; fi
 
 before_script:
   - if [[ -n $SPARK_VER ]]; then travis_retry ./testing/downloadSpark.sh $SPARK_VER $HADOOP_VER; fi
diff --git a/pom.xml b/pom.xml
index 65844c10a0..2465009849 100644
--- a/pom.xml
+++ b/pom.xml
@@ -385,6 +385,7 @@
           <formats>
             <format>html</format>
           </formats>
+          <skip>true</skip>
         </configuration>
         <executions>
           <execution>
@@ -393,8 +394,6 @@
             <goals>
               <goal>cobertura</goal>
             </goals>
-            <configuration>
-            </configuration>
           </execution>
         </executions>
       </plugin>
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java b/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
index 5215027c1f..fca0c57ea4 100644
--- a/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
+++ b/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
@@ -17,20 +17,17 @@
 
 package org.apache.zeppelin.notebook.repo;
 
-
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
+import com.google.common.io.Files;
 import java.io.File;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
-import com.google.common.io.Files;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
@@ -44,10 +41,6 @@
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
 import org.apache.zeppelin.notebook.Paragraph;
-
-import org.apache.zeppelin.notebook.ParagraphJobListener;
-import org.apache.zeppelin.scheduler.Job.Status;
-
 import org.apache.zeppelin.search.SearchService;
 import org.apache.zeppelin.storage.ConfigStorage;
 import org.apache.zeppelin.user.AuthenticationInfo;
@@ -109,7 +102,7 @@ public void setUp() throws Exception {
     notebookAuthorization = NotebookAuthorization.init(conf);
     credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath(), null);
     notebookSync = new Notebook(conf, notebookRepoSync, factory, interpreterSettingManager, search,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
     anonymous = new AuthenticationInfo("anonymous");
   }
 
@@ -249,7 +242,7 @@ public void testOneWaySyncOnReloadedList() throws IOException, SchedulerExceptio
     conf = ZeppelinConfiguration.create();
     notebookRepoSync = new NotebookRepoSync(conf);
     notebookSync = new Notebook(conf, notebookRepoSync, factory, interpreterSettingManager, search,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
 
     // check that both storage repos are empty
     assertTrue(notebookRepoSync.getRepoCount() > 1);
@@ -297,7 +290,7 @@ public void testCheckpointOneStorage() throws IOException, SchedulerException {
 
     NotebookRepoSync vRepoSync = new NotebookRepoSync(vConf);
     Notebook vNotebookSync = new Notebook(vConf, vRepoSync, factory, interpreterSettingManager, search,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
 
     // one git versioned storage initialized
     assertThat(vRepoSync.getRepoCount()).isEqualTo(1);
diff --git a/zeppelin-server/pom.xml b/zeppelin-server/pom.xml
index d30060ddc4..b8da356184 100644
--- a/zeppelin-server/pom.xml
+++ b/zeppelin-server/pom.xml
@@ -372,7 +372,6 @@
         <artifactId>diff-match-patch</artifactId>
         <version>1.1</version>
       </dependency>
-
   </dependencies>
   <build>
     <plugins>
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 2a4dcdaa6a..94d8126bef 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
@@ -19,7 +19,12 @@
 import com.google.common.base.Joiner;
 import com.google.gson.Gson;
 import com.google.gson.JsonParseException;
-
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.PutMethod;
@@ -34,21 +39,13 @@
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.zeppelin.service.ServiceContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashSet;
-import java.util.concurrent.atomic.AtomicInteger;
-
 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;
+import org.apache.zeppelin.service.ServiceContext;
+import org.apache.zeppelin.socket.NotebookServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A {@code Realm} implementation that uses the ZeppelinHub to authenticate users.
@@ -228,7 +225,8 @@ public void onLoginSuccess(String username, String session) {
     ServiceContext context = new ServiceContext(
         new org.apache.zeppelin.user.AuthenticationInfo(username), userAndRoles);
     try {
-      ZeppelinServer.notebookWsServer.broadcastReloadedNoteList(null, context);
+      // This can failed to get NotebookServer instance with very rare cases
+      NotebookServer.getInstance().broadcastReloadedNoteList(null, context);
     } catch (IOException e) {
       LOG.error("Fail to broadcastReloadedNoteList", e);
     }
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/AdminRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/AdminRestApi.java
index c6eda22a2f..e927ba697e 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/AdminRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/AdminRestApi.java
@@ -20,6 +20,7 @@
 import com.google.common.collect.Lists;
 import java.util.List;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -34,6 +35,7 @@
 
 /** This rest apis support some of feature related admin. e.g. changin log level. */
 @Path("/admin")
+@Singleton
 public class AdminRestApi {
   private static final Logger logger = LoggerFactory.getLogger(AdminRestApi.class);
 
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java
index 140fdf77ce..06503f81ed 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java
@@ -19,6 +19,7 @@
 import java.io.IOException;
 import java.util.Map;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -33,6 +34,7 @@
 /** Configurations Rest API Endpoint. */
 @Path("/configurations")
 @Produces("application/json")
+@Singleton
 public class ConfigurationsRestApi extends AbstractRestApi {
 
   private ConfigurationService configurationService;
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java
index b433572fef..b517ed6e8e 100755
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java
@@ -23,6 +23,7 @@
 import java.io.IOException;
 import java.util.Map;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
@@ -42,6 +43,7 @@
 /** Credential Rest API. */
 @Path("/credential")
 @Produces("application/json")
+@Singleton
 public class CredentialRestApi {
   Logger logger = LoggerFactory.getLogger(CredentialRestApi.class);
   private Credentials credentials;
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 1c04500c39..f3827b8867 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
@@ -21,6 +21,7 @@
 import com.google.gson.reflect.TypeToken;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -52,6 +53,7 @@
  */
 @Path("/helium")
 @Produces("application/json")
+@Singleton
 public class HeliumRestApi {
   Logger logger = LoggerFactory.getLogger(HeliumRestApi.class);
 
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 d885114003..cd5032b246 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
@@ -19,6 +19,7 @@
 
 import com.google.common.collect.Maps;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.zeppelin.annotation.ZeppelinApi;
 import org.apache.zeppelin.dep.Repository;
@@ -61,6 +62,7 @@
  */
 @Path("/interpreter")
 @Produces("application/json")
+@Singleton
 public class InterpreterRestApi {
 
   private static final Logger logger = LoggerFactory.getLogger(InterpreterRestApi.class);
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
index 84bc1a6faf..66f17f7ff6 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Set;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -59,6 +60,7 @@
  */
 @Path("/login")
 @Produces("application/json")
+@Singleton
 public class LoginRestApi {
   private static final Logger LOG = LoggerFactory.getLogger(LoginRestApi.class);
   private static final Gson gson = new Gson();
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 62f38b980b..b676b80e0f 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
@@ -21,6 +21,7 @@
 import com.google.gson.JsonSyntaxException;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.service.SecurityService;
 import org.apache.zeppelin.service.ServiceContext;
@@ -53,6 +54,7 @@
  */
 @Path("/notebook-repositories")
 @Produces("application/json")
+@Singleton
 public class NotebookRepoRestApi {
   private static final Logger LOG = LoggerFactory.getLogger(NotebookRepoRestApi.class);
 
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 ebeff6f618..6f805c9824 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
@@ -28,6 +28,7 @@
 import java.util.Map;
 import java.util.Set;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -74,6 +75,7 @@
  */
 @Path("/notebook")
 @Produces("application/json")
+@Singleton
 public class NotebookRestApi extends AbstractRestApi {
   private static final Logger LOG = LoggerFactory.getLogger(NotebookRestApi.class);
   private static Gson gson = new Gson();
@@ -95,12 +97,13 @@ public NotebookRestApi(
       SearchService search,
       NotebookAuthorization notebookAuthorization,
       ZeppelinConfiguration zConf,
-      SecurityService securityService) {
+      SecurityService securityService,
+      JobManagerService jobManagerService) {
     super(securityService);
     this.notebook = notebook;
     this.notebookServer = notebookServer;
     this.notebookService = notebookService;
-    this.jobManagerService = new JobManagerService(notebook);
+    this.jobManagerService = jobManagerService;
     this.noteSearchService = search;
     this.notebookAuthorization = notebookAuthorization;
     this.zConf = zConf;
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java
index d6cee2eac7..7a08693f83 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Set;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -43,6 +44,7 @@
  */
 @Path("/security")
 @Produces("application/json")
+@Singleton
 public class SecurityRestApi {
   private static final Logger LOG = LoggerFactory.getLogger(SecurityRestApi.class);
   private static final Gson gson = new Gson();
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ZeppelinRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ZeppelinRestApi.java
index 20d69735cd..f2bfbc1d5f 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ZeppelinRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ZeppelinRestApi.java
@@ -16,6 +16,7 @@
  */
 package org.apache.zeppelin.rest;
 
+import javax.inject.Singleton;
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 
@@ -40,6 +41,7 @@
  * @since 0.3.4
  */
 @Path("/")
+@Singleton
 public class ZeppelinRestApi {
 
   /**
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
index e5724f84dd..c7f13a6017 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
@@ -18,36 +18,30 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.util.Collection;
 import java.util.EnumSet;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
 import javax.servlet.DispatcherType;
-import javax.ws.rs.ApplicationPath;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
 import org.apache.commons.lang.StringUtils;
-import org.apache.shiro.UnavailableSecurityManagerException;
-import org.apache.shiro.realm.Realm;
-import org.apache.shiro.realm.text.IniRealm;
 import org.apache.shiro.web.env.EnvironmentLoaderListener;
-import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 import org.apache.shiro.web.servlet.ShiroFilter;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
+import org.apache.zeppelin.display.AngularObjectRegistryListener;
+import org.apache.zeppelin.helium.ApplicationEventListener;
 import org.apache.zeppelin.helium.Helium;
 import org.apache.zeppelin.helium.HeliumApplicationFactory;
 import org.apache.zeppelin.helium.HeliumBundleFactory;
 import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.interpreter.InterpreterOutput;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
+import org.apache.zeppelin.notebook.NoteEventListener;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
+import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.repo.NotebookRepoSync;
 import org.apache.zeppelin.rest.exception.WebApplicationExceptionMapper;
 import org.apache.zeppelin.search.LuceneSearch;
@@ -55,12 +49,13 @@
 import org.apache.zeppelin.service.AdminService;
 import org.apache.zeppelin.service.ConfigurationService;
 import org.apache.zeppelin.service.InterpreterService;
+import org.apache.zeppelin.service.JobManagerService;
 import org.apache.zeppelin.service.NoSecurityService;
 import org.apache.zeppelin.service.NotebookService;
 import org.apache.zeppelin.service.SecurityService;
+import org.apache.zeppelin.service.ShiroSecurityService;
 import org.apache.zeppelin.socket.NotebookServer;
 import org.apache.zeppelin.user.Credentials;
-import org.apache.zeppelin.service.ShiroSecurityService;
 import org.eclipse.jetty.http.HttpVersion;
 import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -76,151 +71,70 @@
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.webapp.WebAppContext;
-import org.glassfish.hk2.api.Immediate;
+import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
 import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.api.ServiceLocatorFactory;
 import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
-import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.servlet.ServletProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /** Main class of Zeppelin. */
-@ApplicationPath("/api")
 public class ZeppelinServer extends ResourceConfig {
   private static final Logger LOG = LoggerFactory.getLogger(ZeppelinServer.class);
 
-  public static Notebook notebook;
   public static Server jettyWebServer;
-  public static NotebookServer notebookWsServer;
-  public static Helium helium;
-
-  private final InterpreterSettingManager interpreterSettingManager;
-  private InterpreterFactory replFactory;
-  private SearchService noteSearchService;
-  private NotebookRepoSync notebookRepo;
-  private NotebookAuthorization notebookAuthorization;
-  private Credentials credentials;
+  public static ServiceLocator sharedServiceLocator;
 
   @Inject
-  public ZeppelinServer(ServiceLocator serviceLocator) throws Exception {
+  public ZeppelinServer() {
     ZeppelinConfiguration conf = ZeppelinConfiguration.create();
 
     InterpreterOutput.limit = conf.getInt(ConfVars.ZEPPELIN_INTERPRETER_OUTPUT_LIMIT);
 
-    HeliumApplicationFactory heliumApplicationFactory = new HeliumApplicationFactory();
-    HeliumBundleFactory heliumBundleFactory;
-
-    if (isBinaryPackage(conf)) {
-      /* In binary package, zeppelin-web/src/app/visualization and zeppelin-web/src/app/tabledata
-       * are copied to lib/node_modules/zeppelin-vis, lib/node_modules/zeppelin-tabledata directory.
-       * Check zeppelin/zeppelin-distribution/src/assemble/distribution.xml to see how they're
-       * packaged into binary package.
-       */
-      heliumBundleFactory =
-          new HeliumBundleFactory(
-              conf,
-              null,
-              new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO)),
-              new File(conf.getRelativeDir("lib/node_modules/zeppelin-tabledata")),
-              new File(conf.getRelativeDir("lib/node_modules/zeppelin-vis")),
-              new File(conf.getRelativeDir("lib/node_modules/zeppelin-spell")));
-    } else {
-      heliumBundleFactory =
-          new HeliumBundleFactory(
-              conf,
-              null,
-              new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO)),
-              new File(conf.getRelativeDir("zeppelin-web/src/app/tabledata")),
-              new File(conf.getRelativeDir("zeppelin-web/src/app/visualization")),
-              new File(conf.getRelativeDir("zeppelin-web/src/app/spell")));
-    }
-
-    this.interpreterSettingManager =
-        new InterpreterSettingManager(conf, notebookWsServer, notebookWsServer, notebookWsServer);
-    this.replFactory = new InterpreterFactory(interpreterSettingManager);
-    this.notebookRepo = new NotebookRepoSync(conf);
-    this.noteSearchService = new LuceneSearch(conf);
-    this.notebookAuthorization = NotebookAuthorization.getInstance();
-    this.credentials =
-        new Credentials(
-            conf.credentialsPersist(), conf.getCredentialsPath(), conf.getCredentialsEncryptKey());
-    notebook =
-        new Notebook(
-            conf,
-            notebookRepo,
-            replFactory,
-            interpreterSettingManager,
-            noteSearchService,
-            notebookAuthorization,
-            credentials);
-
-    ZeppelinServer.helium =
-        new Helium(
-            conf.getHeliumConfPath(),
-            conf.getHeliumRegistry(),
-            new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO), "helium-registry-cache"),
-            heliumBundleFactory,
-            heliumApplicationFactory,
-            interpreterSettingManager);
-
-    // create bundle
-    try {
-      heliumBundleFactory.buildAllPackages(helium.getBundlePackagesToBundle());
-    } catch (Exception e) {
-      LOG.error(e.getMessage(), e);
-    }
-
-    // to update notebook from application event from remote process.
-    heliumApplicationFactory.setNotebook(notebook);
-    // to update fire websocket event on application event.
-    heliumApplicationFactory.setApplicationEventListener(notebookWsServer);
+    packages("org.apache.zeppelin.rest");
+  }
 
-    notebook.addNotebookEventListener(heliumApplicationFactory);
-    notebook.addNotebookEventListener(notebookWsServer);
+  public static void main(String[] args) throws InterruptedException {
+    final ZeppelinConfiguration conf = ZeppelinConfiguration.create();
+    conf.setProperty("args", args);
 
+    jettyWebServer = setupJettyServer(conf);
 
-    // Register MBean
-    if ("true".equals(System.getenv("ZEPPELIN_JMX_ENABLE"))) {
-      MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
-      try {
-        mBeanServer.registerMBean(
-            notebookWsServer,
-            new ObjectName("org.apache.zeppelin:type=" + NotebookServer.class.getSimpleName()));
-        mBeanServer.registerMBean(
-            interpreterSettingManager,
-            new ObjectName(
-                "org.apache.zeppelin:type=" + InterpreterSettingManager.class.getSimpleName()));
-      } catch (InstanceAlreadyExistsException
-          | MBeanRegistrationException
-          | MalformedObjectNameException
-          | NotCompliantMBeanException e) {
-        LOG.error("Failed to register MBeans", e);
-      }
-    }
+    ContextHandlerCollection contexts = new ContextHandlerCollection();
+    jettyWebServer.setHandler(contexts);
 
-    ServiceLocatorUtilities.enableImmediateScope(serviceLocator);
+    // Web UI
+    final WebAppContext webApp = setupWebAppContext(contexts, conf);
 
-    register(
+    sharedServiceLocator = ServiceLocatorFactory.getInstance().create("shared-locator");
+    ServiceLocatorUtilities.enableImmediateScope(sharedServiceLocator);
+    ServiceLocatorUtilities.bind(
+        sharedServiceLocator,
         new AbstractBinder() {
           @Override
           protected void configure() {
-            bind(notebookRepo).to(NotebookRepoSync.class).in(Singleton.class);
-            bind(notebookWsServer).to(NotebookServer.class).in(Singleton.class);
-            bind(notebook).to(Notebook.class).in(Singleton.class);
-            bind(noteSearchService).to(SearchService.class).in(Singleton.class);
-            bind(helium).to(Helium.class).in(Singleton.class);
-            bind(conf).to(ZeppelinConfiguration.class).in(Singleton.class);
-            bind(interpreterSettingManager).to(InterpreterSettingManager.class).in(Singleton.class);
-            bind(InterpreterService.class).to(InterpreterService.class).in(Immediate.class);
-            bind(credentials).to(Credentials.class).in(Singleton.class);
-            bind(GsonProvider.class).to(GsonProvider.class).in(Singleton.class);
-            bind(WebApplicationExceptionMapper.class)
-                .to(WebApplicationExceptionMapper.class)
-                .in(Singleton.class);
-            bind(AdminService.class).to(AdminService.class).in(Immediate.class);
-            bind(notebookAuthorization).to(NotebookAuthorization.class).in(Singleton.class);
-            bind(ConfigurationService.class).to(ConfigurationService.class).in(Immediate.class);
-            bind(NotebookService.class).to(NotebookService.class).in(Immediate.class);
+            NotebookAuthorization notebookAuthorization = NotebookAuthorization.getInstance();
+            Credentials credentials =
+                new Credentials(
+                    conf.credentialsPersist(),
+                    conf.getCredentialsPath(),
+                    conf.getCredentialsEncryptKey());
+
+            bindAsContract(InterpreterFactory.class).in(Singleton.class);
+            bindAsContract(NotebookRepoSync.class).to(NotebookRepo.class).in(Singleton.class);
+            bind(LuceneSearch.class).to(SearchService.class).in(Singleton.class);
+            bindAsContract(Helium.class).in(Singleton.class);
+            bind(conf).to(ZeppelinConfiguration.class);
+            bindAsContract(InterpreterSettingManager.class).in(Singleton.class);
+            bindAsContract(InterpreterService.class).in(Singleton.class);
+            bind(credentials).to(Credentials.class);
+            bindAsContract(GsonProvider.class).in(Singleton.class);
+            bindAsContract(WebApplicationExceptionMapper.class).in(Singleton.class);
+            bindAsContract(AdminService.class).in(Singleton.class);
+            bind(notebookAuthorization).to(NotebookAuthorization.class);
             // TODO(jl): Will make it more beautiful
             if (!StringUtils.isBlank(conf.getShiroPath())) {
               bind(ShiroSecurityService.class).to(SecurityService.class).in(Singleton.class);
@@ -228,31 +142,40 @@ protected void configure() {
               // TODO(jl): Will be added more type
               bind(NoSecurityService.class).to(SecurityService.class).in(Singleton.class);
             }
+            bindAsContract(HeliumBundleFactory.class).in(Singleton.class);
+            bindAsContract(HeliumApplicationFactory.class).in(Singleton.class);
+            bindAsContract(ConfigurationService.class).in(Singleton.class);
+            bindAsContract(NotebookService.class).in(Singleton.class);
+            bindAsContract(JobManagerService.class).in(Singleton.class);
+            bindAsContract(Notebook.class).in(Singleton.class);
+            bindAsContract(NotebookServer.class)
+                .to(AngularObjectRegistryListener.class)
+                .to(RemoteInterpreterProcessListener.class)
+                .to(ApplicationEventListener.class)
+                .to(NoteEventListener.class)
+                .to(WebSocketServlet.class)
+                .in(Singleton.class);
           }
         });
-    packages("org.apache.zeppelin.rest");
-  }
-
-  public static void main(String[] args) throws InterruptedException {
-    final ZeppelinConfiguration conf = ZeppelinConfiguration.create();
-    conf.setProperty("args", args);
-
-    jettyWebServer = setupJettyServer(conf);
 
-    ContextHandlerCollection contexts = new ContextHandlerCollection();
-    jettyWebServer.setHandler(contexts);
+    webApp.addEventListener(
+        new ServletContextListener() {
+          @Override
+          public void contextInitialized(ServletContextEvent servletContextEvent) {
+            servletContextEvent
+                .getServletContext()
+                .setAttribute(ServletProperties.SERVICE_LOCATOR, sharedServiceLocator);
+          }
 
-    // Web UI
-    final WebAppContext webApp = setupWebAppContext(contexts, conf);
+          @Override
+          public void contextDestroyed(ServletContextEvent servletContextEvent) {}
+        });
 
     // Create `ZeppelinServer` using reflection and setup REST Api
     setupRestApiContextHandler(webApp, conf);
 
     // Notebook server
-    setupNotebookServer(webApp, conf);
-
-    // Below is commented since zeppelin-docs module is removed.
-    // final WebAppContext webAppSwagg = setupWebAppSwagger(conf);
+    setupNotebookServer(webApp, conf, sharedServiceLocator);
 
     LOG.info("Starting zeppelin server");
     try {
@@ -268,23 +191,24 @@ public static void main(String[] args) throws InterruptedException {
 
     Runtime.getRuntime()
         .addShutdownHook(
-            new Thread() {
-              @Override
-              public void run() {
-                LOG.info("Shutting down Zeppelin Server ... ");
-                try {
-                  jettyWebServer.stop();
-                  if (!conf.isRecoveryEnabled()) {
-                    ZeppelinServer.notebook.getInterpreterSettingManager().close();
+            new Thread(
+                () -> {
+                  LOG.info("Shutting down Zeppelin Server ... ");
+                  try {
+                    jettyWebServer.stop();
+                    if (!conf.isRecoveryEnabled()) {
+                      sharedServiceLocator
+                          .getService(Notebook.class)
+                          .getInterpreterSettingManager()
+                          .close();
+                    }
+                    sharedServiceLocator.getService(Notebook.class).close();
+                    Thread.sleep(3000);
+                  } catch (Exception e) {
+                    LOG.error("Error while stopping servlet container", e);
                   }
-                  notebook.close();
-                  Thread.sleep(3000);
-                } catch (Exception e) {
-                  LOG.error("Error while stopping servlet container", e);
-                }
-                LOG.info("Bye");
-              }
-            });
+                  LOG.info("Bye");
+                }));
 
     // when zeppelin is started inside of ide (especially for eclipse)
     // for graceful shutdown, input any key in console window
@@ -299,7 +223,7 @@ public void run() {
 
     jettyWebServer.join();
     if (!conf.isRecoveryEnabled()) {
-      ZeppelinServer.notebook.getInterpreterSettingManager().close();
+      sharedServiceLocator.getService(Notebook.class).getInterpreterSettingManager().close();
     }
   }
 
@@ -318,9 +242,6 @@ private static Server setupJettyServer(ZeppelinConfiguration conf) {
 
       HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
       SecureRequestCustomizer src = new SecureRequestCustomizer();
-      // Only with Jetty 9.3.x
-      // src.setStsMaxAge(2000);
-      // src.setStsIncludeSubDomains(true);
       httpsConfig.addCustomizer(src);
 
       connector =
@@ -357,10 +278,11 @@ private static void configureRequestHeaderSize(
     cf.getHttpConfiguration().setRequestHeaderSize(requestHeaderSize);
   }
 
-  private static void setupNotebookServer(WebAppContext webapp, ZeppelinConfiguration conf) {
-    notebookWsServer = new NotebookServer();
+  private static void setupNotebookServer(
+      WebAppContext webapp, ZeppelinConfiguration conf, ServiceLocator serviceLocator) {
     String maxTextMessageSize = conf.getWebsocketMaxTextMessageSize();
-    final ServletHolder servletHolder = new ServletHolder(notebookWsServer);
+    final ServletHolder servletHolder =
+        new ServletHolder(serviceLocator.getService(NotebookServer.class));
     servletHolder.setInitParameter("maxTextMessageSize", maxTextMessageSize);
 
     final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
@@ -396,7 +318,6 @@ private static void setupRestApiContextHandler(WebAppContext webapp, ZeppelinCon
     servletHolder.setInitParameter("javax.ws.rs.Application", ZeppelinServer.class.getName());
     servletHolder.setName("rest");
     servletHolder.setForcedPath("rest");
-
     webapp.setSessionHandler(new SessionHandler());
     webapp.addServlet(servletHolder, "/api/*");
 
@@ -440,13 +361,4 @@ private static WebAppContext setupWebAppContext(
 
     return webApp;
   }
-
-  /**
-   * Check if it is source build or binary package.
-   *
-   * @return
-   */
-  private static boolean isBinaryPackage(ZeppelinConfiguration conf) {
-    return !new File(conf.getRelativeDir("zeppelin-web")).isDirectory();
-  }
 }
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/service/ConfigurationService.java b/zeppelin-server/src/main/java/org/apache/zeppelin/service/ConfigurationService.java
index 593c17a8bc..4580e75be6 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/service/ConfigurationService.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/service/ConfigurationService.java
@@ -27,31 +27,13 @@
 import java.util.Map;
 
 public class ConfigurationService {
-
   private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationService.class);
-  private static ConfigurationService self;
 
   private ZeppelinConfiguration zConf;
 
   @Inject
   public ConfigurationService(ZeppelinConfiguration zConf) {
     this.zConf = zConf;
-    ConfigurationService.self = this;
-  }
-
-  /**
-   * This is a temporal trick to connect injected class to non-injected class like {@link
-   * org.apache.zeppelin.socket.NotebookServer}. This will be removed after refactoring of Notebook*
-   * classes.
-   *
-   * @return ConfigurationService
-   */
-  public static ConfigurationService getInstance() {
-    if (null == ConfigurationService.self) {
-      throw new IllegalStateException("ConfigurationService should be called after injection");
-    } else {
-      return ConfigurationService.self;
-    }
   }
 
   public Map<String, String> getAllProperties(ServiceContext context,
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/service/JobManagerService.java b/zeppelin-server/src/main/java/org/apache/zeppelin/service/JobManagerService.java
index 374d8ff199..b22d6b3d21 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/service/JobManagerService.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/service/JobManagerService.java
@@ -17,6 +17,7 @@
 
 package org.apache.zeppelin.service;
 
+import javax.inject.Inject;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.Notebook;
@@ -39,6 +40,7 @@
 
   private Notebook notebook;
 
+  @Inject
   public JobManagerService(Notebook notebook) {
     this.notebook = notebook;
   }
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NoSecurityService.java b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NoSecurityService.java
index ab8d4c3398..0413883f27 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NoSecurityService.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NoSecurityService.java
@@ -23,10 +23,19 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import javax.inject.Inject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class NoSecurityService implements SecurityService {
+  private static Logger logger = LoggerFactory.getLogger(NoSecurityService.class);
   private final String ANONYMOUS = "anonymous";
 
+  @Inject
+  public NoSecurityService() {
+    logger.info("NoSecurityService is initialized");
+  }
+
   @Override
   public String getPrincipal() {
     return ANONYMOUS;
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
index d33c237d0b..d7dd33e71d 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
@@ -19,7 +19,18 @@
 package org.apache.zeppelin.service;
 
 
+import static org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN;
+
 import com.google.common.base.Strings;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import javax.inject.Inject;
 import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
@@ -51,18 +62,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.inject.Inject;
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-
-import static org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN;
-
 
 /**
  * Service class for Notebook related operations. It use {@link Notebook} which provides
@@ -79,64 +78,18 @@
   private static final DateTimeFormatter TRASH_CONFLICT_TIMESTAMP_FORMATTER =
       DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
 
-  private static NotebookService self;
-
   private ZeppelinConfiguration zConf;
   private Notebook notebook;
   private NotebookAuthorization notebookAuthorization;
-  private NotebookServer notebookServer;
-  private CountDownLatch notebookServerInjected;
 
   @Inject
-  public NotebookService(Notebook notebook) {
+  public NotebookService(
+      Notebook notebook,
+      NotebookAuthorization notebookAuthorization,
+      ZeppelinConfiguration zeppelinConfiguration) {
     this.notebook = notebook;
-    this.notebookAuthorization = notebook.getNotebookAuthorization();
-    this.zConf = notebook.getConf();
-    NotebookService.self = this;
-    notebookServerInjected = new CountDownLatch(1);
-  }
-
-  /**
-   * This is a temporal trick to connect injected class to non-injected class like {@link
-   * org.apache.zeppelin.socket.NotebookServer}. This will be removed after refactoring of
-   * Notebook\* classes.
-   *
-   * @return NotebookService
-   */
-  public static NotebookService getInstance() {
-    if (null == NotebookService.self) {
-      throw new IllegalStateException("NotebookService should be called after injection");
-    } else {
-      return NotebookService.self;
-    }
-  }
-
-  /**
-   * Only NotebookServer will call this method to register itself. This will be
-   * changed @PostConstruct. Please see {@link NotebookServer#NotebookServer()}
-   *
-   * @param notebookServer NotebookServer instance to be injected
-   */
-  public void injectNotebookServer(NotebookServer notebookServer) {
-    this.notebookServer = notebookServer;
-    // Notebook was initialized by injection, thus it should be not null
-    notebook.setParagraphJobListener(notebookServer);
-    notebookServerInjected.countDown();
-  }
-
-  /**
-   * This is a conservative to avoid timing issue between registering it and using it.
-   *
-   * @return NotebookServer instance
-   */
-  public NotebookServer getNotebookServer() {
-    try {
-      notebookServerInjected.await();
-      return notebookServer;
-    } catch (InterruptedException e) {
-      LOGGER.info("Interrupted. getNotebookServer will return null");
-      return null;
-    }
+    this.notebookAuthorization = notebookAuthorization;
+    this.zConf = zeppelinConfiguration;
   }
 
   public Note getHomeNote(ServiceContext context,
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/service/ShiroSecurityService.java b/zeppelin-server/src/main/java/org/apache/zeppelin/service/ShiroSecurityService.java
index ac8f72174c..07a2663016 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/service/ShiroSecurityService.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/service/ShiroSecurityService.java
@@ -53,7 +53,6 @@
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.realm.ActiveDirectoryGroupRealm;
 import org.apache.zeppelin.realm.LdapRealm;
-import org.apache.zeppelin.server.ZeppelinServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,8 +61,12 @@
 
   private final Logger LOGGER = LoggerFactory.getLogger(ShiroSecurityService.class);
 
+  private final ZeppelinConfiguration zeppelinConfiguration;
+
   @Inject
   public ShiroSecurityService(ZeppelinConfiguration zeppelinConfiguration) throws Exception {
+    LOGGER.info("NoSecurityService is initialized");
+    this.zeppelinConfiguration = zeppelinConfiguration;
     if (zeppelinConfiguration.getShiroPath().length() > 0) {
       try {
         Collection<Realm> realms =
@@ -101,9 +104,9 @@ public String getPrincipal() {
     String principal;
     if (subject.isAuthenticated()) {
       principal = extractPrincipal(subject);
-      if (ZeppelinServer.notebook.getConf().isUsernameForceLowerCase()) {
-        LOGGER.debug(
-            "Converting principal name " + principal + " to lower case:" + principal.toLowerCase());
+      if (zeppelinConfiguration.isUsernameForceLowerCase()) {
+        LOGGER.debug("Converting principal name " + principal
+            + " to lower case:" + principal.toLowerCase());
         principal = principal.toLowerCase();
       }
     } else {
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 a5c0290ce0..40c7461caf 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
@@ -20,6 +20,24 @@
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
@@ -51,7 +69,6 @@
 import org.apache.zeppelin.notebook.socket.Message.OP;
 import org.apache.zeppelin.rest.exception.ForbiddenException;
 import org.apache.zeppelin.scheduler.Job.Status;
-import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.service.ConfigurationService;
 import org.apache.zeppelin.service.JobManagerService;
 import org.apache.zeppelin.service.NotebookService;
@@ -62,38 +79,25 @@
 import org.apache.zeppelin.user.AuthenticationInfo;
 import org.apache.zeppelin.utils.CorsUtils;
 import org.apache.zeppelin.utils.InterpreterBindingUtils;
+import org.apache.zeppelin.utils.TestUtils;
 import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
 import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
+import org.glassfish.hk2.api.ServiceLocator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
 /**
- * Zeppelin websocket service.
+ * Zeppelin websocket service. This class used setter injection because all servlet should have
+ * no-parameter constructor
  */
 public class NotebookServer extends WebSocketServlet
     implements NotebookSocketListener,
-    AngularObjectRegistryListener,
-    RemoteInterpreterProcessListener,
-    ApplicationEventListener,
-    ParagraphJobListener,
-    NoteEventListener,
-    NotebookServerMBean {
+        AngularObjectRegistryListener,
+        RemoteInterpreterProcessListener,
+        ApplicationEventListener,
+        ParagraphJobListener,
+        NoteEventListener,
+        NotebookServerMBean {
 
   /**
    * Job manager service type.
@@ -121,64 +125,71 @@ String getKey() {
       .registerTypeAdapter(Date.class, new NotebookImportDeserializer())
       .setPrettyPrinting()
       .registerTypeAdapterFactory(Input.TypeAdapterFactory).create();
+  private static AtomicReference<NotebookServer> self = new AtomicReference<>();
 
   private ConnectionManager connectionManager;
-  private NotebookService notebookService;
-  private ConfigurationService configurationService;
-  private JobManagerService jobManagerService;
 
   private ExecutorService executorService = Executors.newFixedThreadPool(10);
 
+  private Provider<Notebook> notebookProvider;
+  private Provider<NotebookService> notebookServiceProvider;
+  private Provider<ConfigurationService> configurationServiceProvider;
+  private Provider<JobManagerService> jobManagerServiceProvider;
 
   public NotebookServer() {
     this.connectionManager = new ConnectionManager();
-    // TODO(jl): Replace this code with @PostConstruct after finishing injection
-    new Thread(
-        () -> {
-          Logger innerLogger = LoggerFactory.getLogger("NotebookServerRegister");
-          innerLogger.info("Started registration thread");
-          try {
-            NotebookService notebookService = null;
-            while (null == notebookService) {
-              try {
-                notebookService = getNotebookService();
-              } catch (IllegalStateException ignored) {
-                // ignored
-              }
-              Thread.sleep(100);
-            }
-            getNotebookService().injectNotebookServer(this);
-            innerLogger.info("Completed registration thread");
-          } catch (InterruptedException e) {
-            innerLogger.info("Interrupted. will stop registration process");
-          }
-        }, "NotebookServerRegister")
-      .start();
+    NotebookServer.self.set(this);
+    LOG.info("NotebookServer instantiated: {}", this);
   }
 
-  private Notebook notebook() {
-    return ZeppelinServer.notebook;
+  @Inject
+  public void setServiceLocator(ServiceLocator serviceLocator) {
+    LOG.info("Injected ServiceLocator: {}", serviceLocator);
   }
 
-  public synchronized NotebookService getNotebookService() {
-    if (this.notebookService == null) {
-      this.notebookService = NotebookService.getInstance();
-    }
-    return this.notebookService;
+  @Inject
+  public void setNotebook(Provider<Notebook> notebookProvider) {
+    this.notebookProvider = notebookProvider;
+    LOG.info("Injected NotebookProvider");
   }
 
-  public synchronized ConfigurationService getConfigurationService() {
-    if (this.configurationService == null) {
-      this.configurationService = ConfigurationService.getInstance();
-    }
-    return this.configurationService;
+  @Inject
+  public void setNotebookService(
+      Provider<NotebookService> notebookServiceProvider) {
+    this.notebookServiceProvider = notebookServiceProvider;
+    LOG.info("Injected NotebookServiceProvider");
+  }
+
+  @Inject
+  public void setConfigurationService(
+      Provider<ConfigurationService> configurationServiceProvider) {
+    this.configurationServiceProvider = configurationServiceProvider;
+  }
+
+  @Inject
+  public void setJobManagerService(
+      Provider<JobManagerService> jobManagerServiceProvider) {
+    this.jobManagerServiceProvider = jobManagerServiceProvider;
+  }
+
+  public static NotebookServer getInstance() {
+    return TestUtils.getInstance(NotebookServer.class);
+  }
+
+  public Notebook getNotebook() {
+    return notebookProvider.get();
+  }
+
+  public NotebookService getNotebookService() {
+    return notebookServiceProvider.get();
+  }
+
+  public ConfigurationService getConfigurationService() {
+    return configurationServiceProvider.get();
   }
 
   public synchronized JobManagerService getJobManagerService() {
-    if (this.jobManagerService == null) {
-      this.jobManagerService = new JobManagerService(notebook());
-    }
-    return this.jobManagerService;
+    return jobManagerServiceProvider.get();
   }
 
   @Override
@@ -203,7 +214,6 @@ public void onOpen(NotebookSocket conn) {
 
   @Override
   public void onMessage(NotebookSocket conn, String msg) {
-    Notebook notebook = notebook();
     try {
       Message messagereceived = deserializeMessage(msg);
       if (messagereceived.op != OP.PING) {
@@ -241,7 +251,7 @@ public void onMessage(NotebookSocket conn, String msg) {
       }
 
       if (Message.isDisabledForRunningNotes(messagereceived.op)) {
-        Note note = notebook.getNote((String) messagereceived.get("noteId"));
+        Note note = getNotebook().getNote((String) messagereceived.get("noteId"));
         if (note != null && note.isRunning()) {
           throw new Exception("Note is now running sequentially. Can not be performed: " +
                   messagereceived.op);
@@ -490,7 +500,7 @@ public void unsubscribeNoteJobInfo(NotebookSocket conn) {
   public void getInterpreterBindings(NotebookSocket conn, Message fromMessage) throws IOException {
     String noteId = (String) fromMessage.data.get("noteId");
     List<InterpreterSettingsList> settingList =
-        InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId);
+        InterpreterBindingUtils.getInterpreterBindings(getNotebook(), noteId);
     conn.send(serializeMessage(
         new Message(OP.INTERPRETER_BINDINGS).put("interpreterBindings", settingList)));
   }
@@ -532,7 +542,7 @@ public void broadcastNoteList(AuthenticationInfo subject, Set<String> userAndRol
       subject = new AuthenticationInfo(StringUtils.EMPTY);
     }
     //send first to requesting user
-    List<NoteInfo> notesInfo = notebook().getNotesInfo(userAndRoles);
+    List<NoteInfo> notesInfo = getNotebook().getNotesInfo(userAndRoles);
     connectionManager.multicastToUser(subject.getUser(),
         new Message(OP.NOTES_INFO).put("notes", notesInfo));
     //to others afterwards
@@ -1058,7 +1068,7 @@ protected void angularObjectClientBind(NotebookSocket conn,
     String varName = fromMessage.getType("name");
     Object varValue = fromMessage.get("value");
     String paragraphId = fromMessage.getType("paragraphId");
-    Note note = notebook().getNote(noteId);
+    Note note = getNotebook().getNote(noteId);
 
     if (paragraphId == null) {
       throw new IllegalArgumentException(
@@ -1084,7 +1094,7 @@ protected void angularObjectClientUnbind(NotebookSocket conn,
     String noteId = fromMessage.getType("noteId");
     String varName = fromMessage.getType("name");
     String paragraphId = fromMessage.getType("paragraphId");
-    Note note = notebook().getNote(noteId);
+    Note note = getNotebook().getNote(noteId);
 
     if (paragraphId == null) {
       throw new IllegalArgumentException(
@@ -1265,7 +1275,7 @@ private void sendAllConfigurations(NotebookSocket conn,
           public void onSuccess(Map<String, String> properties,
                                 ServiceContext context) throws IOException {
             super.onSuccess(properties, context);
-            properties.put("isRevisionSupported", String.valueOf(notebook().isRevisionSupported()));
+            properties.put("isRevisionSupported", String.valueOf(getNotebook().isRevisionSupported()));
             conn.send(serializeMessage(
                 new Message(OP.CONFIGURATIONS_INFO).put("configurations", properties)));
           }
@@ -1284,7 +1294,7 @@ public void onSuccess(Revision revision, ServiceContext context) throws IOExcept
             super.onSuccess(revision, context);
             if (!Revision.isEmpty(revision)) {
               List<Revision> revisions =
-                  notebook().listRevisionHistory(noteId, notebook().getNote(noteId).getPath(),
+                  getNotebook().listRevisionHistory(noteId, getNotebook().getNote(noteId).getPath(),
                       context.getAutheInfo());
               conn.send(
                   serializeMessage(new Message(OP.LIST_REVISION_HISTORY).put("revisionList",
@@ -1322,7 +1332,7 @@ private void setNoteRevision(NotebookSocket conn,
           @Override
           public void onSuccess(Note note, ServiceContext context) throws IOException {
             super.onSuccess(note, context);
-            Note reloadedNote = notebook().loadNoteFromRepo(noteId, context.getAutheInfo());
+            Note reloadedNote = getNotebook().loadNoteFromRepo(noteId, context.getAutheInfo());
             conn.send(serializeMessage(new Message(OP.SET_NOTE_REVISION).put("status", true)));
             broadcastNote(reloadedNote);
           }
@@ -1385,7 +1395,7 @@ public void onOutputUpdated(String noteId, String paragraphId, int index,
                               InterpreterResult.Type type, String output) {
     Message msg = new Message(OP.PARAGRAPH_UPDATE_OUTPUT).put("noteId", noteId)
         .put("paragraphId", paragraphId).put("index", index).put("type", type).put("data", output);
-    Note note = notebook().getNote(noteId);
+    Note note = getNotebook().getNote(noteId);
 
     if (note.isPersonalizedMode()) {
       String user = note.getParagraph(paragraphId).getUser();
@@ -1402,8 +1412,7 @@ public void onOutputUpdated(String noteId, String paragraphId, int index,
    */
   @Override
   public void onOutputClear(String noteId, String paragraphId) {
-    Notebook notebook = notebook();
-    final Note note = notebook.getNote(noteId);
+    final Note note = getNotebook().getNote(noteId);
 
     note.clearParagraphOutput(paragraphId);
     Paragraph paragraph = note.getParagraph(paragraphId);
@@ -1455,8 +1464,7 @@ public void runParagraphs(String noteId,
                             List<Integer> paragraphIndices,
                             List<String> paragraphIds,
                             String curParagraphId) throws IOException {
-    Notebook notebook = notebook();
-    final Note note = notebook.getNote(noteId);
+    final Note note = getNotebook().getNote(noteId);
     final List<String> toBeRunParagraphIds = new ArrayList<>();
     if (note == null) {
       throw new IOException("Not existed noteId: " + noteId);
@@ -1610,7 +1618,7 @@ public void onStatusChange(Paragraph p, Status before, Status after) {
       }
 
       try {
-        notebook().saveNote(p.getNote(), p.getAuthenticationInfo());
+        getNotebook().saveNote(p.getNote(), p.getAuthenticationInfo());
       } catch (IOException e) {
         LOG.error(e.toString(), e);
       }
@@ -1618,7 +1626,7 @@ public void onStatusChange(Paragraph p, Status before, Status after) {
 
     p.setStatusToUserParagraph(p.getStatus());
     broadcastParagraph(p.getNote(), p);
-    //    for (NoteEventListener listener : notebook().getNoteEventListeners()) {
+    //    for (NoteEventListener listener : notebook.getNoteEventListeners()) {
     //      listener.onParagraphStatusChange(p, after);
     //    }
 
@@ -1668,7 +1676,7 @@ public void noteRunningStatusChange(String noteId, boolean newStatus) {
   private void sendAllAngularObjects(Note note, String user, NotebookSocket conn)
       throws IOException {
     List<InterpreterSetting> settings =
-        notebook().getInterpreterSettingManager().getInterpreterSettings(note.getId());
+        getNotebook().getInterpreterSettingManager().getInterpreterSettings(note.getId());
     if (settings == null || settings.size() == 0) {
       return;
     }
@@ -1697,19 +1705,18 @@ public void onAdd(String interpreterGroupId, AngularObject object) {
 
   @Override
   public void onUpdate(String interpreterGroupId, AngularObject object) {
-    Notebook notebook = notebook();
-    if (notebook == null) {
+    if (getNotebook() == null) {
       return;
     }
 
-    List<Note> notes = notebook.getAllNotes();
+    List<Note> notes = getNotebook().getAllNotes();
     for (Note note : notes) {
       if (object.getNoteId() != null && !note.getId().equals(object.getNoteId())) {
         continue;
       }
 
       List<InterpreterSetting> intpSettings =
-          notebook.getInterpreterSettingManager().getInterpreterSettings(note.getId());
+          getNotebook().getInterpreterSettingManager().getInterpreterSettings(note.getId());
       if (intpSettings.isEmpty()) {
         continue;
       }
@@ -1723,15 +1730,14 @@ public void onUpdate(String interpreterGroupId, AngularObject object) {
 
   @Override
   public void onRemove(String interpreterGroupId, String name, String noteId, String paragraphId) {
-    Notebook notebook = notebook();
-    List<Note> notes = notebook.getAllNotes();
+    List<Note> notes = getNotebook().getAllNotes();
     for (Note note : notes) {
       if (noteId != null && !note.getId().equals(noteId)) {
         continue;
       }
 
       List<String> settingIds =
-          notebook.getInterpreterSettingManager().getSettingIds();
+          getNotebook().getInterpreterSettingManager().getSettingIds();
       for (String id : settingIds) {
         if (interpreterGroupId.contains(id)) {
           connectionManager.broadcast(note.getId(),
@@ -1770,7 +1776,7 @@ public void onFailure(Exception ex, ServiceContext context) throws IOException {
 
   private void getInterpreterSettings(NotebookSocket conn)
       throws IOException {
-    List<InterpreterSetting> availableSettings = notebook().getInterpreterSettingManager().get();
+    List<InterpreterSetting> availableSettings = getNotebook().getInterpreterSettingManager().get();
     conn.send(serializeMessage(
         new Message(OP.INTERPRETER_SETTINGS).put("interpreterSettings", availableSettings)));
   }
@@ -1778,11 +1784,11 @@ private void getInterpreterSettings(NotebookSocket conn)
   @Override
   public void onParaInfosReceived(String noteId, String paragraphId,
                                   String interpreterSettingId, Map<String, String> metaInfos) {
-    Note note = notebook().getNote(noteId);
+    Note note = getNotebook().getNote(noteId);
     if (note != null) {
       Paragraph paragraph = note.getParagraph(paragraphId);
       if (paragraph != null) {
-        InterpreterSetting setting = notebook().getInterpreterSettingManager()
+        InterpreterSetting setting = getNotebook().getInterpreterSettingManager()
             .get(interpreterSettingId);
         String label = metaInfos.get("label");
         String tooltip = metaInfos.get("tooltip");
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/TestUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/TestUtils.java
new file mode 100644
index 0000000000..9876ab60f6
--- /dev/null
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/TestUtils.java
@@ -0,0 +1,49 @@
+/*
+ * 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.utils;
+
+import java.util.Arrays;
+import org.apache.zeppelin.server.ZeppelinServer;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.api.ServiceLocatorFactory;
+
+public class TestUtils {
+  public static <T> T getInstance(Class<T> clazz) {
+    checkCalledByTestMethod();
+    return getInstance(ZeppelinServer.sharedServiceLocator, clazz);
+  }
+
+  public static void clearInstances() {
+    checkCalledByTestMethod();
+    ServiceLocatorFactory.getInstance().destroy("shared-locator");
+  }
+
+  static <T> T getInstance(ServiceLocator serviceLocator, Class<T> clazz) {
+    return serviceLocator.getService(clazz);
+  }
+
+  static void checkCalledByTestMethod() {
+    StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
+    // The first element of [0] indicates 'java.lang.Thread.getStackTrace'.
+    // The second element of [1] indicates this method.
+    // The third element of [2] indicates a caller of this method.
+    if (Arrays.stream(stackTraceElements)
+        .noneMatch(stackTraceElement -> stackTraceElement.getClassName().contains("Test"))) {
+      throw new RuntimeException("This method shouldn't be used in production");
+    }
+  }
+}
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/recovery/RecoveryTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/recovery/RecoveryTest.java
index dfb442ab31..04a2e16f08 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/recovery/RecoveryTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/recovery/RecoveryTest.java
@@ -22,31 +22,33 @@
 import com.google.common.io.Files;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
-
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.io.FileUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
 import java.io.File;
 import java.util.Map;
-
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.io.FileUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.interpreter.ManagedInterpreterGroup;
 import org.apache.zeppelin.interpreter.recovery.FileSystemRecoveryStorage;
 import org.apache.zeppelin.interpreter.recovery.StopInterpreter;
 import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.rest.AbstractTestRestApi;
 import org.apache.zeppelin.scheduler.Job;
 import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.user.AuthenticationInfo;
+import org.apache.zeppelin.utils.TestUtils;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
 
 public class RecoveryTest extends AbstractTestRestApi {
   private Gson gson = new Gson();
   private static File recoveryDir = null;
 
+  private Notebook notebook;
+
   @BeforeClass
   public static void init() throws Exception {
     System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_RECOVERY_STORAGE_CLASS.getVarName(),
@@ -55,7 +57,7 @@ public static void init() throws Exception {
     System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_RECOVERY_DIR.getVarName(),
             recoveryDir.getAbsolutePath());
     startUp(RecoveryTest.class.getSimpleName());
-    ZeppelinServer.notebook.setParagraphJobListener(ZeppelinServer.notebookWsServer);
+    //TestUtils.getInstance(Notebook.class).setParagraphJobListener(NotebookServer.getInstance());
   }
 
   @AfterClass
@@ -64,9 +66,14 @@ public static void destroy() throws Exception {
     FileUtils.deleteDirectory(recoveryDir);
   }
 
+  @Before
+  public void setUp() {
+    notebook = ZeppelinServer.sharedServiceLocator.getService(Notebook.class);
+  }
+
   @Test
   public void testRecovery() throws Exception {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", AuthenticationInfo.ANONYMOUS);
+    Note note1 = notebook.createNote("note1", AuthenticationInfo.ANONYMOUS);
 
     // run python interpreter and create new variable `user`
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -78,14 +85,14 @@ public void testRecovery() throws Exception {
     assertEquals(resp.get("status"), "OK");
     post.releaseConnection();
     assertEquals(Job.Status.FINISHED, p1.getStatus());
-    ZeppelinServer.notebook.saveNote(note1, AuthenticationInfo.ANONYMOUS);
+    TestUtils.getInstance(Notebook.class).saveNote(note1, AuthenticationInfo.ANONYMOUS);
 
     // shutdown zeppelin and restart it
     shutDown();
     startUp(RecoveryTest.class.getSimpleName(), false);
 
     // run the paragraph again, but change the text to print variable `user`
-    note1 = ZeppelinServer.notebook.getNote(note1.getId());
+    note1 = TestUtils.getInstance(Notebook.class).getNote(note1.getId());
     p1 = note1.getParagraph(p1.getId());
     p1.setText("%python print(user)");
     post = httpPost("/notebook/job/" + note1.getId(), "");
@@ -97,7 +104,7 @@ public void testRecovery() throws Exception {
 
   @Test
   public void testRecovery_2() throws Exception {
-    Note note1 = ZeppelinServer.notebook.createNote("note2", AuthenticationInfo.ANONYMOUS);
+    Note note1 = notebook.createNote("note2", AuthenticationInfo.ANONYMOUS);
 
     // run python interpreter and create new variable `user`
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -109,9 +116,9 @@ public void testRecovery_2() throws Exception {
     assertEquals(resp.get("status"), "OK");
     post.releaseConnection();
     assertEquals(Job.Status.FINISHED, p1.getStatus());
-    ZeppelinServer.notebook.saveNote(note1, AuthenticationInfo.ANONYMOUS);
+    TestUtils.getInstance(Notebook.class).saveNote(note1, AuthenticationInfo.ANONYMOUS);
     // restart the python interpreter
-    ZeppelinServer.notebook.getInterpreterSettingManager().restart(
+    TestUtils.getInstance(Notebook.class).getInterpreterSettingManager().restart(
         ((ManagedInterpreterGroup) p1.getBindedInterpreter().getInterpreterGroup())
             .getInterpreterSetting().getId()
     );
@@ -122,7 +129,7 @@ public void testRecovery_2() throws Exception {
 
     // run the paragraph again, but change the text to print variable `user`.
     // can not recover the python interpreter, because it has been shutdown.
-    note1 = ZeppelinServer.notebook.getNote(note1.getId());
+    note1 = TestUtils.getInstance(Notebook.class).getNote(note1.getId());
     p1 = note1.getParagraph(p1.getId());
     p1.setText("%python print(user)");
     post = httpPost("/notebook/job/" + note1.getId(), "");
@@ -133,7 +140,7 @@ public void testRecovery_2() throws Exception {
 
   @Test
   public void testRecovery_3() throws Exception {
-    Note note1 = ZeppelinServer.notebook.createNote("note3", AuthenticationInfo.ANONYMOUS);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note3", AuthenticationInfo.ANONYMOUS);
 
     // run python interpreter and create new variable `user`
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -145,7 +152,7 @@ public void testRecovery_3() throws Exception {
     assertEquals(resp.get("status"), "OK");
     post.releaseConnection();
     assertEquals(Job.Status.FINISHED, p1.getStatus());
-    ZeppelinServer.notebook.saveNote(note1, AuthenticationInfo.ANONYMOUS);
+    TestUtils.getInstance(Notebook.class).saveNote(note1, AuthenticationInfo.ANONYMOUS);
 
     // shutdown zeppelin and restart it
     shutDown();
@@ -155,7 +162,7 @@ public void testRecovery_3() throws Exception {
 
     // run the paragraph again, but change the text to print variable `user`.
     // can not recover the python interpreter, because it has been shutdown.
-    note1 = ZeppelinServer.notebook.getNote(note1.getId());
+    note1 = TestUtils.getInstance(Notebook.class).getNote(note1.getId());
     p1 = note1.getParagraph(p1.getId());
     p1.setText("%python print(user)");
     post = httpPost("/notebook/job/" + note1.getId(), "");
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 e4d161fe19..a36b419d9c 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
@@ -35,7 +35,9 @@
 import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.plugin.PluginManager;
+import org.apache.zeppelin.utils.TestUtils;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
@@ -159,6 +161,7 @@ protected static String getUrlToTest() {
     @Override
     public void run() {
       try {
+        TestUtils.clearInstances();
         ZeppelinServer.main(new String[]{""});
       } catch (Exception e) {
         LOG.error("Exception in WebDriverManager while getWebDriver ", e);
@@ -246,7 +249,7 @@ private static void start(boolean withAuth,
       if (started == false) {
         throw new RuntimeException("Can not start Zeppelin server");
       }
-      ZeppelinServer.notebook.setParagraphJobListener(ZeppelinServer.notebookWsServer);
+      //ZeppelinServer.notebook.setParagraphJobListener(NotebookServer.getInstance());
       LOG.info("Test Zeppelin stared.");
     }
   }
@@ -281,13 +284,14 @@ protected static void shutDown() throws Exception {
   }
 
   protected static void shutDown(final boolean deleteConfDir) throws Exception {
-    if (!WAS_RUNNING && ZeppelinServer.notebook != null) {
+
+    if (!WAS_RUNNING && TestUtils.getInstance(Notebook.class) != null) {
       // restart interpreter to stop all interpreter processes
-      List<InterpreterSetting> settingList = ZeppelinServer.notebook.getInterpreterSettingManager()
+      List<InterpreterSetting> settingList = TestUtils.getInstance(Notebook.class).getInterpreterSettingManager()
               .get();
-      if (!ZeppelinServer.notebook.getConf().isRecoveryEnabled()) {
+      if (!TestUtils.getInstance(Notebook.class).getConf().isRecoveryEnabled()) {
         for (InterpreterSetting setting : settingList) {
-          ZeppelinServer.notebook.getInterpreterSettingManager().restart(setting.getId());
+          TestUtils.getInstance(Notebook.class).getInterpreterSettingManager().restart(setting.getId());
         }
       }
       if (shiroIni != null) {
@@ -319,13 +323,14 @@ protected static void shutDown(final boolean deleteConfDir) throws Exception {
             .clearProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED.getVarName());
       }
 
-      if (deleteConfDir && !ZeppelinServer.notebook.getConf().isRecoveryEnabled()) {
+      if (deleteConfDir && !TestUtils.getInstance(Notebook.class).getConf().isRecoveryEnabled()) {
         // don't delete interpreter.json when recovery is enabled. otherwise the interpreter setting
         // id will change after zeppelin restart, then we can not recover interpreter process
         // properly
         FileUtils.deleteDirectory(confDir);
       }
     }
+
   }
 
   protected static boolean checkIfServerIsRunning() {
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java
index 6f8edfd5bf..00fa5a2b19 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java
@@ -26,6 +26,8 @@
 
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.zeppelin.helium.Helium;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -41,14 +43,15 @@
 import org.apache.zeppelin.helium.HeliumPackage;
 import org.apache.zeppelin.helium.HeliumRegistry;
 import org.apache.zeppelin.helium.HeliumType;
-import org.apache.zeppelin.server.ZeppelinServer;
 
 public class HeliumRestApiTest extends AbstractTestRestApi {
-  Gson gson = new Gson();
+  private Gson gson = new Gson();
+  private static Helium helium;
 
   @BeforeClass
   public static void init() throws Exception {
     AbstractTestRestApi.startUp(HeliumRestApi.class.getSimpleName());
+    helium = TestUtils.getInstance(Helium.class);
   }
 
   @AfterClass
@@ -59,33 +62,34 @@ public static void destroy() throws Exception {
   @Before
   public void setUp() throws IOException {
     HeliumTestRegistry registry = new HeliumTestRegistry("r1", "r1");
-    ZeppelinServer.helium.clear();
-    ZeppelinServer.helium.addRegistry(registry);
+    helium.clear();
 
     registry.add(new HeliumPackage(
-                HeliumType.APPLICATION,
-                "name1",
-                "desc1",
-                "artifact1",
-                "className1",
-                new String[][]{},
-                "",
-                ""));
+        HeliumType.APPLICATION,
+        "name1",
+        "desc1",
+        "artifact1",
+        "className1",
+        new String[][]{},
+        "",
+        ""));
 
     registry.add(new HeliumPackage(
-                HeliumType.APPLICATION,
-                "name2",
-                "desc2",
-                "artifact2",
-                "className2",
-                new String[][]{},
-                "",
-                ""));
+        HeliumType.APPLICATION,
+        "name2",
+        "desc2",
+        "artifact2",
+        "className2",
+        new String[][]{},
+        "",
+        ""));
+
+    helium.addRegistry(registry);
   }
 
   @After
   public void tearDown() {
-    ZeppelinServer.helium.clear();
+    helium.clear();
   }
 
   @Test
@@ -96,7 +100,7 @@ public void testGetAllPackageInfo() throws IOException {
             new TypeToken<Map<String, Object>>() { }.getType());
     Map<String, Set<String>> body = (Map<String, Set<String>>) resp.get("body");
 
-    assertEquals(body.size(), 2);
+    assertEquals(2, body.size());
     assertTrue(body.containsKey("name1"));
     assertTrue(body.containsKey("name2"));
   }
@@ -112,7 +116,7 @@ public void testGetAllEnabledPackageInfo() throws IOException {
     assertEquals(body1.size(), 0);
 
     // Enable "name1" package
-    ZeppelinServer.helium.enable("name1", "artifact1");
+    helium.enable("name1", "artifact1");
 
     GetMethod get2 = httpGet("/helium/enabledPackage");
     assertThat(get2, isAllowed());
@@ -196,7 +200,7 @@ public void testVisualizationPackageOrder() throws IOException {
     assertEquals(body1.size(), 0);
 
     //We assume allPackages list has been refreshed before sorting
-    ZeppelinServer.helium.getAllPackageInfo();
+    helium.getAllPackageInfo();
 
     String postRequestJson = "[name2, name1]";
     PostMethod post = httpPost("/helium/order/visualization", postRequestJson);
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
index 75845d412a..8283e945cb 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
@@ -28,10 +28,12 @@
 import org.apache.zeppelin.interpreter.InterpreterOption;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.Job.Status;
 import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.user.AuthenticationInfo;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -78,7 +80,7 @@ public void getAvailableInterpreters() throws IOException {
 
     // then
     assertThat(get, isAllowed());
-    assertEquals(ZeppelinServer.notebook.getInterpreterSettingManager()
+    assertEquals(TestUtils.getInstance(Notebook.class).getInterpreterSettingManager()
                     .getInterpreterSettingTemplates().size(), body.entrySet().size());
     get.releaseConnection();
   }
@@ -234,7 +236,7 @@ public void testSettingsCreateWithEmptyJson() throws IOException {
 
   public void testInterpreterRestart() throws IOException, InterruptedException {
     // when: create new note
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     Paragraph p = note.getLastParagraph();
     Map config = p.getConfig();
@@ -251,7 +253,7 @@ public void testInterpreterRestart() throws IOException, InterruptedException {
     assertEquals(p.getReturn().message().get(0).getData(), getSimulatedMarkdownResult("markdown"));
 
     // when: restart interpreter
-    for (InterpreterSetting setting : ZeppelinServer.notebook.getInterpreterSettingManager()
+    for (InterpreterSetting setting : TestUtils.getInstance(Notebook.class).getInterpreterSettingManager()
             .getInterpreterSettings(note.getId())) {
       if (setting.getName().equals("md")) {
         // call restart interpreter API
@@ -275,13 +277,13 @@ public void testInterpreterRestart() throws IOException, InterruptedException {
     // then
     assertEquals(p.getReturn().message().get(0).getData(),
             getSimulatedMarkdownResult("markdown restarted"));
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRestartInterpreterPerNote() throws IOException, InterruptedException {
     // when: create new note
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     Paragraph p = note.getLastParagraph();
     Map config = p.getConfig();
@@ -299,7 +301,7 @@ public void testRestartInterpreterPerNote() throws IOException, InterruptedExcep
 
     // when: get md interpreter
     InterpreterSetting mdIntpSetting = null;
-    for (InterpreterSetting setting : ZeppelinServer.notebook.getInterpreterSettingManager()
+    for (InterpreterSetting setting : TestUtils.getInstance(Notebook.class).getInterpreterSettingManager()
             .getInterpreterSettings(note.getId())) {
       if (setting.getName().equals("md")) {
         mdIntpSetting = setting;
@@ -327,7 +329,7 @@ public void testRestartInterpreterPerNote() throws IOException, InterruptedExcep
     assertThat("shared interpreter restart:", put, isAllowed());
     put.releaseConnection();
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
index daf74b80d5..87c791b073 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
@@ -28,6 +28,9 @@
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.socket.NotebookServer;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -43,7 +46,6 @@
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.Job;
-import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.user.AuthenticationInfo;
 
 /**
@@ -57,7 +59,7 @@
   @BeforeClass
   public static void init() throws Exception {
     startUp(NotebookRestApiTest.class.getSimpleName());
-    ZeppelinServer.notebook.setParagraphJobListener(ZeppelinServer.notebookWsServer);
+    TestUtils.getInstance(Notebook.class).setParagraphJobListener(NotebookServer.getInstance());
   }
 
   @AfterClass
@@ -72,7 +74,7 @@ public void setUp() {
 
   @Test
   public void testGetNoteParagraphJobStatus() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
     String paragraphId = note1.getLastParagraph().getId();
@@ -88,12 +90,12 @@ public void testGetNoteParagraphJobStatus() throws IOException {
     assertEquals(paragraphStatus.get("status"), "READY");
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 
   @Test
   public void testRunParagraphJob() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
     Paragraph p = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -118,12 +120,12 @@ public void testRunParagraphJob() throws IOException {
     assertNotEquals(p.getStatus(), Job.Status.READY);
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 
   @Test
   public void testRunParagraphSynchronously() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
     Paragraph p = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -147,12 +149,12 @@ public void testRunParagraphSynchronously() throws IOException {
     assertEquals(text, p.getText());
 
     // cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 
   @Test
   public void testRunAllParagraph_AllSuccess() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     // 2 paragraphs
     // P1:
     //    %python
@@ -180,12 +182,12 @@ public void testRunAllParagraph_AllSuccess() throws IOException {
     assertEquals(Job.Status.FINISHED, p2.getStatus());
     assertEquals("abc\n", p2.getReturn().message().get(0).getData());
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 
   @Test
   public void testRunAllParagraph_FirstFailed() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     // 2 paragraphs
     // P1:
     //    %python
@@ -214,12 +216,12 @@ public void testRunAllParagraph_FirstFailed() throws IOException {
     assertEquals(Job.Status.READY, p2.getStatus());
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 
   @Test
   public void testCloneNote() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     PostMethod post = httpPost("/notebook/" + note1.getId(), "");
     LOG.info("testCloneNote response\n" + post.getResponseBodyAsString());
     assertThat(post, isAllowed());
@@ -238,14 +240,14 @@ public void testCloneNote() throws IOException {
     get.releaseConnection();
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
-    ZeppelinServer.notebook.removeNote(clonedNoteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(clonedNoteId, anonymous);
   }
 
   @Test
   public void testRenameNote() throws IOException {
     String oldName = "old_name";
-    Note note = ZeppelinServer.notebook.createNote(oldName, anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote(oldName, anonymous);
     assertEquals(note.getName(), oldName);
     String noteId = note.getId();
 
@@ -259,12 +261,12 @@ public void testRenameNote() throws IOException {
     assertEquals(note.getName(), newName);
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(noteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(noteId, anonymous);
   }
 
   @Test
   public void testUpdateParagraphConfig() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     String noteId = note.getId();
     Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     assertNull(p.getConfig().get("colWidth"));
@@ -282,17 +284,17 @@ public void testUpdateParagraphConfig() throws IOException {
     put.releaseConnection();
 
     assertEquals(config.get("colWidth"), 6.0);
-    note = ZeppelinServer.notebook.getNote(noteId);
+    note = TestUtils.getInstance(Notebook.class).getNote(noteId);
     assertEquals(note.getParagraph(paragraphId).getConfig().get("colWidth"), 6.0);
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(noteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(noteId, anonymous);
   }
 
   @Test
   public void testClearAllParagraphOutput() throws IOException {
     // Create note and set result explicitly
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p1 = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     InterpreterResult result = new InterpreterResult(InterpreterResult.Code.SUCCESS,
             InterpreterResult.Type.TEXT, "result");
@@ -324,12 +326,12 @@ public void testClearAllParagraphOutput() throws IOException {
     get.releaseConnection();
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRunWithServerRestart() throws Exception {
-    Note note1 = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note1 = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     // 2 paragraphs
     // P1:
     //    %python
@@ -358,7 +360,7 @@ public void testRunWithServerRestart() throws Exception {
     AbstractTestRestApi.shutDown(false);
     startUp(NotebookRestApiTest.class.getSimpleName(), false);
 
-    note1 = ZeppelinServer.notebook.getNote(note1.getId());
+    note1 = TestUtils.getInstance(Notebook.class).getNote(note1.getId());
     p1 = note1.getParagraph(p1.getId());
     p2 = note1.getParagraph(p2.getId());
 
@@ -375,6 +377,6 @@ public void testRunWithServerRestart() throws Exception {
     assertEquals("abc\n", p2.getReturn().message().get(0).getData());
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note1.getId(), anonymous);
   }
 }
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java
index 209a272c48..ca3b897dcd 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java
@@ -24,25 +24,23 @@
 
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
-
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
 import org.apache.commons.httpclient.HttpMethodBase;
 import org.apache.commons.httpclient.methods.DeleteMethod;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.utils.TestUtils;
 import org.hamcrest.Matcher;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-
-import org.apache.zeppelin.notebook.Note;
-import org.apache.zeppelin.server.ZeppelinServer;
-
 public class NotebookSecurityRestApiTest extends AbstractTestRestApi {
   Gson gson = new Gson();
 
@@ -110,7 +108,7 @@ public void testThatWriterCannotRemoveNote() throws IOException {
     userTryRemoveNote(noteId, "user2", "password3", isForbidden());
     userTryRemoveNote(noteId, "user1", "password2", isAllowed());
     
-    Note deletedNote = ZeppelinServer.notebook.getNote(noteId);
+    Note deletedNote = TestUtils.getInstance(Notebook.class).getNote(noteId);
     assertNull("Deleted note should be null", deletedNote);
   }
 
@@ -161,11 +159,13 @@ private String createNoteForUser(String noteName, String user, String pwd) throw
     String jsonRequest = "{\"name\":\"" + noteName + "\"}";
     PostMethod post = httpPost("/notebook/", jsonRequest, user, pwd);
     assertThat("test note create method:", post, isAllowed());
-    Map<String, Object> resp = gson.fromJson(post.getResponseBodyAsString(),
-            new TypeToken<Map<String, Object>>() {}.getType());
+    Map<String, Object> resp =
+        gson.fromJson(
+            post.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {}.getType());
     post.releaseConnection();
-    String newNoteId =  (String) resp.get("body");
-    Note newNote = ZeppelinServer.notebook.getNote(newNoteId);
+    String newNoteId = (String) resp.get("body");
+    Notebook notebook = TestUtils.getInstance(Notebook.class);
+    Note newNote = notebook.getNote(newNoteId);
     assertNotNull("Can not find new note by id", newNote);
     return newNoteId;
   }
@@ -176,7 +176,7 @@ private void deleteNoteForUser(String noteId, String user, String pwd) throws IO
     delete.releaseConnection();
     // make sure note is deleted
     if (!noteId.isEmpty()) {
-      Note deletedNote = ZeppelinServer.notebook.getNote(noteId);
+      Note deletedNote = TestUtils.getInstance(Notebook.class).getNote(noteId);
       assertNull("Deleted note should be null", deletedNote);
     }
   }
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index 2e5a024102..252b29fa56 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -32,6 +32,8 @@
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.PutMethod;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -90,7 +92,7 @@ public void getApiRoot() throws IOException {
   public void testGetNoteInfo() throws IOException {
     LOG.info("testGetNoteInfo");
     // Create note to get info
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -99,7 +101,7 @@ public void testGetNoteInfo() throws IOException {
     paragraph.setConfig(config);
     String paragraphText = "%md This is my new paragraph in my new note";
     paragraph.setText(paragraphText);
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
 
     String sourceNoteId = note.getId();
     GetMethod get = httpGet("/notebook/" + sourceNoteId);
@@ -118,7 +120,7 @@ public void testGetNoteInfo() throws IOException {
     assertTrue(paragraphs.size() > 0);
     assertEquals(paragraphText, paragraphs.get(0).get("text"));
     //
-    ZeppelinServer.notebook.removeNote(sourceNoteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(sourceNoteId, anonymous);
   }
 
   @Test
@@ -152,7 +154,7 @@ public void testNoteCreateWithParagraphs() throws IOException {
 
     String newNoteId =  (String) resp.get("body");
     LOG.info("newNoteId:=" + newNoteId);
-    Note newNote = ZeppelinServer.notebook.getNote(newNoteId);
+    Note newNote = TestUtils.getInstance(Notebook.class).getNote(newNoteId);
     assertNotNull("Can not find new note by id", newNote);
     // This is partial test as newNote is in memory but is not persistent
     String newNoteName = newNote.getName();
@@ -178,7 +180,7 @@ public void testNoteCreateWithParagraphs() throws IOException {
       }
     }
     // cleanup
-    ZeppelinServer.notebook.removeNote(newNoteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(newNoteId, anonymous);
     post.releaseConnection();
   }
 
@@ -194,7 +196,7 @@ private void testNoteCreate(String noteName) throws IOException {
 
     String newNoteId =  (String) resp.get("body");
     LOG.info("newNoteId:=" + newNoteId);
-    Note newNote = ZeppelinServer.notebook.getNote(newNoteId);
+    Note newNote = TestUtils.getInstance(Notebook.class).getNote(newNoteId);
     assertNotNull("Can not find new note by id", newNote);
     // This is partial test as newNote is in memory but is not persistent
     String newNoteName = newNote.getName();
@@ -204,7 +206,7 @@ private void testNoteCreate(String noteName) throws IOException {
     }
     assertEquals("compare note name", noteName, newNoteName);
     // cleanup
-    ZeppelinServer.notebook.removeNote(newNoteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(newNoteId, anonymous);
     post.releaseConnection();
   }
 
@@ -212,7 +214,7 @@ private void testNoteCreate(String noteName) throws IOException {
   public void testDeleteNote() throws IOException {
     LOG.info("testDeleteNote");
     //Create note and get ID
-    Note note = ZeppelinServer.notebook.createNote("note1_testDeletedNote", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testDeletedNote", anonymous);
     String noteId = note.getId();
     testDeleteNote(noteId);
   }
@@ -226,7 +228,7 @@ public void testDeleteNoteBadId() throws IOException {
   @Test
   public void testExportNote() throws IOException {
     LOG.info("testExportNote");
-    Note note = ZeppelinServer.notebook.createNote("note1_testExportNote", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testExportNote", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("source note for export");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -234,7 +236,7 @@ public void testExportNote() throws IOException {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String sourceNoteId = note.getId();
     // Call export Note REST API
     GetMethod get = httpGet("/notebook/export/" + sourceNoteId);
@@ -248,7 +250,7 @@ public void testExportNote() throws IOException {
     String exportJSON = (String) resp.get("body");
     assertNotNull("Can not find new notejson", exportJSON);
     LOG.info("export JSON:=" + exportJSON);
-    ZeppelinServer.notebook.removeNote(sourceNoteId, anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(sourceNoteId, anonymous);
     get.releaseConnection();
   }
 
@@ -258,7 +260,7 @@ public void testImportNotebook() throws IOException {
     String noteName = "source note for import";
     LOG.info("testImportNote");
     // create test note
-    Note note = ZeppelinServer.notebook.createNote("note1_testImportNotebook", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testImportNotebook", anonymous);
     assertNotNull("can't create new note", note);
     note.setName(noteName);
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -266,12 +268,12 @@ public void testImportNotebook() throws IOException {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String sourceNoteId = note.getId();
     // get note content as JSON
     String oldJson = getNoteContent(sourceNoteId);
     // delete it first then import it
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
     // call note post
     PostMethod importPost = httpPost("/notebook/import/", oldJson);
     assertThat(importPost, isAllowed());
@@ -281,12 +283,12 @@ public void testImportNotebook() throws IOException {
     String importId = (String) resp.get("body");
 
     assertNotNull("Did not get back a note id in body", importId);
-    Note newNote = ZeppelinServer.notebook.getNote(importId);
+    Note newNote = TestUtils.getInstance(Notebook.class).getNote(importId);
     assertEquals("Compare note names", noteName, newNote.getName());
     assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs()
         .size());
     // cleanup
-    ZeppelinServer.notebook.removeNote(newNote.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(newNote.getId(), anonymous);
     importPost.releaseConnection();
   }
 
@@ -311,7 +313,7 @@ private void testDeleteNote(String noteId) throws IOException {
     delete.releaseConnection();
     // make sure note is deleted
     if (!noteId.isEmpty()) {
-      Note deletedNote = ZeppelinServer.notebook.getNote(noteId);
+      Note deletedNote = TestUtils.getInstance(Notebook.class).getNote(noteId);
       assertNull("Deleted note should be null", deletedNote);
     }
   }
@@ -327,7 +329,7 @@ private void testDeleteNotExistNote(String noteId) throws IOException {
   public void testCloneNote() throws IOException, IllegalArgumentException {
     LOG.info("testCloneNote");
     // Create note to clone
-    Note note = ZeppelinServer.notebook.createNote("note1_testCloneNote", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testCloneNote", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("source note for clone");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -335,7 +337,7 @@ public void testCloneNote() throws IOException, IllegalArgumentException {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String sourceNoteId = note.getId();
 
     String noteName = "clone Note Name";
@@ -350,14 +352,14 @@ public void testCloneNote() throws IOException, IllegalArgumentException {
 
     String newNoteId =  (String) resp.get("body");
     LOG.info("newNoteId:=" + newNoteId);
-    Note newNote = ZeppelinServer.notebook.getNote(newNoteId);
+    Note newNote = TestUtils.getInstance(Notebook.class).getNote(newNoteId);
     assertNotNull("Can not find new note by id", newNote);
     assertEquals("Compare note names", noteName, newNote.getName());
     assertEquals("Compare paragraphs count", note.getParagraphs().size(),
             newNote.getParagraphs().size());
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
-    ZeppelinServer.notebook.removeNote(newNote.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(newNote.getId(), anonymous);
     post.releaseConnection();
   }
 
@@ -371,7 +373,7 @@ public void testListNotes() throws IOException {
     List<Map<String, String>> body = (List<Map<String, String>>) resp.get("body");
     //TODO(khalid): anonymous or specific user notes?
     HashSet<String> anonymous = Sets.newHashSet("anonymous");
-    assertEquals("List notes are equal", ZeppelinServer.notebook.getAllNotes(anonymous)
+    assertEquals("List notes are equal", TestUtils.getInstance(Notebook.class).getAllNotes(anonymous)
             .size(), body.size());
     get.releaseConnection();
   }
@@ -380,7 +382,7 @@ public void testListNotes() throws IOException {
   public void testNoteJobs() throws IOException, InterruptedException {
     LOG.info("testNoteJobs");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote("note1_testNoteJobs", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testNoteJobs", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -390,7 +392,7 @@ public void testNoteJobs() throws IOException, InterruptedException {
     paragraph.setConfig(config);
 
     paragraph.setText("%md This is test paragraph.");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String noteId = note.getId();
 
     note.runAll(anonymous, true);
@@ -428,14 +430,14 @@ public void testNoteJobs() throws IOException, InterruptedException {
     Thread.sleep(1000);
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testGetNoteJob() throws IOException, InterruptedException {
     LOG.info("testGetNoteJob");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote("note1_testGetNoteJob", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testGetNoteJob", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -446,7 +448,7 @@ public void testGetNoteJob() throws IOException, InterruptedException {
 
     paragraph.setText("%sh sleep 1");
     paragraph.setAuthenticationInfo(anonymous);
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String noteId = note.getId();
 
     note.runAll(anonymous, true);
@@ -476,14 +478,14 @@ public void testGetNoteJob() throws IOException, InterruptedException {
       }
     }
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRunParagraphWithParams() throws IOException, InterruptedException {
     LOG.info("testRunParagraphWithParams");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote("note1_testRunParagraphWithParams", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testRunParagraphWithParams", anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -493,7 +495,7 @@ public void testRunParagraphWithParams() throws IOException, InterruptedExceptio
     paragraph.setConfig(config);
 
     paragraph.setText("%spark\nval param = z.input(\"param\").toString\nprintln(param)");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
     String noteId = note.getId();
 
     note.runAll(anonymous, true);
@@ -505,20 +507,20 @@ public void testRunParagraphWithParams() throws IOException, InterruptedExceptio
     postParagraph.releaseConnection();
     Thread.sleep(1000);
 
-    Note retrNote = ZeppelinServer.notebook.getNote(noteId);
+    Note retrNote = TestUtils.getInstance(Notebook.class).getNote(noteId);
     Paragraph retrParagraph = retrNote.getParagraph(paragraph.getId());
     Map<String, Object> params = retrParagraph.settings.getParams();
     assertEquals("hello", params.get("param"));
     assertEquals("world", params.get("param2"));
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testJobs() throws InterruptedException, IOException{
     // create a note and a paragraph
-    Note note = ZeppelinServer.notebook.createNote("note1_testJobs", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testJobs", anonymous);
 
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -553,14 +555,14 @@ public void testJobs() throws InterruptedException, IOException{
     DeleteMethod deleteCron = httpDelete("/notebook/cron/" + note.getId());
     assertThat("", deleteCron, isAllowed());
     deleteCron.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testCronDisable() throws InterruptedException, IOException{
     // create a note and a paragraph
     System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_CRON_ENABLE.getVarName(), "false");
-    Note note = ZeppelinServer.notebook.createNote("note1_testCronDisable", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testCronDisable", anonymous);
 
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -595,18 +597,18 @@ public void testCronDisable() throws InterruptedException, IOException{
     Thread.sleep(1000);
 
     System.clearProperty(ConfVars.ZEPPELIN_NOTEBOOK_CRON_FOLDERS.getVarName());
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRegressionZEPPELIN_527() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testRegressionZEPPELIN_527", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testRegressionZEPPELIN_527", anonymous);
 
     note.setName("note for run test");
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     paragraph.setText("%spark\nval param = z.input(\"param\").toString\nprintln(param)");
 
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
 
     GetMethod getNoteJobs = httpGet("/notebook/job/" + note.getId());
     assertThat("test note jobs run:", getNoteJobs, isAllowed());
@@ -617,12 +619,12 @@ public void testRegressionZEPPELIN_527() throws IOException {
     assertFalse(body.get(0).containsKey("finished"));
     getNoteJobs.releaseConnection();
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testInsertParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testInsertParagraph", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testInsertParagraph", anonymous);
 
     String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}";
     PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
@@ -636,7 +638,7 @@ public void testInsertParagraph() throws IOException {
     String newParagraphId = (String) resp.get("body");
     LOG.info("newParagraphId:=" + newParagraphId);
 
-    Note retrNote = ZeppelinServer.notebook.getNote(note.getId());
+    Note retrNote = TestUtils.getInstance(Notebook.class).getNote(note.getId());
     Paragraph newParagraph = retrNote.getParagraph(newParagraphId);
     assertNotNull("Can not find new paragraph by id", newParagraph);
 
@@ -675,12 +677,12 @@ public void testInsertParagraph() throws IOException {
     assertEquals(9.0, p.getConfig().get("colWidth"));
     assertTrue(((boolean) p.getConfig().get("title")));
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testUpdateParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testUpdateParagraph", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testUpdateParagraph", anonymous);
 
     String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}";
     PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
@@ -689,7 +691,7 @@ public void testUpdateParagraph() throws IOException {
     post.releaseConnection();
 
     String newParagraphId = (String) resp.get("body");
-    Paragraph newParagraph = ZeppelinServer.notebook.getNote(note.getId())
+    Paragraph newParagraph = TestUtils.getInstance(Notebook.class).getNote(note.getId())
             .getParagraph(newParagraphId);
 
     assertEquals("title1", newParagraph.getTitle());
@@ -701,7 +703,7 @@ public void testUpdateParagraph() throws IOException {
     assertThat("Test update method:", put, isAllowed());
     put.releaseConnection();
 
-    Paragraph updatedParagraph = ZeppelinServer.notebook.getNote(note.getId())
+    Paragraph updatedParagraph = TestUtils.getInstance(Notebook.class).getNote(note.getId())
             .getParagraph(newParagraphId);
 
     assertEquals("title1", updatedParagraph.getTitle());
@@ -712,23 +714,23 @@ public void testUpdateParagraph() throws IOException {
             updateBothRequest);
     updatePut.releaseConnection();
 
-    Paragraph updatedBothParagraph = ZeppelinServer.notebook.getNote(note.getId())
+    Paragraph updatedBothParagraph = TestUtils.getInstance(Notebook.class).getNote(note.getId())
             .getParagraph(newParagraphId);
 
     assertEquals("updated title", updatedBothParagraph.getTitle());
     assertEquals("updated text 2", updatedBothParagraph.getText());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testGetParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testGetParagraph", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testGetParagraph", anonymous);
 
     Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     p.setTitle("hello");
     p.setText("world");
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
 
     GetMethod get = httpGet("/notebook/" + note.getId() + "/paragraph/" + p.getId());
     LOG.info("testGetParagraph response\n" + get.getResponseBodyAsString());
@@ -747,12 +749,12 @@ public void testGetParagraph() throws IOException {
     assertEquals("hello", body.get("title"));
     assertEquals("world", body.get("text"));
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testMoveParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testMoveParagraph", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testMoveParagraph", anonymous);
 
     Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     p.setTitle("title1");
@@ -762,14 +764,14 @@ public void testMoveParagraph() throws IOException {
     p2.setTitle("title2");
     p2.setText("text2");
 
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
 
     PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph/" + p2.getId() +
             "/move/" + 0, "");
     assertThat("Test post method: ", post, isAllowed());
     post.releaseConnection();
 
-    Note retrNote = ZeppelinServer.notebook.getNote(note.getId());
+    Note retrNote = TestUtils.getInstance(Notebook.class).getNote(note.getId());
     Paragraph paragraphAtIdx0 = retrNote.getParagraphs().get(0);
 
     assertEquals(p2.getId(), paragraphAtIdx0.getId());
@@ -781,33 +783,33 @@ public void testMoveParagraph() throws IOException {
     assertThat("Test post method: ", post2, isBadRequest());
     post.releaseConnection();
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testDeleteParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testDeleteParagraph", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testDeleteParagraph", anonymous);
 
     Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     p.setTitle("title1");
     p.setText("text1");
 
-    ZeppelinServer.notebook.saveNote(note, anonymous);
+    TestUtils.getInstance(Notebook.class).saveNote(note, anonymous);
 
     DeleteMethod delete = httpDelete("/notebook/" + note.getId() + "/paragraph/" + p.getId());
     assertThat("Test delete method: ", delete, isAllowed());
     delete.releaseConnection();
 
-    Note retrNote = ZeppelinServer.notebook.getNote(note.getId());
+    Note retrNote = TestUtils.getInstance(Notebook.class).getNote(note.getId());
     Paragraph retrParagrah = retrNote.getParagraph(p.getId());
     assertNull("paragraph should be deleted", retrParagrah);
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testTitleSearch() throws IOException, InterruptedException {
-    Note note = ZeppelinServer.notebook.createNote("note1_testTitleSearch", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1_testTitleSearch", anonymous);
     String jsonRequest = "{\"title\": \"testTitleSearchOfParagraph\", " +
             "\"text\": \"ThisIsToTestSearchMethodWithTitle \"}";
     PostMethod postNoteText = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
@@ -830,6 +832,6 @@ public void testTitleSearch() throws IOException, InterruptedException {
     }
     assertEquals("Paragraph title hits must be at-least one", true, numberOfTitleHits >= 1);
     searchNote.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 }
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 c9cbca0d2e..de2c061d17 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
@@ -21,6 +21,8 @@
 
 import org.apache.commons.io.FileUtils;
 import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -94,7 +96,7 @@ public ZeppelinSparkClusterTest(String sparkVersion) throws Exception {
   }
 
   public void setupSparkInterpreter(String sparkHome) throws InterpreterException {
-    InterpreterSetting sparkIntpSetting = ZeppelinServer.notebook.getInterpreterSettingManager()
+    InterpreterSetting sparkIntpSetting = TestUtils.getInstance(Notebook.class).getInterpreterSettingManager()
         .getInterpreterSettingByName("spark");
 
     Map<String, InterpreterProperty> sparkProperties =
@@ -120,7 +122,7 @@ public void setupSparkInterpreter(String sparkHome) throws InterpreterException
             new InterpreterProperty("zeppelin.spark.test", "true"));
     sparkProperties.put("spark.serializer",
             new InterpreterProperty("spark.serializer", "org.apache.spark.serializer.KryoSerializer"));
-    ZeppelinServer.notebook.getInterpreterSettingManager().restart(sparkIntpSetting.getId());
+    TestUtils.getInstance(Notebook.class).getInterpreterSettingManager().restart(sparkIntpSetting.getId());
   }
 
   @BeforeClass
@@ -160,7 +162,7 @@ private void waitForRunning(Paragraph p) {
   @Test
   public void scalaOutputTest() throws IOException, InterruptedException {
     // create new note
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
     p.setText("%spark import java.util.Date\n" +
         "import java.net.URL\n" +
@@ -196,24 +198,24 @@ public void scalaOutputTest() throws IOException, InterruptedException {
     waitForFinish(p);
     assertEquals(Status.ABORT, p.getStatus());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void basicRDDTransformationAndActionTest() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
     p.setText("%spark print(sc.parallelize(1 to 10).reduce(_ + _))");
     note.run(p.getId(), true);
     assertEquals(Status.FINISHED, p.getStatus());
     assertEquals("55", p.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void sparkSQLTest() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     // test basic dataframe api
     Paragraph p = note.addNewParagraph(anonymous);
     p.setText("%spark val df=sqlContext.createDataFrame(Seq((\"hello\",20)))\n" +
@@ -243,12 +245,12 @@ public void sparkSQLTest() throws IOException {
       assertEquals("_1\t_2\nhello\t20\n", p.getReturn().message().get(0).getData());
     }
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void sparkRTest() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
 
     String sqlContextName = "sqlContext";
     if (isSpark2()) {
@@ -263,13 +265,13 @@ public void sparkRTest() throws IOException {
     assertEquals(Status.FINISHED, p.getStatus());
     assertEquals("[1] 3", p.getReturn().message().get(0).getData().trim());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   // @Test
   public void pySparkTest() throws IOException {
     // create new note
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
 
     // run markdown paragraph, again
     Paragraph p = note.addNewParagraph(anonymous);
@@ -344,13 +346,13 @@ public void pySparkTest() throws IOException {
           "[Row(len='3')]\n".equals(p.getReturn().message().get(0).getData()));
     }
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void zRunTest() throws IOException {
     // create new note
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p0 = note.addNewParagraph(anonymous);
     // z.run(paragraphIndex)
     p0.setText("%spark z.run(1)");
@@ -394,7 +396,7 @@ public void zRunTest() throws IOException {
     assertEquals("END\n", p3.getReturn().message().get(0).getData());
 
     // run paragraph in note2 via paragraph in note1
-    Note note2 = ZeppelinServer.notebook.createNote("note2", anonymous);
+    Note note2 = TestUtils.getInstance(Notebook.class).createNote("note2", anonymous);
     Paragraph p20 = note2.addNewParagraph(anonymous);
     p20.setText("%spark val a = 1");
     Paragraph p21 = note2.addNewParagraph(anonymous);
@@ -415,13 +417,13 @@ public void zRunTest() throws IOException {
     assertEquals(Status.FINISHED, p21.getStatus());
     assertEquals("1", p21.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
-    ZeppelinServer.notebook.removeNote(note2.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note2.getId(), anonymous);
   }
 
   @Test
   public void testZeppelinContextResource() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
 
     Paragraph p1 = note.addNewParagraph(anonymous);
     p1.setText("%spark z.put(\"var_1\", \"hello world\")");
@@ -449,12 +451,12 @@ public void testZeppelinContextResource() throws IOException {
     assertEquals(Status.FINISHED, p4.getStatus());
     assertEquals("hello world\n", p4.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testZeppelinContextHook() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
 
     // register global hook & note1 hook
     Paragraph p1 = note.addNewParagraph(anonymous);
@@ -474,22 +476,22 @@ public void testZeppelinContextHook() throws IOException {
     assertEquals(Status.FINISHED, p2.getStatus());
     assertEquals("1\n3\n5\n4\n2\n", p2.getReturn().message().get(0).getData());
 
-    Note note2 = ZeppelinServer.notebook.createNote("note2", anonymous);
+    Note note2 = TestUtils.getInstance(Notebook.class).createNote("note2", anonymous);
     Paragraph p3 = note2.addNewParagraph(anonymous);
     p3.setText("%python print(6)");
     note2.run(p3.getId(), true);
     assertEquals("1\n6\n2\n", p3.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
-    ZeppelinServer.notebook.removeNote(note2.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note2.getId(), anonymous);
   }
 
   @Test
   public void pySparkDepLoaderTest() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
 
     // restart spark interpreter to make dep loader work
-    ZeppelinServer.notebook.getInterpreterSettingManager().close();
+    TestUtils.getInstance(Notebook.class).getInterpreterSettingManager().close();
 
     // load dep
     Paragraph p0 = note.addNewParagraph(anonymous);
@@ -517,11 +519,11 @@ public void pySparkDepLoaderTest() throws IOException {
     assertEquals(Status.FINISHED, p1.getStatus());
     assertEquals("2\n", p1.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   private void verifySparkVersionNumber() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
 
     p.setText("%spark print(sc.version)");
@@ -530,7 +532,7 @@ private void verifySparkVersionNumber() throws IOException {
     assertEquals(Status.FINISHED, p.getStatus());
     assertEquals(sparkVersion, p.getReturn().message().get(0).getData());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   private int toIntSparkVersion(String sparkVersion) {
@@ -545,7 +547,7 @@ private boolean isSpark2() {
 
   @Test
   public void testSparkZeppelinContextDynamicForms() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
     String code = "%spark.spark println(z.textbox(\"my_input\", \"default_name\"))\n" +
         "println(z.password(\"my_pwd\"))\n" +
@@ -574,12 +576,12 @@ public void testSparkZeppelinContextDynamicForms() throws IOException {
     assertEquals("2", result[3]);
     assertEquals("items: Seq[Any] = Buffer(2)", result[4]);
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testPySparkZeppelinContextDynamicForms() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
     String code = "%spark.pyspark print(z.input('my_input', 'default_name'))\n" +
         "print(z.password('my_pwd'))\n" +
@@ -606,12 +608,12 @@ public void testPySparkZeppelinContextDynamicForms() throws IOException {
     assertEquals("1", result[2]);
     assertEquals("2", result[3]);
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testAngularObjects() throws IOException, InterpreterNotFoundException {
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p1 = note.addNewParagraph(anonymous);
 
     // add local angular object
@@ -653,13 +655,13 @@ public void testAngularObjects() throws IOException, InterpreterNotFoundExceptio
             .getAngularObjectRegistry().getAll(note.getId(), null);
     assertEquals(0, globalAngularObjects.size());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testConfInterpreter() throws IOException {
-    ZeppelinServer.notebook.getInterpreterSettingManager().close();
-    Note note = ZeppelinServer.notebook.createNote("note1", anonymous);
+    TestUtils.getInstance(Notebook.class).getInterpreterSettingManager().close();
+    Note note = TestUtils.getInstance(Notebook.class).createNote("note1", anonymous);
     Paragraph p = note.addNewParagraph(anonymous);
     p.setText("%spark.conf spark.jars.packages\tcom.databricks:spark-csv_2.11:1.2.0");
     note.run(p.getId(), true);
@@ -670,6 +672,6 @@ public void testConfInterpreter() throws IOException {
     note.run(p1.getId(), true);
     assertEquals(Status.FINISHED, p1.getStatus());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    TestUtils.getInstance(Notebook.class).removeNote(note.getId(), anonymous);
   }
 }
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/service/ConfigurationServiceTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/service/ConfigurationServiceTest.java
index ee4f4fcd2f..1adabbe1dd 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/service/ConfigurationServiceTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/service/ConfigurationServiceTest.java
@@ -21,7 +21,9 @@
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.rest.AbstractTestRestApi;
 import org.apache.zeppelin.server.ZeppelinServer;
+import org.apache.zeppelin.socket.NotebookServer;
 import org.apache.zeppelin.user.AuthenticationInfo;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -50,7 +52,7 @@ public static void setUp() throws Exception {
     System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_HELIUM_REGISTRY.getVarName(),
         "helium");
     AbstractTestRestApi.startUp(ConfigurationServiceTest.class.getSimpleName());
-    configurationService = ZeppelinServer.notebookWsServer.getConfigurationService();
+    configurationService = TestUtils.getInstance(ConfigurationService.class);
   }
 
   @AfterClass
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/service/NotebookServiceTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/service/NotebookServiceTest.java
index 90f3533acf..8962482286 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/service/NotebookServiceTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/service/NotebookServiceTest.java
@@ -18,9 +18,29 @@
 
 package org.apache.zeppelin.service;
 
-import com.google.common.collect.Maps;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.interpreter.Interpreter;
@@ -38,7 +58,6 @@
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.notebook.repo.InMemoryNotebookRepo;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
-import org.apache.zeppelin.notebook.repo.NotebookRepoSettingsInfo;
 import org.apache.zeppelin.search.LuceneSearch;
 import org.apache.zeppelin.search.SearchService;
 import org.apache.zeppelin.user.AuthenticationInfo;
@@ -46,29 +65,6 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class NotebookServiceTest {
 
   private static NotebookService notebookService;
@@ -110,8 +106,9 @@ public void setUp() throws Exception {
             mockInterpreterSettingManager,
             searchService,
             notebookAuthorization,
-            credentials);
-    notebookService = new NotebookService(notebook);
+            credentials,
+            null);
+    notebookService = new NotebookService(notebook, notebookAuthorization, zeppelinConfiguration);
 
     String interpreterName = "test";
     when(mockInterpreterSetting.getName()).thenReturn(interpreterName);
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/service/ShiroSecurityServiceTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/service/ShiroSecurityServiceTest.java
index a02e8f2fc1..d4267f7366 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/service/ShiroSecurityServiceTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/service/ShiroSecurityServiceTest.java
@@ -31,6 +31,7 @@
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.server.ZeppelinServer;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -82,13 +83,8 @@ private void setupPrincipalName(String expectedName) {
 
     Notebook notebook = Mockito.mock(Notebook.class);
     try {
-      setFinalStatic(ZeppelinServer.class.getDeclaredField("notebook"), notebook);
-      when(ZeppelinServer.notebook.getConf())
+      when(notebook.getConf())
           .thenReturn(new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml")));
-    } catch (NoSuchFieldException e) {
-      e.printStackTrace();
-    } catch (IllegalAccessException e) {
-      e.printStackTrace();
     } catch (ConfigurationException e) {
       e.printStackTrace();
     }
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 e894778d93..ab805b89ab 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
@@ -34,8 +34,8 @@
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.HashSet;
 import java.util.List;
+import javax.inject.Provider;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
@@ -45,15 +45,16 @@
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.notebook.NotebookAuthorization;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.notebook.socket.Message;
 import org.apache.zeppelin.notebook.socket.Message.OP;
 import org.apache.zeppelin.rest.AbstractTestRestApi;
 import org.apache.zeppelin.scheduler.Job;
-import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.service.ConfigurationService;
 import org.apache.zeppelin.service.NotebookService;
 import org.apache.zeppelin.user.AuthenticationInfo;
+import org.apache.zeppelin.utils.TestUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -64,15 +65,18 @@
 public class NotebookServerTest extends AbstractTestRestApi {
   private static Notebook notebook;
   private static NotebookServer notebookServer;
+  private static NotebookService notebookService;
   private HttpServletRequest mockRequest;
   private AuthenticationInfo anonymous;
 
   @BeforeClass
   public static void init() throws Exception {
     AbstractTestRestApi.startUp(NotebookServerTest.class.getSimpleName());
-    notebook = ZeppelinServer.notebook;
-    notebookServer = spy(ZeppelinServer.notebookWsServer);
-    NotebookService notebookService = new NotebookService(notebook);
+    notebook = TestUtils.getInstance(Notebook.class);
+    notebookServer = spy(NotebookServer.getInstance());
+    notebookService =
+        new NotebookService(
+            notebook, NotebookAuthorization.getInstance(), ZeppelinConfiguration.create());
     ConfigurationService configurationService = new ConfigurationService(notebook.getConf());
     when(notebookServer.getNotebookService()).thenReturn(notebookService);
     when(notebookServer.getConfigurationService()).thenReturn(configurationService);
@@ -92,6 +96,8 @@ public void setUp() {
   @Test
   public void checkOrigin() throws UnknownHostException {
     NotebookServer server = new NotebookServer();
+    server.setNotebook(() -> notebook);
+    server.setNotebookService(() -> notebookService);
     String origin = "http://" + InetAddress.getLocalHost().getHostName() + ":8080";
 
     assertTrue("Origin " + origin + " is not allowed. Please check your hostname.",
@@ -101,6 +107,8 @@ public void checkOrigin() throws UnknownHostException {
   @Test
   public void checkInvalidOrigin(){
     NotebookServer server = new NotebookServer();
+    server.setNotebook(() -> notebook);
+    server.setNotebookService(() -> notebookService);
     assertFalse(server.checkOrigin(mockRequest, "http://evillocalhost:8080"));
   }
 
@@ -275,11 +283,11 @@ public void bindAngularObjectToRemoteForParagraphs() throws Exception {
             .put("value", value)
             .put("paragraphId", "paragraphId");
 
-    final NotebookServer server = new NotebookServer();
     final Notebook notebook = mock(Notebook.class);
+    final NotebookServer server = new NotebookServer();
+    server.setNotebook(() -> notebook);
+    server.setNotebookService(() -> notebookService);
     final Note note = mock(Note.class, RETURNS_DEEP_STUBS);
-    Notebook originalNotebook = ZeppelinServer.notebook;
-    ZeppelinServer.notebook = notebook;
 
     when(notebook.getNote("noteId")).thenReturn(note);
     final Paragraph paragraph = mock(Paragraph.class, RETURNS_DEEP_STUBS);
@@ -315,9 +323,6 @@ public void bindAngularObjectToRemoteForParagraphs() throws Exception {
     verify(mdRegistry, never()).addAndNotifyRemoteProcess(varName, value, "noteId", null);
 
     verify(otherConn).send(mdMsg1);
-
-    // reset it to original notebook
-    ZeppelinServer.notebook = originalNotebook;
   }
 
   @Test
@@ -330,10 +335,10 @@ public void unbindAngularObjectFromRemoteForParagraphs() throws Exception {
             .put("name", varName)
             .put("paragraphId", "paragraphId");
 
-    final NotebookServer server = new NotebookServer();
     final Notebook notebook = mock(Notebook.class);
-    Notebook originalNotebook = ZeppelinServer.notebook;
-    ZeppelinServer.notebook = notebook;
+    final NotebookServer server = new NotebookServer();
+    server.setNotebook(() -> notebook);
+    server.setNotebookService(() -> notebookService);
     final Note note = mock(Note.class, RETURNS_DEEP_STUBS);
     when(notebook.getNote("noteId")).thenReturn(note);
     final Paragraph paragraph = mock(Paragraph.class, RETURNS_DEEP_STUBS);
@@ -366,9 +371,6 @@ public void unbindAngularObjectFromRemoteForParagraphs() throws Exception {
     verify(mdRegistry, never()).removeAndNotifyRemoteProcess(varName, "noteId", null);
 
     verify(otherConn).send(mdMsg1);
-
-    // reset it to original notebook
-    ZeppelinServer.notebook = originalNotebook;
   }
 
   @Test
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 399aea879a..e0a3845942 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
@@ -16,9 +16,24 @@
  */
 package org.apache.zeppelin.helium;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.gson.Gson;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Inject;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterNotFoundException;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
@@ -26,14 +41,13 @@
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
 import org.apache.zeppelin.notebook.Paragraph;
-import org.apache.zeppelin.resource.*;
+import org.apache.zeppelin.resource.DistributedResourcePool;
+import org.apache.zeppelin.resource.Resource;
+import org.apache.zeppelin.resource.ResourcePool;
+import org.apache.zeppelin.resource.ResourceSet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
 /**
  * Manages helium packages
  */
@@ -52,6 +66,22 @@
   private final HeliumApplicationFactory applicationFactory;
   private final InterpreterSettingManager interpreterSettingManager;
 
+  @Inject
+  public Helium(
+      ZeppelinConfiguration conf,
+      HeliumBundleFactory heliumBundleFactory,
+      HeliumApplicationFactory heliumApplicationFactory,
+      InterpreterSettingManager interpreterSettingManager) throws IOException {
+    this(
+        conf.getHeliumConfPath(),
+        conf.getHeliumRegistry(),
+        new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO), "helium-registry-cache"),
+        heliumBundleFactory,
+        heliumApplicationFactory,
+        interpreterSettingManager);
+  }
+
+  @VisibleForTesting
   public Helium(
       String heliumConfPath,
       String registryPaths,
@@ -68,6 +98,13 @@ public Helium(
     this.interpreterSettingManager = interpreterSettingManager;
     heliumConf = loadConf(heliumConfPath);
     allPackages = getAllPackageInfo();
+
+    // TODO(jl): Refactor it
+    try {
+      bundleFactory.buildAllPackages(getBundlePackagesToBundle());
+    } catch (Exception e) {
+      logger.error(e.getMessage(), e);
+    }
   }
 
   /**
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 473befb75b..2251e22e4e 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,22 +16,30 @@
  */
 package org.apache.zeppelin.helium;
 
-import org.apache.zeppelin.interpreter.*;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import javax.inject.Inject;
+import org.apache.zeppelin.interpreter.Interpreter;
+import org.apache.zeppelin.interpreter.InterpreterException;
+import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.interpreter.ManagedInterpreterGroup;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
 import org.apache.zeppelin.interpreter.thrift.RemoteApplicationResult;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
-import org.apache.zeppelin.notebook.*;
+import org.apache.zeppelin.notebook.ApplicationState;
+import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.NoteEventListener;
+import org.apache.zeppelin.notebook.Notebook;
+import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.scheduler.ExecutorFactory;
 import org.apache.zeppelin.scheduler.Job;
 import org.apache.zeppelin.user.AuthenticationInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-
 /**
  * HeliumApplicationFactory
  */
@@ -41,9 +49,16 @@
   private Notebook notebook;
   private ApplicationEventListener applicationEventListener;
 
-  public HeliumApplicationFactory() {
-    executor = ExecutorFactory.singleton().createOrGet(
-        HeliumApplicationFactory.class.getName(), 10);
+  @Inject
+  public HeliumApplicationFactory(
+      Notebook notebook, ApplicationEventListener applicationEventListener) {
+    this.executor =
+        ExecutorFactory.singleton().createOrGet(HeliumApplicationFactory.class.getName(), 10);
+    this.notebook = notebook;
+    this.applicationEventListener = applicationEventListener;
+
+    // TODO(jl): Hmmmmmmmm...
+    this.notebook.addNotebookEventListener(this);
   }
 
   private boolean isRemote(InterpreterGroup group) {
@@ -396,22 +411,6 @@ private ApplicationState getAppState(String noteId, String paragraphId, String a
     return appFound;
   }
 
-  public Notebook getNotebook() {
-    return notebook;
-  }
-
-  public void setNotebook(Notebook notebook) {
-    this.notebook = notebook;
-  }
-
-  public ApplicationEventListener getApplicationEventListener() {
-    return applicationEventListener;
-  }
-
-  public void setApplicationEventListener(ApplicationEventListener applicationEventListener) {
-    this.applicationEventListener = applicationEventListener;
-  }
-
   @Override
   public void onNoteRemove(Note note, AuthenticationInfo subject) throws IOException {
   }
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 3b5aa3b523..61e8897b47 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
@@ -16,14 +16,40 @@
  */
 package org.apache.zeppelin.helium;
 
-import com.github.eirslett.maven.plugins.frontend.lib.*;
-
+import com.github.eirslett.maven.plugins.frontend.lib.FrontendPluginFactory;
+import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
+import com.github.eirslett.maven.plugins.frontend.lib.NPMInstaller;
+import com.github.eirslett.maven.plugins.frontend.lib.NodeInstaller;
+import com.github.eirslett.maven.plugins.frontend.lib.NpmRunner;
+import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;
+import com.github.eirslett.maven.plugins.frontend.lib.TaskRunnerException;
+import com.github.eirslett.maven.plugins.frontend.lib.YarnInstaller;
+import com.github.eirslett.maven.plugins.frontend.lib.YarnRunner;
 import com.google.common.base.Charsets;
 import com.google.common.io.Resources;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.stream.JsonReader;
-
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import javax.inject.Inject;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
@@ -35,15 +61,11 @@
 import org.apache.log4j.WriterAppender;
 import org.apache.log4j.spi.Filter;
 import org.apache.log4j.spi.LoggingEvent;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.*;
-import java.net.URI;
-import java.util.*;
-
-import org.apache.zeppelin.conf.ZeppelinConfiguration;
-
 /**
  * Load helium visualization & spell
  */
@@ -84,38 +106,35 @@
 
   private ByteArrayOutputStream out  = new ByteArrayOutputStream();
 
-  public HeliumBundleFactory(
-      ZeppelinConfiguration conf,
-      File nodeInstallationDir,
-      File moduleDownloadPath,
-      File tabledataModulePath,
-      File visualizationModulePath,
-      File spellModulePath) throws TaskRunnerException {
-    this(conf, nodeInstallationDir, moduleDownloadPath);
-    this.tabledataModulePath = tabledataModulePath;
-    this.visualizationModulePath = visualizationModulePath;
-    this.spellModulePath = spellModulePath;
-  }
-
-  private HeliumBundleFactory(
-      ZeppelinConfiguration conf,
-      File nodeInstallationDir,
-      File moduleDownloadPath) throws TaskRunnerException {
-    this.heliumLocalRepoDirectory = new File(moduleDownloadPath, HELIUM_LOCAL_REPO);
+  @Inject
+  public HeliumBundleFactory(ZeppelinConfiguration conf) {
+    this.heliumLocalRepoDirectory =
+        new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO), HELIUM_LOCAL_REPO);
     this.heliumBundleDirectory = new File(heliumLocalRepoDirectory, HELIUM_BUNDLES_DIR);
     this.heliumLocalModuleDirectory = new File(heliumLocalRepoDirectory, HELIUM_LOCAL_MODULE_DIR);
     this.yarnCacheDir = new File(heliumLocalRepoDirectory, YARN_CACHE_DIR);
     this.defaultNodeInstallerUrl = conf.getHeliumNodeInstallerUrl();
     this.defaultNpmInstallerUrl = conf.getHeliumNpmInstallerUrl();
     this.defaultYarnInstallerUrl = conf.getHeliumYarnInstallerUrl();
+    this.nodeInstallationDirectory = this.heliumLocalRepoDirectory;
 
-    nodeInstallationDirectory = (nodeInstallationDir == null) ?
-        heliumLocalRepoDirectory : nodeInstallationDir;
+    this.frontEndPluginFactory =
+        new FrontendPluginFactory(heliumLocalRepoDirectory, nodeInstallationDirectory);
 
-    frontEndPluginFactory = new FrontendPluginFactory(
-            heliumLocalRepoDirectory, nodeInstallationDirectory);
+    this.gson = new Gson();
 
-    gson = new Gson();
+    File zeppelinWebPath = new File(conf.getRelativeDir("zeppelin-web"));
+    if (!zeppelinWebPath.isDirectory()) {
+      this.tabledataModulePath =
+          new File(conf.getRelativeDir("lib/node_modules/zeppelin-tabledata"));
+      this.visualizationModulePath = new File(conf.getRelativeDir("lib/node_modules/zeppelin-vis"));
+      this.spellModulePath = new File(conf.getRelativeDir("lib/node_modules/zeppelin-spell"));
+    } else {
+      this.tabledataModulePath = new File(conf.getRelativeDir("zeppelin-web/src/app/tabledata"));
+      this.visualizationModulePath =
+          new File(conf.getRelativeDir("zeppelin-web/src/app/visualization"));
+      this.spellModulePath = new File(conf.getRelativeDir("zeppelin-web/src/app/spell"));
+    }
   }
 
   void installNodeAndNpm() throws TaskRunnerException {
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 e045a597f7..a3bc3331a3 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,6 +18,7 @@
 package org.apache.zeppelin.interpreter;
 
 import com.google.common.base.Preconditions;
+import javax.inject.Inject;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,6 +36,7 @@
 
   private final InterpreterSettingManager interpreterSettingManager;
 
+  @Inject
   public InterpreterFactory(InterpreterSettingManager interpreterSettingManager) {
     this.interpreterSettingManager = interpreterSettingManager;
   }
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 be6e8f45f7..d4468ff49b 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
@@ -26,6 +26,7 @@
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
 import java.util.Set;
+import javax.inject.Inject;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
@@ -126,6 +127,7 @@
   private ConfigStorage configStorage;
   private RemoteInterpreterEventServer interpreterEventServer;
 
+  @Inject
   public InterpreterSettingManager(ZeppelinConfiguration zeppelinConfiguration,
                                    AngularObjectRegistryListener angularObjectRegistryListener,
                                    RemoteInterpreterProcessListener
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 671a0cb4b1..ccb9b9544e 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
@@ -18,6 +18,19 @@
 package org.apache.zeppelin.notebook;
 
 import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.inject.Inject;
 import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
@@ -51,19 +64,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
 /**
  * High level api of Notebook related operations, such as create, move & delete note/folder.
  * It will also do other thing which is caused by these operation, such as update index,
@@ -100,7 +100,8 @@ public Notebook(
       InterpreterSettingManager interpreterSettingManager,
       SearchService noteSearchService,
       NotebookAuthorization notebookAuthorization,
-      Credentials credentials) throws IOException, SchedulerException {
+      Credentials credentials)
+      throws IOException, SchedulerException {
     this.noteManager = new NoteManager(notebookRepo);
     this.conf = conf;
     this.notebookRepo = notebookRepo;
@@ -119,6 +120,31 @@ public Notebook(
     this.noteEventListeners.add(this.interpreterSettingManager);
   }
 
+  @Inject
+  public Notebook(
+      ZeppelinConfiguration conf,
+      NotebookRepo notebookRepo,
+      InterpreterFactory replFactory,
+      InterpreterSettingManager interpreterSettingManager,
+      SearchService noteSearchService,
+      NotebookAuthorization notebookAuthorization,
+      Credentials credentials,
+      NoteEventListener noteEventListener)
+      throws IOException, SchedulerException {
+    this(
+        conf,
+        notebookRepo,
+        replFactory,
+        interpreterSettingManager,
+        noteSearchService,
+        notebookAuthorization,
+        credentials);
+    if (null != noteEventListener) {
+      this.noteEventListeners.add(noteEventListener);
+    }
+    this.paragraphJobListener = (ParagraphJobListener) noteEventListener;
+  }
+
   /**
    * This method will be called only NotebookService to register {@link *
    * org.apache.zeppelin.notebook.ParagraphJobListener}.
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
index eda6e10df1..be20cfba43 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
@@ -18,6 +18,7 @@
 package org.apache.zeppelin.notebook.repo;
 
 import com.google.common.collect.Lists;
+import javax.inject.Inject;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.notebook.Note;
@@ -52,6 +53,7 @@
    * @param conf
    */
   @SuppressWarnings("static-access")
+  @Inject
   public NotebookRepoSync(ZeppelinConfiguration conf) throws IOException {
     init(conf);
   }
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
index d04dcd4e65..ebc7ad4df9 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import javax.inject.Inject;
 import org.apache.commons.io.FileUtils;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.TokenStream;
@@ -84,6 +85,7 @@
   private IndexWriterConfig indexWriterConfig;
   private IndexWriter indexWriter;
 
+  @Inject
   public LuceneSearch(ZeppelinConfiguration zeppelinConfiguration) {
     super("LuceneSearch-Thread");
     this.zeppelinConfiguration = zeppelinConfiguration;
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
index 4b57b007c0..763b5fa6d8 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
@@ -50,7 +50,6 @@
   public void setUp() throws Exception {
     super.setUp();
 
-    heliumAppFactory = new HeliumApplicationFactory();
     // set AppEventListener properly
     for (InterpreterSetting interpreterSetting : interpreterSettingManager.get()) {
       interpreterSetting.setAppEventListener(heliumAppFactory);
@@ -59,7 +58,7 @@ public void setUp() throws Exception {
     SearchService search = mock(SearchService.class);
     notebookRepo = mock(NotebookRepo.class);
     NotebookAuthorization notebookAuthorization = NotebookAuthorization.init(conf);
-    notebook =
+    /*notebook =
         new Notebook(
             conf,
             notebookRepo,
@@ -67,10 +66,9 @@ public void setUp() throws Exception {
             interpreterSettingManager,
             search,
             notebookAuthorization,
-            new Credentials(false, null, null));
+            new Credentials(false, null, null));*/
 
-
-    heliumAppFactory.setNotebook(notebook);
+    heliumAppFactory = new HeliumApplicationFactory(notebook, null);
 
     notebook.addNotebookEventListener(heliumAppFactory);
 
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java
index a09fe77f5c..3428c95bf8 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java
@@ -16,62 +16,49 @@
  */
 package org.apache.zeppelin.helium;
 
+import static org.apache.zeppelin.helium.HeliumBundleFactory.HELIUM_LOCAL_REPO;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
 import com.github.eirslett.maven.plugins.frontend.lib.TaskRunnerException;
 import com.google.common.io.Resources;
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.util.LinkedList;
 import java.util.List;
-
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
-
-import static org.junit.Assert.*;
+import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 public class HeliumBundleFactoryTest {
-  private File tmpDir;
-  private ZeppelinConfiguration conf;
   private HeliumBundleFactory hbf;
-  private static File nodeInstallationDir = new File(
-      System.getProperty("java.io.tmpdir") + "/ZeppelinLTest_nodeCache");
-
-  @BeforeClass
-  static public void beforeAll() throws IOException {
-    FileUtils.deleteDirectory(nodeInstallationDir);
-  }
+  private File nodeInstallationDir;
+  private String zeppelinHomePath;
 
   @Before
   public void setUp() throws InstallationException, TaskRunnerException, IOException {
-    tmpDir = new File(System.getProperty("java.io.tmpdir") + "/ZeppelinLTest_" + System.currentTimeMillis());
-    tmpDir.mkdirs();
-
-    // get module dir
-    URL res = Resources.getResource("helium/webpack.config.js");
-    String resDir = new File(res.getFile()).getParent();
-    File moduleDir = new File(resDir + "/../../../../zeppelin-web/src/app/");
+    zeppelinHomePath = System.getProperty(ConfVars.ZEPPELIN_HOME.getVarName());
+    System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), "../");
 
-    conf = new ZeppelinConfiguration();
-
-    hbf = new HeliumBundleFactory(conf,
-        nodeInstallationDir,
-        tmpDir,
-        new File(moduleDir, "tabledata"),
-        new File(moduleDir, "visualization"),
-        new File(moduleDir, "spell"));
+    ZeppelinConfiguration conf = ZeppelinConfiguration.create();
+    nodeInstallationDir =
+        new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO), HELIUM_LOCAL_REPO);
+    hbf = new HeliumBundleFactory(conf);
     hbf.installNodeAndNpm();
     hbf.copyFrameworkModulesToInstallPath(true);
   }
 
   @After
   public void tearDown() throws IOException {
-    FileUtils.deleteDirectory(tmpDir);
+    if (null != zeppelinHomePath) {
+      System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), zeppelinHomePath);
+    }
   }
 
   @Test
@@ -83,33 +70,33 @@ public void testInstallNpm() throws InstallationException {
 
   @Test
   public void downloadPackage() throws TaskRunnerException {
-    HeliumPackage pkg = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "lodash",
-        "lodash",
-        "lodash@3.9.3",
-        "",
-        null,
-        "license",
-        "icon"
-    );
+    HeliumPackage pkg =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "lodash",
+            "lodash",
+            "lodash@3.9.3",
+            "",
+            null,
+            "license",
+            "icon");
     hbf.install(pkg);
-    assertTrue(new File(tmpDir,
-        HeliumBundleFactory.HELIUM_LOCAL_REPO + "/node_modules/lodash").isDirectory());
+    System.out.println(new File(nodeInstallationDir, "/node_modules/lodash"));
+    assertTrue(new File(nodeInstallationDir, "/node_modules/lodash").isDirectory());
   }
 
   @Test
   public void bundlePackage() throws IOException, TaskRunnerException {
-    HeliumPackage pkg = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart@0.0.3",
-        "",
-        null,
-        "license",
-        "icon"
-    );
+    HeliumPackage pkg =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart@0.0.3",
+            "",
+            null,
+            "license",
+            "icon");
     File bundle = hbf.buildPackage(pkg, true, true);
     assertTrue(bundle.isFile());
     long lastModified = bundle.lastModified();
@@ -125,37 +112,37 @@ public void bundleLocalPackage() throws IOException, TaskRunnerException {
     String resDir = new File(res.getFile()).getParent();
     String localPkg = resDir + "/../../../src/test/resources/helium/vis1";
 
-    HeliumPackage pkg = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "vis1",
-        "vis1",
-        localPkg,
-        "",
-        null,
-        "license",
-        "fa fa-coffee"
-    );
+    HeliumPackage pkg =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "vis1",
+            "vis1",
+            localPkg,
+            "",
+            null,
+            "license",
+            "fa fa-coffee");
     File bundle = hbf.buildPackage(pkg, true, true);
     assertTrue(bundle.isFile());
   }
 
-  //TODO(zjffdu) Ignore flaky test, enable it later after fixing this flaky test
-  //@Test
+  // TODO(zjffdu) Ignore flaky test, enable it later after fixing this flaky test
+  // @Test
   public void bundleErrorPropagation() throws IOException, TaskRunnerException {
     URL res = Resources.getResource("helium/webpack.config.js");
     String resDir = new File(res.getFile()).getParent();
     String localPkg = resDir + "/../../../src/test/resources/helium/vis2";
 
-    HeliumPackage pkg = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "vis2",
-        "vis2",
-        localPkg,
-        "",
-        null,
-        "license",
-        "fa fa-coffee"
-    );
+    HeliumPackage pkg =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "vis2",
+            "vis2",
+            localPkg,
+            "",
+            null,
+            "license",
+            "fa fa-coffee");
     File bundle = null;
     try {
       bundle = hbf.buildPackage(pkg, true, true);
@@ -172,27 +159,27 @@ public void switchVersion() throws IOException, TaskRunnerException {
     URL res = Resources.getResource("helium/webpack.config.js");
     String resDir = new File(res.getFile()).getParent();
 
-    HeliumPackage pkgV1 = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart@0.0.3",
-        "",
-        null,
-        "license",
-        "icon"
-    );
-
-    HeliumPackage pkgV2 = new HeliumPackage(
-        HeliumType.VISUALIZATION,
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart",
-        "zeppelin-bubblechart@0.0.1",
-        "",
-        null,
-        "license",
-        "icon"
-    );
+    HeliumPackage pkgV1 =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart@0.0.3",
+            "",
+            null,
+            "license",
+            "icon");
+
+    HeliumPackage pkgV2 =
+        new HeliumPackage(
+            HeliumType.VISUALIZATION,
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart",
+            "zeppelin-bubblechart@0.0.1",
+            "",
+            null,
+            "license",
+            "icon");
     List<HeliumPackage> pkgsV1 = new LinkedList<>();
     pkgsV1.add(pkgV1);
 
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 4e2d95a02c..e3ce1aa0f5 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
@@ -94,7 +94,7 @@ public void setUp() throws Exception {
     notebookAuthorization = NotebookAuthorization.init(conf);
     credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath(), null);
     notebook = new Notebook(conf, notebookRepo, interpreterFactory, interpreterSettingManager, search,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
     notebook.setParagraphJobListener(this);
 
   }
@@ -112,13 +112,13 @@ public void testRevisionSupported() throws IOException, SchedulerException {
     notebookRepo = new DummyNotebookRepo();
     notebook = new Notebook(conf, notebookRepo, interpreterFactory,
         interpreterSettingManager, null,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
     assertFalse("Revision is not supported in DummyNotebookRepo", notebook.isRevisionSupported());
 
     notebookRepo = new DummyNotebookRepoWithVersionControl();
     notebook = new Notebook(conf, notebookRepo, interpreterFactory,
         interpreterSettingManager, null,
-        notebookAuthorization, credentials);
+        notebookAuthorization, credentials, null);
     assertTrue("Revision is supported in DummyNotebookRepoWithVersionControl",
         notebook.isRevisionSupported());
   }
@@ -372,12 +372,12 @@ public void testPersist() throws IOException, SchedulerException {
     p1.setText("hello world");
     notebook.saveNote(note, anonymous);
 
-    Notebook notebook2 = new Notebook(
-        conf, notebookRepo,
-        new InterpreterFactory(interpreterSettingManager),
-        interpreterSettingManager, null, null, null);
+//    Notebook notebook2 = new Notebook(
+//        conf, notebookRepo,
+//        new InterpreterFactory(interpreterSettingManager),
+//        interpreterSettingManager, null, null, null);
 
-    assertEquals(1, notebook2.getAllNotes().size());
+    //assertEquals(1, notebook2.getAllNotes().size());
     notebook.removeNote(note.getId(), anonymous);
   }
 
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/search/LuceneSearchTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/search/LuceneSearchTest.java
index 0c5bf6c717..5ac09a685d 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/search/LuceneSearchTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/search/LuceneSearchTest.java
@@ -23,8 +23,6 @@
 
 import com.google.common.base.Splitter;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
@@ -32,17 +30,14 @@
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
 import org.apache.zeppelin.notebook.Note;
-import org.apache.zeppelin.notebook.NoteEventListener;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
 import org.apache.zeppelin.notebook.Paragraph;
-import org.apache.zeppelin.notebook.ParagraphJobListener;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.user.AuthenticationInfo;
 import org.apache.zeppelin.user.Credentials;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.quartz.SchedulerException;
 
@@ -63,7 +58,7 @@ public void startUp() throws IOException, SchedulerException {
     notebook = new Notebook(ZeppelinConfiguration.create(), mock(NotebookRepo.class),
         mock(InterpreterFactory.class), interpreterSettingManager,
         noteSearchService, mock(NotebookAuthorization.class),
-        mock(Credentials.class));
+        mock(Credentials.class), null);
   }
 
   @After


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services