broken kernel... pty issue?
Opened this issue · 31 comments
Hi,
I've seen the message and experienced the problem: java_kernel does not work. However, not sure this is related to an update of ipython.
I tried the following setup on both a Linux debian (+/- uptodate) and an OsX 10.11.6
(jupyter) ~> pip freeze | grep jupyter
jupyter==1.0.0
jupyter-client==4.3.0
jupyter-console==4.1.1
jupyter-core==4.1.0
jupyterhub==0.6.1
(jupyter) ~> pip freeze | grep ipython
ipython==4.2.1
ipython-genutils==0.1.0
kulla, java-9 +/- up-to-date.
It works on OSX, but jshell does not start up. I dug down to the pexcept pseudo-terminal startup code. In bpyhton, this call blocks:
ptyprocess.PtyProcess.spawn(["/home/jupyterhub/java/jdk-9/bin/java", "-jar", "/home/jupyterhub/java/kulla/kulla.jar"])
and when looking at the user's processes, there is only a python3 child process, but no java process. Looks like the exec call in the PtyProcess does not take place?
Do you think that is the right direction to look for problems? (I understand you don't have time currently to do that yourself.)
Thanks a lot,
Holger
That seems very likely. If you wanna take a stab at it I would appreciate it.
And yeah. Life has gotten particularly busy recently and I have not had time for side projects. Good things mostly :-)
ok - but not getting any progress. I asked here:
http://stackoverflow.com/questions/40937420/drive-java-kulla-from-pexpect-context-jupyter
Let's see... thanks!
Is this still an issue? I'm running within the docker image, and it seems to work just fine?
Appears to be an issue with later versions of jdk-9. Downgrading to jdk-9.ea+100 works for me.
Yes, still an issue for me; with jdk build 9-ea+147
Good to know there is one version known to work ...
In case you are looking: this is available here http://download.java.net/java/jdk9/archive/100/binaries/jre-9-ea+100_linux-x64_bin.tar.gz
(Oracle makes you edit download links by hand to protect you against yourself ... 👎 )
Yeah, build 132 works, but not 151.
Error:
Traceback (most recent call last):
File "/opt/conda/lib/python3.5/site-packages/pexpect/spawnbase.py", line 150, in read_nonblocking
s = os.read(self.child_fd, size)
OSError: [Errno 5] Input/output error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/conda/lib/python3.5/site-packages/pexpect/expect.py", line 99, in expect_loop
incoming = spawn.read_nonblocking(spawn.maxread, timeout)
File "/opt/conda/lib/python3.5/site-packages/pexpect/pty_spawn.py", line 465, in read_nonblocking
return super(spawn, self).read_nonblocking(size)
File "/opt/conda/lib/python3.5/site-packages/pexpect/spawnbase.py", line 155, in read_nonblocking
raise EOF('End Of File (EOF). Exception style platform.')
pexpect.exceptions.EOF: End Of File (EOF). Exception style platform.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/conda/lib/python3.5/runpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "/opt/conda/lib/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/jovyan/javakernel/__main__.py", line 9, in <module>
IPKernelApp.launch_instance(kernel_class=JavaKernel)
File "/opt/conda/lib/python3.5/site-packages/traitlets/config/application.py", line 652, in launch_instance
app.initialize(argv)
File "<decorator-gen-120>", line 2, in initialize
File "/opt/conda/lib/python3.5/site-packages/traitlets/config/application.py", line 87, in catch_config_error
return method(app, *args, **kwargs)
File "/opt/conda/lib/python3.5/site-packages/ipykernel/kernelapp.py", line 454, in initialize
self.init_kernel()
File "/opt/conda/lib/python3.5/site-packages/ipykernel/kernelapp.py", line 365, in init_kernel
user_ns=self.user_ns,
File "/opt/conda/lib/python3.5/site-packages/traitlets/config/configurable.py", line 412, in instance
inst = cls(*args, **kwargs)
File "/home/jovyan/javakernel/kernel.py", line 34, in __init__
self._start_java_repl()
File "/home/jovyan/javakernel/kernel.py", line 52, in _start_java_repl
continuation_prompt=u' ...> '
File "/opt/conda/lib/python3.5/site-packages/pexpect/replwrap.py", line 55, in __init__
self._expect_prompt()
File "/opt/conda/lib/python3.5/site-packages/pexpect/replwrap.py", line 66, in _expect_prompt
timeout=timeout)
File "/opt/conda/lib/python3.5/site-packages/pexpect/spawnbase.py", line 390, in expect_exact
return exp.expect_loop(timeout)
File "/opt/conda/lib/python3.5/site-packages/pexpect/expect.py", line 105, in expect_loop
return self.eof(e)
File "/opt/conda/lib/python3.5/site-packages/pexpect/expect.py", line 50, in eof
raise EOF(msg)
pexpect.exceptions.EOF: End Of File (EOF). Exception style platform.
<pexpect.pty_spawn.spawn object at 0x7f781850beb8>
command: /home/jovyan/jdk-9/bin/java
args: [b'/home/jovyan/jdk-9/bin/java', b'-jar', b'/home/jovyan/kulla.jar']
buffer (last 100 chars): ''
before (last 100 chars): 'void main(String[] args)\r\nor a JavaFX application class must extend javafx.application.Application\r\n'
after: <class 'pexpect.exceptions.EOF'>
match: None
match_index: None
exitstatus: None
flag_eof: True
pid: 21
child_fd: 34
closed: False
timeout: 30
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_string:
0: "jshell> "
1: " ...> "
```
This might have something to do with it: `void main(String[] args) or a JavaFX application class must extend javafx.application.Application`
This might have something to do with it: http://hg.openjdk.java.net/jdk9/jdk9/langtools/rev/e5a42ddaf633
Seems like the main
method in JShellTool
is gone.
If the launcher script changes java -jar kulla.jar
to java -cp kulla.jar jdk.internal.jshell.tool.JShellToolProvider
, it might work. Giving it a try.
It gets rid of the kernel crash, but executing statements never terminates, so there's still something else that is wrong...
I'm pretty sure this has something to do with ansi escape sequences to do. After digging deeper, it hangs when the jshell process outputs the sequence \x1b[6n
@nilsga I agree, exactly. I also found this same issue when running jshell inside an Emacs shell.
But reverting back to an earlier jdk-9 avoids this problem.
It would be very interesting to find out exact which version broke it, to pinpoint the exact change that caused it. For me, it works with build 132 but not 151. Have not tested any builds in between.
Also, I don't think the kulla.jar
is actually required anymore, since the downloadable JDK eap contains the jshell
binary.
@nilsga I believe that you are correct: using jdk-9ea+100/bin/jshell
should work (although I did not try yet). I did try using pexpect with jdk-9ea+150/bin/jshell
and that did NOT work because of the same control character issue described above.
Im wondering if this is the kind of thing we could report to the openJDK team. Thoughts?
That's very useful, thanks. But I am surprised you got ea+132 to work? It fails for me when trying multi-line commands (e.g., defining a class over multiple lines). ea-100 shows the same problem.
More precisely, it works for single-line commands.
It works for multi-line commands when running:
hkarl@gp1 ~/tmp % /home/jupyterhub/java/jdk-9/bin/java -jar $KULLA_HOME
| Welcome to JShell -- Version 9-ea
| Type /help for help
-> class A {
>> }
| Added class A
but it fails with EOF when running under pexpect, just like in @nilsga comment above.
(Little program to test that without having to go through the jupyter context; example for ea-100 continuation prompts; same behavior with ea-132):
from pexpect import replwrap, EOF
jw = replwrap.REPLWrapper("/home/jupyterhub/java/jdk-9/bin/java -jar /home/jupyterhub/java/kulla/kulla.jar", "-> ", None, continuation_prompt=">> ")
print(jw)
commands = ("""class A {""", """}""")
for code in commands:
print("-----")
try:
output = jw.run_command(code)
print("output: ", output)
except EOF:
print("Ignoring EOF")
I have only tested with the jupyter notebook, and it seems to work with ea-132. I did modify the kernel to run jshell
directly though. Nevertheless, it might be that it is not possible to use the replwrapper with jshell
anymore, and that one have to use a more "proper" ANSI terminal to capture output and send input.
As @nilsga mentions, the notebook always sends complete cells, so this won't be a problem there. Likewise, if you always send complete code in the jupyter console, you won't see this problem.
BTW, if you use metakernel as the base, it will wait for a command completion in the console (for Java, it just waits for an empty line in input). But metakernel also has a wrapper around pexpect to try to fix some issues like this. I'm not sure if it will help in this situation though. Might be worth a try if you really want partial code in a cell. (metakernel also provides a common set of magics too, and shell, and parallel execution).
@nilsga ah, ok, running jshell rather than kulla does the trick. Very nice! I am now using, in java_kernel:
self.javawrapper = replwrap.REPLWrapper(
"{}/bin/jshell".format(self.env['JAVA_9_HOME']),
u'jshell> ',
None,
continuation_prompt=u' ...> '
which seems to work (on ea-132).
(I want to use this for students, so actually need solutions that also work with imperfect input. This way, we are limited to jupyter notebook rather than console, but that's ok)
Thanks!
@hkarl I am also using this with students... I have some customizations I'd be willing to share [1]. Last time I tried (Spring 2016) kulla.jar was pretty slow for even fairly small classes... how do you find it now?
@dsblank Interesting... we have so far done Python and will move into Java soon for the remaining of the term. Unfortunately, all my material is in German (don't ask ...). You could perhaps get some idea of our setup here: http://groups.uni-paderborn.de/fg-karl/lehre/ws1617/gp1/index.html
So no real experience on Kulla performance, but it looks like this just got dumped in favour of jshell, in any case. But that is also sure not to win any performance prices...
jshell
is Kulla (or rather, the other way around), btw. Kulla was just the "codename" before they merged it into the main JDK9 repository.
I was hoping to have time to clean up the changes I have made, but alas not. But you are free to compare mine to this repo:
https://athena.brynmawr.edu/jupyter/hub/dblank/public/Experiments/Java9
I use metakernel (to get shell and other magics) and made some changes to the output. I think by default it echos everything, and I tried to remove that (doesn't work on lines longer than something like 70 chars). Echo is used to get the return values to show up in Jupyter return lines. And there are some times where getting the echo back displays useful information.
I'll be using this in class again in a few weeks, so I'll get back into it. Currently, I'm using the Calysto Processing kernel, which does compile Java (before converting to Javascript) and also has all of the cool Processing art/java simplifications:
https://github.com/Calysto/calysto_processing
If you are interested in that, I just made some local changes to it I'd be willing to share too (eg, println shows up in Jupyter's output area).
I have a slightly different setup than Doug. I'm using it for a general-purpose programming class, so I want to stay fairly close to Java. Java9 actually is confusing those students already familiar with Java, but so be it.
In consequence, I ended up making relatively few changes:
- No Kulla, but use jshell instead
- JDK-9 ea 132 seems to work ok, but not perfect - the kernel does occasionally hang; it looks like a jshell issue but did not investigate.
- Fairly obvious changes to javakernel/kernel.py from this repo:
--- a/javakernel/kernel.py
+++ b/javakernel/kernel.py
@@ -43,10 +43,7 @@ class JavaKernel(Kernel):
sig = signal.signal(signal.SIGINT, signal.SIG_DFL)
try:
self.javawrapper = replwrap.REPLWrapper(
- "{} -jar {}".format(
- self._JAVA_COMMAND,
- self._KULLA_LOCATION
- ),
+ "{}/bin/jshell".format(self.env['JAVA_9_HOME']),
u'jshell> ',
None,
continuation_prompt=u' ...> '
- kernel.json unchanged (apart for paths, of course), but KULLA_HOME is no longer necessary.
I observed issues similar to Doug; long lines cause problems; jshell parser does not treat things like
if (bla) {
... }
else ...
correctly; etc. So it is workable, but not perfect.
- For what is is worth, we are also collecting homework assignments in java via nbgrader. That is ok, but from what we have seen so far, it looks like autograding does not work. The java programs get executed and the results get copied into the notebook, but exceptions thrown by a java autograder test are ignored by nbgrader (whereas for Python programs, nbgrader correctly uses exceptions to give or deny points from autograded tests). So this is something that helps, but is not as useful as under Python.
In total: YMMV!
@hkarl We should try to put all of the good stuff here, when java9 is finally out.
I had updated java to ea132, and saw some weirdness this week. I think I'll retreat to ea100.
I also use nbgrader, but largely to disseminate/collect homework (everything is printed and manually graded). BUT, I think we can make the autograding work with some small changes. We made some enhancements in metakernel recently to make the Jupyter error handling API work properly, and I think we can do the same here. I'll try to look at that in a month, as it would be very useful.
Thank you guys for sharing your work. I'm currently having some issue with dependencies running on Fedora 25, so I'm trying to apply them to the Dockerbuild file and see if everything resolves find there.
thanks so far
Thanks guys, it works. Unluckily trying with different newer versions fails and to output is returned.
Some recent comments:
- I'm still using the older jar file due to the control codes in more modern jshells
- I've started a conversation at beakerx to discuss a jshell-based kernel (twosigma/beakerx#5428)
- Even with the old kulla code, a recent change of use was quite nice: when you send code with newlines, there is about a 0.05 second delay per line. That adds up pretty quickly with 100-line code. The solution was to remove the newlines before sending to the jshell process. However, that created some complications when reporting errors. My recent version: https://github.com/dsblank/jupyter.brynmawr/blob/master/java9/kernel.py#L152-L188