66 */
77package org .hibernate .bytecode .enhance .internal .bytebuddy ;
88
9- import java .util .Objects ;
10- import java .util .concurrent .ConcurrentHashMap ;
11-
129import net .bytebuddy .dynamic .ClassFileLocator ;
1310import net .bytebuddy .pool .TypePool ;
1411
12+ import java .util .Objects ;
13+
1514/**
1615 * A TypePool suitable for loading user's classes,
1716 * potentially in parallel operations.
1817 */
1918public class ModelTypePool extends TypePool .Default implements EnhancerClassLocator {
2019
21- private final ConcurrentHashMap <String , Resolution > resolutions = new ConcurrentHashMap <>();
22- private final OverridingClassFileLocator locator ;
23- private final SafeCacheProvider poolCache ;
20+ private final EnhancerClassFileLocator locator ;
21+ private final EnhancerCacheProvider poolCache ;
2422
25- private ModelTypePool (SafeCacheProvider cacheProvider , OverridingClassFileLocator classFileLocator , CoreTypePool parent ) {
23+ private ModelTypePool (EnhancerCacheProvider cacheProvider , EnhancerClassFileLocator classFileLocator , CoreTypePool parent ) {
2624 super ( cacheProvider , classFileLocator , ReaderMode .FAST , parent );
2725 this .poolCache = cacheProvider ;
2826 this .locator = classFileLocator ;
@@ -64,7 +62,7 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
6462 * @return
6563 */
6664 public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool ) {
67- return buildModelTypePool ( classFileLocator , coreTypePool , new SafeCacheProvider () );
65+ return buildModelTypePool ( classFileLocator , coreTypePool , new EnhancerCacheProvider () );
6866 }
6967
7068 /**
@@ -74,44 +72,35 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
7472 * @param cacheProvider
7573 * @return
7674 */
77- public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , SafeCacheProvider cacheProvider ) {
75+ static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , EnhancerCacheProvider cacheProvider ) {
7876 Objects .requireNonNull ( classFileLocator );
7977 Objects .requireNonNull ( coreTypePool );
8078 Objects .requireNonNull ( cacheProvider );
81- return new ModelTypePool ( cacheProvider , new OverridingClassFileLocator ( classFileLocator ), coreTypePool );
82- }
83-
84- @ Override
85- protected Resolution doDescribe (final String name ) {
86- final Resolution resolution = resolutions .get ( name );
87- if ( resolution != null ) {
88- return resolution ;
89- }
90- else {
91- return resolutions .computeIfAbsent ( name , super ::doDescribe );
92- }
79+ return new ModelTypePool ( cacheProvider , new EnhancerClassFileLocator ( cacheProvider , classFileLocator ), coreTypePool );
9380 }
9481
9582 @ Override
9683 public void registerClassNameAndBytes (final String className , final byte [] bytes ) {
97- //Very important: ensure the registered override is actually effective in case this class
98- //was already resolved in the recent past; this could have happened for example as a side effect
99- //of symbol resolution during enhancement of a different class, or very simply when attempting
100- //to re-enhanced the same class - which happens frequently in WildFly because of the class transformers
101- //being triggered concurrently by multiple parallel deployments.
102- resolutions .remove ( className );
103- poolCache .remove ( className );
104- locator .put ( className , new ClassFileLocator .Resolution .Explicit ( Objects .requireNonNull ( bytes ) ) );
84+ final EnhancerCacheProvider .EnhancementState currentEnhancementState = poolCache .getEnhancementState ();
85+ if ( currentEnhancementState != null ) {
86+ throw new IllegalStateException ( "Re-entrant enhancement is not supported: " + className );
87+ }
88+ final EnhancerCacheProvider .EnhancementState state = new EnhancerCacheProvider .EnhancementState (
89+ className ,
90+ new ClassFileLocator .Resolution .Explicit ( Objects .requireNonNull ( bytes ) )
91+ );
92+ // Set the state first because the ClassFileLocator needs this in the doDescribe() call below
93+ poolCache .setEnhancementState ( state );
94+ state .setTypePoolResolution ( doDescribe ( className ) );
10595 }
10696
10797 @ Override
108- public void deregisterClassNameAndBytes (final String className ) {
109- locator . remove ( className );
98+ public void deregisterClassNameAndBytes (String className ) {
99+ poolCache . removeEnhancementState ( );
110100 }
111101
112102 @ Override
113103 public ClassFileLocator asClassFileLocator () {
114104 return locator ;
115105 }
116-
117106}
0 commit comments