Skip to content

Commit 73c490c

Browse files
committed
HHH-14694 Use stable proxy names to avoid managing proxy state
1 parent e6816f5 commit 73c490c

File tree

3 files changed

+91
-14
lines changed

3 files changed

+91
-14
lines changed

hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BasicProxyFactoryImpl.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
import org.hibernate.internal.util.collections.ArrayHelper;
1616
import org.hibernate.proxy.ProxyConfiguration;
1717

18-
import net.bytebuddy.NamingStrategy;
19-
import net.bytebuddy.TypeCache;
2018
import net.bytebuddy.description.modifier.Visibility;
2119
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
2220

@@ -40,13 +38,12 @@ public BasicProxyFactoryImpl(final Class superClass, final Class interfaceClass,
4038
}
4139

4240
final Class<?> superClassOrMainInterface = superClass != null ? superClass : interfaceClass;
43-
final TypeCache.SimpleKey cacheKey = new TypeCache.SimpleKey( superClassOrMainInterface );
41+
final ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
42+
final String proxyClassName = superClassOrMainInterface.getName() + "$" + PROXY_NAMING_SUFFIX;
4443

45-
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
46-
47-
this.proxyClass = byteBuddyState.loadBasicProxy( superClassOrMainInterface, cacheKey, byteBuddy ->
44+
this.proxyClass = byteBuddyState.loadBasicProxy( superClassOrMainInterface, proxyClassName, (byteBuddy, namingStrategy) ->
4845
helpers.appendIgnoreAlsoAtEnd( byteBuddy
49-
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( superClassOrMainInterface.getName() ) ) )
46+
.with( namingStrategy )
5047
.subclass( superClass == null ? Object.class : superClass, ConstructorStrategy.Default.DEFAULT_CONSTRUCTOR )
5148
.implement( interfaceClass == null ? NO_INTERFACES : new Class[]{ interfaceClass } )
5249
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )

hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
import java.security.PrivilegedAction;
2626
import java.util.ArrayList;
2727
import java.util.List;
28+
import java.util.function.BiFunction;
2829
import java.util.function.Function;
2930

