Skip to content

Conversation

@Leemoonsoo
Copy link
Contributor

Running interpreter in separate process discussed in #278 and mailinglist. @bzz made PoC of it https://github.com/bzz/zeppelin-multiprocess-interpreter-poc

This PR implements #278 using thrift.

  • make zeppelin-interpreter submodule to minimize separate interpreter process's own dependency.
  • shell script for run interpreter process bin/interpreter.sh
  • thrift IDL(zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift) and server/client implementation for communication with interpreter process.
  • make client connection pool
  • scheduler in remote process
  • correctly handle output
  • take care of dynamic form
  • handle some exceptional cases. make test
  • separate environment variable for interpreter process
  • user interface to enable remote process option
  • documentation
  • remote scheduler

@swkimme
Copy link
Contributor

swkimme commented Feb 27, 2015

I've failed to launch Zeppelin in this branch. Attaching log.

==> ./logs/zeppelin-swkim-SangWoos-MacBook-Pro.local.out <==
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/swkim/Documents/zeppelin/zeppelin-server/target/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/swkim/Documents/zeppelin/zeppelin-zengine/target/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/swkim/Documents/zeppelin/zeppelin-interpreter/target/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

==> ./logs/zeppelin-swkim-SangWoos-MacBook-Pro.local.log <==
WARN [2015-02-27 15:22:47,417]({main} ZeppelinConfiguration.java[create]:76) - Failed to load configuration, proceeding with a default
INFO [2015-02-27 15:22:47,593]({main} NotebookServer.java[creatingwebSocketServerLog]:41) - Create zeppelin websocket on port 8081
INFO [2015-02-27 15:22:47,826]({main} ZeppelinServer.java[main]:82) - Start zeppelin server
INFO [2015-02-27 15:22:47,830]({main} Server.java[doStart]:272) - jetty-8.1.14.v20131031
INFO [2015-02-27 15:22:48,257]({main} InterpreterFactory.java[init]:79) - Reading /Users/swkim/Documents/zeppelin/interpreter/md
INFO [2015-02-27 15:22:48,266]({main} InterpreterFactory.java[init]:96) - Interpreter md found. class=com.nflabs.zeppelin.markdown.Markdown
INFO [2015-02-27 15:22:48,266]({main} InterpreterFactory.java[init]:79) - Reading /Users/swkim/Documents/zeppelin/interpreter/sh
INFO [2015-02-27 15:22:48,278]({main} InterpreterFactory.java[init]:96) - Interpreter sh found. class=com.nflabs.zeppelin.shell.ShellInterpreter
INFO [2015-02-27 15:22:48,278]({main} InterpreterFactory.java[init]:79) - Reading /Users/swkim/Documents/zeppelin/interpreter/spark
INFO [2015-02-27 15:22:48,379]({main} InterpreterFactory.java[init]:96) - Interpreter spark found. class=com.nflabs.zeppelin.spark.SparkInterpreter
INFO [2015-02-27 15:22:48,389]({main} InterpreterFactory.java[init]:96) - Interpreter sql found. class=com.nflabs.zeppelin.spark.SparkSqlInterpreter
INFO [2015-02-27 15:22:48,393]({main} InterpreterFactory.java[init]:96) - Interpreter dep found. class=com.nflabs.zeppelin.spark.DepInterpreter
INFO [2015-02-27 15:22:48,415]({main} InterpreterFactory.java[createRepl]:503) - Create repl com.nflabs.zeppelin.shell.ShellInterpreter from /Users/swkim/Documents/zeppelin/interpreter/sh
INFO [2015-02-27 15:22:48,418]({main} InterpreterFactory.java[createRepl]:503) - Create repl com.nflabs.zeppelin.spark.SparkInterpreter from /Users/swkim/Documents/zeppelin/interpreter/spark
INFO [2015-02-27 15:22:48,423]({main} InterpreterFactory.java[createRepl]:503) - Create repl com.nflabs.zeppelin.spark.SparkSqlInterpreter from /Users/swkim/Documents/zeppelin/interpreter/spark
INFO [2015-02-27 15:22:48,424]({main} InterpreterFactory.java[createRepl]:503) - Create repl com.nflabs.zeppelin.spark.DepInterpreter from /Users/swkim/Documents/zeppelin/interpreter/spark
INFO [2015-02-27 15:22:48,427]({main} InterpreterFactory.java[createRepl]:503) - Create repl com.nflabs.zeppelin.markdown.Markdown from /Users/swkim/Documents/zeppelin/interpreter/md
INFO [2015-02-27 15:22:48,428]({main} InterpreterFactory.java[init]:154) - Interpreter setting group sh : id=2AHXRKVFG, name=sh
INFO [2015-02-27 15:22:48,428]({main} InterpreterFactory.java[init]:157) - className = com.nflabs.zeppelin.shell.ShellInterpreter
INFO [2015-02-27 15:22:48,428]({main} InterpreterFactory.java[init]:154) - Interpreter setting group spark : id=2AH9MEKF8, name=spark
INFO [2015-02-27 15:22:48,428]({main} InterpreterFactory.java[init]:157) - className = com.nflabs.zeppelin.spark.SparkInterpreter
INFO [2015-02-27 15:22:48,429]({main} InterpreterFactory.java[init]:157) - className = com.nflabs.zeppelin.spark.SparkSqlInterpreter
INFO [2015-02-27 15:22:48,429]({main} InterpreterFactory.java[init]:157) - className = com.nflabs.zeppelin.spark.DepInterpreter
INFO [2015-02-27 15:22:48,429]({main} InterpreterFactory.java[init]:154) - Interpreter setting group md : id=2AFTTP29X, name=md
INFO [2015-02-27 15:22:48,429]({main} InterpreterFactory.java[init]:157) - className = com.nflabs.zeppelin.markdown.Markdown
INFO [2015-02-27 15:22:48,463]({main} StdSchedulerFactory.java[instantiate]:1184) - Using default implementation for ThreadExecutor
INFO [2015-02-27 15:22:48,466]({main} SimpleThreadPool.java[initialize]:268) - Job execution threads will use class loader of thread: main
INFO [2015-02-27 15:22:48,481]({main} SchedulerSignalerImpl.java[]:61) - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
INFO [2015-02-27 15:22:48,482]({main} QuartzScheduler.java[]:240) - Quartz Scheduler v.2.2.1 created.
INFO [2015-02-27 15:22:48,483]({main} RAMJobStore.java[initialize]:155) - RAMJobStore initialized.
INFO [2015-02-27 15:22:48,484]({main} QuartzScheduler.java[initialize]:305) - Scheduler meta-data: Quartz Scheduler (v2.2.1) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

INFO [2015-02-27 15:22:48,484]({main} StdSchedulerFactory.java[instantiate]:1339) - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
INFO [2015-02-27 15:22:48,484]({main} StdSchedulerFactory.java[instantiate]:1343) - Quartz scheduler version: 2.2.1
INFO [2015-02-27 15:22:48,485]({main} QuartzScheduler.java[start]:575) - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
INFO [2015-02-27 15:22:48,696]({main} ServerImpl.java[initDestination]:94) - Setting the server's publish address to be /
INFO [2015-02-27 15:22:48,853]({main} StandardDescriptorProcessor.java[visitServlet]:284) - NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet

==> ./logs/zeppelin-swkim-SangWoos-MacBook-Pro.local.out <==
Feb 27, 2015 3:22:48 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.nflabs.zeppelin.rest
com.wordnik.swagger.jersey.listing
Feb 27, 2015 3:22:48 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.nflabs.zeppelin.rest.InterpreterRestApi
class com.wordnik.swagger.jersey.listing.ApiListingResourceJSON
class com.nflabs.zeppelin.rest.NotebookRestApi
class com.nflabs.zeppelin.rest.ZeppelinRestApi
Feb 27, 2015 3:22:48 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Provider classes found:
class com.wordnik.swagger.jersey.listing.JerseyResourceListingProvider
class com.wordnik.swagger.jersey.listing.JerseyApiDeclarationProvider
Feb 27, 2015 3:22:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.9 09/02/2011 11:17 AM'
Feb 27, 2015 3:22:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Adding the following classes declared in META-INF/services/jersey-server-components to the resource configuration:
class org.atmosphere.jersey.AtmosphereResourceConfigurator
Feb 27, 2015 3:22:49 PM com.sun.jersey.spi.inject.Errors processErrorMessages
WARNING: The following warnings have been detected with resource and/or provider classes:
WARNING: A HTTP GET method, public javax.ws.rs.core.Response com.nflabs.zeppelin.rest.InterpreterRestApi.listInterpreter(java.lang.String), should not consume any entity.

==> ./logs/zeppelin-swkim-SangWoos-MacBook-Pro.local.log <==
INFO [2015-02-27 15:22:49,802]({main} StandardDescriptorProcessor.java[visitServlet]:284) - NO JSP Support for /docs, did not find org.apache.jasper.servlet.JspServlet
INFO [2015-02-27 15:22:49,809]({main} AbstractConnector.java[doStart]:338) - Started SocketConnector@0.0.0.0:8080
INFO [2015-02-27 15:22:49,809]({main} ZeppelinServer.java[main]:84) - Started
INFO [2015-02-27 15:22:49,810]({Thread-20} ZeppelinServer.java[run]:88) - Shutting down Zeppelin Server ...
INFO [2015-02-27 15:22:49,822]({Thread-20} ELContextCleaner.java[contextDestroyed]:63) - javax.el.BeanELResolver purged
INFO [2015-02-27 15:22:49,823]({Thread-20} ContextHandler.java[doStop]:843) - stopped o.e.j.w.WebAppContext{/docs,file:/Users/swkim/Documents/zeppelin/zeppelin-docs/target/zeppelin-api-ui/},/Users/swkim/Documents/zeppelin/zeppelin-docs/target/zeppelin-api-ui.war
INFO [2015-02-27 15:22:49,824]({Thread-20} ELContextCleaner.java[contextDestroyed]:63) - javax.el.BeanELResolver purged
INFO [2015-02-27 15:22:49,824]({Thread-20} ContextHandler.java[doStop]:843) - stopped o.e.j.w.WebAppContext{/,file:/Users/swkim/Documents/zeppelin/zeppelin-web/src/main/webapp/}
INFO [2015-02-27 15:22:49,826]({Thread-20} ContextHandler.java[doStop]:843) - stopped o.e.j.s.ServletContextHandler{/api,null}
INFO [2015-02-27 15:22:49,826]({Thread-20} ContextHandler.java[doStop]:843) - stopped o.e.j.s.ServletContextHandler{/,null}
INFO [2015-02-27 15:22:49,880]({Thread-20} ZeppelinServer.java[run]:97) - Bye

@Leemoonsoo
Copy link
Contributor Author

@swkimme I've pushed a fix.
FYI, until it get's user interface implemented, to turn this feature on,
you should manually modify the code (InterpreterFactory.java, Line 337) from

