Proper NoClassDefFoundError check against BeanUtils.instantiateClass
Issue: SPR-16369
This commit is contained in:
@@ -98,12 +98,18 @@ public abstract class BeanUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a class using its no-arg constructor.
|
||||
* Instantiate a class using its 'primary' constructor (for Kotlin classes,
|
||||
* potentially having default arguments declared) or its default constructor
|
||||
* (for regular Java classes, expecting a standard no-arg setup).
|
||||
* <p>Note that this method tries to set the constructor accessible
|
||||
* if given a non-accessible (that is, non-public) constructor.
|
||||
* @param clazz class to instantiate
|
||||
* @param clazz the class to instantiate
|
||||
* @return the new instance
|
||||
* @throws BeanInstantiationException if the bean cannot be instantiated
|
||||
* @throws BeanInstantiationException if the bean cannot be instantiated.
|
||||
* The cause may notably indicate a {@link NoSuchMethodException} if no
|
||||
* primary/default constructor was found - or an exception thrown from
|
||||
* the constructor invocation attempt, including a runtime-generated
|
||||
* {@link NoClassDefFoundError} in case of an unresolvable dependency.
|
||||
* @see Constructor#newInstance
|
||||
*/
|
||||
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
|
||||
@@ -113,10 +119,7 @@ public abstract class BeanUtils {
|
||||
}
|
||||
try {
|
||||
Constructor<T> ctor = (KotlinDetector.isKotlinType(clazz) ?
|
||||
KotlinDelegate.findPrimaryConstructor(clazz) : clazz.getDeclaredConstructor());
|
||||
if (ctor == null) {
|
||||
throw new BeanInstantiationException(clazz, "No default constructor found");
|
||||
}
|
||||
KotlinDelegate.getPrimaryConstructor(clazz) : clazz.getDeclaredConstructor());
|
||||
return instantiateClass(ctor);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
@@ -693,10 +696,26 @@ public abstract class BeanUtils {
|
||||
private static class KotlinDelegate {
|
||||
|
||||
/**
|
||||
* Return the Java constructor corresponding to the Kotlin primary constructor if any.
|
||||
* Determine the Java constructor corresponding to the Kotlin primary constructor.
|
||||
* @param clazz the {@link Class} of the Kotlin class
|
||||
* @throws NoSuchMethodException if no such constructor found
|
||||
* @since 5.0.3
|
||||
* @see #findPrimaryConstructor
|
||||
* @see Class#getDeclaredConstructor
|
||||
*/
|
||||
public static <T> Constructor<T> getPrimaryConstructor(Class<T> clazz) throws NoSuchMethodException {
|
||||
Constructor<T> ctor = findPrimaryConstructor(clazz);
|
||||
if (ctor == null) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
return ctor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Java constructor corresponding to the Kotlin primary constructor, if any.
|
||||
* @param clazz the {@link Class} of the Kotlin class
|
||||
* @see <a href="http://kotlinlang.org/docs/reference/classes.html#constructors">
|
||||
* http://kotlinlang.org/docs/reference/classes.html#constructors</a>
|
||||
* http://kotlinlang.org/docs/reference/classes.html#constructors</a>
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> Constructor<T> findPrimaryConstructor(Class<T> clazz) {
|
||||
@@ -706,8 +725,10 @@ public abstract class BeanUtils {
|
||||
return null;
|
||||
}
|
||||
Constructor<T> constructor = ReflectJvmMapping.getJavaConstructor(primaryCtor);
|
||||
Assert.notNull(constructor,
|
||||
() -> "Failed to find Java constructor for Kotlin primary constructor: " + clazz.getName());
|
||||
if (constructor == null) {
|
||||
throw new IllegalStateException(
|
||||
"Failed to find Java constructor for Kotlin primary constructor: " + clazz.getName());
|
||||
}
|
||||
return constructor;
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
@@ -718,7 +739,8 @@ public abstract class BeanUtils {
|
||||
/**
|
||||
* Instantiate a Kotlin class using the provided constructor.
|
||||
* @param ctor the constructor of the Kotlin class to instantiate
|
||||
* @param args the constructor arguments to apply (use null for unspecified parameter if needed)
|
||||
* @param args the constructor arguments to apply
|
||||
* (use {@code null} for unspecified parameter if needed)
|
||||
*/
|
||||
public static <T> T instantiateClass(Constructor<T> ctor, Object... args)
|
||||
throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
|
||||
Reference in New Issue
Block a user