From 39132718fbf7cd43d1dbee5fd5365638ddd9fd90 Mon Sep 17 00:00:00 2001 From: Brett Okken Date: Thu, 4 May 2023 12:52:29 -0500 Subject: [PATCH] retry looking up a class if trying to define it fails --- .../dynamic/loading/ClassInjector.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/loading/ClassInjector.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/loading/ClassInjector.java index 5880b2dde6f..c51ad13508a 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/loading/ClassInjector.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/loading/ClassInjector.java @@ -1818,9 +1818,24 @@ public Map> injectRaw(Map types) { : classLoader) { for (Map.Entry entry : types.entrySet()) { try { + // first try to load the class from the given class loader result.put(entry.getKey(), Class.forName(entry.getKey(), false, classLoader)); } catch (ClassNotFoundException ignored) { - result.put(entry.getKey(), dispatcher.defineClass(classLoader, entry.getKey(), entry.getValue(), protectionDomain)); + try { + // if the class does not exist, try to define it + result.put(entry.getKey(), dispatcher.defineClass(classLoader, entry.getKey(), entry.getValue(), protectionDomain)); + } catch (Exception defFailure) { + // when the bootstrap loader is in use (i.e. the classloader is null), synchronizing on the BOOTSTRAP_LOADER_LOCK + // is sufficient to prevent this instance of ClassInjector from concurrently trying to define a class. + // however, in an environment where many ClassInjectors exist (either because shaded into multiple projects or + // it is present in multiple classloaders) + try { + result.put(entry.getKey(), Class.forName(entry.getKey(), false, classLoader)); + } catch (ClassNotFoundException ignored2) { + //throw the failure from actually trying to define the class + throw defFailure; + } + } } } }