0

I am attempting to make a Java program in which a user can select any .class or .jar file from their computer. My program will then pop up a JInternalFrame with a JEditorPane in it as the console, capturing any console output from the user's program. Note that I do not want to capture just System.err or System.out calls, but ALL PrintStream calls that go to the console.

(individual question from IDE-Style program running )

asked Oct 29, 2010 at 19:38

2 Answers 2

3

You can catch everything that is printed through System.out using System.setOut like this:

import java.io.*;
class SystemOutLogging {
 public static void main(String[] args) throws IOException,
 ClassNotFoundException {
 final PrintStream original = System.out;
 System.setOut(new PrintStream("programlog.txt") {
 public void println(String str) {
 process(str + "\n");
 }
 public void print(String str) {
 process(str);
 }
 private void process(String str) {
 // Fill some JEditorPane
 original.println("Program printed: \"" + str + "\"");
 }
 });
 System.out.print("Hello ");
 System.out.println(" World");
 }
}

Prints:

Program printed: "Hello "
Program printed: " World
"

(There is a System.setErr and System.setIn that works similarly.)

If you want to catch stuff that the "subprogram" prints through System.out.println you're in trouble, because System.out is a static so if you launch multiple "subprograms" you'll end up with a mess (since you can't hand a separate System class to each subprogram).

In a situation like this, I honestly think it would be a better idea to launch a separate process through ProcessBuilder. The standard input / output streams of the resulting process could easily be logged.

(p.s. When I think about it, you could probably check the current thread group in the println implementation, and from that decide which subprogram that actually invoked the println method)

answered Oct 29, 2010 at 19:43
Sign up to request clarification or add additional context in comments.

5 Comments

IDEs like NetBeans seem to have no trouble capturing multiple programs' System.out calls. Also, this does not address the part about placing all the calls in a JEditorPane
NetBeans and Eclipse are extremely complex pieces of software. Don't expect to be able to replicate their systems. The example I provided gives you a "process"-method. You do whatever you need with the strings in that method. Appending it to a JEditorPane shouldn't be too hard from that point.
while it's true that a single programmer should baulk before attempting something the size of Eclipse or NetBeans, they're still just programs. Replicating a bit of their functionality (in this case capturing process output) is not necessarily hard or something outside reasonable expectations.
@Burleigh Bear, agreed. In this case however, he doesn't want to spawn a new process. I for one can't see how to solve this elegantly...
ah, I didn't read his other question. Silly me. By the way, I like your p.s. in the answer. +1.
0

If you're starting the user's .jar file using Runtime.exec(), you'll get a Process object. That Object will allow you access to the launched processes System.out, System.in and System.err streams.

See: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html

You can take read from the err and out streams, and append to your JEditorPane using the usual setText type methods.

answered Oct 29, 2010 at 21:18

1 Comment

If you read the related question, you'd know that he doesn't consider this as an option.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.