Repository: zeppelin
Updated Branches:
refs/heads/master 89cf8262e -> c484619d1
[ZEPPELIN-1482] Load updated dependency library on interpreter restart
### What is this PR for?
If user specifies library path in interpreter dependency setting, even when the
file on this path is updated, new file doesn't take effect on interpreter
_restart_ but does only when user _clicks Edit -> Save._
The mechanism of dependency loading is copying all dependency libraries under
`local-repo/
{interpreterId}` and add these directory to classpath of interpreter process.
Zeppelin copies these dependencies either on Zeppelin startup or dependency
saving/editing.
This PR checks if the library on specified local path is updated, and copy them
to `local-repo/
{interpreterId}` on restart if there is change.
### What type of PR is it?
Bug Fix & Improvement
### What is the Jira issue?
[ZEPPELIN-1482](https://issues.apache.org/jira/browse/ZEPPELIN-1482)
### How should this be tested?
1. Download commons-csv-1.1.jar and commons-csv-1.2.jar to /my/path
2. cp commons-csv-1.2.jar /my/path/commons-csv.jar
3. Set dependency artifact of spark interpreter to /my/path/commons-csv.jar
4. Run `%spark import org.apache.commons.csv.CSVFormat.Predefined` in paragraph
and see if it runs without error
5. cp commons-csv-1.1.jar /my/path/commons-csv.jar
6. Restart spark interpreter
7. Run `%spark import org.apache.commons.csv.CSVFormat.Predefined` in paragraph
and see if error occurs.
### Questions:
* Does the licenses files need update? no
* Is there breaking changes for older versions? no
* Does this needs documentation? no
Author: Mina Lee <[email protected]>
Closes #1453 from minahlee/ZEPPELIN-1482 and squashes the following commits:
ea11664 [Mina Lee] Check if dependency library on specified path has changed
and copy them under local-repo/{interpreterId} on interpreter restart
Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/c484619d
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/c484619d
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/c484619d
Branch: refs/heads/master
Commit: c484619d19f53fb522a9cb5a05c83192f49961e4
Parents: 89cf826
Author: Mina Lee <[email protected]>
Authored: Fri Sep 23 19:29:21 2016 +0900
Committer: Mina Lee <[email protected]>
Committed: Tue Sep 27 10:39:54 2016 +0900
----------------------------------------------------------------------
.../apache/zeppelin/dep/DependencyResolver.java | 15 ++++++
.../interpreter/InterpreterFactory.java | 50 ++++++++++++++++++--
2 files changed, 61 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/c484619d/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/DependencyResolver.java
----------------------------------------------------------------------
diff --git
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/DependencyResolver.java
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/DependencyResolver.java
index 214175a..87d9178 100644
---
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/DependencyResolver.java
+++
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/dep/DependencyResolver.java
@@ -104,6 +104,21 @@ public class DependencyResolver extends
AbstractDependencyResolver {
return libs;
}
+ public synchronized void copyLocalDependency(String srcPath, File destPath)
+ throws IOException {
+ if (StringUtils.isBlank(srcPath)) {
+ return;
+ }
+
+ File srcFile = new File(srcPath);
+ File destFile = new File(destPath, srcFile.getName());
+
+ if (!destFile.exists() || !FileUtils.contentEquals(srcFile, destFile)) {
+ FileUtils.copyFile(srcFile, destFile);
+ logger.info("copy {} to {}", srcFile.getAbsolutePath(), destPath);
+ }
+ }
+
private List<File> loadFromMvn(String artifact, Collection<String> excludes)
throws RepositoryException {
Collection<String> allExclusions = new LinkedList<String>();
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/c484619d/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
----------------------------------------------------------------------
diff --git
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
index 40dcc30..58adb48 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
@@ -197,10 +197,10 @@ public class InterpreterFactory implements
InterpreterGroupFactory {
Set<String> interpreterKeys =
Interpreter.registeredInterpreters.keySet();
for (String interpreterKey : interpreterKeys) {
if (className
-
.equals(Interpreter.registeredInterpreters.get(interpreterKey)
- .getClassName())) {
+
.equals(Interpreter.registeredInterpreters.get(interpreterKey)
+ .getClassName())) {
Interpreter.registeredInterpreters.get(interpreterKey)
- .setPath(interpreterDirString);
+ .setPath(interpreterDirString);
logger.info("Interpreter " + interpreterKey + " found.
class=" + className);
cleanCl.put(interpreterDirString, ccl);
}
@@ -431,7 +431,6 @@ public class InterpreterFactory implements
InterpreterGroupFactory {
}
private void loadInterpreterDependencies(final InterpreterSetting setting) {
-
setting.setStatus(InterpreterSetting.Status.DOWNLOADING_DEPENDENCIES);
interpreterSettings.put(setting.getId(), setting);
synchronized (interpreterSettings) {
@@ -477,6 +476,46 @@ public class InterpreterFactory implements
InterpreterGroupFactory {
}
}
+ /**
+ * Overwrite dependency jar under local-repo/{interpreterId}
+ * if jar file in original path is changed
+ */
+ private void copyDependenciesFromLocalPath(final InterpreterSetting setting)
{
+ setting.setStatus(InterpreterSetting.Status.DOWNLOADING_DEPENDENCIES);
+ interpreterSettings.put(setting.getId(), setting);
+ synchronized (interpreterSettings) {
+ final Thread t = new Thread() {
+ public void run() {
+ try {
+ List<Dependency> deps = setting.getDependencies();
+ if (deps != null) {
+ for (Dependency d : deps) {
+ File destDir = new
File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO));
+
+ int numSplits = d.getGroupArtifactVersion().split(":").length;
+ if (!(numSplits >= 3 && numSplits <= 6)) {
+ depResolver.copyLocalDependency(d.getGroupArtifactVersion(),
+ new File(destDir, setting.getId()));
+ }
+ }
+ }
+ setting.setStatus(InterpreterSetting.Status.READY);
+ } catch (Exception e) {
+ logger.error(String.format("Error while copying deps for
interpreter group : %s," +
+ " go to interpreter setting page click on edit and save it
again to make " +
+ "this interpreter work properly.",
+ setting.getGroup()), e);
+ setting.setErrorReason(e.getLocalizedMessage());
+ setting.setStatus(InterpreterSetting.Status.ERROR);
+ } finally {
+ interpreterSettings.put(setting.getId(), setting);
+ }
+ }
+ };
+ t.start();
+ }
+ }
+
private void saveToFile() throws IOException {
String jsonString;
@@ -900,6 +939,9 @@ public class InterpreterFactory implements
InterpreterGroupFactory {
public void restart(String id) {
synchronized (interpreterSettings) {
InterpreterSetting intpsetting = interpreterSettings.get(id);
+ // Check if dependency in specified path is changed
+ // If it did, overwrite old dependency jar with new one
+ copyDependenciesFromLocalPath(intpsetting);
if (intpsetting != null) {
stopJobAllInterpreter(intpsetting);