44 */
55package org .hibernate .bytecode .enhance .internal .bytebuddy ;
66
7- import java .util .Objects ;
8- import java .util .concurrent .ConcurrentHashMap ;
9-
107import net .bytebuddy .dynamic .ClassFileLocator ;
118import net .bytebuddy .pool .TypePool ;
129
10+ import java .util .Objects ;
11+
1312/**
1413 * A TypePool suitable for loading user's classes,
1514 * potentially in parallel operations.
1615 */
1716public class ModelTypePool extends TypePool .Default implements EnhancerClassLocator {
1817
19- private final ConcurrentHashMap <String , Resolution > resolutions = new ConcurrentHashMap <>();
20- private final OverridingClassFileLocator locator ;
21- private final SafeCacheProvider poolCache ;
18+ private final EnhancerClassFileLocator locator ;
19+ private final EnhancerCacheProvider poolCache ;
2220
23- private ModelTypePool (SafeCacheProvider cacheProvider , OverridingClassFileLocator classFileLocator , CoreTypePool parent ) {
21+ private ModelTypePool (EnhancerCacheProvider cacheProvider , EnhancerClassFileLocator classFileLocator , CoreTypePool parent ) {
2422 super ( cacheProvider , classFileLocator , ReaderMode .FAST , parent );
2523 this .poolCache = cacheProvider ;
2624 this .locator = classFileLocator ;
@@ -62,7 +60,7 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
6260 * @return
6361 */
6462 public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool ) {
65- return buildModelTypePool ( classFileLocator , coreTypePool , new SafeCacheProvider () );
63+ return buildModelTypePool ( classFileLocator , coreTypePool , new EnhancerCacheProvider () );
6664 }
6765
6866 /**
@@ -72,44 +70,35 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
7270 * @param cacheProvider
7371 * @return
7472 */
75- public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , SafeCacheProvider cacheProvider ) {
73+ static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , EnhancerCacheProvider cacheProvider ) {
7674 Objects .requireNonNull ( classFileLocator );
7775 Objects .requireNonNull ( coreTypePool );
7876 Objects .requireNonNull ( cacheProvider );
79- return new ModelTypePool ( cacheProvider , new OverridingClassFileLocator ( classFileLocator ), coreTypePool );
80- }
81-
82- @ Override
83- protected Resolution doDescribe (final String name ) {
84- final Resolution resolution = resolutions .get ( name );
85- if ( resolution != null ) {
86- return resolution ;
87- }
88- else {
89- return resolutions .computeIfAbsent ( name , super ::doDescribe );
90- }
77+ return new ModelTypePool ( cacheProvider , new EnhancerClassFileLocator ( cacheProvider , classFileLocator ), coreTypePool );
9178 }
9279
9380 @ Override
9481 public void registerClassNameAndBytes (final String className , final byte [] bytes ) {
95- //Very important: ensure the registered override is actually effective in case this class
96- //was already resolved in the recent past; this could have happened for example as a side effect
97- //of symbol resolution during enhancement of a different class, or very simply when attempting
98- //to re-enhanced the same class - which happens frequently in WildFly because of the class transformers
99- //being triggered concurrently by multiple parallel deployments.
100- resolutions .remove ( className );
101- poolCache .remove ( className );
102- locator .put ( className , new ClassFileLocator .Resolution .Explicit ( Objects .requireNonNull ( bytes ) ) );
82+ final EnhancerCacheProvider .EnhancementState currentEnhancementState = poolCache .getEnhancementState ();
83+ if ( currentEnhancementState != null ) {
84+ throw new IllegalStateException ( "Re-entrant enhancement is not supported: " + className );
85+ }
86+ final EnhancerCacheProvider .EnhancementState state = new EnhancerCacheProvider .EnhancementState (
87+ className ,
88+ new ClassFileLocator .Resolution .Explicit ( Objects .requireNonNull ( bytes ) )
89+ );
90+ // Set the state first because the ClassFileLocator needs this in the doDescribe() call below
91+ poolCache .setEnhancementState ( state );
92+ state .setTypePoolResolution ( doDescribe ( className ) );
10393 }
10494
10595 @ Override
106- public void deregisterClassNameAndBytes (final String className ) {
107- locator . remove ( className );
96+ public void deregisterClassNameAndBytes (String className ) {
97+ poolCache . removeEnhancementState ( );
10898 }
10999
110100 @ Override
111101 public ClassFileLocator asClassFileLocator () {
112102 return locator ;
113103 }
114-
115104}
0 commit comments