I am calling a function in a java library from jython which prints to stdout. I would like to suppress this output from the jython script. I attempt the python idiom replacing sys.stdout with a file like object (StringIO), but this does not capture the output of the java library. I'm guessing sys.stdout does not affect the java program. Is there a standard convention for redirecting or suppressing this output programatically in jython? If not what ways can I accomplish this?
You can use System.setOut, like this:
>>> from java.lang import System
>>> from java.io import PrintStream, OutputStream
>>> oldOut = System.out
>>> class NoOutputStream(OutputStream):
... def write(self, b, off, len): pass
...
>>> System.setOut(PrintStream(NoOutputStream()))
>>> System.out.println('foo')
>>> System.setOut(oldOut)
>>> System.out.println('foo')
foo
Note that this won't affect Python output, because Jython grabs System.out when it starts up so you can reassign sys.stdout as you'd expect.
I've created a context manager to mimic (Python3's) contextlib's redirect_stdout (gist here):
'''Wouldn't it be nice if sys.stdout knew how to redirect the JVM's stdout? Shooting star.
Author: Sean Summers <seansummers#gmail.com> 2015-09-28 v0.1
Permalink: https://gist.githubusercontent.com/seansummers/bbfe021e83935b3db01d/raw/redirect_java_stdout.py
'''
from java import io, lang
from contextlib import contextmanager
#contextmanager
def redirect_stdout(new_target):
''' Context manager for temporarily redirecting sys.stdout to another file or file-like object
see contextlib.redirect_stdout documentation for usage
'''
# file objects aren't java.io.File objects...
if isinstance(new_target, file):
new_target.close()
new_target = io.PrintStream(new_target.name)
old_target, target = lang.System.out, new_target
try:
lang.System.setOut(target)
yield None
finally:
lang.System.setOut(old_target)
Related
I need to check if a specified process is currently running using Scala.
All I have is the PID.
Does Scala have an internal function or do I need to parse it using ps?
Thank you.
You can import sys.process._
General example
import sys.process._
scala> import sys.process._
import sys.process._
scala> "ps" !
PID TTY TIME CMD
570 ttys000 0:00.02 -bash
591 ttys000 0:00.01 bash /usr/local/bin/scala
getting the PID for the process scala
// !! to get result as String
scala> "\\d+".r.findFirstIn( "ps" #| "grep /usr/local/bin/scala" !! )
res9: Option[String] = Some(591)
for a more information see: http://www.scala-lang.org/api/current/index.html#scala.sys.process.package
When running Scala on Java 9, we can take advantage of Java's ProcessHandle which makes it easier to identify and work with native processes:
ProcessHandle.of(5210) match { case p => p.isPresent && p.get.isAlive }
where 5210 is the pid of the process you're interested in getting the status for.
This:
First creates a Java Optional<ProcessHandle> from the given pid.
If the process exists, this Optional must be present (which might be enough to tell if the process is alive depending on the system).
And finally checks that the process is alive using ProcessHandle::isAlive.
No import necessary as ProcessHandle is part of java.lang.
AFAIK, Java or Scala doesn't have such functionality. If you are on UNIX based machine, yes, your best bet is to use ps command.
You can use the PID with ps command as follows:
ps -p 8238 -o "pid="
Here PID is 8283, and we ask ps to search for it, and if it exists, just print it.
scala> import sys.process._
import sys.process._
scala> def processExists(pid: Int) = pid == {try { (List("ps", "-p", s"$pid", "-o", "pid=") !!).trim.toInt } catch { case _: Throwable => -1 }}
warning: there was one feature warning; re-run with -feature for details
processExists: (pid: Int)Boolean
scala> val pid = 8238
pid: Int = 8238
scala> processExists(pid)
res11: Boolean = true
scala> processExists(1234)
res12: Boolean = false
If I try to evaluate the following code in my emacs cider-repl, nil is returned, as expected, but none of the printing takes place in the repl buffer or console. How can I make this print out as intended?
(dotimes [i 5]
(.start
(Thread.
(fn []
(Thread/sleep (rand 500))
(println (format "Finished %d on %s" i (Thread/currentThread)))))))
;=> nil
This works fine, however:
(println (format "Finished 1 on %s" (Thread/currentThread)))
;=> Finished 1 on Thread[nREPL-worker-18,5,main]
----------- mini-buffer -----------------
nil
The behavior of println is to use a dynamically bound var called *out* as its output stream. emacs dynamically binds *out* to go to the repl buffer for code evaluated in the repl buffer, but if you create a thread, that thread's *out* gets the root binding of *out*, which in the case of cider will not be the repl buffer.
If you started the repl using cider-jack-in, when you look at you buffer list there should be a buffer with a name like *nrepl-server* which contains the output of the root *out* binding. Here is the contents of mine after running your code:
nREPL server started on port 52034 on host 127.0.0.1 - nrepl://127.0.0.1:52034
Finished 1 on Thread[Thread-9,5,main]
Finished 0 on Thread[Thread-8,5,main]
Finished 2 on Thread[Thread-10,5,main]
Finished 3 on Thread[Thread-11,5,main]
Finished 4 on Thread[Thread-12,5,main]
If you did not use cider-jack-in, the output will print to the terminal where you started the nrepl process.
*out* is the dynamic variable determining where output from println and similar functions goes. It is thread-bound to someplace that causes stuff to be sent back to emacs for display by cider; if you start a new thread, that binding is not present, and the output goes elsewhere (probably to the stdout of the nrepl server emacs/leiningen started in the background).
You can address this in a few ways. You could capture the value of *out* from the parent thread, and then pass it along to the child thread in a closure, and rebind *out* to it:
(let [out *out*]
(.start (Thread. (fn []
(binding [*out* out]
(println "test"))))))
Or you can use a future instead of starting the thread yourself: Clojure automatically conveys relevant thread-local bindings to new threads started for a future.
Execute the following expression in the repl, then all output will end up in the repl:
(alter-var-root #'*out* (constantly *out*))
original answer:
https://groups.google.com/d/msg/cider-emacs/bIVBvRnGO-U/nDszDbGoVzgJ
If you are using Figwheel, then doing prn/println in ring handlers (which are actually similar to the Threads example shown above) can also be swallowed by Fighweel itself. Check your project's project.clj (look for the key :server-logfile inside the :figwheel map), where you can control if out should go to the repl or to a logfile. Please note, this only applies if you are using figwheel, otherwise the printing to the REPL of course works fine.
See my answer on this question for more details: Output compojure server print statements into figwheel terminal?
I'm looking for a way to start up a subprocess in clojure (java is fine to) and have the output of it get sent directly to stdout in real-time. The closest I've been able to find is the Conch library for clojure, which allows you to send the output to *out*, but it doesn't actually display the output until the process is done running.
Not sure if there is a convenient Clojure wrapper for this:
(->> (.. Runtime getRuntime (exec "ls") getInputStream)
java.io.InputStreamReader.
java.io.BufferedReader.
line-seq
(map println))
It's worth noting in practice that you need to read both stdin and stderr
regularly or the process can hang when one of the buffers fill.
I marked Arthur's answer as correct since it led me to the solution, and it basically is what someone would want in the basic case. I ended up building out a larger method which does more though, and figured I'd put it here in case anyone else found it useful
(defn- print-return-stream
[stream]
(let [stream-seq (->> stream
(java.io.InputStreamReader.)
(java.io.BufferedReader.)
line-seq)]
(doall (reduce
(fn [acc line]
(println line)
(if (empty? acc) line (str acc "\n" line)))
""
stream-seq))))
(defn exec-stream
"Executes a command in the given dir, streaming stdout and stderr to stdout,
and once the exec is finished returns a vector of the return code, a string of
all the stdout output, and a string of all the stderr output"
[dir command & args]
(let [runtime (Runtime/getRuntime)
proc (.exec runtime (into-array (cons command args)) nil (File. dir))
stdout (.getInputStream proc)
stderr (.getErrorStream proc)
outfut (future (print-return-stream stdout))
errfut (future (print-return-stream stderr))
proc-ret (.waitFor proc)]
[proc-ret #outfut #errfut]
))
I have an python script which I need to run in my java application. I tried to execute it from jython but I have strange problem:
from sys import getdlopenflags
I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name getdlopenflags
When I try to check contents of sys:
import sys
dir(sys)
the output is:
['JYTHON_DEV_JAR', 'JYTHON_JAR', 'PYTHON_CACHEDIR', 'PYTHON_CACHEDIR_SKIP', 'PYTHON_CONSOLE_ENCODING', '__delattr__', '__dict__', '__displayhook__', '__excepthook__', '__findattr_ex__', '__name__', '__new__', '__rawdir__', '__setattr__', '__stderr__', '__stdin__', '__stdout__', '_getframe', '_jy_interpreter', '_systemRestart', 'add_classdir', 'add_extdir', 'add_package', 'argv', 'builtin_module_names', 'builtins', 'byteorder', 'classDictInit', 'classLoader', 'cleanup', 'copyright', 'currentWorkingDir', 'defaultencoding', 'determinePlatform', 'displayhook', 'doInitialize', 'exc_clear', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'filesystemencoding', 'getBaseProperties', 'getBuiltin', 'getBuiltins', 'getClassLoader', 'getCurrentWorkingDir', 'getDefaultBuiltins', 'getPath', 'getPathLazy', 'getPlatform', 'getWarnoptions', 'getdefaultencoding', 'getfilesystemencoding', 'getrecursionlimit', 'hexversion', 'initialize', 'isPackageCacheEnabled', 'last_traceback', 'last_type', 'last_value', 'maxint', 'maxunicode', 'meta_path', 'minint', 'modules', 'packageManager', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'recursionlimit', 'registerCloser', 'registry', 'setBuiltins', 'setClassLoader', 'setCurrentWorkingDir', 'setPlatform', 'setWarnoptions', 'setprofile', 'setrecursionlimit', 'settrace', 'shadow', 'stderr', 'stdin', 'stdout', 'subversion', 'toString', 'unregisterCloser', 'version', 'version_info', 'warnoptions']
obviously getdlopenflags is missing. Is it possible to use this function in jython (I have the newest - 2.5.2) According to the documentation on the http://jython.org/docs/library/sys.html the sys.getdlopenflags is present.
Thanks for help
It says "Availability: Unix" in the documentation. The Jython docs seem to have copied that unchanged from the CPython docs. So this function is only available on a Unix installation. Possibly Jython doesn't have it at all - I don't know Java well enough, but since it's supposedly platform-independent, it can't support system-specific functions.
All versions of Java require the user to close resources manually - usually handled in the finally block. Java 7 is about to get ARM (automatic resource management) blocks.
Firstly I don't see a finally block concept in python. Or do you close resources in the catch for each raised exceptions ?
Is there a library that performs ARM in python ? If not, then what is the pythonic way to do ARM ?
There is a try: except: finally: in python.
You can also use the with: statement, which I believe is what you are after for ARM. These are called context managers. http://www.python.org/dev/peps/pep-0343/
There is some automated resource management in Python. Most objects who open resources will close them when they get garbage collected. When that happens is undefined, and it may not happen at all, so this only works if you don't use very many resources, don't care if they are open long and the resources will be closed by the operating system when the program exits.
Otherwise, use context managers and the with statement as per Matthews answer.
Here is a simple example that redirects stdout:
>>> import sys
>>> class redirect_stdout:
... def __init__(self, target):
... self.stdout = sys.stdout
... self.target = target
...
... def __enter__(self):
... sys.stdout = self.target
...
... def __exit__(self, type, value, tb):
... sys.stdout = self.stdout
...
>>> from StringIO import StringIO
>>> out = StringIO()
>>> with redirect_stdout(out):
... print 'Test'
...
>>> out.getvalue() == 'Test\n'
True