HHH-17970 Remove support for running under a SecurityManager
This commit is contained in:
parent
0b770f9b17
commit
1f5d2fb417
|
@ -67,7 +67,7 @@ See the <<chapters/pc/BytecodeEnhancement.adoc#BytecodeEnhancement,Bytecode Enha
|
||||||
The entity class should have a no-argument constructor. Both Hibernate and Jakarta Persistence require this.
|
The entity class should have a no-argument constructor. Both Hibernate and Jakarta Persistence require this.
|
||||||
|
|
||||||
Jakarta Persistence requires that this constructor be defined as public or protected.
|
Jakarta Persistence requires that this constructor be defined as public or protected.
|
||||||
Hibernate, for the most part, does not care about the constructor visibility, as long as the system SecurityManager allows overriding the visibility setting.
|
Hibernate, for the most part, does not care about the constructor visibility, and will override the visibility setting.
|
||||||
That said, the constructor should be defined with at least package visibility if you wish to leverage runtime proxy generation.
|
That said, the constructor should be defined with at least package visibility if you wish to leverage runtime proxy generation.
|
||||||
|
|
||||||
[[entity-pojo-accessors]]
|
[[entity-pojo-accessors]]
|
||||||
|
|
|
@ -10,8 +10,6 @@ import java.io.InputStream;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -83,11 +81,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
|
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
|
||||||
|
|
||||||
// now build the aggregated class loader...
|
// now build the aggregated class loader...
|
||||||
this.aggregatedClassLoader = AccessController.doPrivileged( new PrivilegedAction<AggregatedClassLoader>() {
|
this.aggregatedClassLoader = new AggregatedClassLoader( orderedClassLoaderSet, lookupPrecedence );
|
||||||
public AggregatedClassLoader run() {
|
|
||||||
return new AggregatedClassLoader( orderedClassLoaderSet, lookupPrecedence );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,8 +21,6 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -33,15 +31,12 @@ import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
|
||||||
import org.hibernate.bytecode.spi.BasicProxyFactory;
|
import org.hibernate.bytecode.spi.BasicProxyFactory;
|
||||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
import org.hibernate.proxy.ProxyConfiguration;
|
import org.hibernate.proxy.ProxyConfiguration;
|
||||||
import org.hibernate.proxy.ProxyFactory;
|
import org.hibernate.proxy.ProxyFactory;
|
||||||
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.ClassFileVersion;
|
import net.bytebuddy.ClassFileVersion;
|
||||||
import net.bytebuddy.TypeCache;
|
import net.bytebuddy.TypeCache;
|
||||||
import net.bytebuddy.asm.AsmVisitorWrapper.ForDeclaredMethods;
|
|
||||||
import net.bytebuddy.asm.MemberSubstitution;
|
|
||||||
import net.bytebuddy.description.method.MethodDescription;
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import net.bytebuddy.dynamic.DynamicType.Unloaded;
|
import net.bytebuddy.dynamic.DynamicType.Unloaded;
|
||||||
|
@ -51,7 +46,6 @@ import net.bytebuddy.implementation.FieldAccessor;
|
||||||
import net.bytebuddy.implementation.MethodDelegation;
|
import net.bytebuddy.implementation.MethodDelegation;
|
||||||
import net.bytebuddy.implementation.bytecode.assign.Assigner;
|
import net.bytebuddy.implementation.bytecode.assign.Assigner;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import net.bytebuddy.matcher.ElementMatchers;
|
|
||||||
import net.bytebuddy.pool.TypePool;
|
import net.bytebuddy.pool.TypePool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,16 +84,8 @@ public final class ByteBuddyState {
|
||||||
|
|
||||||
ByteBuddyState(ClassFileVersion classFileVersion) {
|
ByteBuddyState(ClassFileVersion classFileVersion) {
|
||||||
this.byteBuddy = new ByteBuddy( classFileVersion ).with( TypeValidation.DISABLED );
|
this.byteBuddy = new ByteBuddy( classFileVersion ).with( TypeValidation.DISABLED );
|
||||||
|
|
||||||
this.proxyCache = new TypeCache( TypeCache.Sort.WEAK );
|
this.proxyCache = new TypeCache( TypeCache.Sort.WEAK );
|
||||||
this.basicProxyCache = new TypeCache( TypeCache.Sort.WEAK );
|
this.basicProxyCache = new TypeCache( TypeCache.Sort.WEAK );
|
||||||
|
|
||||||
if ( SystemSecurityManager.isSecurityManagerEnabled() ) {
|
|
||||||
this.classRewriter = new SecurityManagerClassRewriter();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.classRewriter = new StandardClassRewriter();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,22 +186,12 @@ public final class ByteBuddyState {
|
||||||
return cache.findOrInsert(
|
return cache.findOrInsert(
|
||||||
referenceClass.getClassLoader(),
|
referenceClass.getClassLoader(),
|
||||||
cacheKey,
|
cacheKey,
|
||||||
() -> {
|
() -> make( makeProxyFunction.apply( byteBuddy ) )
|
||||||
PrivilegedAction<Class<?>> delegateToPrivilegedAction = new PrivilegedAction<Class<?>>() {
|
|
||||||
@Override
|
|
||||||
public Class<?> run() {
|
|
||||||
return make( makeProxyFunction.apply( byteBuddy ) )
|
|
||||||
.load(
|
.load(
|
||||||
referenceClass.getClassLoader(),
|
referenceClass.getClassLoader(),
|
||||||
resolveClassLoadingStrategy( referenceClass )
|
resolveClassLoadingStrategy( referenceClass )
|
||||||
)
|
)
|
||||||
.getLoaded();
|
.getLoaded(),
|
||||||
}
|
|
||||||
};
|
|
||||||
return SystemSecurityManager.isSecurityManagerEnabled() ? AccessController.doPrivileged(
|
|
||||||
delegateToPrivilegedAction ) :
|
|
||||||
delegateToPrivilegedAction.run();
|
|
||||||
},
|
|
||||||
cache
|
cache
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -233,8 +209,6 @@ public final class ByteBuddyState {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Unloaded<?> make(TypePool typePool, DynamicType.Builder<?> builder) {
|
private Unloaded<?> make(TypePool typePool, DynamicType.Builder<?> builder) {
|
||||||
builder = classRewriter.installReflectionMethodVisitors( builder );
|
|
||||||
|
|
||||||
Unloaded<?> unloadedClass;
|
Unloaded<?> unloadedClass;
|
||||||
if ( typePool != null ) {
|
if ( typePool != null ) {
|
||||||
unloadedClass = builder.make( typePool );
|
unloadedClass = builder.make( typePool );
|
||||||
|
@ -251,9 +225,6 @@ public final class ByteBuddyState {
|
||||||
LOG.warn( "Unable to save generated class %1$s", unloadedClass.getTypeDescription().getName(), e );
|
LOG.warn( "Unable to save generated class %1$s", unloadedClass.getTypeDescription().getName(), e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
classRewriter.registerAuthorizedClass( unloadedClass );
|
|
||||||
|
|
||||||
return unloadedClass;
|
return unloadedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,33 +286,11 @@ public final class ByteBuddyState {
|
||||||
toFullyIgnore.add( isDeclaredBy( m.getReturnType() ).and( named( m.getName() ) ).and( takesNoArguments() ) );
|
toFullyIgnore.add( isDeclaredBy( m.getReturnType() ).and( named( m.getName() ) ).and( takesNoArguments() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivilegedAction<MethodDelegation> delegateToInterceptorDispatcherMethodDelegationPrivilegedAction =
|
this.delegateToInterceptorDispatcherMethodDelegation = MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class );
|
||||||
new PrivilegedAction<MethodDelegation>() {
|
|
||||||
|
|
||||||
@Override
|
this.interceptorFieldAccessor = FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME )
|
||||||
public MethodDelegation run() {
|
|
||||||
return MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.delegateToInterceptorDispatcherMethodDelegation = SystemSecurityManager.isSecurityManagerEnabled()
|
|
||||||
? AccessController.doPrivileged( delegateToInterceptorDispatcherMethodDelegationPrivilegedAction )
|
|
||||||
: delegateToInterceptorDispatcherMethodDelegationPrivilegedAction.run();
|
|
||||||
|
|
||||||
PrivilegedAction<FieldAccessor.PropertyConfigurable> interceptorFieldAccessorPrivilegedAction =
|
|
||||||
new PrivilegedAction<FieldAccessor.PropertyConfigurable>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldAccessor.PropertyConfigurable run() {
|
|
||||||
return FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME )
|
|
||||||
.withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC );
|
.withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC );
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
this.interceptorFieldAccessor = SystemSecurityManager.isSecurityManagerEnabled()
|
|
||||||
? AccessController.doPrivileged( interceptorFieldAccessorPrivilegedAction )
|
|
||||||
: interceptorFieldAccessorPrivilegedAction.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ElementMatcher<? super MethodDescription> getGroovyGetMetaClassFilter() {
|
public ElementMatcher<? super MethodDescription> getGroovyGetMetaClassFilter() {
|
||||||
return groovyGetMetaClassFilter;
|
return groovyGetMetaClassFilter;
|
||||||
|
@ -371,71 +320,6 @@ public final class ByteBuddyState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface ClassRewriter {
|
|
||||||
DynamicType.Builder<?> installReflectionMethodVisitors(DynamicType.Builder<?> builder);
|
|
||||||
|
|
||||||
void registerAuthorizedClass(Unloaded<?> unloadedClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SecurityManagerClassRewriter implements ClassRewriter {
|
|
||||||
|
|
||||||
private final ForDeclaredMethods getDeclaredMethodMemberSubstitution;
|
|
||||||
private final ForDeclaredMethods getMethodMemberSubstitution;
|
|
||||||
|
|
||||||
private SecurityManagerClassRewriter() {
|
|
||||||
this.getDeclaredMethodMemberSubstitution = getDeclaredMethodMemberSubstitution();
|
|
||||||
this.getMethodMemberSubstitution = getMethodMemberSubstitution();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicType.Builder<?> installReflectionMethodVisitors(DynamicType.Builder<?> builder) {
|
|
||||||
builder = builder.visit( getDeclaredMethodMemberSubstitution );
|
|
||||||
return builder.visit( getMethodMemberSubstitution );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerAuthorizedClass(Unloaded<?> unloadedClass) {
|
|
||||||
// we authorize the proxy class to access the method lookup dispatcher
|
|
||||||
HibernateMethodLookupDispatcher.registerAuthorizedClass( unloadedClass.getTypeDescription().getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ForDeclaredMethods getDeclaredMethodMemberSubstitution() {
|
|
||||||
// this should only be called if the security manager is enabled, thus the privileged calls
|
|
||||||
return MemberSubstitution.relaxed()
|
|
||||||
.method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class,
|
|
||||||
"getDeclaredMethod", String.class, Class[].class ) ) ) )
|
|
||||||
.replaceWith(
|
|
||||||
AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class,
|
|
||||||
"getDeclaredMethod", Class.class, String.class, Class[].class ) ) )
|
|
||||||
.on( ElementMatchers.isTypeInitializer() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ForDeclaredMethods getMethodMemberSubstitution() {
|
|
||||||
// this should only be called if the security manager is enabled, thus the privileged calls
|
|
||||||
return MemberSubstitution.relaxed()
|
|
||||||
.method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class,
|
|
||||||
"getMethod", String.class, Class[].class ) ) ) )
|
|
||||||
.replaceWith(
|
|
||||||
AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class,
|
|
||||||
"getMethod", Class.class, String.class, Class[].class ) ) )
|
|
||||||
.on( ElementMatchers.isTypeInitializer() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class StandardClassRewriter implements ClassRewriter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicType.Builder<?> installReflectionMethodVisitors(DynamicType.Builder<?> builder) {
|
|
||||||
// do nothing
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerAuthorizedClass(Unloaded<?> unloadedClass) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ClassLoadingStrategy<ClassLoader> resolveClassLoadingStrategy(Class<?> originalClass) {
|
private static ClassLoadingStrategy<ClassLoader> resolveClassLoadingStrategy(Class<?> originalClass) {
|
||||||
try {
|
try {
|
||||||
return ClassLoadingStrategy.UsingLookup.of( MethodHandles.privateLookupIn( originalClass, LOOKUP ) );
|
return ClassLoadingStrategy.UsingLookup.of( MethodHandles.privateLookupIn( originalClass, LOOKUP ) );
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.bytecode.internal.bytebuddy;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This dispatcher analyzes the stack frames to detect if a particular call should be authorized.
|
|
||||||
* <p>
|
|
||||||
* Authorized classes are registered when creating the ByteBuddy proxies.
|
|
||||||
* <p>
|
|
||||||
* It should only be used when the Security Manager is enabled.
|
|
||||||
*/
|
|
||||||
public class HibernateMethodLookupDispatcher {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The minimum number of stack frames to drop before we can hope to find the caller frame.
|
|
||||||
*/
|
|
||||||
private static final int MIN_STACK_FRAMES = 3;
|
|
||||||
/**
|
|
||||||
* The maximum number of stack frames to explore to find the caller frame.
|
|
||||||
* <p>
|
|
||||||
* Beyond that, we give up and throw an exception.
|
|
||||||
*/
|
|
||||||
private static final int MAX_STACK_FRAMES = 16;
|
|
||||||
private static final PrivilegedAction<Class<?>[]> GET_CALLER_STACK_ACTION;
|
|
||||||
|
|
||||||
// Currently, the bytecode provider is created statically and shared between all the session factories. Thus we
|
|
||||||
// can't clear this set when we close a session factory as we might remove elements coming from another one.
|
|
||||||
// Considering we can't clear these elements, we use the class names instead of the classes themselves to avoid
|
|
||||||
// issues.
|
|
||||||
private static Set<String> authorizedClasses = ConcurrentHashMap.newKeySet();
|
|
||||||
|
|
||||||
public static Method getDeclaredMethod(Class<?> type, String name, Class<?>[] parameters) {
|
|
||||||
PrivilegedAction<Method> getDeclaredMethodAction = new PrivilegedAction<Method>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method run() {
|
|
||||||
try {
|
|
||||||
return type.getDeclaredMethod( name, parameters );
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException | SecurityException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return doPrivilegedAction( getDeclaredMethodAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Method getMethod(Class<?> type, String name, Class<?>[] parameters) {
|
|
||||||
PrivilegedAction<Method> getMethodAction = new PrivilegedAction<Method>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method run() {
|
|
||||||
try {
|
|
||||||
return type.getMethod( name, parameters );
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException | SecurityException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return doPrivilegedAction( getMethodAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method doPrivilegedAction(PrivilegedAction<Method> privilegedAction) {
|
|
||||||
Class<?> callerClass = getCallerClass();
|
|
||||||
|
|
||||||
if ( !authorizedClasses.contains( callerClass.getName() ) ) {
|
|
||||||
throw new SecurityException( "Unauthorized call by class " + callerClass );
|
|
||||||
}
|
|
||||||
|
|
||||||
return SystemSecurityManager.isSecurityManagerEnabled() ? AccessController.doPrivileged( privilegedAction ) :
|
|
||||||
privilegedAction.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void registerAuthorizedClass(String className) {
|
|
||||||
authorizedClasses.add( className );
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
// The action below will return the action used at runtime to retrieve the caller stack
|
|
||||||
PrivilegedAction<PrivilegedAction<Class<?>[]>> initializeGetCallerStackAction = new PrivilegedAction<PrivilegedAction<Class<?>[]>>() {
|
|
||||||
@Override
|
|
||||||
public PrivilegedAction<Class<?>[]> run() {
|
|
||||||
try {
|
|
||||||
return new StackWalkerGetCallerStackAction(StackWalker.getInstance( StackWalker.Option.RETAIN_CLASS_REFERENCE) );
|
|
||||||
}
|
|
||||||
catch (Throwable e) {
|
|
||||||
throw new HibernateException( "Unable to initialize the stack walker", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GET_CALLER_STACK_ACTION = SystemSecurityManager.isSecurityManagerEnabled()
|
|
||||||
? AccessController.doPrivileged( initializeGetCallerStackAction )
|
|
||||||
: initializeGetCallerStackAction.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?> getCallerClass() {
|
|
||||||
Class<?>[] stackTrace = SystemSecurityManager.isSecurityManagerEnabled()
|
|
||||||
? AccessController.doPrivileged( GET_CALLER_STACK_ACTION )
|
|
||||||
: GET_CALLER_STACK_ACTION.run();
|
|
||||||
|
|
||||||
// this shouldn't happen but let's be safe
|
|
||||||
if ( stackTrace.length <= MIN_STACK_FRAMES ) {
|
|
||||||
throw new SecurityException( "Unable to determine the caller class" );
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hibernateMethodLookupDispatcherDetected = false;
|
|
||||||
// start at the 4th frame and limit that to the MAX_STACK_FRAMES first frames
|
|
||||||
int maxFrames = Math.min( MAX_STACK_FRAMES, stackTrace.length );
|
|
||||||
for ( int i = MIN_STACK_FRAMES; i < maxFrames; i++ ) {
|
|
||||||
if ( stackTrace[i].getName().equals( HibernateMethodLookupDispatcher.class.getName() ) ) {
|
|
||||||
hibernateMethodLookupDispatcherDetected = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( hibernateMethodLookupDispatcherDetected ) {
|
|
||||||
return stackTrace[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new SecurityException( "Unable to determine the caller class" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A privileged action that retrieves the caller stack using a stack walker.
|
|
||||||
*/
|
|
||||||
private static class StackWalkerGetCallerStackAction implements PrivilegedAction<Class<?>[]> {
|
|
||||||
private final StackWalker stackWalker;
|
|
||||||
|
|
||||||
StackWalkerGetCallerStackAction(StackWalker stackWalker) {
|
|
||||||
this.stackWalker = stackWalker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?>[] run() {
|
|
||||||
try {
|
|
||||||
return stackWalker.walk( stackFrameExtractFunction );
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
throw new SecurityException( "Unable to determine the caller class", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Function<Stream<StackWalker.StackFrame>, Class<?>[]> stackFrameExtractFunction = new Function<>() {
|
|
||||||
@Override
|
|
||||||
public Class<?>[] apply(Stream<StackWalker.StackFrame> stream) {
|
|
||||||
return stream.map( stackFrameGetDeclaringClassFunction )
|
|
||||||
.limit( MAX_STACK_FRAMES )
|
|
||||||
.toArray( Class<?>[]::new );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Function<StackWalker.StackFrame, Class<?>> stackFrameGetDeclaringClassFunction = new Function<>() {
|
|
||||||
@Override
|
|
||||||
public Class<?> apply(StackWalker.StackFrame frame) {
|
|
||||||
try {
|
|
||||||
return frame.getDeclaringClass();
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
throw new HibernateException( "Unable to get stack frame declaring class", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,8 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.connections.internal;
|
package org.hibernate.engine.jdbc.connections.internal;
|
||||||
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.Driver;
|
import java.sql.Driver;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
|
@ -34,7 +32,6 @@ import org.hibernate.dialect.SimpleDatabaseVersion;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
|
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
import org.hibernate.service.UnknownUnwrapTypeException;
|
import org.hibernate.service.UnknownUnwrapTypeException;
|
||||||
import org.hibernate.service.spi.Configurable;
|
import org.hibernate.service.spi.Configurable;
|
||||||
import org.hibernate.service.spi.ServiceException;
|
import org.hibernate.service.spi.ServiceException;
|
||||||
|
@ -614,22 +611,7 @@ public class DriverManagerConnectionProviderImpl
|
||||||
ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( pool.getUrl() );
|
ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( pool.getUrl() );
|
||||||
active = false;
|
active = false;
|
||||||
if ( executorService != null ) {
|
if ( executorService != null ) {
|
||||||
PrivilegedAction delegateToPrivilegedAction =
|
|
||||||
new PrivilegedAction() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object run() {
|
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if ( SystemSecurityManager.isSecurityManagerEnabled() ) {
|
|
||||||
AccessController.doPrivileged(
|
|
||||||
delegateToPrivilegedAction );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delegateToPrivilegedAction.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
executorService = null;
|
executorService = null;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
package org.hibernate.event.spi;
|
package org.hibernate.event.spi;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -85,8 +83,9 @@ public final class EventType<T> {
|
||||||
* Maintain a map of {@link EventType} instances keyed by name for lookup by name as well as {@link #values()}
|
* Maintain a map of {@link EventType} instances keyed by name for lookup by name as well as {@link #values()}
|
||||||
* resolution.
|
* resolution.
|
||||||
*/
|
*/
|
||||||
private static final Map<String,EventType<?>> STANDARD_TYPE_BY_NAME_MAP = AccessController.doPrivileged(
|
private static final Map<String,EventType<?>> STANDARD_TYPE_BY_NAME_MAP = initStandardTypeNameMap();
|
||||||
(PrivilegedAction<Map<String, EventType<?>>>) () -> {
|
|
||||||
|
private static Map<String, EventType<?>> initStandardTypeNameMap() {
|
||||||
final Map<String, EventType<?>> typeByNameMap = new HashMap<>();
|
final Map<String, EventType<?>> typeByNameMap = new HashMap<>();
|
||||||
for ( Field field : EventType.class.getDeclaredFields() ) {
|
for ( Field field : EventType.class.getDeclaredFields() ) {
|
||||||
if ( EventType.class.isAssignableFrom( field.getType() ) ) {
|
if ( EventType.class.isAssignableFrom( field.getType() ) ) {
|
||||||
|
@ -99,10 +98,8 @@ public final class EventType<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.unmodifiableMap( typeByNameMap );
|
return Collections.unmodifiableMap( typeByNameMap );
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
private static <T> EventType<T> create(String name, Class<T> listenerRole) {
|
private static <T> EventType<T> create(String name, Class<T> listenerRole) {
|
||||||
return new EventType<>( name, listenerRole, STANDARD_TYPE_COUNTER.getAndIncrement(), true );
|
return new EventType<>( name, listenerRole, STANDARD_TYPE_COUNTER.getAndIncrement(), true );
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.internal.util.securitymanager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encapsulates access to {@link System#getSecurityManager()},
|
|
||||||
* in preparation of it being phased out by the JDK.
|
|
||||||
*
|
|
||||||
* Since JDK 17 the security manager can be disabled by setting
|
|
||||||
* the system property {@code java.security.manager} to {@code disallow};
|
|
||||||
* to prepare for this we also offer the option of setting
|
|
||||||
* {@code org.hibernate.internal.util.securitymanager.FULLY_DISABLE} to {@code true}
|
|
||||||
* to have the same effect, although limited to the Hibernate ORM code.
|
|
||||||
*/
|
|
||||||
public final class SystemSecurityManager {
|
|
||||||
|
|
||||||
public static final String FULLY_DISABLE_PROP_NAME = "org.hibernate.internal.util.securitymanager.FULLY_DISABLE";
|
|
||||||
private static final boolean disabledForced = Boolean.getBoolean( FULLY_DISABLE_PROP_NAME );
|
|
||||||
|
|
||||||
private static final boolean SM_IS_ENABLED = (!disabledForced) && (System.getSecurityManager() != null );
|
|
||||||
|
|
||||||
public static boolean isSecurityManagerEnabled() {
|
|
||||||
return SM_IS_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//N.B. do not expose a "doPrivileged" helper as that would introduce a security problem
|
|
||||||
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -26,14 +25,12 @@ import org.hibernate.collection.spi.LazyInitializable;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
|
|
||||||
import static jakarta.persistence.spi.LoadState.LOADED;
|
import static jakarta.persistence.spi.LoadState.LOADED;
|
||||||
import static jakarta.persistence.spi.LoadState.NOT_LOADED;
|
import static jakarta.persistence.spi.LoadState.NOT_LOADED;
|
||||||
import static jakarta.persistence.spi.LoadState.UNKNOWN;
|
import static jakarta.persistence.spi.LoadState.UNKNOWN;
|
||||||
import static java.security.AccessController.doPrivileged;
|
|
||||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||||
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||||
|
@ -353,7 +350,6 @@ public final class PersistenceUtilHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttributeAccess buildAttributeAccess(final String attributeName) {
|
private AttributeAccess buildAttributeAccess(final String attributeName) {
|
||||||
final PrivilegedAction<AttributeAccess> action = () -> {
|
|
||||||
for ( Class<?> clazz : classHierarchy ) {
|
for ( Class<?> clazz : classHierarchy ) {
|
||||||
try {
|
try {
|
||||||
return new FieldAttributeAccess( clazz.getDeclaredField( attributeName ) );
|
return new FieldAttributeAccess( clazz.getDeclaredField( attributeName ) );
|
||||||
|
@ -367,8 +363,6 @@ public final class PersistenceUtilHelper {
|
||||||
}
|
}
|
||||||
//we could not find any match
|
//we could not find any match
|
||||||
return new NoSuchAttributeAccess( specifiedClass, attributeName );
|
return new NoSuchAttributeAccess( specifiedClass, attributeName );
|
||||||
};
|
|
||||||
return SystemSecurityManager.isSecurityManagerEnabled() ? doPrivileged( action ) : action.run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ package org.hibernate.proxy.pojo.bytebuddy;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
@ -18,7 +16,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.ProxyConfiguration;
|
import org.hibernate.proxy.ProxyConfiguration;
|
||||||
import org.hibernate.proxy.ProxyFactory;
|
import org.hibernate.proxy.ProxyFactory;
|
||||||
|
@ -109,18 +106,11 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This technically returns a HibernateProxy, but declaring that type as the return
|
* This technically returns a HibernateProxy, but declaring that type as the return
|
||||||
* type for the privileged action triggers an implicit case of type pollution.
|
* type for the newInstance() action triggers an implicit case of type pollution.
|
||||||
* We therefore declare it as PrimeAmongSecondarySupertypes, and require the
|
* We therefore declare it as PrimeAmongSecondarySupertypes, and require the
|
||||||
* invoker to perform the narrowing
|
* invoker to perform the narrowing
|
||||||
*/
|
*/
|
||||||
private PrimeAmongSecondarySupertypes getHibernateProxyInternal()
|
private PrimeAmongSecondarySupertypes getHibernateProxyInternal() throws HibernateException {
|
||||||
throws HibernateException {
|
|
||||||
|
|
||||||
final PrivilegedAction<PrimeAmongSecondarySupertypes> action = new PrivilegedAction<PrimeAmongSecondarySupertypes>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PrimeAmongSecondarySupertypes run() {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (PrimeAmongSecondarySupertypes) proxyClass.getConstructor().newInstance();
|
return (PrimeAmongSecondarySupertypes) proxyClass.getConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
@ -134,10 +124,6 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
|
||||||
LOG.error( logMessage, t );
|
LOG.error( logMessage, t );
|
||||||
throw new HibernateException( logMessage, t );
|
throw new HibernateException( logMessage, t );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return SystemSecurityManager.isSecurityManagerEnabled() ? AccessController.doPrivileged( action ) : action.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.bytecode.internal.bytebuddy;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class HibernateMethodLookupDispatcherTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAuthorizedClass() {
|
|
||||||
HibernateMethodLookupDispatcher.registerAuthorizedClass( AuthorizedClass.class.getName() );
|
|
||||||
|
|
||||||
AuthorizedClass authorizedClass = new AuthorizedClass();
|
|
||||||
assertNotNull( authorizedClass.declaredMethod );
|
|
||||||
assertEquals( "myMethod", authorizedClass.declaredMethod.getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test( expected = SecurityException.class )
|
|
||||||
public void testUnauthorizedClass() {
|
|
||||||
new UnauthorizedClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AuthorizedClass {
|
|
||||||
|
|
||||||
private Method declaredMethod;
|
|
||||||
|
|
||||||
public AuthorizedClass() {
|
|
||||||
declaredMethod = HibernateMethodLookupDispatcher.getDeclaredMethod( AuthorizedClass.class, "myMethod",
|
|
||||||
new Class<?>[]{ String.class } );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void myMethod(String myParameter) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UnauthorizedClass {
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private Method declaredMethod;
|
|
||||||
|
|
||||||
public UnauthorizedClass() {
|
|
||||||
declaredMethod = HibernateMethodLookupDispatcher.getDeclaredMethod( AuthorizedClass.class, "myMethod",
|
|
||||||
new Class<?>[]{ String.class } );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void myMethod(String myParameter) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,15 +8,11 @@ package org.hibernate.envers.internal.entities.mapper;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.envers.exception.AuditException;
|
import org.hibernate.envers.exception.AuditException;
|
||||||
import org.hibernate.envers.internal.entities.PropertyData;
|
import org.hibernate.envers.internal.entities.PropertyData;
|
||||||
import org.hibernate.envers.internal.tools.ReflectionTools;
|
import org.hibernate.envers.internal.tools.ReflectionTools;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -28,22 +24,6 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractMapper {
|
public abstract class AbstractMapper {
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an action in a privileged block.
|
|
||||||
*
|
|
||||||
* @param block the lambda to executed in privileged.
|
|
||||||
* @param <T> the return type
|
|
||||||
* @return the result of the privileged call, may be {@literal null}
|
|
||||||
*/
|
|
||||||
protected <T> T doPrivileged(Supplier<T> block) {
|
|
||||||
if ( SystemSecurityManager.isSecurityManagerEnabled() ) {
|
|
||||||
return AccessController.doPrivileged( (PrivilegedAction<T>) block::get );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return block.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a value from the specified object.
|
* Get a value from the specified object.
|
||||||
*
|
*
|
||||||
|
@ -55,10 +35,8 @@ public abstract class AbstractMapper {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T getValueFromObject(PropertyData propertyData, Object object, ServiceRegistry serviceRegistry) {
|
protected <T> T getValueFromObject(PropertyData propertyData, Object object, ServiceRegistry serviceRegistry) {
|
||||||
return doPrivileged( () -> {
|
|
||||||
final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyData, serviceRegistry );
|
final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyData, serviceRegistry );
|
||||||
return (T) getter.get( object );
|
return (T) getter.get( object );
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,17 +44,15 @@ public abstract class AbstractMapper {
|
||||||
*
|
*
|
||||||
* @param propertyName the property name, should not be {@literal null}
|
* @param propertyName the property name, should not be {@literal null}
|
||||||
* @param accessType the property access type, should not be {@literal null}
|
* @param accessType the property access type, should not be {@literal null}
|
||||||
* @param object the object for hwich the value should be read, should not be {@literal null}
|
* @param object the object for which the value should be read, should not be {@literal null}
|
||||||
* @param serviceRegistry the service registry, should not be {@literal null}
|
* @param serviceRegistry the service registry, should not be {@literal null}
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @return the value read from the object, may be {@literal null}
|
* @return the value read from the object, may be {@literal null}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T getValueFromObject(String propertyName, String accessType, Object object, ServiceRegistry serviceRegistry) {
|
protected <T> T getValueFromObject(String propertyName, String accessType, Object object, ServiceRegistry serviceRegistry) {
|
||||||
return doPrivileged( () -> {
|
|
||||||
final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyName, accessType, serviceRegistry );
|
final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyName, accessType, serviceRegistry );
|
||||||
return (T) getter.get( object );
|
return (T) getter.get( object );
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,11 +64,8 @@ public abstract class AbstractMapper {
|
||||||
* @param serviceRegistry the service registry, should not be {@literal null}
|
* @param serviceRegistry the service registry, should not be {@literal null}
|
||||||
*/
|
*/
|
||||||
protected void setValueOnObject(PropertyData propertyData, Object object, Object value, ServiceRegistry serviceRegistry) {
|
protected void setValueOnObject(PropertyData propertyData, Object object, Object value, ServiceRegistry serviceRegistry) {
|
||||||
doPrivileged( () -> {
|
|
||||||
final Setter setter = ReflectionTools.getSetter(object.getClass(), propertyData, serviceRegistry );
|
final Setter setter = ReflectionTools.getSetter(object.getClass(), propertyData, serviceRegistry );
|
||||||
setter.set( object, value );
|
setter.set( object, value );
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,12 +77,9 @@ public abstract class AbstractMapper {
|
||||||
* @param serviceRegistry the service registry, should not be {@literal null}
|
* @param serviceRegistry the service registry, should not be {@literal null}
|
||||||
*/
|
*/
|
||||||
protected void getAndSetValue(PropertyData propertyData, Object source, Object destination, ServiceRegistry serviceRegistry) {
|
protected void getAndSetValue(PropertyData propertyData, Object source, Object destination, ServiceRegistry serviceRegistry) {
|
||||||
doPrivileged( () -> {
|
|
||||||
final Getter getter = ReflectionTools.getGetter( source.getClass(), propertyData, serviceRegistry );
|
final Getter getter = ReflectionTools.getGetter( source.getClass(), propertyData, serviceRegistry );
|
||||||
final Setter setter = ReflectionTools.getSetter( destination.getClass(), propertyData, serviceRegistry );
|
final Setter setter = ReflectionTools.getSetter( destination.getClass(), propertyData, serviceRegistry );
|
||||||
setter.set( destination, getter.get( source ) );
|
setter.set( destination, getter.get( source ) );
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +91,6 @@ public abstract class AbstractMapper {
|
||||||
* @return a new instance of the class
|
* @return a new instance of the class
|
||||||
*/
|
*/
|
||||||
protected <T> T newObjectInstance(Class<T> clazz, Object... args) {
|
protected <T> T newObjectInstance(Class<T> clazz, Object... args) {
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
final Constructor<T> constructor = ReflectHelper.getDefaultConstructor( clazz );
|
final Constructor<T> constructor = ReflectHelper.getDefaultConstructor( clazz );
|
||||||
if ( constructor == null ) {
|
if ( constructor == null ) {
|
||||||
|
@ -132,6 +101,5 @@ public abstract class AbstractMapper {
|
||||||
catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,6 @@ public class ComponentPropertyMapper extends AbstractPropertyMapper implements C
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if ( isDynamicComponentMap() ) {
|
if ( isDynamicComponentMap() ) {
|
||||||
|
@ -184,9 +183,6 @@ public class ComponentPropertyMapper extends AbstractPropertyMapper implements C
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -202,7 +198,6 @@ public class ComponentPropertyMapper extends AbstractPropertyMapper implements C
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
final Object subObj;
|
final Object subObj;
|
||||||
if ( isDynamicComponentMap() ) {
|
if ( isDynamicComponentMap() ) {
|
||||||
|
@ -252,7 +247,6 @@ public class ComponentPropertyMapper extends AbstractPropertyMapper implements C
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllPropertiesNull(Map data) {
|
private boolean isAllPropertiesNull(Map data) {
|
||||||
|
|
|
@ -103,7 +103,6 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten
|
||||||
final Map<String, Object> data,
|
final Map<String, Object> data,
|
||||||
final Object newObj,
|
final Object newObj,
|
||||||
final Object oldObj) {
|
final Object oldObj) {
|
||||||
return doPrivileged( () -> {
|
|
||||||
boolean ret = false;
|
boolean ret = false;
|
||||||
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
|
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
|
||||||
final PropertyData propertyData = entry.getKey();
|
final PropertyData propertyData = entry.getKey();
|
||||||
|
@ -140,7 +139,6 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,7 +147,6 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten
|
||||||
final Map<String, Object> data,
|
final Map<String, Object> data,
|
||||||
final Object newObj,
|
final Object newObj,
|
||||||
final Object oldObj) {
|
final Object oldObj) {
|
||||||
doPrivileged( () -> {
|
|
||||||
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
|
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
|
||||||
final PropertyData propertyData = entry.getKey();
|
final PropertyData propertyData = entry.getKey();
|
||||||
final PropertyMapper propertyMapper = entry.getValue();
|
final PropertyMapper propertyMapper = entry.getValue();
|
||||||
|
@ -184,9 +181,6 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten
|
||||||
oldObj == null ? null : getter.get( oldObj )
|
oldObj == null ? null : getter.get( oldObj )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -107,7 +107,6 @@ public class SinglePropertyMapper extends AbstractPropertyMapper implements Simp
|
||||||
map.put( propertyData.getBeanName(), value );
|
map.put( propertyData.getBeanName(), value );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
doPrivileged( () -> {
|
|
||||||
final Setter setter = ReflectionTools.getSetter(
|
final Setter setter = ReflectionTools.getSetter(
|
||||||
obj.getClass(),
|
obj.getClass(),
|
||||||
propertyData,
|
propertyData,
|
||||||
|
@ -118,9 +117,6 @@ public class SinglePropertyMapper extends AbstractPropertyMapper implements Simp
|
||||||
if ( value != null || !isPrimitive( setter, propertyData, obj.getClass() ) ) {
|
if ( value != null || !isPrimitive( setter, propertyData, obj.getClass() ) ) {
|
||||||
setter.set( obj, value );
|
setter.set( obj, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,13 +64,11 @@ public abstract class AbstractCompositeIdMapper extends AbstractIdMapper impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object instantiateCompositeId() {
|
protected Object instantiateCompositeId() {
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance();
|
return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance();
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return doPrivileged( () -> {
|
|
||||||
final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() );
|
final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() );
|
||||||
try {
|
try {
|
||||||
final Object subObj = instantiateCompositeId();
|
final Object subObj = instantiateCompositeId();
|
||||||
|
@ -77,7 +76,6 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -63,7 +63,6 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
doPrivileged( () -> {
|
|
||||||
final Getter getter = ReflectionTools.getGetter(
|
final Getter getter = ReflectionTools.getGetter(
|
||||||
objFrom.getClass(),
|
objFrom.getClass(),
|
||||||
propertyData,
|
propertyData,
|
||||||
|
@ -79,7 +78,7 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
||||||
// Get the value from the containing entity
|
// Get the value from the containing entity
|
||||||
final Object value = getter.get( objFrom );
|
final Object value = getter.get( objFrom );
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !value.getClass().equals( propertyData.getVirtualReturnClass() ) ) {
|
if ( !value.getClass().equals( propertyData.getVirtualReturnClass() ) ) {
|
||||||
|
@ -89,9 +88,6 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
||||||
// This means we're setting the object
|
// This means we're setting the object
|
||||||
setter.set( objTo, value );
|
setter.set( objTo, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,7 +101,6 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return doPrivileged( () -> {
|
|
||||||
final Setter setter = ReflectionTools.getSetter(
|
final Setter setter = ReflectionTools.getSetter(
|
||||||
obj.getClass(),
|
obj.getClass(),
|
||||||
propertyData,
|
propertyData,
|
||||||
|
@ -125,7 +120,6 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,10 +8,7 @@ package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.envers.boot.internal.EnversService;
|
import org.hibernate.envers.boot.internal.EnversService;
|
||||||
|
@ -20,7 +17,6 @@ import org.hibernate.envers.internal.entities.EntityInstantiator;
|
||||||
import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator;
|
import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator;
|
||||||
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a persistent collection.
|
* Initializes a persistent collection.
|
||||||
|
@ -67,22 +63,6 @@ public abstract class AbstractCollectionInitializor<T> implements Initializor<T>
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an action in a privileged block.
|
|
||||||
*
|
|
||||||
* @param block the lambda to executed in privileged.
|
|
||||||
* @param <R> the return type
|
|
||||||
* @return the result of the privileged call, may be {@literal null}
|
|
||||||
*/
|
|
||||||
protected <R> R doPrivileged(Supplier<R> block) {
|
|
||||||
if ( SystemSecurityManager.isSecurityManagerEnabled() ) {
|
|
||||||
return AccessController.doPrivileged( (PrivilegedAction<R>) block::get );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return block.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new object based on the specified class with the given constructor arguments.
|
* Creates a new object based on the specified class with the given constructor arguments.
|
||||||
*
|
*
|
||||||
|
@ -92,7 +72,6 @@ public abstract class AbstractCollectionInitializor<T> implements Initializor<T>
|
||||||
* @return a new instance of the class
|
* @return a new instance of the class
|
||||||
*/
|
*/
|
||||||
protected <R> R newObjectInstance(Class<R> clazz, Object... args) {
|
protected <R> R newObjectInstance(Class<R> clazz, Object... args) {
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
final Constructor<R> constructor = ReflectHelper.getDefaultConstructor( clazz );
|
final Constructor<R> constructor = ReflectHelper.getDefaultConstructor( clazz );
|
||||||
if ( constructor == null ) {
|
if ( constructor == null ) {
|
||||||
|
@ -103,6 +82,5 @@ public abstract class AbstractCollectionInitializor<T> implements Initializor<T>
|
||||||
catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ public class SortedMapCollectionInitializor extends MapCollectionInitializor<Sor
|
||||||
if ( comparator == null ) {
|
if ( comparator == null ) {
|
||||||
return super.initializeCollection( size );
|
return super.initializeCollection( size );
|
||||||
}
|
}
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
return collectionClass.getConstructor( Comparator.class ).newInstance( comparator );
|
return collectionClass.getConstructor( Comparator.class ).newInstance( comparator );
|
||||||
}
|
}
|
||||||
|
@ -67,7 +66,6 @@ public class SortedMapCollectionInitializor extends MapCollectionInitializor<Sor
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ public class SortedSetCollectionInitializor extends BasicCollectionInitializor<S
|
||||||
if ( comparator == null ) {
|
if ( comparator == null ) {
|
||||||
return super.initializeCollection( size );
|
return super.initializeCollection( size );
|
||||||
}
|
}
|
||||||
return doPrivileged( () -> {
|
|
||||||
try {
|
try {
|
||||||
return collectionClass.getConstructor( Comparator.class ).newInstance(comparator);
|
return collectionClass.getConstructor( Comparator.class ).newInstance(comparator);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +67,5 @@ public class SortedSetCollectionInitializor extends BasicCollectionInitializor<S
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
throw new AuditException( e );
|
throw new AuditException( e );
|
||||||
}
|
}
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue