Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9에서 StackWalker로 리플렉션 프레임을 표시하는 방법

Java 9부터는 java.lang.StackWalker 클래스를 통해 스택 프레임을 다루는 표준 API가 제공됩니다. 이 클래스는 스택 프레임에 대한 지연(lazy) 접근 방식을 허용하여 높은 효율성을 갖도록 설계되었습니다. 또한 구현(implementation) 프레임이나 리플렉션(reflection) 프레임까지 포함한 스택 트레이스를 얻을 수 있는 여러 옵션도 함께 제공되며, 이러한 기능은 디버깅 작업 시 특히 유용하게 활용됩니다.

예를 들어, StackWalker 인스턴스를 생성하는 시점에 SHOW_REFLECT_FRAMES 옵션을 지정하면 리플렉션 메서드에 해당하는 프레임들도 함께 출력할 수 있습니다.

아래 예제를 통해 StackFrame의 리플렉션 프레임을 표시하는 방법을 살펴보겠습니다.

예제

import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

public class ReflectionFrameTest {
   public static void main(String args[]) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
      Method test1Method = Test1.class.getDeclaredMethod("test1", (Class[]) null);
      test1Method.invoke(null, (Object[]) null);
   }
}
class Test1 {
   protected static void test1() {
      Test2.test2();
   }
}
class Test2 {
   protected static void test2() {
      // 리플렉션 메서드 표시
      List<StackFrame> stack = StackWalker.getInstance(Option.SHOW_REFLECT_FRAMES).walk((s) -> s.collect(Collectors.toList()));
      for(StackFrame frame : stack) {
         System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " + frame.getMethodName());
      }
   }
}

실행 결과

Test2 22 test2
Test1 16 test1
jdk.internal.reflect.NativeMethodAccessorImpl -2 invoke0
jdk.internal.reflect.NativeMethodAccessorImpl 62 invoke
jdk.internal.reflect.DelegatingMethodAccessorImpl 43 invoke
java.lang.reflect.Method 564 invoke
ReflectionFrameTest 11 main

위 실행 결과를 보면, SHOW_REFLECT_FRAMES 옵션 덕분에 일반 애플리케이션 프레임(Test2, Test1, main)뿐만 아니라 jdk.internal.reflect 패키지와 java.lang.reflect.Method에 속한 내부 리플렉션 프레임들까지 모두 스택 트레이스에 포함되어 출력된 것을 확인할 수 있습니다. 이처럼 StackWalker를 활용하면 리플렉션 호출 경로를 명확하게 추적할 수 있어 문제 원인 분석에 큰 도움이 됩니다.