Skip to content

Commit 39da445

Browse files
committed
HHH-14694 Use stable proxy names to avoid managing proxy state
1 parent 903c435 commit 39da445

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
@@ -13,8 +13,6 @@
1313
import org.hibernate.internal.util.collections.ArrayHelper;
1414
import org.hibernate.proxy.ProxyConfiguration;
1515

16-
import net.bytebuddy.NamingStrategy;
17-
import net.bytebuddy.TypeCache;
1816
import net.bytebuddy.description.modifier.Visibility;
1917
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
2018

@@ -37,13 +35,12 @@ public BasicProxyFactoryImpl(final Class superClass, final Class interfaceClass,
3735
}
3836

3937
final Class<?> superClassOrMainInterface = superClass != null ? superClass : interfaceClass;
40-
final TypeCache.SimpleKey cacheKey = new TypeCache.SimpleKey( superClassOrMainInterface );
38+
final ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
39+
final String proxyClassName = superClassOrMainInterface.getName() + "$" + PROXY_NAMING_SUFFIX;
4140

42-
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
43-
44-
this.proxyClass = byteBuddyState.loadBasicProxy( superClassOrMainInterface, cacheKey, byteBuddy ->
41+
this.proxyClass = byteBuddyState.loadBasicProxy( superClassOrMainInterface, proxyClassName, (byteBuddy, namingStrategy) ->
4542
helpers.appendIgnoreAlsoAtEnd( byteBuddy
46-
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( superClassOrMainInterface.getName() ) ) )
43+
.with( namingStrategy )
4744
.subclass( superClass == null ? Object.class : superClass, ConstructorStrategy.Default.DEFAULT_CONSTRUCTOR )
4845
.implement( interfaceClass == null ? NO_INTERFACES : new Class[]{ interfaceClass } )
4946
.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
@@ -10,8 +10,11 @@
1010
import java.lang.reflect.Method;
1111
import java.util.ArrayList;
1212
import java.util.List;
13+
import java.util.function.BiFunction;
1314
import java.util.function.Function;
1415

16+
import net.bytebuddy.NamingStrategy;
17+
import net.bytebuddy.description.type.TypeDescription;
1518
import org.hibernate.HibernateException;
1619
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImplConstants;
1720
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
@@ -94,7 +97,9 @@ public ByteBuddyState() {
9497
* @param cacheKey The cache key.
9598
* @param makeProxyFunction A function building the proxy.
9699
* @return The loaded proxy class.
100+
* @deprecated Use {@link #loadProxy(Class, String, BiFunction)} instead.
97101
*/
102+
@Deprecated(forRemoval = true, since = "6.6")
98103
public Class<?> loadProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
99104
Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
100105
return load( referenceClass, proxyCache, cacheKey, makeProxyFunction );
@@ -107,12 +112,40 @@ public Class<?> loadProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
107112
* @param cacheKey The cache key.
108113
* @param makeProxyFunction A function building the proxy.
109114
* @return The loaded proxy class.
115+
* @deprecated Use {@link #loadBasicProxy(Class, String, BiFunction)} instead.
110116
*/
117+
@Deprecated(forRemoval = true, since = "6.6")
111118
Class<?> loadBasicProxy(Class<?> referenceClass, TypeCache.SimpleKey cacheKey,
112119
Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
113120
return load( referenceClass, basicProxyCache, cacheKey, makeProxyFunction );
114121
}
115122

123+
/**
124+
* Load a proxy as generated by the {@link ProxyFactory}.
125+
*
126+
* @param referenceClass The main class to proxy - might be an interface.
127+
* @param proxyClassName The proxy class name.
128+
* @param makeProxyFunction A function building the proxy.
129+
* @return The loaded proxy class.
130+
*/
131+
public Class<?> loadProxy(Class<?> referenceClass, String proxyClassName,
132+
BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
133+
return load( referenceClass, proxyClassName, makeProxyFunction );
134+
}
135+
136+
/**
137+
* Load a proxy as generated by the {@link BasicProxyFactory}.
138+
*
139+
* @param referenceClass The main class to proxy - might be an interface.
140+
* @param proxyClassName The proxy class name.
141+
* @param makeProxyFunction A function building the proxy.
142+
* @return The loaded proxy class.
143+
*/
144+
Class<?> loadBasicProxy(Class<?> referenceClass, String proxyClassName,
145+
BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
146+
return load( referenceClass, proxyClassName, makeProxyFunction );
147+
}
148+
116149
/**
117150
* Load a class generated by ByteBuddy.
118151
*
@@ -180,6 +213,31 @@ void clearState() {
180213
basicProxyCache.clear();
181214
}
182215

216+
private Class<?> load(Class<?> referenceClass, String proxyClassName, BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeProxyFunction) {
217+
try {
218+
return referenceClass.getClassLoader().loadClass( proxyClassName );
219+
}
220+
catch (ClassNotFoundException e) {
221+
// Ignore
222+
}
223+
try {
224+
return make( makeProxyFunction.apply( byteBuddy, new FixedNamingStrategy( proxyClassName ) ) )
225+
.load(
226+
referenceClass.getClassLoader(),
227+
resolveClassLoadingStrategy( referenceClass )
228+
)
229+
.getLoaded();
230+
}
231+
catch (LinkageError e) {
232+
try {
233+
return referenceClass.getClassLoader().loadClass( proxyClassName );
234+
}
235+
catch (ClassNotFoundException ex) {
236+
throw new RuntimeException( "Couldn't load or define class [" + proxyClassName + "]", e );
237+
}
238+
}
239+
}
240+
183241
private Class<?> load(Class<?> referenceClass, TypeCache<TypeCache.SimpleKey> cache,
184242
TypeCache.SimpleKey cacheKey, Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
185243
return cache.findOrInsert(
@@ -325,4 +383,16 @@ private static ClassLoadingStrategy<ClassLoader> resolveClassLoadingStrategy(Cla
325383
}
326384
}
327385

386+
private static class FixedNamingStrategy extends NamingStrategy.AbstractBase {
387+
private final String className;
388+
389+
public FixedNamingStrategy(String className) {
390+
this.className = className;
391+
}
392+
393+
@Override
394+
protected String name(TypeDescription typeDescription) {
395+
return className;
396+
}
397+
}
328398
}

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
@@ -11,6 +11,7 @@
1111
import java.util.HashSet;
1212
import java.util.Locale;
1313
import java.util.Set;
14+
import java.util.function.BiFunction;
1415
import java.util.function.Function;
1516

1617
import org.hibernate.HibernateException;
@@ -22,7 +23,6 @@
2223

2324
import net.bytebuddy.ByteBuddy;
2425
import net.bytebuddy.NamingStrategy;
25-
import net.bytebuddy.TypeCache;
2626
import net.bytebuddy.description.modifier.Visibility;
2727
import net.bytebuddy.description.type.TypeDefinition;
2828
import net.bytebuddy.description.type.TypeDescription;
@@ -53,7 +53,8 @@ public Class buildProxy(
5353
}
5454
Collections.addAll( key, interfaces );
5555

56-
return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey( key ),
56+
final String proxyClassName = persistentClass.getTypeName() + "$" + PROXY_NAMING_SUFFIX;
57+
return byteBuddyState.loadProxy( persistentClass, proxyClassName,
5758
proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ), new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
5859
}
5960

@@ -62,7 +63,7 @@ public Class buildProxy(
6263
*/
6364
@Deprecated
6465
public DynamicType.Unloaded<?> buildUnloadedProxy(final Class<?> persistentClass, final Class<?>[] interfaces) {
65-
return byteBuddyState.make( proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ),
66+
return byteBuddyState.make( proxyBuilderLegacy( TypeDescription.ForLoadedType.of( persistentClass ),
6667
new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
6768
}
6869

@@ -71,15 +72,24 @@ public DynamicType.Unloaded<?> buildUnloadedProxy(final Class<?> persistentClass
7172
*/
7273
public DynamicType.Unloaded<?> buildUnloadedProxy(TypePool typePool, TypeDefinition persistentClass,
7374
Collection<? extends TypeDefinition> interfaces) {
74-
return byteBuddyState.make( typePool, proxyBuilder( persistentClass, interfaces ) );
75+
return byteBuddyState.make( typePool, proxyBuilderLegacy( persistentClass, interfaces ) );
7576
}
7677

77-
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
78+
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilderLegacy(TypeDefinition persistentClass,
79+
Collection<? extends TypeDefinition> interfaces) {
80+
final BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> proxyBuilder =
81+
proxyBuilder( persistentClass, interfaces );
82+
final NamingStrategy.Suffixing namingStrategy =
83+
new NamingStrategy.Suffixing( PROXY_NAMING_SUFFIX, new NamingStrategy.Suffixing.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) );
84+
return byteBuddy -> proxyBuilder.apply( byteBuddy, namingStrategy );
85+
}
86+
87+
private BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
7888
Collection<? extends TypeDefinition> interfaces) {
7989
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
80-
return byteBuddy -> helpers.appendIgnoreAlsoAtEnd( byteBuddy
90+
return (byteBuddy, namingStrategy) -> helpers.appendIgnoreAlsoAtEnd( byteBuddy
8191
.ignore( helpers.getGroovyGetMetaClassFilter() )
82-
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.Suffixing.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) ) )
92+
.with( namingStrategy )
8393
.subclass( interfaces.size() == 1 ? persistentClass : OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
8494
.implement( interfaces )
8595
.method( helpers.getVirtualNotFinalizerFilter() )

0 commit comments

Comments
 (0)