intp = createRepl(info.getPath(),

to

intp = createRemoteRepl(info.getPath(),

, to test this branch. (it results all interpreter run in separate process. After GUI implemented, it'll be able to selectively turn on/off)

@swkimme
Copy link
Contributor

swkimme commented Feb 27, 2015

Now it works!
Let me test more complicated codes.

@Leemoonsoo
Copy link
Contributor Author

I have added gui to control this feature. Check on 'fork' launch interpreter in separate process, in 'interpreter' page.

image

Don't need modify InterpreterFactory.java, Line 337 manually, anymore, to try this branch.

@swkimme
Copy link
Contributor

swkimme commented Mar 1, 2015

I got exception while running %dep

com.nflabs.zeppelin.interpreter.remote.RemoteInterpreter.getFormType(RemoteInterpreter.java:201) 
com.nflabs.zeppelin.interpreter.LazyOpenInterpreter.getFormType(LazyOpenInterpreter.java:84) 
com.nflabs.zeppelin.notebook.Paragraph.jobRun(Paragraph.java:173) 
com.nflabs.zeppelin.scheduler.Job.run(Job.java:147) 
com.nflabs.zeppelin.scheduler.ParallelScheduler$JobRunner.run(ParallelScheduler.java:110) 
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
java.util.concurrent.FutureTask.run(FutureTask.java:262) 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
java.lang.Thread.run(Thread.java:745)

@swkimme
Copy link
Contributor

swkimme commented Mar 1, 2015

Also got similar exception while running a simple paragraph in spark local mode.

com.nflabs.zeppelin.interpreter.remote.RemoteInterpreter.open(RemoteInterpreter.java:91) 
com.nflabs.zeppelin.interpreter.LazyOpenInterpreter.open(LazyOpenInterpreter.java:52) 
com.nflabs.zeppelin.interpreter.LazyOpenInterpreter.getFormType(LazyOpenInterpreter.java:83) 
com.nflabs.zeppelin.notebook.Paragraph.jobRun(Paragraph.java:173) 
com.nflabs.zeppelin.scheduler.Job.run(Job.java:147) 
com.nflabs.zeppelin.scheduler.ParallelScheduler$JobRunner.run(ParallelScheduler.java:110) 
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
java.util.concurrent.FutureTask.run(FutureTask.java:262) 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
java.lang.Thread.run(Thread.java:745)


com.nflabs.zeppelin.interpreter.InterpreterException: com.nflabs.zeppelin.interpreter.InterpreterException: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused
    at com.nflabs.zeppelin.interpreter.remote.RemoteInterpreter.open(RemoteInterpreter.java:91)
    at com.nflabs.zeppelin.interpreter.LazyOpenInterpreter.open(LazyOpenInterpreter.java:52)
    at com.nflabs.zeppelin.interpreter.LazyOpenInterpreter.getFormType(LazyOpenInterpreter.java:83)
    at com.nflabs.zeppelin.notebook.Paragraph.jobRun(Paragraph.java:173)
    at com.nflabs.zeppelin.scheduler.Job.run(Job.java:147)
    at com.nflabs.zeppelin.scheduler.ParallelScheduler$JobRunner.run(ParallelScheduler.java:110)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.nflabs.zeppelin.interpreter.InterpreterException: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused
    at com.nflabs.zeppelin.interpreter.remote.ClientFactory.create(ClientFactory.java:37)
    at com.nflabs.zeppelin.interpreter.remote.ClientFactory.create(ClientFactory.java:21)
    at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:60)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:861)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
    at com.nflabs.zeppelin.interpreter.remote.RemoteInterpreterProcess.getClient(RemoteInterpreterProcess.java:114)
    at com.nflabs.zeppelin.interpreter.remote.RemoteInterpreter.open(RemoteInterpreter.java:89)
    ... 12 more
Caused by: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused
    at org.apache.thrift.transport.TSocket.open(TSocket.java:185)
    at com.nflabs.zeppelin.interpreter.remote.ClientFactory.create(ClientFactory.java:35)
    ... 19 more
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:579)
    at org.apache.thrift.transport.TSocket.open(TSocket.java:180)
    ... 20 more

@swkimme
Copy link
Contributor

swkimme commented Mar 2, 2015

I tested this branch,
Works well in overall except the issues I posted above.

@Leemoonsoo
Copy link
Contributor Author

@swkimme I think i fixed exception related to getFormType().

@swkimme
Copy link
Contributor

swkimme commented Mar 11, 2015

@swkimme
Copy link
Contributor

swkimme commented Mar 11, 2015

The issue still exists in Spark 1.3.

@swkimme
Copy link
Contributor

swkimme commented Mar 12, 2015

Created an issue for it.
https://issues.apache.org/jira/browse/SPARK-6299

@Leemoonsoo
Copy link
Contributor Author

Ready to be merged. Please review and test.

This PR resolves classloader issue by separating JVM process. The issues was blocking support for Spark 1.2.x. I'm running this branch with some spark 1.2.1 clusters and everything looks fine to me.

Changes

  • New submodule (artifact) and package moved
    zeppelin-interpreter submodule is created.
    Interpreter class (which is base class to develop new interpreter) moved to 'zeppelin-interpreter' from 'zeppelin-zengine'.
  • Interpreter API changes
    public abstract Object getValue(String name);
    public abstract void bindValue(String name, Object o);
    are removed from Interpreter class
  • 'Fork' option is added
    Fork option is added in interpreter setting, to enable/disable separate interpreter process.
  • Launch script added
    launch script for separate JVM process added in bin/interpreter.sh

@swkimme
Copy link
Contributor

swkimme commented Mar 12, 2015

