1

当我尝试在开发模式下在 Quarkus 中返回一个键入 java.util.List 的 Uni 时,我得到一个 ClassNotFound 异常。我已经阅读了有关 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);
    }

我试图返回的 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$1.run(StartupActionImpl.java:98)
        at java.base/java.lang.Thread.run(Thread.java:829)

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

很高兴有任何提示可以为我指明正确的方向

4

1 回答 1

3

Vert.x EventBus 有一个限制,它会阻止直接对列表或集合进行编码/解码。

您可以为您的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;
}
于 2021-08-18T13:29:13.980 回答