Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting symlinks for JEP (Fedora 24) #27

Closed
penningavery opened this issue Nov 24, 2016 · 18 comments
Closed

Setting symlinks for JEP (Fedora 24) #27

penningavery opened this issue Nov 24, 2016 · 18 comments

Comments

@penningavery
Copy link

penningavery commented Nov 24, 2016

Hi,

I am trying to use python with QuPath via JEP, as per the docs. I am using linux (Fedora 24) and am having trouble locating the JEP directory to symlink, and also I am not sure from the docs exactly which directory to put the symlink in.

I've tried symlinking from the jep folder in the python installation site-packages directory, to the jars directory under qpath. I've also symlinked all the contents of the jep folder, including the jep-3.6.1.jar, into the QuPath/apps/jars directory. I still get 3 errors when I run the groovy script provided in the docs; they are just 'unable to resolve class jep.Jep', etc.

I appreciate your help, thanks.

@petebankhead
Copy link
Member

Hi,

Looking back that the documentation, I see it wasn't the clearest...

I've just tested the following on macOS Sierra with a downloaded QuPath and I was able to run the script in the docs after the following steps:

  1. If you don't already have a QuPath extensions directory, you can either set one under Edit → Preferences or follow the process to install any extension that takes your interest here.

  2. Next, locate where JEP is installed and create a symbolic link in your QuPath extensions directory to its Jar file. For me, this was the command:

ln -s /usr/local/lib/python2.7/site-packages/jep/jep-3.5.3.jar /Users/pete/QuPath/extensions/jep.jar
  1. Alongside the Jar, there were also two native files jep.so and libjep.jnilib. The easiest way to get QuPath to see them is simply to copy these into your QuPath directory containing QuPathApp.jar (there should already be other native libraries there too).

I haven't tested this on Linux, but would be very interested to know if it works (or, indeed, if other things are working fine for you with Fedora). If so I'll update the docs to be a bit clearer.

Note that I never took the use of JEP with QuPath far enough for it to be genuinely useful, since I didn't have a sufficient need for it myself until now. But I think the ability to run Python scripts could be really valuable, so I'd be happy to help with setting this up or coming up with a neat way to wrap or convert data structures.

If you'd like to discuss more the kind of applications you see this being useful for (e.g. segmentation, classification, manipulating objects, statistical analysis...) just let me know.

@penningavery
Copy link
Author

penningavery commented Nov 24, 2016

Hello,
Thanks for the detailed and rapid reply. I have made some progress following your instructions and am now at a different error message.

ERROR: Error at line 17: Cannot invoke method getServer() on null object
ERROR: Script error

at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at Script1.run(Script1.groovy:18)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:343)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:152)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:757)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:687)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:669)
at qupath.lib.scripting.DefaultScriptEditor.access$3(DefaultScriptEditor.java:659)
at qupath.lib.scripting.DefaultScriptEditor$2.run(DefaultScriptEditor.java:979)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

I should say that I wasn't able to copy libjep.jnilib as it doesn't exist on my system, instead it's called libjep.so. I don't know if that might be causing some problem.

I am quite keen to run some python image processing code that I have via QuPath so I will keep on helping with this if I am able. Just getting the jep connection running would let me see if I can begin to work on wrapping/exchanging data issues.

Thanks!

@petebankhead
Copy link
Member

petebankhead commented Nov 24, 2016

Thanks for your reply - yes, jnilib should be an apple-only thing. Sounds good that it's getting through the imports now.

Do you have an (RGB) image open when you run the script? The script assumes that you do.

If you do have an image open, yet it still doesn't work, could you try the following simple script to check what QuPath is seeing:

print("Current image data: " + getCurrentImageData())
print("Current image server: " + getCurrentImageData().getServer())

@penningavery
Copy link
Author

penningavery commented Nov 24, 2016

Hi, ah, silly error on my part. Thanks.

Ok, so now the imports seem to work, but something isn't connecting right for the jep section of the script.


INFO: Mean red (from Java): 86.81525
INFO: Mean green (from Java): 72.492275
INFO: Mean blue (from Java): 68.141675
INFO: java.lang.UnsatisfiedLinkError: no jep in java.library.path

I tried the script you sent and received:


