4141/**
4242 * Java instrumentation transformer.
4343 * <p/>
44- * The is the single instance of transformer registered by HotswapAgent. It will delegate to plugins to
44+ * This is the single instance of transformer registered by HotswapAgent. It will delegate to plugins to
4545 * do the transformer work.
4646 *
4747 * @author Jiri Bubnik
@@ -107,7 +107,7 @@ public List<Pattern> getExcludedClassLoaderPatterns() {
107107 * @param classLoader the classloader to which this transformation is associated
108108 * @param classNameRegexp regexp to match fully qualified class name.
109109 * Because "." is any character in regexp, this will match / in the transform method as well
110- * (diffentence between java/lang/String and java.lang.String).
110+ * (difference between java/lang/String and java.lang.String).
111111 * @param transformer the transformer to be called for each class matching regexp.
112112 */
113113 public void registerTransformer (ClassLoader classLoader , String classNameRegexp , HaClassFileTransformer transformer ) {
@@ -184,7 +184,7 @@ public void closeClassLoader(ClassLoader classLoader) {
184184 * <p>It does not do the instrumentation itself, instead iterates registered transformers and compares
185185 * registration class regexp - if the regexp matches, the classloader is called.
186186 * <p/>
187- * <p>Note that class bytes may be send to multiple transformers, but the order is not defined.
187+ * <p>Note that class bytes may be sent to multiple transformers, but the order is not defined.
188188 *
189189 * @see ClassFileTransformer#transform(ClassLoader, String, Class, java.security.ProtectionDomain, byte[])
190190 */
@@ -204,7 +204,7 @@ public byte[] transform(final ClassLoader classLoader, String className, Class<?
204204 List <PluginClassFileTransformer > pluginTransformers = new ArrayList <>();
205205 try {
206206 // 1. call transform method of defining transformers
207- for (RegisteredTransformersRecord transformerRecord : new ArrayList <RegisteredTransformersRecord >(otherTransformers .values ())) {
207+ for (RegisteredTransformersRecord transformerRecord : new ArrayList <>(otherTransformers .values ())) {
208208 if ((className != null && transformerRecord .pattern .matcher (className ).matches ()) ||
209209 (redefiningClass != null && transformerRecord .pattern .matcher (redefiningClass .getName ()).matches ())) {
210210 for (ClassFileTransformer transformer : new ArrayList <ClassFileTransformer >(transformerRecord .transformerList )) {
@@ -221,7 +221,7 @@ public byte[] transform(final ClassLoader classLoader, String className, Class<?
221221 }
222222 // 2. call transform method of redefining transformers
223223 if (redefiningClass != null && className != null ) {
224- for (RegisteredTransformersRecord transformerRecord : new ArrayList <RegisteredTransformersRecord >(redefinitionTransformers .values ())) {
224+ for (RegisteredTransformersRecord transformerRecord : new ArrayList <>(redefinitionTransformers .values ())) {
225225 if (transformerRecord .pattern .matcher (className ).matches ()) {
226226 for (ClassFileTransformer transformer : new ArrayList <ClassFileTransformer >(transformerRecord .transformerList )) {
227227 if (transformer instanceof PluginClassFileTransformer ) {
@@ -308,11 +308,11 @@ LinkedList<PluginClassFileTransformer> reduce(final ClassLoader classLoader, Lis
308308 }
309309 /**
310310 * Every classloader should be initialized. Usually if anything interesting happens,
311- * it is initialized during plugin initialization process. However, some plugins (e.g. Hotswapper)
311+ * it is initialized during the plugin initialization process. However, some plugins (e.g. Hotswapper)
312312 * are triggered during classloader initialization process itself (@Init on static method). In this case,
313313 * the plugin will be never invoked, until the classloader initialization is invoked from here.
314314 *
315- * Schedule with some timeout to allow standard plugin initialization process to precede.
315+ * Schedule with some timeout to allow a standard plugin initialization process to precede.
316316 *
317317 * @param classLoader the classloader to which this transformation is associated
318318 * @param protectionDomain associated protection domain (if any)
@@ -322,7 +322,13 @@ protected boolean ensureClassLoaderInitialized(final ClassLoader classLoader, fi
322322
323323 if (classLoader == null ) {
324324 // directly init null (bootstrap) classloader
325- PluginManager .getInstance ().initClassLoader (null , protectionDomain );
325+ if (PluginManager .getInstance ().getInitClassLoaderLock ().tryLock ()) {
326+ try {
327+ PluginManager .getInstance ().initClassLoader (null , protectionDomain );
328+ } finally {
329+ PluginManager .getInstance ().getInitClassLoaderLock ().unlock ();
330+ }
331+ }
326332 } else {
327333 // ensure the classloader should not be excluded
328334 if (shouldScheduleClassLoader (classLoader )) {
@@ -364,10 +370,13 @@ private boolean shouldScheduleClassLoader(final ClassLoader classLoader) {
364370
365371
366372 /**
367- * Transform type to ^regexp$ form - match only whole pattern.
373+ * Normalizes a given regular expression for matching types by ensuring
374+ * it starts with a caret (^) and ends with a dollar sign ($).
368375 *
369- * @param registeredType type
370- * @return
376+ * @param registeredType the input regular expression for a type which may or may not
377+ * include starting or ending anchors.
378+ * @return a string representing the normalized regular expression, guaranteed
379+ * to start with ^ and end with $.
371380 */
372381 protected String normalizeTypeRegexp (String registeredType ) {
373382 String regexp = registeredType ;
0 commit comments