Class 尝试从 Quarkus 中的 consumeEvent return 列表时未找到

Class not found when trying to return List from consumeEvent in Quarkus

当我尝试在 Quarkus 中以开发模式 return 一个类型为 java.util.List 的 Uni 时,我得到一个 ClassNotFound 异常。我读过有关在不同配置文件中使用不同 class 加载程序的 Quarkus,但我没有看到我做了什么花哨的事情。

这是发件人

@Query("offers")
public Uni<List<OfferResponse>> getOffers(@PathParam("category") Integer categoryId) {
    OfferRequest event = new OfferRequest();
    event.setCategoryId(categoryId);
    Uni<List<OfferResponse>> offers = bus.<List<OfferResponse>>request(OfferRequest.ADDRESS, event).onItem().transform(Message::body);
    return offers;
}

这是消费者

@ConsumeEvent(OfferRequest.ADDRESS)
    public Uni<List<OfferResponse>> onOfferQuery(OfferRequest request) {
        List<KelkooOffer> offers = getOffers(request.getCategoryId());
        List<OfferResponse> responses = new ArrayList<OfferResponse>();
        for (KelkooOffer offer : offers) {
            responses.add(offer.getEventResponse());
        }
        return Uni.createFrom().item(responses);
    }

我正在尝试 return 的 bean 只是一个 POJO

和错误信息

2021-08-18 11:11:16,186 ERROR [io.qua.run.Application] (Quarkus Main Thread) Failed to start application (with profile dev): java.lang.ClassNotFoundException: java.util.List<se.bryderi.events.OfferResponse>
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:414)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:414)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        at io.quarkus.deployment.steps.VertxProcessor$build609260703.deploy_0(VertxProcessor$build609260703.zig:142)
        at io.quarkus.deployment.steps.VertxProcessor$build609260703.deploy(VertxProcessor$build609260703.zig:40)
        at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:784)
        at io.quarkus.runtime.Application.start(Application.java:101)
        at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:101)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:66)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:98)
        at java.base/java.lang.Thread.run(Thread.java:829)

如果我 运行 开发配置文件或 运行 打包的 fast-jar,我会得到相同的结果。

很高兴能给我指明正确方向的任何提示

Vert.x EventBus 有一个限制,它阻止 encode/decode 直接列出或设置。

您可以为 OfferResponse 列表创建一个包装器:

import java.util.AbstractList;
import java.util.List;

public class OfferResponseList extends AbstractList<OfferResponse> {

    private List<OfferResponse> wrapped;

    private OfferResponseList(List<OfferResponse> wrapped) {
        this.wrapped = wrapped;
    }

    public static OfferResponseList wrap(List<OfferResponse> list) {
        return new OfferResponseList(list);
    }

    @Override
    public OfferResponse get(int index) {
        return wrapped.get(index);
    }

    @Override
    public int size() {
        return wrapped.size();
    }
}

然后将您的消费者转换为:

@ConsumeEvent(OfferRequest.ADDRESS)
public Uni<OfferResponseList> onOfferQuery(OfferRequest request) {
    List<KelkooOffer> offers = getOffers(request.getCategoryId());
    List<OfferResponse> responses = new ArrayList<OfferResponse>();
    for (KelkooOffer offer : offers) {
        responses.add(offer.getEventResponse());
    }
    // Notice the call to OfferResponseList.wrap here
    return Uni.createFrom().item(OfferResponseList.wrap(responses));
}

就是这样。 Quarkus 将自动为 OfferResponseList 注册编解码器。

在客户端,您无需更改代码:

@Query("offers")
public Uni<List<OfferResponse>> getOffers(@PathParam("category") Integer categoryId) {
    OfferRequest event = new OfferRequest();
    event.setCategoryId(categoryId);
    // You can use Uni<List<OfferResponse>> or Uni<OfferResponseList>
    Uni<List<OfferResponse>> offers = bus.<List<OfferResponse>>request(OfferRequest.ADDRESS, event).onItem().transform(Message::body);
    return offers;
}