INFO: Current image data: ImageData: Fluorescence, IMG_5_11_sq
INFO: Current image server: ImageJ server: /home/bl/Documents/IMG_5_11_sq.png (IMG_5_11_sq.png)

I should say that I think jep is installed ok, though I have only played with for a second this morning. But I can start jep, and do the basic test on the jep git Getting Started page (the python to java one).

@penningavery
Copy link
Author

penningavery commented Nov 24, 2016

I should say that I also did try setting the CLASSPATH to include the jep-3.6.1.jar and also the LD_LIBRARY_PATH to include the two .so library files. But so far, still stuck at the java.lang.UnsatisfiedLinkError

Actually, when I run it again, the error changes to:

INFO: java.lang.NoClassDefFoundError: Could not initialize class jep.Jep

@petebankhead
Copy link
Member

It sounds like jep-3.6.1jar is not a problem any more, and it is instead related to the native libraries.

I've just had a look on Ubuntu, and there's a jep.so and libjep.so. Do you have both, and did you copy them both in?

When I do that in Ubuntu I don't get any library or class def errors. It still doesn't work though, due to an attr not found problem...

@penningavery
Copy link
Author

penningavery commented Nov 24, 2016

Hi,
Yes, I have both jep.so and libjep.so copied in the folder and am still getting the error message I reported. I didn't realize initially but libjep.so is just a symlink to jep.so.

@petebankhead
Copy link
Member

Hi,

Strange... my quick attempt on Ubuntu also didn't work, but apparently for a different reason...

An alternative method to add to your library path would be to track down the QuPath.cfg file within your QuPath installation, and amend it - something like the following:

[JVMOptions]
-Djava.library.path=.:/usr/local/lib/python2.7/dist-packages/jep/

With this, it shouldn't be necessary to copy the files. Does this help at all, or is it the same error?

@penningavery
Copy link
Author

penningavery commented Nov 25, 2016

Well, that definitely did something - I managed to crash QuPath. One thing - I am trying to run a 64 bit installation, perhaps that is causing some kind of conflict? I checked just to be sure and my python is 64 bit and the error message below discusses a 64-bit Open-JDK server, so this may not be the issue.

I am going to paste the (very long) error message. I can trim this down and get rid of the OpenCV and OpenSlide parts if it's too long.

[bl@QuPath]$ ./QuPath&
[1] 27357
[bl@QuPath]$ 02:39:33.387 [main] [INFO ] qupath.QuPath - Launching QuPath with args: 
02:39:34.264 [JavaFX Application Thread] [INFO ] qupath.lib.gui.prefs.PathPrefs - Tile cache size: 624.00 MB
02:39:37.713 [JavaFX Application Thread] [INFO ] qupath.lib.gui.QuPathGUI - Refreshing extensions in /home/bl/ip/QuPath/extensions
02:39:37.715 [JavaFX Application Thread] [INFO ] qupath.lib.gui.QuPathGUI - Added extension: /home/bl/ip/QuPath/extensions/jep.jar
OpenJDK 64-Bit Server VM warning: You have loaded library /home/bl/ip/QuPath/app/libopencv_java310.so which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
02:39:37.931 [JavaFX Application Thread] [ERROR] qupath.opencv.OpenCVExtension - Unable to load OpenCV libraries!
java.lang.UnsatisfiedLinkError: /home/bl/ip/QuPath/app/libopencv_java310.so: libavcodec-ffmpeg.so.56: cannot open shared object file: No such file or directory
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at qupath.opencv.OpenCVExtension.loadNativeLibrary(OpenCVExtension.java:60)
	at qupath.opencv.OpenCVExtension.addQuPathCommands(OpenCVExtension.java:73)
	at qupath.opencv.OpenCVExtension.installExtension(OpenCVExtension.java:120)
	at qupath.lib.gui.QuPathGUI.refreshExtensions(QuPathGUI.java:1092)
	at qupath.lib.gui.QuPathGUI.<init>(QuPathGUI.java:633)
	at qupath.lib.gui.QuPathGUI.<init>(QuPathGUI.java:418)
	at qupath.lib.gui.QuPathApp.start(QuPathApp.java:59)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$106(LauncherImpl.java:863)
	at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$119(PlatformImpl.java:326)
	at com.sun.javafx.application.PlatformImpl.lambda$null$117(PlatformImpl.java:295)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$118(PlatformImpl.java:294)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
	at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
	at com.sun.glass.ui.gtk.GtkApplication.lambda$null$450(GtkApplication.java:139)
	at java.lang.Thread.run(Thread.java:745)