@Leemoonsoo
Do we need 'fork' option, tough doing fork is default?

@Leemoonsoo
Copy link
Contributor Author

@swkimme
What do you think? Will it be better it always fork without providing option?

@swkimme
Copy link
Contributor

swkimme commented Mar 12, 2015

@Leemoonsoo
Definitely it is. Is there any expected problem when we remove option and making it always fork?

@Leemoonsoo
Copy link
Contributor Author

@swkimme No problem. I'll update the code to not show 'fork' option.

@Leemoonsoo
Copy link
Contributor Author

@swkimme I've removed fork option.

@swkimme
Copy link
Contributor

swkimme commented Mar 13, 2015

LGTM and tested with complex codes, works great.

@Leemoonsoo
Copy link
Contributor Author

I'm merging this PR if there're no more discussions!

@jongyoul
Copy link
Contributor

@Leemoonsoo This PR doesn't pass ZEPPELIN_JAVA_OPTS. I have a ZEPPELIN_JAVA_OPTS="-Dspark.io.compress.codec=lzf". This is configured on ZeppelinServer but spark doesn't read this. I'm debugging now.

@jongyoul
Copy link
Contributor

@Leemoonsoo Unlikely from zeppelin-daemon.sh, interpreter.sh launches interpreter without JAVA_OPTS. Please add this when Z executes remoteInterpreter.

@Leemoonsoo
Copy link
Contributor Author

@jongyoul Thanks for the feedback. I just pushed a fix.

The problem was because of ZEPPELIN_JAVA_OPTS is not used in interpreter JVM process.
For interpreter JVM process ZEPPELIN_INTP_JAVA_OPTS is do the same thing.
And this fix is taking ZEPPELIN_JAVA_OPTS as default value of ZEPPELIN_INTP_JAVA_OPTS.

conf/zeppelin-env.sh.templates have short description.

@jongyoul
Copy link
Contributor

@Leemoonsoo Good!

@swkimme
Copy link
Contributor

swkimme commented Mar 13, 2015

@jongyoul
Oh, I didn't catch that since I don't use ZEPPELIN_JAVA_OPTS today.
Great!

Leemoonsoo added a commit that referenced this pull request Mar 13, 2015
@Leemoonsoo Leemoonsoo merged commit 6f100f5 into master Mar 13, 2015
@Leemoonsoo Leemoonsoo deleted the new/separate_process_interpreter branch March 13, 2015 17:26
Leemoonsoo added a commit that referenced this pull request Mar 15, 2015
Update documentation for separate interpreter process #364
asfgit pushed a commit to apache/zeppelin that referenced this pull request Mar 30, 2015
This PR came from ZEPL/zeppelin#397

After ZEPL/zeppelin#364, order of submitted job to the remote interpreter is not preserved.
Result is, when user run a lot of paragraphs in a short time, they run in random order(like click run 'Run all paragraphs). https://github.com/NFLabs/zeppelin/issues/395 is one of the possible problem.

this PR adds some unittests and fix the problem.

Ready to merge.

Author: Lee moon soo <leemoonsoo@gmail.com>
Author: Lee moon soo <moon@apache.org>

Closes #8 from Leemoonsoo/fix/run_order and squashes the following commits:

4a6a230 [Lee moon soo] Prevent status remaining RUNNING after job executed
1fb3715 [Lee moon soo] Fix daedlock
6405abe [Lee moon soo] Update RemoteSchedulerTest
c31a807 [Lee moon soo] Make RemoteScheduler keep order of job submitted
epahomov pushed a commit to epahomov/zeppelin that referenced this pull request Jul 23, 2016
This PR addresses https://issues.apache.org/jira/browse/ZEPPELIN-360
Removing "Copyright 2014, NFLabs inc." from LICENSE.

Author: Lee moon soo <moon@apache.org>

Closes ZEPL#364 from Leemoonsoo/ZEPPELIN-360 and squashes the following commits:

cfb814b [Lee moon soo] Remove "Copyright (c) 2010-2015 NFLabs Inc." from NOTICE
fb75e86 [Lee moon soo] ZEPPELIN-360 Remove "Copyright 2014, NFLabs inc." from LICENSE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants