Skip to content

Commit

Permalink
Merge branch '5.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoeller committed Feb 28, 2019
2 parents c41616e + 5d8a34f commit a7db395
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 197 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -129,7 +129,7 @@ public TestEventWithNoValidOneArgObjectCtor() {
public static class FactoryBeanTestListener extends TestListener implements FactoryBean<Object> {

@Override
public Object getObject() throws Exception {
public Object getObject() {
return "test";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,28 @@ public class PayloadApplicationEventTests {

@Test
public void testEventClassWithInterface() {
ApplicationContext ac = new AnnotationConfigApplicationContext(Listener.class);
MyEventClass event = new MyEventClass<>(this, "xyz");
ApplicationContext ac = new AnnotationConfigApplicationContext(AuditableListener.class);
AuditablePayloadEvent event = new AuditablePayloadEvent<>(this, "xyz");
ac.publishEvent(event);
assertTrue(ac.getBean(Listener.class).events.contains(event));
assertTrue(ac.getBean(AuditableListener.class).events.contains(event));
}


public interface Auditable {
}


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

public MyEventClass(Object source, GT payload) {
public AuditablePayloadEvent(Object source, T payload) {
super(source, payload);
}

public String toString() {
return "Payload: " + getPayload();
}
}


@Component
public static class Listener {
public static class AuditableListener {

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,10 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader,
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {

Class c = null;
if (contextClass != null && privateLookupInMethod != null && lookupDefineClassMethod != null) {

// Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches
if (contextClass != null && contextClass.getClassLoader() == loader &&
privateLookupInMethod != null && lookupDefineClassMethod != null) {
try {
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
Expand All @@ -510,29 +513,52 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader,
throw new CodeGenerationException(ex);
}
}
if (protectionDomain == null) {
protectionDomain = PROTECTION_DOMAIN;
}
if (c == null) {
if (classLoaderDefineClassMethod != null) {
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
try {
if (!classLoaderDefineClassMethod.isAccessible()) {
classLoaderDefineClassMethod.setAccessible(true);
}
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
}
catch (InvocationTargetException ex) {
throw new CodeGenerationException(ex.getTargetException());

// Classic option: protected ClassLoader.defineClass method
if (c == null && classLoaderDefineClassMethod != null) {
if (protectionDomain == null) {
protectionDomain = PROTECTION_DOMAIN;
}
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
try {
if (!classLoaderDefineClassMethod.isAccessible()) {
classLoaderDefineClassMethod.setAccessible(true);
}
catch (Throwable ex) {
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
}
catch (InvocationTargetException ex) {
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
// Fall through if setAccessible fails with InaccessibleObjectException on JDK 9+
// (on the module path and/or with a JVM bootstrapped with --illegal-access=deny)
if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) {
throw new CodeGenerationException(ex);
}
}
else {
throw new CodeGenerationException(THROWABLE);
}

// Fallback option: JDK 9+ Lookup.defineClass API even if ClassLoader does not match
if (c == null && contextClass != null && contextClass.getClassLoader() != loader &&
privateLookupInMethod != null && lookupDefineClassMethod != null) {
try {
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
c = (Class) lookupDefineClassMethod.invoke(lookup, b);
}
catch (InvocationTargetException ex) {
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
throw new CodeGenerationException(ex);
}
}

// No defineClass variant available at all?
if (c == null) {
throw new CodeGenerationException(THROWABLE);
}

// Force static initializers to run.
Class.forName(className, true, loader);
return c;
Expand Down
Loading

0 comments on commit a7db395

Please sign in to comment.