Strange, I've cherrypicked the patch to my master branch of scijava-common and have successfully run it against the master branch of imagej and I don't see your error message when I close.
The patch is general and solves the case where you open a sample image and close - both cases catch the error. I could implement Curtis's suggestion and mark the status service as closed after dispatch - that's probably the correct way to do it, but this is pretty robust and does something useful with status messages sent during shutdown. On Wed, Oct 16, 2013 at 4:25 PM, Barry DeZonia <[email protected]> wrote: > Lee, > > Using your patch I have an error. Open program and exit and I get this: > > java.lang.IllegalStateException: Context already injected: > org.scijava.AbstractContextual#context > > at org.scijava.Context.inject(Context.java:281) > > at org.scijava.AbstractContextual.setContext(AbstractContextual.java:66) > > at org.scijava.event.DefaultEventService.publishLater( > DefaultEventService.java:100) > > at org.scijava.app.DefaultStatusService.publish( > DefaultStatusService.java:123) > > at org.scijava.app.DefaultStatusService.showStatus( > DefaultStatusService.java:76) > > at imagej.module.ModuleRunner.run(ModuleRunner.java:155) > > at imagej.module.ModuleRunner.call(ModuleRunner.java:129) > > at imagej.module.ModuleRunner.call(ModuleRunner.java:1) > > at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) > > at java.util.concurrent.FutureTask.run(FutureTask.java:138) > > at java.util.concurrent.ThreadPoolExecutor$Worker.runTask( > ThreadPoolExecutor.java:895) > > at java.util.concurrent.ThreadPoolExecutor$Worker.run( > ThreadPoolExecutor.java:918) > > at java.lang.Thread.run(Thread.java:680) > > > Plus said patch will not affect the open sample image and then exit > crashes. But that may need to be filed as a separate bug. > > > On Wed, Oct 16, 2013 at 3:04 PM, Lee Kamentsky <[email protected]>wrote: > >> Maybe I wasn't patient enough about refreshing everything.... will submit >> patch momentarily, but have only tested it on a modified version of the >> scijava-common-2.2.0 branch. I'd appreciate you merging and trying it. >> >> >> On Wed, Oct 16, 2013 at 3:54 PM, Barry DeZonia <[email protected]>wrote: >> >>> In imagej/pom.xml I added: >>> >>> <scijava-common.version>2.2.1-SNAPSHOT</scijava-common.version> >>> >>> in the <properties> section >>> >>> >>> On Wed, Oct 16, 2013 at 2:46 PM, Lee Kamentsky >>> <[email protected]>wrote: >>> >>>> Are you editing one of the POMs to pick up the 2.2.1-SNAPSHOT version >>>> of scijava-common? >>>> >>>> >>>> On Wed, Oct 16, 2013 at 3:45 PM, Barry DeZonia <[email protected]>wrote: >>>> >>>>> I'm not having any problems building scijava-common master against IJ2 >>>>> master. >>>>> >>>>> >>>>> On Wed, Oct 16, 2013 at 2:25 PM, Lee Kamentsky < >>>>> [email protected]> wrote: >>>>> >>>>>> I have a very simple fix in scijava-common, but it seems that the >>>>>> head of the scijava-common master branch is not going to build with the >>>>>> head of the imagej master branch. How should I proceed? I could branch >>>>>> off >>>>>> off scijava-common-2.2.0 I suppose. >>>>>> >>>>>> >>>>>> On Wed, Oct 16, 2013 at 2:44 PM, Barry DeZonia <[email protected]>wrote: >>>>>> >>>>>>> Thanks. I also updated the ticket a bit a few minutes ago. In my >>>>>>> second example problem (closing app with sample image open) it looks >>>>>>> like >>>>>>> the original open samples legacy command was not finishing its run. Not >>>>>>> sure if this is related to your event processing changes. >>>>>>> >>>>>>> >>>>>>> On Wed, Oct 16, 2013 at 1:19 PM, Lee Kamentsky < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Sorry, I missed it. I'll see if I can take a look at it, >>>>>>>> >>>>>>>> >>>>>>>> On Wed, Oct 16, 2013 at 2:15 PM, Barry DeZonia >>>>>>>> <[email protected]>wrote: >>>>>>>> >>>>>>>>> Lee did you see I reopened ticket #1992 ( >>>>>>>>> http://trac.imagej.net/ticket/1992) that was related to this code >>>>>>>>> change? >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, Oct 7, 2013 at 10:15 AM, Barry DeZonia <[email protected] >>>>>>>>> > wrote: >>>>>>>>> >>>>>>>>>> Merged >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, Sep 30, 2013 at 2:34 PM, Lee Kamentsky < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> I submitted a patch to scijava-common with the changes. >>>>>>>>>>> >>>>>>>>>>> https://github.com/scijava/scijava-common/pull/13 >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Mon, Sep 30, 2013 at 3:32 PM, Barry DeZonia < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> A proposed fix would be good Lee. I'd like to test the async >>>>>>>>>>>> status update code for responsiveness (i.e. when opening a large >>>>>>>>>>>> image >>>>>>>>>>>> let's say). Let me know when your fix is in place. Thanks. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Sep 27, 2013 at 6:54 AM, Lee Kamentsky < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Thanks Barry, the email was a little rushed - finished it >>>>>>>>>>>>> while going out the door. What do you think about sending the >>>>>>>>>>>>> status >>>>>>>>>>>>> messages asynchronously? It looks to me like the AWT event >>>>>>>>>>>>> processing will >>>>>>>>>>>>> display them in the order received, so that makes sure that a >>>>>>>>>>>>> "Finished" >>>>>>>>>>>>> message will be seen after a "% complete" message. Status >>>>>>>>>>>>> reporting is such >>>>>>>>>>>>> a common thing - it'd be a shame for all the worker threads to >>>>>>>>>>>>> stall >>>>>>>>>>>>> because a user was using ImageJ to watch a movie of a cat falling >>>>>>>>>>>>> off a TV >>>>>>>>>>>>> while their batch job was running. >>>>>>>>>>>>> >>>>>>>>>>>>> I think I'll submit a patch to DefaultStatusService for asynch >>>>>>>>>>>>> reporting and maybe Curtis or you could look it over and accept >>>>>>>>>>>>> it. If you >>>>>>>>>>>>> reject, NP. >>>>>>>>>>>>> >>>>>>>>>>>>> --Lee >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Sep 26, 2013 at 7:53 PM, Barry DeZonia < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Lee, >>>>>>>>>>>>>> >>>>>>>>>>>>>> I added the synchronized keyword yesterday to fix a bug. We >>>>>>>>>>>>>> can undo that change. I can work around the problem in another >>>>>>>>>>>>>> fashion if >>>>>>>>>>>>>> necessary. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Sep 26, 2013 at 3:57 PM, Lee Kamentsky < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi all, I'm getting a deadly embrace that happens when the >>>>>>>>>>>>>>> AWT event queue thread tries to get a lock within >>>>>>>>>>>>>>> DefaultDatasetView.getColor and when >>>>>>>>>>>>>>> DefaultStatusService.showStatus on a >>>>>>>>>>>>>>> worker thread tries to publish a synchronous request for status >>>>>>>>>>>>>>> display >>>>>>>>>>>>>>> after taking the DefaultDatasetView's lock in >>>>>>>>>>>>>>> DefaultDatasetView.rebuild. >>>>>>>>>>>>>>> It happens periodically, but it's timing-dependent, so not so >>>>>>>>>>>>>>> reproducible. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The bug is somewhat debatable. Possible candidates: It's a >>>>>>>>>>>>>>> little drastic for DefaultDatasetView.getColor to synchronize >>>>>>>>>>>>>>> on the view >>>>>>>>>>>>>>> itself. Maybe some proxy for the color system could have a >>>>>>>>>>>>>>> synchronizing >>>>>>>>>>>>>>> object. The other candidate is DefaultEventService.showStatus >>>>>>>>>>>>>>> which could >>>>>>>>>>>>>>> use EventService.publishLater - I don't think there's much need >>>>>>>>>>>>>>> for status >>>>>>>>>>>>>>> publishers to wait around for the status to show on the screen. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The two stack traces: >>>>>>>>>>>>>>> Thread [AWT-EventQueue-0] (Suspended) >>>>>>>>>>>>>>> DefaultDatasetView.getColor(ChannelCollection) line: 261 >>>>>>>>>>>>>>> Synchronized >>>>>>>>>>>>>>> method on DefaultDatasetView >>>>>>>>>>>>>>> FgColorTool(AbstractColorTool).drawIcon() line: 175 >>>>>>>>>>>>>>> FgColorTool(AbstractColorTool).onEvent(DisplayActivatedEvent) >>>>>>>>>>>>>>> line: 184 >>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) >>>>>>>>>>>>>>> line: not available [native method] >>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 >>>>>>>>>>>>>>> DelegatingMethodAccessorImpl.invoke(Object, Object[]) >>>>>>>>>>>>>>> line: 25 >>>>>>>>>>>>>>> Method.invoke(Object, Object...) line: 597 >>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(E) line: 282 >>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(Object) line: >>>>>>>>>>>>>>> 1 >>>>>>>>>>>>>>> DefaultEventBus(ThreadSafeEventService).publish(Object, >>>>>>>>>>>>>>> String, Object, List, List, StackTraceElement[]) line: 971 >>>>>>>>>>>>>>> DefaultEventBus.access$1(DefaultEventBus, Object, String, >>>>>>>>>>>>>>> Object, List, List, StackTraceElement[]) line: 1 >>>>>>>>>>>>>>> DefaultEventBus$1.run() line: 201 >>>>>>>>>>>>>>> DefaultThreadService.invoke(Runnable) line: 91 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object, String, Object, List, >>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object) line: 86 >>>>>>>>>>>>>>> DefaultEventService.publish(E) line: 95 >>>>>>>>>>>>>>> DefaultDisplayService.setActiveDisplay(Display<?>) line: >>>>>>>>>>>>>>> 129 >>>>>>>>>>>>>>> DefaultDisplayService.onEvent(WinActivatedEvent) line: 247 >>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) >>>>>>>>>>>>>>> line: not available [native method] >>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 >>>>>>>>>>>>>>> DelegatingMethodAccessorImpl.invoke(Object, Object[]) >>>>>>>>>>>>>>> line: 25 >>>>>>>>>>>>>>> Method.invoke(Object, Object...) line: 597 >>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(E) line: 282 >>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(Object) line: >>>>>>>>>>>>>>> 1 >>>>>>>>>>>>>>> DefaultEventBus(ThreadSafeEventService).publish(Object, >>>>>>>>>>>>>>> String, Object, List, List, StackTraceElement[]) line: 971 >>>>>>>>>>>>>>> DefaultEventBus.access$1(DefaultEventBus, Object, String, >>>>>>>>>>>>>>> Object, List, List, StackTraceElement[]) line: 1 >>>>>>>>>>>>>>> DefaultEventBus$1.run() line: 201 >>>>>>>>>>>>>>> DefaultThreadService.invoke(Runnable) line: 91 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object, String, Object, List, >>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object) line: 86 >>>>>>>>>>>>>>> DefaultEventService.publish(E) line: 95 >>>>>>>>>>>>>>> AWTWindowEventDispatcher.windowActivated(WindowEvent) >>>>>>>>>>>>>>> line: 94 >>>>>>>>>>>>>>> SwingDisplayWindow(Window).processWindowEvent(WindowEvent) >>>>>>>>>>>>>>> line: 1877 >>>>>>>>>>>>>>> SwingDisplayWindow(JFrame).processWindowEvent(WindowEvent) >>>>>>>>>>>>>>> line: 274 >>>>>>>>>>>>>>> SwingDisplayWindow(Window).processEvent(AWTEvent) line: 1823 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 4630 >>>>>>>>>>>>>>> SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 2099 >>>>>>>>>>>>>>> SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 2478 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEvent(AWTEvent) line: >>>>>>>>>>>>>>> 4460 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> DefaultKeyboardFocusManager(KeyboardFocusManager).redispatchEvent(Component, >>>>>>>>>>>>>>> AWTEvent) line: 1850 >>>>>>>>>>>>>>> DefaultKeyboardFocusManager.typeAheadAssertions(Component, >>>>>>>>>>>>>>> AWTEvent) line: 910 >>>>>>>>>>>>>>> DefaultKeyboardFocusManager.dispatchEvent(AWTEvent) line: >>>>>>>>>>>>>>> 409 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 4502 >>>>>>>>>>>>>>> SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 2099 >>>>>>>>>>>>>>> SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent) line: >>>>>>>>>>>>>>> 2478 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEvent(AWTEvent) >>>>>>>>>>>>>>> line: 4460 >>>>>>>>>>>>>>> EventQueue.dispatchEvent(AWTEvent) line: 599 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent(SentEvent).dispatch() >>>>>>>>>>>>>>> line: 55 >>>>>>>>>>>>>>> DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent.dispatch() >>>>>>>>>>>>>>> line: 183 >>>>>>>>>>>>>>> DefaultKeyboardFocusManager.sendMessage(Component, >>>>>>>>>>>>>>> AWTEvent) line: 210 >>>>>>>>>>>>>>> DefaultKeyboardFocusManager.dispatchEvent(AWTEvent) line: 286 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 4502 >>>>>>>>>>>>>>> SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 2099 >>>>>>>>>>>>>>> SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent) >>>>>>>>>>>>>>> line: 2478 >>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEvent(AWTEvent) line: >>>>>>>>>>>>>>> 4460 >>>>>>>>>>>>>>> EventQueue.dispatchEvent(AWTEvent) line: 599 >>>>>>>>>>>>>>> SequencedEvent.dispatch() line: 101 >>>>>>>>>>>>>>> EventQueue.dispatchEvent(AWTEvent) line: 597 >>>>>>>>>>>>>>> EventDispatchThread.pumpOneEventForFilters(int) line: 269 >>>>>>>>>>>>>>> EventDispatchThread.pumpEventsForFilter(int, Conditional, >>>>>>>>>>>>>>> EventFilter) line: 184 >>>>>>>>>>>>>>> EventDispatchThread.pumpEventsForHierarchy(int, Conditional, >>>>>>>>>>>>>>> Component) line: 174 >>>>>>>>>>>>>>> EventDispatchThread.pumpEvents(int, Conditional) line: 169 >>>>>>>>>>>>>>> EventDispatchThread.pumpEvents(Conditional) line: 161 >>>>>>>>>>>>>>> EventDispatchThread.run() line: 122 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thread [SciJava-4b2922f6-Thread-27] (Suspended) >>>>>>>>>>>>>>> Object.wait(long) line: not available [native method] >>>>>>>>>>>>>>> EventQueue$1AWTInvocationLock(Object).wait() line: 485 Waiting >>>>>>>>>>>>>>> for AWT event thread to read invocation request. >>>>>>>>>>>>>>> EventQueue.invokeAndWait(Runnable) line: 993 >>>>>>>>>>>>>>> DefaultThreadService.invoke(Runnable) line: 95 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object, String, Object, List, >>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195 >>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object) line: 86 >>>>>>>>>>>>>>> DefaultEventService.publish(E) line: 95 >>>>>>>>>>>>>>> DefaultStatusService.showStatus(int, int, String) line: 77 >>>>>>>>>>>>>>> DefaultMinMaxMethod<T>.report() line: 296 >>>>>>>>>>>>>>> DefaultMinMaxMethod<T>.process() line: 155 >>>>>>>>>>>>>>> DefaultAutoscaleMethod<T>.getRange(IterableInterval<T>) >>>>>>>>>>>>>>> line: 70 >>>>>>>>>>>>>>> DefaultAutoscaleService.getDefaultIntervalRange(IterableInterval<RealType<?>>) >>>>>>>>>>>>>>> line: 97 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> DefaultAutoscaleService.getDefaultRandomAccessRange(RandomAccessibleInterval<RealType<?>>) >>>>>>>>>>>>>>> line: 105 >>>>>>>>>>>>>>> DefaultDatasetView.autoscale(int) line: 176 >>>>>>>>>>>>>>> DefaultDatasetView.initializeView(boolean) line: 499 >>>>>>>>>>>>>>> DefaultDatasetView.rebuild() line: 383 Takes the >>>>>>>>>>>>>>> DefaultDatasetView lock. >>>>>>>>>>>>>>> DefaultImageDisplay.rebuild() line: 140 >>>>>>>>>>>>>>> DefaultImageDisplay.display(Object) line: 273 >>>>>>>>>>>>>>> DefaultOverlayService.addOverlays(ImageDisplay, >>>>>>>>>>>>>>> List<Overlay>) line: 148 >>>>>>>>>>>>>>> TurboRegRegister.run() line: 144 >>>>>>>>>>>>>>> CommandModule.run() line: 196 >>>>>>>>>>>>>>> ModuleRunner.run() line: 168 >>>>>>>>>>>>>>> ModuleRunner.call() line: 129 >>>>>>>>>>>>>>> ModuleRunner.call() line: 1 >>>>>>>>>>>>>>> FutureTask$Sync.innerRun() line: 303 >>>>>>>>>>>>>>> FutureTask<V>.run() line: 138 >>>>>>>>>>>>>>> ThreadPoolExecutor$Worker.runTask(Runnable) line: 886 >>>>>>>>>>>>>>> ThreadPoolExecutor$Worker.run() line: 908 >>>>>>>>>>>>>>> Thread.run() line: 662 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> ImageJ-devel mailing list >>>>>>>>>>>>>>> [email protected] >>>>>>>>>>>>>>> http://imagej.net/mailman/listinfo/imagej-devel >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >
_______________________________________________ ImageJ-devel mailing list [email protected] http://imagej.net/mailman/listinfo/imagej-devel
