Avoid UndeclaredThrowableStrategy with 1.8 bytecode level (CGLIB 3.3)

ClassLoaderAwareUndeclaredThrowableStrategy fails with a VerifyError on recent JDKs after the CGLIB 3.3 upgrade. The alternative is to replace it with a plain ClassLoaderAwareGeneratorStrategy (extracted from CglibSubclassingInstantiationStrategy) and custom UndeclaredThrowableException handling in CglibMethodInvocation.

See gh-23453
This commit is contained in:
Juergen Hoeller
2019-08-14 00:14:14 +02:00
parent 561af5f8f9
commit 9bd3a535cd
5 changed files with 96 additions and 106 deletions

View File

@@ -26,8 +26,7 @@ import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.cglib.core.ClassGenerator;
import org.springframework.cglib.core.DefaultGeneratorStrategy;
import org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
@@ -187,53 +186,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
}
/**
* CGLIB GeneratorStrategy variant which exposes the application ClassLoader
* as thread context ClassLoader for the time of class generation
* (in order for ASM to pick it up when doing common superclass resolution).
*/
private static class ClassLoaderAwareGeneratorStrategy extends DefaultGeneratorStrategy {
@Nullable
private final ClassLoader classLoader;
public ClassLoaderAwareGeneratorStrategy(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public byte[] generate(ClassGenerator cg) throws Exception {
if (this.classLoader == null) {
return super.generate(cg);
}
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader;
try {
threadContextClassLoader = currentThread.getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
return super.generate(cg);
}
boolean overrideClassLoader = !this.classLoader.equals(threadContextClassLoader);
if (overrideClassLoader) {
currentThread.setContextClassLoader(this.classLoader);
}
try {
return super.generate(cg);
}
finally {
if (overrideClassLoader) {
// Reset original thread context ClassLoader.
currentThread.setContextClassLoader(threadContextClassLoader);
}
}
}
}
/**
* CGLIB callback for filtering method interception behavior.
*/