These are chat archives for fiji/fiji

2nd
May 2017
Philipp Hanslovsky
@hanslovsky
May 02 2017 15:49

@ctrueden I currently call the constructor of ij.ImageJ from python to create imagej with qt console support. In order to make it to the 21st century, I would rather start an imagej2 instance. Is the correct way to do so

ImageJ  = autoclass( 'net.imagej.ImageJ' )
ij2 = ImageJ()
ij2.launch( ij_args )

Note that autoclass is a PyJNIus wrapper around java classes.

Hadrien Mary
@hadim
May 02 2017 15:54
I think you can use Main.launch(args)
from net.imagej.Main
Philipp Hanslovsky
@hanslovsky
May 02 2017 15:58

I tried both from java code but in python, they fail for me, both with the same exception:

java.lang.IllegalArgumentException: Cannot handle app name in ij.gui.YesNoCancelDialog's public <init>(java.awt.Frame parent, java.lang.String title, java.lang.String msg)
        at net.imagej.patcher.CodeHacker.replaceAppNameInCall(CodeHacker.java:446)
        at net.imagej.patcher.LegacyExtensions.insertAppNameHooks(LegacyExtensions.java:419)
        at net.imagej.patcher.LegacyExtensions.injectHooks(LegacyExtensions.java:291)
        at net.imagej.patcher.LegacyInjector.inject(LegacyInjector.java:308)
        at net.imagej.patcher.LegacyInjector.injectHooks(LegacyInjector.java:109)
        at net.imagej.patcher.LegacyEnvironment.initialize(LegacyEnvironment.java:101)
        at net.imagej.patcher.LegacyEnvironment.applyPatches(LegacyEnvironment.java:495)
        at net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:397)
        at net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:376)
        at net.imagej.legacy.LegacyService.<clinit>(LegacyService.java:134)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at org.scijava.service.ServiceHelper.createServiceRecursively(ServiceHelper.java:302)
        at org.scijava.service.ServiceHelper.createExactService(ServiceHelper.java:269)
        at org.scijava.service.ServiceHelper.loadService(ServiceHelper.java:231)
        at org.scijava.service.ServiceHelper.createServiceRecursively(ServiceHelper.java:340)
        at org.scijava.service.ServiceHelper.createExactService(ServiceHelper.java:269)
        at org.scijava.service.ServiceHelper.loadService(ServiceHelper.java:231)
        at org.scijava.service.ServiceHelper.loadService(ServiceHelper.java:194)
        at org.scijava.service.ServiceHelper.loadServices(ServiceHelper.java:166)
        at org.scijava.Context.<init>(Context.java:278)
        at org.scijava.Context.<init>(Context.java:234)
        at org.scijava.Context.<init>(Context.java:174)
        at org.scijava.Context.<init>(Context.java:160)
        at net.imagej.ImageJ.<init>(ImageJ.java:77)
        at net.imagej.Main.launch(Main.java:61)
Caused by: javassist.CannotCompileException: No code replaced!
        at net.imagej.patcher.CodeHacker$EagerExprEditor.instrument(CodeHacker.java:1280)
        at net.imagej.patcher.CodeHacker.replaceAppNameInCall(CodeHacker.java:443)
        ... 28 more
Traceback (most recent call last):
  File "imagey/imagey.py", line 139, in <module>
    Main.launch()
  File "jnius/jnius_export_class.pxi", line 637, in jnius.JavaMethod.__call__ (jnius/jnius.c:26001)
  File "jnius/jnius_export_class.pxi", line 803, in jnius.JavaMethod.call_staticmethod (jnius/jnius.c:28027)
  File "jnius/jnius_utils.pxi", line 93, in jnius.check_exception (jnius/jnius.c:5115)
jnius.JavaException: JVM exception occurred: Invalid service: net.imagej.legacy.LegacyConsoleService

I guess that this might be caused by incompatibilities in jars. This might be a compatibility issue, as I am using all jars from my local Fiji.app/jars directory except for imglib2 and bigdataviewer-core, which I need in a more recent version for shared memory access between numpy and imglib

