Search code examples
javamax-msp-jitter

Java: How to explicitly redirect System.err to the console (i.e. restore the default behavior)?


I'm writing a plugin for a closed source application called Max/MSP. To work with Max/MSP, my code needs to extend a class provided by the vendor (com.cycling74.max.MaxObject). This class overrides System.err, so that calls to System.err.println direct messages to a special error log provided by the application.

This behaviour is fine in deployment, but it's problematic during testing. I'm presently trying to write a test suite that runs my code outside of the host application. When I do this, calls to System.err raise exceptions because the application's error log isn't available.

Does anyone know how I can "undo" Max/MSP's error redirection, so that, during testing, calls to System.err.println show up in the java console?

EDIT

I tried @MadProgrammer's suggestion of cacheing a reference to the error PrintStream before creating my Max object.

import com.cycling74.max.*;

public class MyMaxObject extends MaxObject{

    public MyMaxObject(){}

    public static void main(String[] args){
        PrintStream oldError = System.err;
        MyMaxObject o = new MyMaxObject();
        System.setErr(oldError);
}

I can't get this to work. When I run this code in a debugger, I find that System.err has type com.cycling74.io.ErrorStream at the first line of my main method. So it seems that the redirection has already happened by then. If this is the case, how can I get a reference to the error stream before it's redirected? (Where on earth would I put that code, if not at the top of Main?)

EDIT 2

Ok, figured it out. I just needed to move my test code (e.g. the Main method above) into a separate class. Once I did this @MadProgrammer's solution worked perfectly.


Solution

  • First, you need a reference to System.err BEFORE it's redirected.

    PrintStream oldError = System.err;
    

    Once you've initialized MaxObject (or what ever part of the system overrides the System.err you need to reassign the reference...

    System.setErr(oldError);