2626import java .util .concurrent .Future ;
2727import java .util .concurrent .ScheduledExecutorService ;
2828import java .util .concurrent .TimeUnit ;
29+ import java .util .concurrent .atomic .AtomicBoolean ;
2930
3031import static net .bytebuddy .matcher .ElementMatchers .named ;
3132import static net .bytebuddy .matcher .ElementMatchers .none ;
@@ -59,8 +60,10 @@ public void setUp() throws Exception {
5960 @ AgentAttachmentRule .Enforce (retransformsClasses = true )
6061 @ IntegrationRule .Enforce
6162 public void testResubmission () throws Exception {
62- // A redefinition reflects on loaded types which are eagerly validated types (Java 7- for redefinition).
63- // This causes type equality for outer/inner classes to fail which is why an external class is used.
63+ // The transformer deliberately fails on the first, unloaded transformation attempt to trigger a
64+ // resubmission. The resubmitted retransformation of the now-loaded type then succeeds. An external
65+ // class is used as the resubmission reflects on loaded types which, for outer/inner classes, causes
66+ // type equality to fail during the eager validation of a redefinition (Java 7- for redefinition).
6467 final ScheduledExecutorService scheduledExecutorService = Executors .newSingleThreadScheduledExecutor ();
6568 try {
6669 assertThat (ByteBuddyAgent .install (), instanceOf (Instrumentation .class ));
@@ -79,7 +82,7 @@ public Cancelable schedule(final Runnable job) {
7982 }
8083 })
8184 .resubmitOnError ()
82- .type (ElementMatchers .is (SimpleType .class ), ElementMatchers .is (classLoader )).transform (new SampleTransformer ())
85+ .type (ElementMatchers .is (SimpleType .class ), ElementMatchers .is (classLoader )).transform (new FailingTransformer ())
8386 .installOnByteBuddyAgent ();
8487 try {
8588 Class <?> type = classLoader .loadClass (SimpleType .class .getName ());
@@ -153,4 +156,20 @@ public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
153156 return builder .method (named (FOO )).intercept (FixedValue .value (BAR ));
154157 }
155158 }
159+
160+ private static class FailingTransformer implements AgentBuilder .Transformer {
161+
162+ private final AtomicBoolean failed = new AtomicBoolean ();
163+
164+ public DynamicType .Builder <?> transform (DynamicType .Builder <?> builder ,
165+ TypeDescription typeDescription ,
166+ ClassLoader classLoader ,
167+ JavaModule module ,
168+ ProtectionDomain protectionDomain ) {
169+ if (failed .compareAndSet (false , true )) {
170+ throw new RuntimeException ("Failing first transformation attempt to enforce a resubmission" );
171+ }
172+ return builder .method (named (FOO )).intercept (FixedValue .value (BAR ));
173+ }
174+ }
156175}
0 commit comments