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

zeppelin git commit: ZEPPELIN-3179. Improve error message when IPython is not available

Repository: zeppelin
Updated Branches:
  refs/heads/master 36d726d6d -> 8ad8c7da6


ZEPPELIN-3179. Improve error message when IPython is not available

### What is this PR for?
Minor change to improve the error message when IPython is not available. See the following screenshot.

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

### Todos
* [ ] - Task

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-3179

### How should this be tested?
* Manually
![screen shot 2018-01-20 at 5 00 25 pm](https://user-images.githubusercontent.com/164491/35190572-baec39a6-fe9f-11e7-9f8c-f92f8ed01d38.png)
![screen shot 2018-01-20 at 5 00 19 pm](https://user-images.githubusercontent.com/164491/35190573-bb169890-fe9f-11e7-9702-9998485e4899.png)

 verified

### Screenshots (if appropriate)

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

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

Closes #2736 from zjffdu/ZEPPELIN-3179 and squashes the following commits:

0157e27 [Jeff Zhang] ZEPPELIN-3179. Improve error message when IPython is not available


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

Branch: refs/heads/master
Commit: 8ad8c7da6181b7a91f6c89c9927a71619f4ea619
Parents: 36d726d
Author: Jeff Zhang <zj...@apache.org>
Authored: Sat Jan 20 17:02:44 2018 +0800
Committer: Jeff Zhang <zj...@apache.org>
Committed: Wed Jan 24 11:30:03 2018 +0800

----------------------------------------------------------------------
 .../zeppelin/python/IPythonInterpreter.java     | 40 ++++++++++++--------
 .../zeppelin/python/PythonInterpreter.java      |  3 +-
 .../zeppelin/spark/PySparkInterpreter.java      |  3 +-
 3 files changed, 28 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/8ad8c7da/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
----------------------------------------------------------------------
diff --git a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
index 5ae03f0..bd687be 100644
--- a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
@@ -25,9 +25,11 @@ import org.apache.commons.exec.ExecuteWatchdog;
 import org.apache.commons.exec.LogOutputStream;
 import org.apache.commons.exec.PumpStreamHandler;
 import org.apache.commons.exec.environment.EnvironmentUtils;
+import org.apache.commons.httpclient.util.ExceptionUtil;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterContext;
 import org.apache.zeppelin.interpreter.InterpreterException;
@@ -121,7 +123,11 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
       }
       pythonExecutable = getProperty("zeppelin.python", "python");
       LOGGER.info("Python Exec: " + pythonExecutable);
-
+      String checkPrerequisiteResult = checkIPythonPrerequisite(pythonExecutable);
+      if (!StringUtils.isEmpty(checkPrerequisiteResult)) {
+        throw new InterpreterException("IPython prerequisite is not meet: " +
+            checkPrerequisiteResult);
+      }
       ipythonLaunchTimeout = Long.parseLong(
           getProperty("zeppelin.ipython.launch.timeout", "30000"));
       this.zeppelinContext = new PythonZeppelinContext(
@@ -139,8 +145,15 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
     }
   }
 
-  public boolean checkIPythonPrerequisite() {
-    ProcessBuilder processBuilder = new ProcessBuilder("pip", "freeze");
+  /**
+   * non-empty return value mean the errors when checking ipython prerequisite.
+   * empty value mean IPython prerequisite is meet.
+   * 
+   * @param pythonExec
+   * @return
+   */
+  public String checkIPythonPrerequisite(String pythonExec) {
+    ProcessBuilder processBuilder = new ProcessBuilder(pythonExec, "-m", "pip", "freeze");
     try {
       File stderrFile = File.createTempFile("zeppelin", ".txt");
       processBuilder.redirectError(stderrFile);
@@ -150,33 +163,28 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
       Process proc = processBuilder.start();
       int ret = proc.waitFor();
       if (ret != 0) {
-        LOGGER.warn("Fail to run pip freeze.\n" +
-            IOUtils.toString(new FileInputStream(stderrFile)));
-        return false;
+        return "Fail to run pip freeze.\n" +
+            IOUtils.toString(new FileInputStream(stderrFile));
       }
       String freezeOutput = IOUtils.toString(new FileInputStream(stdoutFile));
       if (!freezeOutput.contains("jupyter-client=")) {
-        InterpreterContext.get().out.write("jupyter-client is not installed\n".getBytes());
-        return false;
+        return "jupyter-client is not installed.";
       }
       if (!freezeOutput.contains("ipykernel=")) {
-        InterpreterContext.get().out.write("ipkernel is not installed\n".getBytes());
-        return false;
+        return "ipkernel is not installed";
       }
       if (!freezeOutput.contains("ipython=")) {
-        InterpreterContext.get().out.write("ipython is not installed\n".getBytes());
-        return false;
+        return "ipython is not installed";
       }
       if (!freezeOutput.contains("grpcio=")) {
-        InterpreterContext.get().out.write("grpcio is not installed\n".getBytes());
-        return false;
+        return "grpcio is not installed";
       }
       LOGGER.info("IPython prerequisite is meet");
-      return true;
     } catch (Exception e) {
       LOGGER.warn("Fail to checkIPythonPrerequisite", e);
-      return false;
+      return "Fail to checkIPythonPrerequisite: " + ExceptionUtils.getStackTrace(e);
     }
+    return "";
   }
 
   private void setupJVMGateway(int jvmGatewayPort) throws IOException {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/8ad8c7da/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
----------------------------------------------------------------------
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
index 051e1fa..b13cb8a 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
@@ -44,6 +44,7 @@ import org.apache.commons.exec.ExecuteWatchdog;
 import org.apache.commons.exec.PumpStreamHandler;
 import org.apache.commons.exec.environment.EnvironmentUtils;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.display.GUI;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.InterpreterResult.Code;
@@ -228,7 +229,7 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
         getInterpreterGroup().getInterpreterHookRegistry(),
         Integer.parseInt(getProperty("zeppelin.python.maxResult", "1000")));
     if (getProperty("zeppelin.python.useIPython", "true").equals("true") &&
-      iPythonInterpreter.checkIPythonPrerequisite()) {
+        StringUtils.isEmpty(iPythonInterpreter.checkIPythonPrerequisite(getPythonBindPath()))) {
       try {
         iPythonInterpreter.open();
         if (InterpreterContext.get() != null) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/8ad8c7da/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
----------------------------------------------------------------------
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
index 21a1649..47ffe14 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
@@ -116,7 +116,8 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
     // try IPySparkInterpreter first
     iPySparkInterpreter = getIPySparkInterpreter();
     if (getProperty("zeppelin.pyspark.useIPython", "true").equals("true") &&
-        iPySparkInterpreter.checkIPythonPrerequisite()) {
+        StringUtils.isEmpty(
+            iPySparkInterpreter.checkIPythonPrerequisite(getPythonExec(getProperties())))) {
       try {
         iPySparkInterpreter.open();
         if (InterpreterContext.get() != null) {