0

Im running some code and expecting to get a specific message sent to Systen.err to come out at one point, but for some reason its coming out at another point. Here is the code -

public static void main(String[] args) throws Exception {       
        System.out.println("File 1:");      
        for (NormalizedEntity ne : theSolution.entities.values()){
            System.out.println(ne);
        }

        System.out.println("\nFile 2:");
        for (NormalizedEntity ne : theSubmission.entities.values()){
            System.out.println(ne);
        }
        System.out.println(check());
    }

    static String check() {
        StringBuilder resultString = new StringBuilder();

        System.out.println("\nstarting check");
        for (NormalizedEntity solutionEntity : theSolution.entities.values()){
            NormalizedEntity submissionEntity = theSubmission.entities.get(solutionEntity.name);

            if(solutionEntity instanceof NormalizedClass){
                if(!(submissionEntity instanceof NormalizedClass)){
                    System.err.println("***WARNING: solutionEntity " + solutionEntity + "is a class but submissionEntity " + submissionEntity + " is not");//<---This line should be second to last
                    resultString.append("Expected " + submissionEntity + " to be a class called " + solutionEntity);
                }               
            }   

            //System.out.println("Found: " + ne + " in both");
        }
        return resultString.toString();
    }

And here is the output -

***WARNING: solutionEntity Class C {x=private int x, y=private int y} {C=C{1thParam=int, 2thParam=int}} {getX=int getX{}}is a class but submissionEntity null is not <--------- THIS LINE SHOULD BE AT THE END
File 1:
Class C {x=private int x, y=private int y} {C=C{1thParam=int, 2thParam=int}} {getX=int getX{}}
Class SubC {z=private int z} {} {}
C c
double d
int f{}
int i
SubC subC

File 2:
Class D {x=private int x, y=private int y} {D=D{1thParam=int, 2thParam=int}} {getX=int getX{}}
Class SubC {z=private int z} {} {}
D c
double d
int f{}
int i
SubC subC

starting check
Expected null to be a class called Class C {x=private int x, y=private int y} {C=C{1thParam=int, 2thParam=int}} {getX=int getX{}}

Now based on the code the first line of output should be the second to last line. However, when I run this in eclipse it comes out as the first line. Why is this? I also noticed that if I change the System.err to System.out it comes out as expected. So it seems like Eclipse first collects all the error output and then deals with the standard output?

1
  • err takes precedence and immediately gets printed out. I've had cases where a stack trace has been printed in the middle of a line. Commented Jun 21, 2013 at 17:22

1 Answer 1

1

Writing to two different streams is inherently prone to out of order display, however, System.out.println should auto-flush with each call, meaning that the situation you are seeing should not be possible, or at worst should be able to be mitigated with synchronization.

Unfortunately, a bug in eclipse is actually preventing this from working correctly and leading to the out of order lines you are seeing: Synchronisation problem between System.out and System.err in the console

You may want to consider using a logging framework such as logback (+ SLF4J if desired) to allow you to log different levels of messages while maintaining a consistent ordering.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.