Login  Register

Re: Using System.out and System.err from ImageJ plugins (Java)

Posted by dscho on Feb 28, 2013; 8:17pm
URL: http://imagej.273.s1.nabble.com/Using-System-out-and-System-err-from-ImageJ-plugins-Java-tp5001799p5001921.html

Dear Wayne,

On Wed, 27 Feb 2013, Rasband, Wayne (NIH/NIMH) [E] wrote:

> On Feb 27, 2013, at 4:24 PM, Johannes Schindelin wrote:
>
> > On Wed, 27 Feb 2013, Johannes Schindelin wrote:
> >
> >> On Wed, 27 Feb 2013, Johannes Schindelin wrote:
> >>
> >>> On Wed, 27 Feb 2013, Rasband, Wayne (NIH/NIMH) [E] wrote:
> >>>
> >>>> You can redirect System.out and System.err messages to the Log
> >>>> window by enabling debug mode in Edit>Options>Misc.
> >>>
> >>> [...] this interferes with Fiji's stdout/stderr handling. I am fixing
> >>> it as we speak.
> >>
> >> I just tested this Javascript after downloading and starting
> >> http://imagej.net/ij.jar:
> >>
> >> importClass(Packages.java.lang.System);
> >> System.err.println("Hello");
> >>
> >> It did not interfere with Fiji's redirection -- unexpectedly.
> >
> > I found out why it did not work in my test: I activated the debug mode
> > using the -debug command-line option. And while it seems that the very
> > same code was added in three places (ij.macro.Functions#setOption(),
> > ij.plugin.Options#miscOptions() and
> > ij.text.TextWindow#close(boolean)), it was not added at the two other
> > places in ij.jar where debugMode can be activated:
> > ij.macro.Functions#restoreSettings() and ij.ImageJ#main(String[]).
>
> I think I fixed these problems (in ImageJ 1.47m9) by adding a
> IJ.setDebugMode(boolean) method and replacing all instances of
> "IJ.debugMode=b" with "IJ.setDebugMode(b)". I also updated the Git
> repository.

Great!

> > And of course, all 3rd-party plugins setting IJ.debugMode directly
> > cannot trigger the redirection automatically. That is why I took pains
> > of switching on the redirection at all times, mirroring the text to
> > the Log window only when IJ.debugMode == true.
>
> Plugins can use IJ.setDebugMode(true).

Of course plugins using newer ij.jar can, but as you know, not everybody
has the luxury of being able to upgrade.

And for backwards-compatibility, the public static boolean needs to be
preserved and it will be all-too-easy to set it directly for plugin
developers.

Nevertheless, I really like that setDebugMode() was added!

> > This is unfortunately not the only issue I fixed in Fiji's redirection
> > and that frustratingly now crops up again in ImageJ 1.x'
> > reimplementation:
> >
> > In batch mode, one needs to take great pains to avoid the redirection.
> > Otherwise, IJ#log(String) will detect that ImageJ is running in batch
> > mode and print to stdout instead. Which will ask IJ#log(String) to
> > output again, causing an infinite loop.
>
> I fixed this, I think, by changing
>
>    } else
>       System.out.println(s);
>
> to
>
>    } else {
>       LogStream.redirectSystem(false);
>       System.out.println(s);
>    }
>
> in the IJ.log() method.

Without having tested it, I fear that this switches off the redirection if
somebody runs a macro that prints anything to the log, even if the debug
mode was not switched off. And even redirecting again after calling
System.out.println() would be dangerous: it is not at all thread-safe.

Hence my insistence on a way to detect whether stdout/stderr is already
redirected.

Ciao,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html