Fix the problem that generateing OpenAPI defined in Plugin may not work (#3729)

#### What type of PR is this?

/kind bug
/area core

#### What this PR does / why we need it:

- Use the class loader belonging to the parameter type when creating a generic class.
- Use full qualified class name when generating a generic class.

Before testing, you have to set property `springdoc.cache.disabled` to `true`.

#### Which issue(s) this PR fixes:

Fixes #3728 

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/3739/head
John Niang 2023-04-10 23:20:25 +08:00 committed by GitHub
parent cab3432d03
commit 2bbdb96979
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 14 deletions

View File

@ -9,8 +9,6 @@ import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.Data; import lombok.Data;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.type.TypeDescription;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import run.halo.app.infra.utils.GenericClassUtils; import run.halo.app.infra.utils.GenericClassUtils;
@ -96,15 +94,12 @@ public class ListResult<T> implements Iterable<T>, Supplier<Stream<T>> {
* @return generic ListResult class. * @return generic ListResult class.
*/ */
public static Class<?> generateGenericClass(Scheme scheme) { public static Class<?> generateGenericClass(Scheme scheme) {
var generic = return GenericClassUtils.generateConcreteClass(ListResult.class,
TypeDescription.Generic.Builder.parameterizedType(ListResult.class, scheme.type()) scheme.type(),
.build(); () -> {
return new ByteBuddy() var pkgName = scheme.type().getPackageName();
.subclass(generic) return pkgName + '.' + scheme.groupVersionKind().kind() + "List";
.name(scheme.groupVersionKind().kind() + "List") });
.make()
.load(ListResult.class.getClassLoader())
.getLoaded();
} }
/** /**
@ -116,7 +111,7 @@ public class ListResult<T> implements Iterable<T>, Supplier<Stream<T>> {
*/ */
public static <T> Class<?> generateGenericClass(Class<T> type) { public static <T> Class<?> generateGenericClass(Class<T> type) {
return GenericClassUtils.generateConcreteClass(ListResult.class, type, return GenericClassUtils.generateConcreteClass(ListResult.class, type,
() -> type.getSimpleName() + "List"); () -> type.getName() + "List");
} }
public static <T> ListResult<T> emptyResult() { public static <T> ListResult<T> emptyResult() {

View File

@ -19,7 +19,7 @@ public enum GenericClassUtils {
*/ */
public static <T> Class<?> generateConcreteClass(Class<?> rawClass, Class<T> parameterType) { public static <T> Class<?> generateConcreteClass(Class<?> rawClass, Class<T> parameterType) {
return generateConcreteClass(rawClass, parameterType, () -> return generateConcreteClass(rawClass, parameterType, () ->
parameterType.getSimpleName() + rawClass.getSimpleName()); parameterType.getName() + rawClass.getSimpleName());
} }
/** /**
@ -39,7 +39,7 @@ public enum GenericClassUtils {
.subclass(concreteType) .subclass(concreteType)
.name(nameGenerator.get()) .name(nameGenerator.get())
.make()) { .make()) {
return unloaded.load(rawClass.getClassLoader()).getLoaded(); return unloaded.load(parameterType.getClassLoader()).getLoaded();
} catch (IOException e) { } catch (IOException e) {
// Should never happen // Should never happen
throw Exceptions.propagate(e); throw Exceptions.propagate(e);

View File

@ -0,0 +1,19 @@
package run.halo.app.infra.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import run.halo.app.core.extension.content.Post;
import run.halo.app.extension.ListResult;
class GenericClassUtilsTest {
@Test
void generateConcreteClass() {
var clazz = GenericClassUtils.generateConcreteClass(ListResult.class, Post.class,
() -> Post.class.getName() + "List");
assertEquals("run.halo.app.core.extension.content.PostList", clazz.getName());
assertEquals("run.halo.app.core.extension.content", clazz.getPackageName());
}
}