6
6
*/
7
7
package org .hibernate .bytecode .enhance .internal .bytebuddy ;
8
8
9
- import java .util .Objects ;
10
- import java .util .concurrent .ConcurrentHashMap ;
11
-
12
9
import net .bytebuddy .dynamic .ClassFileLocator ;
13
10
import net .bytebuddy .pool .TypePool ;
14
11
12
+ import java .util .Objects ;
13
+
15
14
/**
16
15
* A TypePool suitable for loading user's classes,
17
16
* potentially in parallel operations.
18
17
*/
19
18
public class ModelTypePool extends TypePool .Default implements EnhancerClassLocator {
20
19
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 ;
24
22
25
- private ModelTypePool (SafeCacheProvider cacheProvider , OverridingClassFileLocator classFileLocator , CoreTypePool parent ) {
23
+ private ModelTypePool (EnhancerCacheProvider cacheProvider , EnhancerClassFileLocator classFileLocator , CoreTypePool parent ) {
26
24
super ( cacheProvider , classFileLocator , ReaderMode .FAST , parent );
27
25
this .poolCache = cacheProvider ;
28
26
this .locator = classFileLocator ;
@@ -64,7 +62,7 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
64
62
* @return
65
63
*/
66
64
public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool ) {
67
- return buildModelTypePool ( classFileLocator , coreTypePool , new SafeCacheProvider () );
65
+ return buildModelTypePool ( classFileLocator , coreTypePool , new EnhancerCacheProvider () );
68
66
}
69
67
70
68
/**
@@ -74,44 +72,35 @@ public static EnhancerClassLocator buildModelTypePool(ClassFileLocator classFile
74
72
* @param cacheProvider
75
73
* @return
76
74
*/
77
- public static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , SafeCacheProvider cacheProvider ) {
75
+ static EnhancerClassLocator buildModelTypePool (ClassFileLocator classFileLocator , CoreTypePool coreTypePool , EnhancerCacheProvider cacheProvider ) {
78
76
Objects .requireNonNull ( classFileLocator );
79
77
Objects .requireNonNull ( coreTypePool );
80
78
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 );
93
80
}
94
81
95
82
@ Override
96
83
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 ) );
105
95
}
106
96
107
97
@ Override
108
- public void deregisterClassNameAndBytes (final String className ) {
109
- locator . remove ( className );
98
+ public void deregisterClassNameAndBytes (String className ) {
99
+ poolCache . removeEnhancementState ( );
110
100
}
111
101
112
102
@ Override
113
103
public ClassFileLocator asClassFileLocator () {
114
104
return locator ;
115
105
}
116
-
117
106
}
0 commit comments