Skip to content

Commit 61c3db0

Browse files
committed
MethodHandles.Lookup.defineClass for CGLIB class definition purposes
Spring's CGLIB fork is patched with local copies of affected files here, introducing the notion of a "contextClass" (e.g. the proxy superclass) which gets passed through to ReflectUtils.defineClass for delegating to MethodHandles.Lookup.defineClass eventually, against a privateLookupIn(contextClass) lookup context on JDK 9/10/11. Issue: SPR-15859
1 parent cdaa247 commit 61c3db0

File tree

15 files changed

+3153
-206
lines changed

15 files changed

+3153
-206
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -205,9 +205,8 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
205205
return createProxyClassAndInstance(enhancer, callbacks);
206206
}
207207
catch (CodeGenerationException | IllegalArgumentException ex) {
208-
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
209-
this.advised.getTargetClass() + "]: " +
210-
"Common causes of this problem include using a final class or a non-visible class",
208+
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
209+
": Common causes of this problem include using a final class or a non-visible class",
211210
ex);
212211
}
213212
catch (Throwable ex) {
@@ -743,7 +742,7 @@ public CglibMethodInvocation(Object proxy, @Nullable Object target, Method metho
743742
*/
744743
@Override
745744
protected Object invokeJoinpoint() throws Throwable {
746-
if (this.publicMethod) {
745+
if (this.publicMethod && getMethod().getDeclaringClass() != Object.class) {
747746
return this.methodProxy.invoke(this.target, this.arguments);
748747
}
749748
else {

spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java

+49-75
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,22 +82,24 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
8282
@Test
8383
public void testRejectsPerCflowAspect() {
8484
try {
85-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerCflowAspect(),"someBean"));
85+
getFixture().getAdvisors(
86+
new SingletonMetadataAwareAspectInstanceFactory(new PerCflowAspect(), "someBean"));
8687
fail("Cannot accept cflow");
8788
}
8889
catch (AopConfigException ex) {
89-
assertTrue(ex.getMessage().indexOf("PERCFLOW") != -1);
90+
assertTrue(ex.getMessage().contains("PERCFLOW"));
9091
}
9192
}
9293

9394
@Test
9495
public void testRejectsPerCflowBelowAspect() {
9596
try {
96-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerCflowBelowAspect(),"someBean"));
97+
getFixture().getAdvisors(
98+
new SingletonMetadataAwareAspectInstanceFactory(new PerCflowBelowAspect(), "someBean"));
9799
fail("Cannot accept cflowbelow");
98100
}
99101
catch (AopConfigException ex) {
100-
assertTrue(ex.getMessage().indexOf("PERCFLOWBELOW") != -1);
102+
assertTrue(ex.getMessage().contains("PERCFLOWBELOW"));
101103
}
102104
}
103105

@@ -227,9 +229,7 @@ public void testPerTypeWithinAspect() throws SecurityException, NoSuchMethodExce
227229
int realAge = 65;
228230
target.setAge(realAge);
229231
PerTypeWithinAspectInstanceFactory aif = new PerTypeWithinAspectInstanceFactory();
230-
TestBean itb = (TestBean) createProxy(target,
231-
getFixture().getAdvisors(aif),
232-
TestBean.class);
232+
TestBean itb = (TestBean) createProxy(target, getFixture().getAdvisors(aif), TestBean.class);
233233
assertEquals("No method calls", 0, aif.getInstantiationCount());
234234
assertEquals("Around advice must now apply", 0, itb.getAge());
235235

@@ -257,9 +257,7 @@ public void testPerTypeWithinAspect() throws SecurityException, NoSuchMethodExce
257257
assertEquals("Around advice must still apply", 1, itb.getAge());
258258
assertEquals("Around advice must still apply", 2, itb.getAge());
259259

260-
TestBean itb2 = (TestBean) createProxy(target,
261-
getFixture().getAdvisors(aif),
262-
TestBean.class);
260+
TestBean itb2 = (TestBean) createProxy(target, getFixture().getAdvisors(aif), TestBean.class);
263261
assertEquals(1, aif.getInstantiationCount());
264262
assertEquals("Around advice be independent for second instance", 0, itb2.getAge());
265263
assertEquals(2, aif.getInstantiationCount());
@@ -284,7 +282,8 @@ public void testNamedPointcutFromAspectLibrary() {
284282
public void testNamedPointcutFromAspectLibraryWithBinding() {
285283
TestBean target = new TestBean();
286284
ITestBean itb = (ITestBean) createProxy(target,
287-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new NamedPointcutAspectFromLibraryWithBinding(),"someBean")),
285+
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(
286+
new NamedPointcutAspectFromLibraryWithBinding(), "someBean")),
288287
ITestBean.class);
289288
itb.setAge(10);
290289
assertEquals("Around advice must apply", 20, itb.getAge());
@@ -296,7 +295,7 @@ private void testNamedPointcuts(Object aspectInstance) {
296295
int realAge = 65;
297296
target.setAge(realAge);
298297
ITestBean itb = (ITestBean) createProxy(target,
299-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspectInstance,"someBean")),
298+
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspectInstance, "someBean")),
300299
ITestBean.class);
301300
assertEquals("Around advice must apply", -1, itb.getAge());
302301
assertEquals(realAge, target.getAge());
@@ -306,7 +305,8 @@ private void testNamedPointcuts(Object aspectInstance) {
306305
public void testBindingWithSingleArg() {
307306
TestBean target = new TestBean();
308307
ITestBean itb = (ITestBean) createProxy(target,
309-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new BindingAspectWithSingleArg(),"someBean")),
308+
getFixture().getAdvisors(
309+
new SingletonMetadataAwareAspectInstanceFactory(new BindingAspectWithSingleArg(), "someBean")),
310310
ITestBean.class);
311311
itb.setAge(10);
312312
assertEquals("Around advice must apply", 20, itb.getAge());
@@ -317,7 +317,8 @@ public void testBindingWithSingleArg() {
317317
public void testBindingWithMultipleArgsDifferentlyOrdered() {
318318
ManyValuedArgs target = new ManyValuedArgs();
319319
ManyValuedArgs mva = (ManyValuedArgs) createProxy(target,
320-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ManyValuedArgs(),"someBean")),
320+
getFixture().getAdvisors(
321+
new SingletonMetadataAwareAspectInstanceFactory(new ManyValuedArgs(), "someBean")),
321322
ManyValuedArgs.class);
322323

