Ticket #1992 (reopened defect)
Opened 2013-08-27T10:39:58-05:00
Last modified 2013-10-21T14:20:42-05:00
Delete data can throw exception 2
Reported by: | bdezonia | Owned by: | bdezonia |
---|---|---|---|
Priority: | major | Milestone: | imagej2-b8-analysis |
Component: | Analysis Plugins | Version: | |
Severity: | serious | Keywords: | |
Cc: | leek | Blocked By: | |
Blocking: | #1457 |
Description
Open Organ Of Corti
Run Delete Data plugin
Choose Z, 9, 7
Exception thrown (below)
It looks like a color tool's icon color is getting set to null. This is true if DefaultDatasetView's projector == null. Note that stepping through with debugger does not exhibit problem. So this might be a race condition.
Note that there was an almost exact same bug report with different exception reported and fixed previously (see #1922).
Current exception:
java.lang.NullPointerException
at imagej.ui.swing.SwingIconService$SwingIconDrawer.setIconPixel(SwingIconService.java:110)
at imagej.core.tools.AbstractColorTool.draw(AbstractColorTool.java:220)
at imagej.core.tools.AbstractColorTool.drawIcon(AbstractColorTool.java:177)
at imagej.core.tools.AbstractColorTool.onEvent(AbstractColorTool.java:200)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.scijava.event.DefaultEventService$ProxySubscriber.onEvent(DefaultEventService.java:282)
at org.scijava.event.DefaultEventService$ProxySubscriber.onEvent(DefaultEventService.java:256)
at org.bushe.swing.event.ThreadSafeEventService.publish(ThreadSafeEventService.java:971)
at org.scijava.event.DefaultEventBus.access$201(DefaultEventBus.java:60)
at org.scijava.event.DefaultEventBus$2.run(DefaultEventBus.java:227)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
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)
Change History
comment:1 Changed 2013-09-25T14:29:17-05:00 by bdezonia
- Status changed from new to closed
- Resolution set to fixed
comment:2 Changed 2013-09-30T11:43:53-05:00 by bdezonia
- Status changed from closed to reopened
- Resolution fixed deleted
Lee reports that this fix causes hanging issue elsewhere. I have not yet reverted fix. There are ways to accomodate my change. But I am leaning towards reverting it and having DefaultDatasetView::getColor() return BLACK if the view is not initialized. This would always be safe but would sometimes render incorrectly (for toolbar color icons for instance).
comment:3 Changed 2013-09-30T14:38:47-05:00 by bdezonia
Lee Kamentsky is looking at leaving getColor() synchronized and changing the status update mechanism to be asynchronous. See mail list thread here: http://imagej.net/pipermail/imagej-devel/2013-September/001756.html
comment:5 Changed 2013-10-07T10:19:15-05:00 by bdezonia
- Status changed from reopened to closed
- Resolution set to fixed
Lee's changes were merged. Leaving my fix in place.
comment:6 Changed 2013-10-10T12:59:47-05:00 by bdezonia
- Status changed from closed to reopened
- Resolution fixed deleted
comment:7 Changed 2013-10-10T13:01:48-05:00 by bdezonia
Lee, with your fix for the status service publishing later there is now a bug when exiting the program. You can experience it by launching IJ2 and then closing it. Exception follows. Can you look at this? Or let me know if you can't.
java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1774)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:78)
at org.scijava.thread.DefaultThreadService.run(DefaultThreadService.java:77)
at org.scijava.event.DefaultEventBus.publishLater(DefaultEventBus.java:221)
at org.scijava.event.DefaultEventBus.publishLater(DefaultEventBus.java:109)
at org.scijava.event.DefaultEventService.publishLater(DefaultEventService.java:101)
at org.scijava.app.DefaultStatusService.publish(DefaultStatusService.java:116)
at org.scijava.app.DefaultStatusService.showStatus(DefaultStatusService.java:70)
at imagej.data.animation.DefaultAnimationService.stopAll(DefaultAnimationService.java:114)
at imagej.data.animation.DefaultAnimationService.dispose(DefaultAnimationService.java:139)
at org.scijava.Context.dispose(Context.java:305)
at imagej.core.commands.app.QuitProgram.run(QuitProgram.java:94)
at imagej.command.CommandModule.run(CommandModule.java:196)
at imagej.module.ModuleRunner.run(ModuleRunner.java:168)
at imagej.module.ModuleRunner.call(ModuleRunner.java:129)
at imagej.module.ModuleRunner.call(ModuleRunner.java:68)
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)
comment:8 Changed 2013-10-16T13:24:23-05:00 by bdezonia
Note if you remove the status update code from stopAll() in DefaultAnimationService you can get the error in other ways. For instance making such a change you get an error if you open a sample image and then close the app. The exception then becomes:
[ERROR] ImageJ 1.x plugin threw exception
java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1774)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:78)
at org.scijava.thread.DefaultThreadService.run(DefaultThreadService.java:77)
at org.scijava.event.DefaultEventBus.publishLater(DefaultEventBus.java:221)
at org.scijava.event.DefaultEventBus.publishLater(DefaultEventBus.java:109)
at org.scijava.event.DefaultEventService.publishLater(DefaultEventService.java:101)
at imagej.data.display.DefaultDatasetView.updateLUTs(DefaultDatasetView.java:534)
at imagej.data.display.DefaultDatasetView.setColorTable(DefaultDatasetView.java:201)
at imagej.legacy.translate.ColorTableHarmonizer.assignColorTables(ColorTableHarmonizer.java:342)
at imagej.legacy.translate.ColorTableHarmonizer.updateDisplay(ColorTableHarmonizer.java:80)
at imagej.legacy.translate.Harmonizer.updateDisplay(Harmonizer.java:215)
at imagej.legacy.plugin.LegacyCommand$LegacyCommandThread.updateDisplaysFromImagePluses(LegacyCommand.java:378)
at imagej.legacy.plugin.LegacyCommand$LegacyCommandThread.run(LegacyCommand.java:217)
comment:9 Changed 2013-10-16T15:15:45-05:00 by leek
I've submitted a patch for this as a pull request:
https://github.com/scijava/scijava-common/pull/14
The error happens during shutdown when the DefaultThreadService has closed its execution queue, causing rejection of the request to run the runnable. Since the app is on its way to shutting down, there's not much point in publishing the status event since the GUI is being taken down - I catch the exception and redirect the status message to logging.
Fixed with commit 6d4693b790eb19e759d8c0e175a04ecd5f75ea45