31+
import net.bytebuddy.NamingStrategy;
32+
import net.bytebuddy.description.type.TypeDescription;
3033
import org.hibernate.HibernateException;
3134
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImplConstants;
3235
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
@@ -109,7 +112,9 @@ public ByteBuddyState() {
109112
* @param cacheKey The cache key.
110113
* @param makeProxyFunction A function building the proxy.
111114
* @return The loaded proxy class.
115+
* @deprecated Use {@link #loadProxy(Class, String, BiFunction)} instead.
112116
*/
117+
@Deprecated(forRemoval = true, since = "6.6")
113118
public Class<?> loadProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
114119
Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
115120
return load( referenceClass, proxyCache, cacheKey, makeProxyFunction );
@@ -122,12 +127,40 @@ public Class<?> loadProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
122127
* @param cacheKey The cache key.
123128
* @param makeProxyFunction A function building the proxy.
124129
* @return The loaded proxy class.
130+
* @deprecated Use {@link #loadBasicProxy(Class, String, BiFunction)} instead.
125131
*/
132+
@Deprecated(forRemoval = true, since = "6.6")
126133
Class<?> loadBasicProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
127134
Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
128135
return load( referenceClass, basicProxyCache, cacheKey, makeProxyFunction );
129136
}
130137

138+
/**
139+
* Load a proxy as generated by the {@link ProxyFactory}.
140+
*
141+
* @param referenceClass The main class to proxy - might be an interface.
142+
* @param proxyClassName The proxy class name.
143+
* @param makeProxyFunction A function building the proxy.
144+
* @return The loaded proxy class.
145+
*/
146+
public Class<?> loadProxy(Class<?> referenceClass, String proxyClassName,
147+
BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
148+
return load( referenceClass, proxyClassName, makeProxyFunction );
149+
}
150+
151+
/**
152+
* Load a proxy as generated by the {@link BasicProxyFactory}.
153+
*
154+
* @param referenceClass The main class to proxy - might be an interface.
155+
* @param proxyClassName The proxy class name.
156+
* @param makeProxyFunction A function building the proxy.
157+
* @return The loaded proxy class.
158+
*/
159+
Class<?> loadBasicProxy(Class<?> referenceClass, String proxyClassName,
160+
BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
161+
return load( referenceClass, proxyClassName, makeProxyFunction );
162+
}
163+
131164
/**
132165
* Load a class generated by ByteBuddy.
133166
*
@@ -195,6 +228,31 @@ void clearState() {
195228
basicProxyCache.clear();
196229
}
197230

231+
private Class<?> load(Class<?> referenceClass, String proxyClassName, BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
232+
try {
233+
return referenceClass.getClassLoader().loadClass( proxyClassName );
234+
}
235+
catch (ClassNotFoundException e) {
236+
// Ignore
237+
}
238+
try {
239+
return make( makeProxyFunction.apply( byteBuddy, new FixedNamingStrategy( proxyClassName ) ) )
240+
.load(
241+
referenceClass.getClassLoader(),
242+
resolveClassLoadingStrategy( referenceClass )
243+
)
244+
.getLoaded();
245+
}
246+
catch (LinkageError e) {
247+
try {
248+
return referenceClass.getClassLoader().loadClass( proxyClassName );
249+
}
250+
catch (ClassNotFoundException ex) {
251+
throw new RuntimeException( "Couldn't load or define class [" + proxyClassName + "]", e );
252+
}
253+
}
254+
}
255+
198256
private Class<?> load(Class<?> referenceClass, TypeCache<TypeCache.SimpleKey> cache,
199257
TypeCache.SimpleKey cacheKey, Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
200258
return cache.findOrInsert(
@@ -445,4 +503,16 @@ private static ClassLoadingStrategy<ClassLoader> resolveClassLoadingStrategy(Cla
445503
}
446504
}
447505

506+
private static class FixedNamingStrategy extends NamingStrategy.AbstractBase {
507+
private final String className;
508+
509+
public FixedNamingStrategy(String className) {
510+
this.className = className;
511+
}
512+
513+
@Override
514+
protected String name(TypeDescription typeDescription) {
515+
return className;
516+
}
517+
}
448518
}

hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.HashSet;
1616
import java.util.Locale;
1717
import java.util.Set;
18+
import java.util.function.BiFunction;
1819
import java.util.function.Function;
1920

2021
import org.hibernate.HibernateException;
@@ -27,7 +28,6 @@
2728

2829
import net.bytebuddy.ByteBuddy;
2930
import net.bytebuddy.NamingStrategy;
30-
import net.bytebuddy.TypeCache;
3131
import net.bytebuddy.description.modifier.Visibility;
3232
import net.bytebuddy.description.type.TypeDefinition;
3333
import net.bytebuddy.description.type.TypeDescription;
@@ -59,7 +59,8 @@ public Class buildProxy(
5959
}
6060
Collections.addAll( key, interfaces );
6161

62-
return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey( key ),
62+
final String proxyClassName = persistentClass.getTypeName() + "$" + PROXY_NAMING_SUFFIX;
63+
return byteBuddyState.loadProxy( persistentClass, proxyClassName,
6364
proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ), new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
6465
}
6566

@@ -68,7 +69,7 @@ public Class buildProxy(
6869
*/
6970
@Deprecated
7071
public DynamicType.Unloaded<?> buildUnloadedProxy(final Class<?> persistentClass, final Class<?>[] interfaces) {
71-
return byteBuddyState.make( proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ),
72+
return byteBuddyState.make( proxyBuilderLegacy( TypeDescription.ForLoadedType.of( persistentClass ),
7273
new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
7374
}
7475

@@ -77,15 +78,24 @@ public DynamicType.Unloaded<?> buildUnloadedProxy(final Class<?> persistentClass
7778
*/
7879
public DynamicType.Unloaded<?> buildUnloadedProxy(TypePool typePool, TypeDefinition persistentClass,
7980
Collection<? extends TypeDefinition> interfaces) {
80-
return byteBuddyState.make( typePool, proxyBuilder( persistentClass, interfaces ) );
81+
return byteBuddyState.make( typePool, proxyBuilderLegacy( persistentClass, interfaces ) );
8182
}
8283

83-
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
84+
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilderLegacy(TypeDefinition persistentClass,
85+
Collection<? extends TypeDefinition> interfaces) {
86+
final BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> proxyBuilder =
87+
proxyBuilder( persistentClass, interfaces );
88+
final NamingStrategy.Suffixing namingStrategy =
89+
new NamingStrategy.Suffixing( PROXY_NAMING_SUFFIX, new NamingStrategy.Suffixing.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) );
90+
return byteBuddy -> proxyBuilder.apply( byteBuddy, namingStrategy );
91+
}
92+
93+
private BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
8494
Collection<? extends TypeDefinition> interfaces) {
8595
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
86-
return byteBuddy -> helpers.appendIgnoreAlsoAtEnd( byteBuddy
96+
return (byteBuddy, namingStrategy) -> helpers.appendIgnoreAlsoAtEnd( byteBuddy
8797
.ignore( helpers.getGroovyGetMetaClassFilter() )
88-
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.Suffixing.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) ) )
98+
.with( namingStrategy )
8999
.subclass( interfaces.size() == 1 ? persistentClass : OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
90100
.implement( interfaces )
91101
.method( helpers.getVirtualNotFinalizerFilter() )

0 commit comments

Comments
 (0)