You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Per-Erik Svensson <pe...@gmail.com> on 2011/08/14 21:33:51 UTC

Gogo Swing?

Hi,

I'm currently trying to set up a swing frame to display and send commands to
gogo shell. In doing so, I thought it would be ok to do the following

CommandProcessor processor = ...

PipedInputStream outReader = new PipedInputStream();
PrintStream out = new PrintStream(new PipedOutputStream(outReader));

CommandSession session = processor.createSession(System.in, out, out);

And then to "send commands" just using

session.execute(command);

And then read my PipedInputStream (outReader) to echo anything that is
written to "out" into my JFrame. (And if session.execute returns a non-null
object use the session.format to print it to my JFrame directly.)

All this works fine and swell until I try to pipe commands as in

lb | grep org.apache.felix

That command works, but someone is then killing the thread of the "out"
stream because next time I read my PipedInputStream (outReader) i get:

java.io.IOException Pipe broken
    java.io.PipedInputStream.read(PipedInputStream.java:305)
    java.io.PipedInputStream.read(PipedInputStream.java:361)
    java.io.InputStream.read(InputStream.java:85)

net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:59)

net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:22)
    javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    java.util.concurrent.FutureTask.run(FutureTask.java:138)
    javax.swing.SwingWorker.run(SwingWorker.java:316)

java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    java.lang.Thread.run(Thread.java:619)

Which, as far as I know, only occurs if the thread of the writer is dead
(the writer being "out" above).

So, now I'm guessing that I'm doing things wrong. Any suggestions would be
greatly appreciated. The reason I'm doing this is two-fold

a) The command prompt of windows... well.. isn't that great. Copy-Paste is a
starter! :)
b) Our app isn't run through a command prompt so System.out, System.in isn't
really available but it would still be neat to be able to for example list
running bundles and all that good stuff. Mainly for debugging purposes that
is.

As I said, any help would be great! :)

Best regards,
Per-Erik Svensson

Re: Gogo Swing?

Posted by Per-Erik Svensson <pe...@gmail.com>.
Yes, I too suspect that it is somewhere around ThreadIO that the problem
lies. However, I'm not sure if it's me doing anything wrong or if it is a
"bug" in gogo runtime.

The main difference between your code (or rather the telnet gogo code) is
that I use a piped output stream. The problem I see is not that the stream
itself is closed but that the thread dies and the reader-side (input) of the
pipe throws an exception because the "Pipe is broken".

What "the dying thread" is I cannot figure out simply because of the
ThreadIO stuff. I know it's there to guard the streams but I cannot figure
out what thread that needs to be kept alive for the pipe to "not get
broken".

More specifically, I don't know how to guard my pipe!!

If no one can see any obvious reason for why sending a piped output stream
as the printstream parameter to CommandProcessor.createSession, I'll file a
bug for this. I'll test first if anything changes if I send in my own
inputstream (that will mostly go unused anyway, I guess).

And of course, thanks for the answer! :)

Regards,
Per-Erik Svensson


On Wed, Aug 17, 2011 at 8:14 AM, Derek Baum <de...@baums.org.uk> wrote:

> The gogo telnetd (src/main/java/org/apache/felix/gogo/shell/Telnet.java)
> successfully redirects IO to the telnet session:
>
>                final Socket socket = server.accept();
>                PrintStream out = new PrintStream(socket.getOutputStream());
>                final CommandSession session = processor.createSession(
>                    socket.getInputStream(), out, out);
>
>                Thread handler = new Thread()
>                {
>                    public void run()
>                    {
>                        try
>                        {
>                            session.execute("gosh --login --noshutdown");
>
>
> The only difference from what you're doing is that telnetd also supplies a
> new InputStream.
> I don't know why this works and what you're doing doesn't. It is probably
> happening in the ThreadIOImpl, which is responsible for multiplexing
> System.in and System.out between threads.
>
>
> Derek
>
>
>
> On 14 August 2011 20:33, Per-Erik Svensson <pererik.svensson@gmail.com
> >wrote:
>
> > Hi,
> >
> > I'm currently trying to set up a swing frame to display and send commands
> > to
> > gogo shell. In doing so, I thought it would be ok to do the following
> >
> > CommandProcessor processor = ...
> >
> > PipedInputStream outReader = new PipedInputStream();
> > PrintStream out = new PrintStream(new PipedOutputStream(outReader));
> >
> > CommandSession session = processor.createSession(System.in, out, out);
> >
> > And then to "send commands" just using
> >
> > session.execute(command);
> >
> > And then read my PipedInputStream (outReader) to echo anything that is
> > written to "out" into my JFrame. (And if session.execute returns a
> non-null
> > object use the session.format to print it to my JFrame directly.)
> >
> > All this works fine and swell until I try to pipe commands as in
> >
> > lb | grep org.apache.felix
> >
> > That command works, but someone is then killing the thread of the "out"
> > stream because next time I read my PipedInputStream (outReader) i get:
> >
> > java.io.IOException Pipe broken
> >    java.io.PipedInputStream.read(PipedInputStream.java:305)
> >    java.io.PipedInputStream.read(PipedInputStream.java:361)
> >    java.io.InputStream.read(InputStream.java:85)
> >
> >
> >
> net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:59)
> >
> >
> >
> net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:22)
> >    javax.swing.SwingWorker$1.call(SwingWorker.java:277)
> >    java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
> >    java.util.concurrent.FutureTask.run(FutureTask.java:138)
> >    javax.swing.SwingWorker.run(SwingWorker.java:316)
> >
> >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> >
> >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> >    java.lang.Thread.run(Thread.java:619)
> >
> > Which, as far as I know, only occurs if the thread of the writer is dead
> > (the writer being "out" above).
> >
> > So, now I'm guessing that I'm doing things wrong. Any suggestions would
> be
> > greatly appreciated. The reason I'm doing this is two-fold
> >
> > a) The command prompt of windows... well.. isn't that great. Copy-Paste
> is
> > a
> > starter! :)
> > b) Our app isn't run through a command prompt so System.out, System.in
> > isn't
> > really available but it would still be neat to be able to for example
> list
> > running bundles and all that good stuff. Mainly for debugging purposes
> that
> > is.
> >
> > As I said, any help would be great! :)
> >
> > Best regards,
> > Per-Erik Svensson
> >
>

Re: Gogo Swing?

Posted by Derek Baum <de...@baums.org.uk>.
The gogo telnetd (src/main/java/org/apache/felix/gogo/shell/Telnet.java)
successfully redirects IO to the telnet session:

                final Socket socket = server.accept();
                PrintStream out = new PrintStream(socket.getOutputStream());
                final CommandSession session = processor.createSession(
                    socket.getInputStream(), out, out);

                Thread handler = new Thread()
                {
                    public void run()
                    {
                        try
                        {
                            session.execute("gosh --login --noshutdown");


The only difference from what you're doing is that telnetd also supplies a
new InputStream.
I don't know why this works and what you're doing doesn't. It is probably
happening in the ThreadIOImpl, which is responsible for multiplexing
System.in and System.out between threads.


Derek



On 14 August 2011 20:33, Per-Erik Svensson <pe...@gmail.com>wrote:

> Hi,
>
> I'm currently trying to set up a swing frame to display and send commands
> to
> gogo shell. In doing so, I thought it would be ok to do the following
>
> CommandProcessor processor = ...
>
> PipedInputStream outReader = new PipedInputStream();
> PrintStream out = new PrintStream(new PipedOutputStream(outReader));
>
> CommandSession session = processor.createSession(System.in, out, out);
>
> And then to "send commands" just using
>
> session.execute(command);
>
> And then read my PipedInputStream (outReader) to echo anything that is
> written to "out" into my JFrame. (And if session.execute returns a non-null
> object use the session.format to print it to my JFrame directly.)
>
> All this works fine and swell until I try to pipe commands as in
>
> lb | grep org.apache.felix
>
> That command works, but someone is then killing the thread of the "out"
> stream because next time I read my PipedInputStream (outReader) i get:
>
> java.io.IOException Pipe broken
>    java.io.PipedInputStream.read(PipedInputStream.java:305)
>    java.io.PipedInputStream.read(PipedInputStream.java:361)
>    java.io.InputStream.read(InputStream.java:85)
>
>
> net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:59)
>
>
> net.steamingbeans.runrun.ui.StdOutReader.doInBackground(StdOutReader.java:22)
>    javax.swing.SwingWorker$1.call(SwingWorker.java:277)
>    java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
>    java.util.concurrent.FutureTask.run(FutureTask.java:138)
>    javax.swing.SwingWorker.run(SwingWorker.java:316)
>
>
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>    java.lang.Thread.run(Thread.java:619)
>
> Which, as far as I know, only occurs if the thread of the writer is dead
> (the writer being "out" above).
>
> So, now I'm guessing that I'm doing things wrong. Any suggestions would be
> greatly appreciated. The reason I'm doing this is two-fold
>
> a) The command prompt of windows... well.. isn't that great. Copy-Paste is
> a
> starter! :)
> b) Our app isn't run through a command prompt so System.out, System.in
> isn't
> really available but it would still be neat to be able to for example list
> running bundles and all that good stuff. Mainly for debugging purposes that
> is.
>
> As I said, any help would be great! :)
>
> Best regards,
> Per-Erik Svensson
>