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