I will try with jars from Fiji.app/jars only
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:06
Still raises this exception
I'll have a closer look then
Stefan Helfrich
@stelfrich
May 02 2017 16:07
@hanslovsky that’s an issue with the ij1-patcher actually..
it can’t handle recent versions of ImageJ1 (which have introduced the YesNoCancelDialog)
Merged but not released yet: imagej/ij1-patcher#41
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:09
Thanks @stelfrich
I will replace my ij-patcher jar in my Fiji.app/jars folder with the latest build from master and report back in.
Stefan Helfrich
@stelfrich
May 02 2017 16:09
check with ij-1.51m.jar for example
Curtis Rueden
@ctrueden
May 02 2017 16:10
@hadim Actually, I deprecated the Main.launch method. @hanslovsky is right that calling the launch method of ImageJ gateway itself is better. I can explain why if you are curious.
@hanslovsky That "cannot handle app name" error was fixed already...
First of all: you need ImageJ1 / ImageJ Legacy? Yes or no?
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:11
Right now, I don't need it.
Curtis Rueden
@ctrueden
May 02 2017 16:11
If no, then simply do not include imagej-legacy on your classpath.
Hadrien Mary
@hadim
May 02 2017 16:11
Ok.
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:11
Ok, will do that, even easier
Curtis Rueden
@ctrueden
May 02 2017 16:11
If yes, then some JAR or other is an old version... either ij1-patcher or imagej-legacy most likely.
I believe it was @stelfrich who fixed it.
Stefan Helfrich
@stelfrich
May 02 2017 16:12
Wait. Can you see my messages @ctrueden ?
Curtis Rueden
@ctrueden
May 02 2017 16:12
Yes, it was in ij1-patcher. But the new version has not yet been released.
@stelfrich Oh yeah, I see your post above now.
Sorry for the redundancy.
Stefan Helfrich
@stelfrich
May 02 2017 16:13
(np.. just wondering if my messages reached someone :P)
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:13
I got both your messages. :D Thanks @stelfrich and @ctrueden
Curtis Rueden
@ctrueden
May 02 2017 16:13
I am working on cutting all the releases today.
http://status.scijava.org/ for the masochistic.
So @hanslovsky, hopefully you'll have a net.imagej:imagej:2.0.0-rc-60 (rc-60 AGH) by the end of the week, which does not have that bug.
Philipp Hanslovsky
@hanslovsky
May 02 2017 16:14
great, your work is much appreciated @ctrueden !
Philipp Hanslovsky
@hanslovsky
May 02 2017 18:32
@ctrueden What is the easiest way to add a menu item to ImageJ2 gui? In the old ij.ImageJ I could easily manipulate the menubar through getMenuBar.
Philipp Hanslovsky
@hanslovsky
May 02 2017 18:38
Am I on a good path with ImageJ.window()?
Philipp Hanslovsky
@hanslovsky
May 02 2017 19:49
Or, in other words, what is the best way to add an item to a (sub-)menu that just executes a call to Runnable.run or similar?
Curtis Rueden
@ctrueden
May 02 2017 20:22
@hanslovsky Did you have a look at the MenuService?
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:23
Yes, I know how to parse through it, but I don't know a (simple) way to add a leaf or sub-menu
Curtis Rueden
@ctrueden
May 02 2017 20:23
Do you need to do it dynamically? Or just at the beginning before showing the UI?
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:23
Just at the beginning before showing the UI is fine
but from within python
Curtis Rueden
@ctrueden
May 02 2017 20:24
Do you have a Command plugin whose run() method performs the action you want the menu item to do?
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:25
I don't have that, no. Essentially, I just want to call a python function when I click the menu item. In ImageJ1 I could just add a WindowListener that I implemented in python
Curtis Rueden
@ctrueden
May 02 2017 20:25
The UI agnostic way would be to write such a Command and register it with the CommandService.
Well, you can get to the JMenuBar if you must.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:25
Ok, that sounds good
Curtis Rueden
@ctrueden
May 02 2017 20:26
but if you do that, you rely on the UI being the Swing one.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:26
As long as I can implement that command in python, i.e. it doesn't require Java annotations, I should be able to do that
Curtis Rueden
@ctrueden
May 02 2017 20:26
Depends on how broadly you want that menu item to appear and work, I guess.
Well, I know you can do it in Jython.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:27
Actually, I would prefer to be UI agnostic because it doesn't require knowledge about the ui
Curtis Rueden
@ctrueden
May 02 2017 20:27
But I don't know how clever pyjnius is about expressing Python classes as Java classes. I'm guessing... not clever enough.
Can you write Python code that implements a particular Java interface?
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:27
Yes
That won't be an issue
Curtis Rueden
@ctrueden
May 02 2017 20:27
OK, that's cool then.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:27
I cannot implement abstract classes, but interfaces work nicely.
Cool, I will implement that, then
Thanks for the help!
Slowly moving away from IJ1 ;)
Curtis Rueden
@ctrueden
May 02 2017 20:28
So, make an object which implements Command. Make its run() method do what you want.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:28
Great, I'll let you know if it works
Curtis Rueden
@ctrueden
May 02 2017 20:28
Then call commandService.getCommand(myCommand) and it will give you back a CommandInfo.
Then call commandInfo.setMenuPath(...) on that object.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:29
That sounds easy
Curtis Rueden
@ctrueden
May 02 2017 20:29
Then call moduleService.addModule(commandInfo) to register it
I hope that works!
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:30
I hope I can do it before I have to head out to soccer. Currently working on some non-python stuff but I am curious to find out!
Curtis Rueden
@ctrueden
May 02 2017 20:30
Hmm, checking the code, it is possible that commandService.getCommand is not the way to go.
We need to construct a CommandInfo around your class.
Everything else I said is accurate though hopefully.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:30
:+1:
Curtis Rueden
@ctrueden
May 02 2017 20:31
Should be as easy as new CommandInfo(myCommand.getClass())
Keep me posted; happy to help with any obstacles.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:31
Will do.
Curtis Rueden
@ctrueden
May 02 2017 20:32
I'm also happy to add convenience method(s) somewhere to ease this use case, if you have any insight into what would be effective.
Philipp Hanslovsky
@hanslovsky
May 02 2017 20:32
I might have some later today/tomorrow
Philipp Hanslovsky
@hanslovsky
May 02 2017 21:23
Doesn't work yet and I have to leave now, will post more tomorrow!
Philipp Hanslovsky
@hanslovsky
May 02 2017 21:29
Does the command need to be default constructable?
Christian Dietz
@dietzc
May 02 2017 22:33
you mean having an empty constructor?
yep