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