Skip to content

Commit a7db395

Browse files
committed
Merge branch '5.1.x'
2 parents c41616e + 5d8a34f commit a7db395

File tree

5 files changed

+214
-197
lines changed

5 files changed

+214
-197
lines changed

spring-context/src/test/java/org/springframework/context/event/EventPublicationInterceptorTests.java

+2-2
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-2019 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.
@@ -129,7 +129,7 @@ public TestEventWithNoValidOneArgObjectCtor() {
129129
public static class FactoryBeanTestListener extends TestListener implements FactoryBean<Object> {
130130

131131
@Override
132-
public Object getObject() throws Exception {
132+
public Object getObject() {
133133
return "test";
134134
}
135135

spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java

+7-10
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,28 @@ public class PayloadApplicationEventTests {
3535

3636
@Test
3737
public void testEventClassWithInterface() {
38-
ApplicationContext ac = new AnnotationConfigApplicationContext(Listener.class);
39-
MyEventClass event = new MyEventClass<>(this, "xyz");
38+
ApplicationContext ac = new AnnotationConfigApplicationContext(AuditableListener.class);
39+
AuditablePayloadEvent event = new AuditablePayloadEvent<>(this, "xyz");
4040
ac.publishEvent(event);
41-
assertTrue(ac.getBean(Listener.class).events.contains(event));
41+
assertTrue(ac.getBean(AuditableListener.class).events.contains(event));
4242
}
4343

4444

4545
public interface Auditable {
4646
}
4747

4848

49-
public static class MyEventClass<GT> extends PayloadApplicationEvent<GT> implements Auditable {
49+
@SuppressWarnings("serial")
50+
public static class AuditablePayloadEvent<T> extends PayloadApplicationEvent<T> implements Auditable {
5051

51-
public MyEventClass(Object source, GT payload) {
52+
public AuditablePayloadEvent(Object source, T payload) {
5253
super(source, payload);
5354
}
54-
55-
public String toString() {
56-
return "Payload: " + getPayload();
57-
}
5855
}
5956

6057

6158
@Component
62-
public static class Listener {
59+
public static class AuditableListener {
6360

6461
public final List<Auditable> events = new ArrayList<>();
6562

spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java

+44-18
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,10 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader,
491491
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
492492

493493
Class c = null;
494-
if (contextClass != null && privateLookupInMethod != null && lookupDefineClassMethod != null) {
494+
495+
// Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches
496+
if (contextClass != null && contextClass.getClassLoader() == loader &&
497+
privateLookupInMethod != null && lookupDefineClassMethod != null) {
495498
try {
496499
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
497500
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
@@ -510,29 +513,52 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader,
510513
throw new CodeGenerationException(ex);
511514
}
512515
}
513-
if (protectionDomain == null) {
514-
protectionDomain = PROTECTION_DOMAIN;
515-
}
516-
if (c == null) {
517-
if (classLoaderDefineClassMethod != null) {
518-
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
519-
try {
520-
if (!classLoaderDefineClassMethod.isAccessible()) {
521-
classLoaderDefineClassMethod.setAccessible(true);
522-
}
523-
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
524-
}
525-
catch (InvocationTargetException ex) {
526-
throw new CodeGenerationException(ex.getTargetException());
516+
517+
// Classic option: protected ClassLoader.defineClass method
518+
if (c == null && classLoaderDefineClassMethod != null) {
519+
if (protectionDomain == null) {
520+
protectionDomain = PROTECTION_DOMAIN;
521+
}
522+
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
523+
try {
524+
if (!classLoaderDefineClassMethod.isAccessible()) {
525+
classLoaderDefineClassMethod.setAccessible(true);
527526
}
528-
catch (Throwable ex) {
527+
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
528+
}
529+
catch (InvocationTargetException ex) {
530+
throw new CodeGenerationException(ex.getTargetException());
531+
}
532+
catch (Throwable ex) {
533+
// Fall through if setAccessible fails with InaccessibleObjectException on JDK 9+
534+
// (on the module path and/or with a JVM bootstrapped with --illegal-access=deny)
535+
if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) {
529536
throw new CodeGenerationException(ex);
530537
}
531538
}
532-
else {
533-
throw new CodeGenerationException(THROWABLE);
539+
}
540+
541+
// Fallback option: JDK 9+ Lookup.defineClass API even if ClassLoader does not match
542+
if (c == null && contextClass != null && contextClass.getClassLoader() != loader &&
543+
privateLookupInMethod != null && lookupDefineClassMethod != null) {
544+
try {
545+
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
546+
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
547+
c = (Class) lookupDefineClassMethod.invoke(lookup, b);
548+
}
549+
catch (InvocationTargetException ex) {
550+
throw new CodeGenerationException(ex.getTargetException());
551+
}
552+
catch (Throwable ex) {
553+
throw new CodeGenerationException(ex);
534554
}
535555
}
556+
557+
// No defineClass variant available at all?
558+
if (c == null) {
559+
throw new CodeGenerationException(THROWABLE);
560+
}
561+
536562
// Force static initializers to run.
537563
Class.forName(className, true, loader);
538564
return c;

0 commit comments

Comments
 (0)