<< 목차 >>
printStackTrace()는 왜 아래에 찍힐까?
printStackTrace()의 구현은 어떻게 되어 있을까?
err 출력 스트림?
printStackTrace()의 취약점
printStackTrace()는 왜 아래에 찍힐까
< 자바의 정석 > 예제 8-5를 배우고 있었다. 코드는 다음과 같았다.
public class Ex8_5 {
public static void main( String[] args ) {
System.out.println( 1 );
System.out.println( 2 );
try {
System.out.println( 3 );
System.out.println( 0 / 0 );
System.out.println( 4 );
} catch ( ArithmeticException ae ) {
ae.printStackTrace();
// 예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력.
System.out.println( "예외메시지 : " + ae.getMessage() );
}
System.out.println( 6 );
}
}
이렇게 코드를 입력하고 자바 파일을 실행했을 때, 예상되는 출력은
1
2
3 // try
ae.printStackTrace() 내용. ~~때문에 오류 났어!
예외메시지 : ~~~
6
이것이었다. 나도 이렇게 생각했고 책에서도 이렇게 나왔다. 그런데 실제로 출력을 해보면
1
2
3
예외메시지 : / by zero
6
java.lang.ArithmeticException: / by zero
at StandardOfJava.ExceptionStudy.Ex8_5.main(Ex8_5.java:10)
이렇게 출력이 된다.
왜 printStackTrace()는 순서를 무시하고 가장 하단에 출력되었을까?
튜터님께 여쭤보니 printStackTrace()는 err 출력 스트림을 사용하여 다른 출력 스트림을 사용하기 때문에 다른 시점에 나올 수 있다고 하셨다.
printStackTrace()의 구현은 어떻게 되어 있을까?
printStackTrace(PrintStream s), printStackTrace(PrintStreamOrWriter s) 까지 보기에는 아직 내 지식이 얕아 자세하게까지는 보지 못했다. 하지만 일단 이걸로 알게 된 것은 printStackTrace()는 err 출력 스트림을 사용한다는 것!
err 출력 스트림?
오픈 소스를 통해 공부를 해보려 했으나 너무 복잡하여 실패하였다.. 좀 더 자바에 익숙해지면 그 때 다시 한 번 파보기로 하고, 이번엔 <자바의 정석> 책과 다른 티스토리를 참고하여 공부하였다.
자바에서는 표준 입출력(standard I/O)을 위해 3가지 입출력 스트림, System.in, System.out, System.err 을 제공하는데, 이들은 자바 어플리케이션의 실행과 동시에 사용할 수 있게 자동적으로 생성되기 때문에 개발자가 별도로 스트림을 생성하는 코드를 작성하지 않고도 사용이 가능하다.
...
System 클래스의 소스에서 알 수 있듯이 in, out, err은 System 클래스에 선언된 클래스변수(static 변수)이다.선언부분만을 봐서는 out, err, in의 타입은 inputStream과 PrintStream이지만 실제로는 버퍼를 이용하는 BufferedInputStream과 BufferedOutputStream의 인스턴스를 사용한다.
여기서 알 수 있는 것은 err 출력 스트림과, out 출력 스트림은 버퍼를 이용하는 표준 출력 스트림이라는 것.
이 블로그에서는 out 스트림과 err 스트림에 대한 차이를 설명해 주고 있다. 내가 필요한 핵심은 out과 err는 다른 타이밍에 flush를 한다는 것이다. 이것만으로도 약간 모호해서 OKKY에 질문을 올렸다.
많은 답변을 받았는데 사용하는 JDK에 따라, 에러 상황에 따라, 프로세스에서 받아온 Input/OutputStream을 어떻게 사용하느냐에 따라 출력이 다르게 나올 수 있다는 것 같다.
printStackTrace()의 취약점
튜터님께서는 답변을 해주신 다음에 printStackTrace()는 현업에서 보안상의 이유로 잘 쓰지 않고, 로컬로 확인할 때만 쓰고 서비스 배포까지는 올리지 않는다고 하셨다.
튜터님이 첨부해주신 블로그 링크를 확인해보자.
printStackTrace()의 코드 구조와 안 되는 이유에 대해 상세하게 설명해 놓으셨다.. 사실 이 글을 거의 이해하지 못했다..! ㅠㅠ 아직은 내가 이해하지 못하는 말이 너무 많았다. 일단은 나중의 공부를 위해 기록해놓는다.. ㅠㅠ
'STUDY > JAVA' 카테고리의 다른 글
[TIL] ConcurrentModificationException (0) | 2023.06.20 |
---|---|
[TIL] < 자바의 정석 > 예제 HighLow - 예외처리해보기 (0) | 2023.06.15 |
[TIL] Getter와 Setter. 왜 쓸까? (1) | 2023.06.12 |
[TIL] 프로그래머스 - 최댓값과 최솟값 ( 느려지게 하는 범인 찾기 ) (0) | 2023.06.11 |
[TIL] I/O Study - ByteArrayInputStream 예제 01 (0) | 2023.06.08 |