02:39:38.754 [JavaFX Application Thread] [INFO ] qupath.lib.gui.QuPathGUI - Selected style: Modena Dark
02:39:38.757 [JavaFX Application Thread] [INFO ] qupath.lib.gui.QuPathGUI - Performing update check...
02:39:38.781 [JavaFX Application Thread] [INFO ] qupath.lib.gui.QuPathApp - Starting QuPath with parameters: []
02:39:38.837 [JavaFX Application Thread] [INFO ] q.lib.gui.helpers.DisplayHelpers - QuPath Notice: This is a pre-release version of QuPath
  Version: 0.0.6
  Build time: 2016-11-16, 15:54
02:40:13.093 [JavaFX Application Thread] [ERROR] q.l.i.servers.OpenslideServerBuilder - Could not load OpenSlide native library
java.lang.UnsatisfiedLinkError: /home/bl/ip/QuPath/app/libopenslide-jni.so: libopenslide.so.0: cannot open shared object file: No such file or directory
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at org.openslide.OpenSlideJNI.<clinit>(OpenSlideJNI.java:55)
	at org.openslide.OpenSlide.<clinit>(OpenSlide.java:53)
	at qupath.lib.images.servers.OpenslideImageServer.<init>(OpenslideImageServer.java:91)
	at qupath.lib.images.servers.OpenslideServerBuilder.buildServer(OpenslideServerBuilder.java:47)
	at qupath.lib.images.servers.ImageServerProvider.buildServer(ImageServerProvider.java:115)
	at qupath.lib.gui.QuPathGUI.openImage(QuPathGUI.java:2091)
	at qupath.lib.gui.QuPathGUI.openImage(QuPathGUI.java:2015)
	at qupath.lib.gui.commands.OpenCommand.run(OpenCommand.java:51)
	at qupath.lib.gui.QuPathGUI.lambda$43(QuPathGUI.java:2960)
	at org.controlsfx.control.action.Action.handle(Action.java:419)
	at org.controlsfx.control.action.Action.handle(Action.java:64)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
	at javafx.event.Event.fireEvent(Event.java:198)
	at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
	at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
	at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
	at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
	at javafx.event.Event.fireEvent(Event.java:198)
	at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
	at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
	at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
	at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$300(GlassViewEventHandler.java:388)
	at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
	at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
	at com.sun.glass.ui.View.notifyMouse(View.java:937)
	at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
	at com.sun.glass.ui.gtk.GtkApplication.lambda$null$450(GtkApplication.java:139)
	at java.lang.Thread.run(Thread.java:745)
02:40:13.846 [JavaFX Application Thread] [INFO ] q.l.i.servers.ImageServerProvider - Returning server: ImageJ server for /home/bl/Documents/IMG_5_11_sq.png
02:40:14.153 [JavaFX Application Thread] [INFO ] qupath.lib.gui.viewer.QuPathViewer - Image data set to ImageData: Fluorescence, IMG_5_11_sq
02:40:22.852 [JavaFX Application Thread] [INFO ] q.lib.scripting.DefaultScriptEditor - Loading script file /home/bl/ip/QuPath/app/TestJep.groovy
02:40:28.109 [richscripteditor-1] [INFO ] q.lib.scripting.DefaultScriptEditor - Mean red (from Java): 86.81525
02:40:28.121 [richscripteditor-1] [INFO ] q.lib.scripting.DefaultScriptEditor - Mean green (from Java): 72.492275
02:40:28.124 [richscripteditor-1] [INFO ] q.lib.scripting.DefaultScriptEditor - Mean blue (from Java): 68.141675
02:40:28.624 [richscripteditor-1] [INFO ] q.lib.scripting.DefaultScriptEditor - Started JEP: jep.Jep@6bc4b2e2
ImportError: numpy.core.multiarray failed to import
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f930536d03f, pid=27357, tid=0x00007f932091e700
#
# JRE version: OpenJDK Runtime Environment (8.0_111-b14) (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14)
# Java VM: OpenJDK 64-Bit Server VM (25.111-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [jep.so+0x1a03f]  convert_jndarray_pyndarray+0x5bf
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/bl/ip/QuPath/app/hs_err_pid27357.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