323324
String a = "a";
@@ -338,7 +339,7 @@ public void testIntroductionOnTargetNotImplementingInterface() {
338339
assertFalse(notLockableTarget instanceof Lockable);
339340
NotLockable notLockable1 = (NotLockable) createProxy(notLockableTarget,
340341
getFixture().getAdvisors(
341-
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")),
342+
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
342343
NotLockable.class);
343344
assertTrue(notLockable1 instanceof Lockable);
344345
Lockable lockable = (Lockable) notLockable1;
@@ -349,7 +350,7 @@ public void testIntroductionOnTargetNotImplementingInterface() {
349350
NotLockable notLockable2Target = new NotLockable();
350351
NotLockable notLockable2 = (NotLockable) createProxy(notLockable2Target,
351352
getFixture().getAdvisors(
352-
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")),
353+
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
353354
NotLockable.class);
354355
assertTrue(notLockable2 instanceof Lockable);
355356
Lockable lockable2 = (Lockable) notLockable2;
@@ -369,10 +370,10 @@ public void testIntroductionOnTargetNotImplementingInterface() {
369370
public void testIntroductionAdvisorExcludedFromTargetImplementingInterface() {
370371
assertTrue(AopUtils.findAdvisorsThatCanApply(
371372
getFixture().getAdvisors(
372-
new SingletonMetadataAwareAspectInstanceFactory(
373-
new MakeLockable(),"someBean")),
373+
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
374374
CannotBeUnlocked.class).isEmpty());
375-
assertEquals(2, AopUtils.findAdvisorsThatCanApply(getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class).size());
375+
assertEquals(2, AopUtils.findAdvisorsThatCanApply(getFixture().getAdvisors(
376+
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class).size());
376377
}
377378

378379
@Test
@@ -408,42 +409,34 @@ public void testIntroductionOnTargetExcludedByTypePattern() {
408409
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
409410
List.class
410411
),
411-
CannotBeUnlocked.class);
412+
List.class);
412413
assertFalse("Type pattern must have excluded mixin", proxy instanceof Lockable);
413414
}
414415

415-
/* prereq AspectJ 1.6.7
416416
@Test
417-
public void testIntroductionBasedOnAnnotationMatch_Spr5307() {
417+
public void testIntroductionBasedOnAnnotationMatch_SPR5307() {
418418
AnnotatedTarget target = new AnnotatedTargetImpl();
419-
420419
List<Advisor> advisors = getFixture().getAdvisors(
421-
new SingletonMetadataAwareAspectInstanceFactory(new MakeAnnotatedTypeModifiable(),"someBean"));
422-
Object proxy = createProxy(target,
423-
advisors,
424-
AnnotatedTarget.class);
420+
new SingletonMetadataAwareAspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean"));
421+
Object proxy = createProxy(target, advisors, AnnotatedTarget.class);
425422
System.out.println(advisors.get(1));
426423
assertTrue(proxy instanceof Lockable);
427424
Lockable lockable = (Lockable)proxy;
428425
lockable.locked();
429426
}
430-
*/
431427

432428
// TODO: Why does this test fail? It hasn't been run before, so it maybe never actually passed...
433-
434429
@Test
435430
@Ignore
436431
public void testIntroductionWithArgumentBinding() {
437432
TestBean target = new TestBean();
438433

439434
List<Advisor> advisors = getFixture().getAdvisors(
440-
new SingletonMetadataAwareAspectInstanceFactory(new MakeITestBeanModifiable(),"someBean"));
435+
new SingletonMetadataAwareAspectInstanceFactory(new MakeITestBeanModifiable(), "someBean"));
441436
advisors.addAll(getFixture().getAdvisors(
442-
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")));
437+
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")));
443438

444-
Modifiable modifiable = (Modifiable) createProxy(target,
445-
advisors,
446-
ITestBean.class);
439+
Modifiable modifiable = (Modifiable) createProxy(target, advisors, ITestBean.class);
447440
assertThat(modifiable, instanceOf(Modifiable.class));
448441
Lockable lockable = (Lockable) modifiable;
449442
assertFalse(lockable.locked());
@@ -477,11 +470,11 @@ public void testIntroductionWithArgumentBinding() {
477470
public void testAspectMethodThrowsExceptionLegalOnSignature() {
478471
TestBean target = new TestBean();
479472
UnsupportedOperationException expectedException = new UnsupportedOperationException();
480-
List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException),"someBean"));
473+
List<Advisor> advisors = getFixture().getAdvisors(
474+
new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException), "someBean"));
481475
assertEquals("One advice method was found", 1, advisors.size());
482-
ITestBean itb = (ITestBean) createProxy(target,
483-
advisors,
484-
ITestBean.class);
476+
ITestBean itb = (ITestBean) createProxy(target, advisors, ITestBean.class);
477+
485478
try {
486479
itb.getAge();
487480
fail();
@@ -497,11 +490,11 @@ public void testAspectMethodThrowsExceptionLegalOnSignature() {
497490
public void testAspectMethodThrowsExceptionIllegalOnSignature() {
498491
TestBean target = new TestBean();
499492
RemoteException expectedException = new RemoteException();
500-
List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException),"someBean"));
493+
List<Advisor> advisors = getFixture().getAdvisors(
494+
new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException), "someBean"));
501495
assertEquals("One advice method was found", 1, advisors.size());
502-
ITestBean itb = (ITestBean) createProxy(target,
503-
advisors,
504-
ITestBean.class);
496+
ITestBean itb = (ITestBean) createProxy(target, advisors, ITestBean.class);
497+
505498
try {
506499
itb.getAge();
507500
fail();
@@ -522,10 +515,7 @@ protected Object createProxy(Object target, List<Advisor> advisors, Class<?>...
522515

523516
// Required everywhere we use AspectJ proxies
524517
pf.addAdvice(ExposeInvocationInterceptor.INSTANCE);
525-
526-
for (Object a : advisors) {
527-
pf.addAdvisor((Advisor) a);
528-
}
518+
pf.addAdvisors(advisors);
529519

530520
pf.setExposeProxy(true);
531521
return pf.getProxy();
@@ -534,13 +524,11 @@ protected Object createProxy(Object target, List<Advisor> advisors, Class<?>...
534524
@Test
535525
public void testTwoAdvicesOnOneAspect() {
536526
TestBean target = new TestBean();
537-
538527
TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect();
539-
List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(twoAdviceAspect,"someBean"));
528+
List<Advisor> advisors = getFixture().getAdvisors(
529+
new SingletonMetadataAwareAspectInstanceFactory(twoAdviceAspect, "someBean"));
540530
assertEquals("Two advice methods found", 2, advisors.size());
541-
ITestBean itb = (ITestBean) createProxy(target,
542-
advisors,
543-
ITestBean.class);
531+
ITestBean itb = (ITestBean) createProxy(target, advisors, ITestBean.class);
544532
itb.setName("");
545533
assertEquals(0, itb.getAge());
546534
int newAge = 32;
@@ -551,16 +539,15 @@ public void testTwoAdvicesOnOneAspect() {
551539
@Test
552540
public void testAfterAdviceTypes() throws Exception {
553541
Echo target = new Echo();
554-
555542
ExceptionHandling afterReturningAspect = new ExceptionHandling();
556-
List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(afterReturningAspect,"someBean"));
557-
Echo echo = (Echo) createProxy(target,
558-
advisors,
559-
Echo.class);
543+
List<Advisor> advisors = getFixture().getAdvisors(
544+
new SingletonMetadataAwareAspectInstanceFactory(afterReturningAspect, "someBean"));
545+
Echo echo = (Echo) createProxy(target, advisors, Echo.class);
560546
assertEquals(0, afterReturningAspect.successCount);
561547
assertEquals("", echo.echo(""));
562548
assertEquals(1, afterReturningAspect.successCount);
563549
assertEquals(0, afterReturningAspect.failureCount);
550+
564551
try {
565552
echo.echo(new FileNotFoundException());
566553
fail();
@@ -580,30 +567,19 @@ public void testAfterAdviceTypes() throws Exception {
580567
public void testFailureWithoutExplicitDeclarePrecedence() {
581568
TestBean target = new TestBean();
582569
MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
583-
new NoDeclarePrecedenceShouldFail(), "someBean");
570+
new NoDeclarePrecedenceShouldFail(), "someBean");
584571
ITestBean itb = (ITestBean) createProxy(target,
585-
getFixture().getAdvisors(aspectInstanceFactory), ITestBean.class);
572+
getFixture().getAdvisors(aspectInstanceFactory), ITestBean.class);
586573
itb.getAge();
587574
}
588575

589576
@Test(expected = IllegalArgumentException.class)
590577
public void testDeclarePrecedenceNotSupported() {
591578
TestBean target = new TestBean();
592579
MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
593-
new DeclarePrecedenceShouldSucceed(), "someBean");
594-
createProxy(target, getFixture().getAdvisors(aspectInstanceFactory),
595-
ITestBean.class);
596-
}
597-
598-
/** Not supported in 2.0!
599-
public void testExplicitDeclarePrecedencePreventsFailure() {
600-
TestBean target = new TestBean();
601-
ITestBean itb = (ITestBean) createProxy(target,
602-
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new DeclarePrecedenceShouldSucceed(), "someBean")),
603-
ITestBean.class);
604-
assertEquals(666, itb.getAge());
580+
new DeclarePrecedenceShouldSucceed(), "someBean");
581+
createProxy(target, getFixture().getAdvisors(aspectInstanceFactory), ITestBean.class);
605582
}
606-
*/
607583

608584

609585
@Aspect("percflow(execution(* *(..)))")
@@ -1019,9 +995,7 @@ class MakeLockable {
1019995
public static Lockable mixin;
1020996

1021997
@Before(value="execution(void set*(*)) && this(mixin)", argNames="mixin")
1022-
public void checkNotLocked(
1023-
Lockable mixin) // Bind to arg
1024-
{
998+
public void checkNotLocked( Lockable mixin) {
1025999
// Can also obtain the mixin (this) this way
10261000
//Lockable mixin = (Lockable) jp.getThis();
10271001
if (mixin.locked()) {

0 commit comments

Comments
 (0)