diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/HibernateMethodLookupDispatcher.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/HibernateMethodLookupDispatcher.java index 96d5a1651e..79fd59bae8 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/HibernateMethodLookupDispatcher.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/HibernateMethodLookupDispatcher.java @@ -6,7 +6,6 @@ */ package org.hibernate.bytecode.internal.bytebuddy; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; @@ -99,37 +98,11 @@ public class HibernateMethodLookupDispatcher { PrivilegedAction[]>> initializeGetCallerStackAction = new PrivilegedAction[]>>() { @Override public PrivilegedAction[]> run() { - Class stackWalkerClass = null; try { - // JDK 9 introduced the StackWalker - stackWalkerClass = Class.forName( "java.lang.StackWalker" ); + return new StackWalkerGetCallerStackAction(StackWalker.getInstance( StackWalker.Option.RETAIN_CLASS_REFERENCE) ); } - catch (ClassNotFoundException e) { - // ignore, we will deal with that later. - } - - if ( stackWalkerClass != null ) { - // We can use a stack walker - try { - Class optionClass = Class.forName( "java.lang.StackWalker$Option" ); - Object stackWalker = stackWalkerClass.getMethod( "getInstance", optionClass ) - // The first one is RETAIN_CLASS_REFERENCE - .invoke( null, optionClass.getEnumConstants()[0] ); - - Method stackWalkerWalkMethod = stackWalkerClass.getMethod( "walk", Function.class ); - Method stackFrameGetDeclaringClass = Class.forName( "java.lang.StackWalker$StackFrame" ) - .getMethod( "getDeclaringClass" ); - return new StackWalkerGetCallerStackAction( - stackWalker, stackWalkerWalkMethod,stackFrameGetDeclaringClass - ); - } - catch (Throwable e) { - throw new HibernateException( "Unable to initialize the stack walker", e ); - } - } - else { - // We cannot use a stack walker, default to fetching the security manager class context - return new SecurityManagerClassContextGetCallerStackAction(); + catch (Throwable e) { + throw new HibernateException( "Unable to initialize the stack walker", e ); } } }; @@ -165,59 +138,42 @@ public class HibernateMethodLookupDispatcher { throw new SecurityException( "Unable to determine the caller class" ); } - /** - * A privileged action that retrieves the caller stack from the security manager class context. - */ - private static class SecurityManagerClassContextGetCallerStackAction extends SecurityManager - implements PrivilegedAction[]> { - @Override - public Class[] run() { - return getClassContext(); - } - } - /** * A privileged action that retrieves the caller stack using a stack walker. */ private static class StackWalkerGetCallerStackAction implements PrivilegedAction[]> { - private final Object stackWalker; - private final Method stackWalkerWalkMethod; - private final Method stackFrameGetDeclaringClass; + private final StackWalker stackWalker; - StackWalkerGetCallerStackAction(Object stackWalker, Method stackWalkerWalkMethod, - Method stackFrameGetDeclaringClass) { + StackWalkerGetCallerStackAction(StackWalker stackWalker) { this.stackWalker = stackWalker; - this.stackWalkerWalkMethod = stackWalkerWalkMethod; - this.stackFrameGetDeclaringClass = stackFrameGetDeclaringClass; } @Override public Class[] run() { try { - return (Class[]) stackWalkerWalkMethod.invoke( stackWalker, stackFrameExtractFunction ); + return stackWalker.walk( stackFrameExtractFunction ); } - catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + catch (RuntimeException e) { throw new SecurityException( "Unable to determine the caller class", e ); } } - @SuppressWarnings({ "unchecked", "rawtypes" }) - private final Function stackFrameExtractFunction = new Function() { + private final Function, Class[]> stackFrameExtractFunction = new Function<>() { @Override - public Object apply(Stream stream) { + public Class[] apply(Stream stream) { return stream.map( stackFrameGetDeclaringClassFunction ) .limit( MAX_STACK_FRAMES ) .toArray( Class[]::new ); } }; - private final Function> stackFrameGetDeclaringClassFunction = new Function>() { + private final Function> stackFrameGetDeclaringClassFunction = new Function<>() { @Override - public Class apply(Object t) { + public Class apply(StackWalker.StackFrame frame) { try { - return (Class) stackFrameGetDeclaringClass.invoke( t ); + return frame.getDeclaringClass(); } - catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + catch (RuntimeException e) { throw new HibernateException( "Unable to get stack frame declaring class", e ); } }