[1]+  Aborted                 (core dumped) ./QuPath

I am thinking that this might be worth bringing up with the JEP developers. I am going to spend a little more time playing with JEP by itself in order to see if I run into any similar issues.

@petebankhead
Copy link
Member

I realise that doesn't look good, but I think it is progress... the failed import of numpy.core.multiarray is where I was also having problems with Ubuntu (albeit with a less catastrophic-looking exception).

The fact that OpenCV and OpenSlide are also not usable is... disappointing, but not exactly surprising - I have mostly focussed on getting QuPath to work properly on Windows and Mac, and you are the first person I know of using it on Linux. Both OpenCV and OpenSlide have native library issues that might be easier to solve. If you happen to find a way to get them to work, the same solution may help make progress with JEP.

I will look into this some more, but realistically it might take a few weeks before I can give it proper attention.

(It may also be worth keeping javabridge in mind, if you would like some variation...)

@penningavery
Copy link
Author

penningavery commented Nov 25, 2016 via email

@petebankhead
Copy link
Member

While not directly related to the Python problem, v0.0.7 will hopefully do away with the exceptions you were seeing related to OpenSlide and OpenCV (some info here).

At least, I was able to run the this release on a clean installation of Fedora (25) through VirtualBox without major trouble... albeit it still not quite as smoothly as under macOS, Windows or Ubuntu.

@penningavery
Copy link
Author

penningavery commented Nov 28, 2016 via email

@petebankhead
Copy link
Member

So I looked a bit more this morning, and the issue seems to go back to preloading... and it was documented all along in the JEP wiki at https://github.com/mrj0/jep/wiki/Linux#ld_preload

The way I got it to work was by copying the file identified by

which jep

into the base QuPath directory (which contains the launcher) and then modifying it. You can see more about the original contents of this file here.

The end result is that I launched QuPath with the following:

#!/bin/sh

VIRTUAL_ENV=
export VIRTUAL_ENV

LD_LIBRARY_PATH="/usr/lib:/usr/local/lib/python2.7/dist-packages/"; export LD_LIBRARY_PATH
LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libpython2.7.so"; export LD_PRELOAD

if test "x$VIRTUAL_ENV" != "x"; then
  PATH="$VIRTUAL_ENV/bin:$PATH"
  export PATH
  PYTHONHOME="$VIRTUAL_ENV"
  export PYTHONHOME
fi

cp="/usr/local/lib/python2.7/dist-packages/jep/jep-3.6.1.jar"
if test "x$CLASSPATH" != "x"; then
    cp="$cp":"$CLASSPATH"
fi

jni_path="/usr/local/lib/python2.7/dist-packages/jep"

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

exec java -Xmx4G -classpath "$cp:${DIR}/app/QuPathApp.jar" -Djava.library.path="$jni_path:${DIR}:${DIR}/app" qupath.QuPath

After doing this, the Groovy script for testing JEP worked without problems.

One thing in particular to note is the use of -Xmx4G to set the maximum memory to 4GB on my (virtual) machine... it would be good to modify this as required, as the built-in method is modifying the maximum memory within QuPath won't work when it's launched in this way.

I've only tested this in Ubuntu, but hopefully it works for you too.

@penningavery
Copy link
Author

penningavery commented Dec 4, 2016 via email

@petebankhead
Copy link
Member

No worries, I looked at the Wiki multiple times as well and completely missed it :)

I've also updated the Working with Python section of the Wiki and started adding a bit of info about Paths & configuration that might be useful.

@penningavery
Copy link
Author

Easily done I guess!

I for one really appreciate the updated docs with the new example. Thats much more than I was expecting and I am looking forward to testing it out. Thanks again!

@erexhepa
Copy link

Hi,

I'm using JEP at the moment and just wanted to let you know with regard to the Wiki page that the syntax of the method declaring the python packages to be loaded has changed (jep 3.7) is now

addSharedModules("numpy","pandas",...)

otherwise I think is far more optimal compared to Jython although there are still some issues with pandas but as long as you stick to numpy and packages relying on numpy is fine.

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

No branches or pull requests

3 participants