quarkus: IllegalStateException: 你试图对一个IO线程进行阻塞操作。这是不允许的,因为阻塞IO线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了quarkus: IllegalStateException: 你试图对一个IO线程进行阻塞操作。这是不允许的,因为阻塞IO线程相关的知识,希望对你有一定的参考价值。

有一件事我对quarkus的理解有问题,我使用JPA和Oracle。所以我有错误IllegalStateException。你试图对一个IO线程进行阻塞操作。这是不允许的,因为阻塞IO线程,我在Quarkus文档中查看了如何在没有这种困难的情况下进行JPA调用。但是所有的例子和文档都使用PostgreSQL或MariaDB的响应式客户端。但是我没有找到任何经典的JDBC客户端的例子。

我找到了一个部分可行的解决方案。

Uni.cretaFrom().Items(() -> MyBlokingIOCall());

的确,我不再有异常.但MyBlokingIOCall方法可以引发异常.我想我可以使用Uni的onFailure,但我们不能将引发异常的方法传递给我的客户。

Uni.cretaFrom().Items

事实上,这个方法有一个Supplier作为参数,因此必须捕获异常,这个解决方案不可能使用Uni的onFailure。

try 
   Response.ok (myService ());
 catch (throwable e) 
   Response.status (555, e.getMessage ());

我试图徒劳地在反应式formb中这样做,但我没有找到一个解决方案。我没有找到任何帮助,我想象了一些东西,比如:"但这会导致编译错误。

Uni.createFrom().Items(() -> myService())
.onItem().apply(data -> Response.ok(data))
.onFailure().apply(err -> Response.status(555, err.getMessage()))

但是这导致了编译错误.确实方法myService不能在Supplier中使用,因为它会抛出一个异常.因此它必须被捕获。但这样我们就不再进入Uni的onFailure,我们就无法追踪我们捕获的错误。

我想我想的太多了,穿我的命令式代码,而不是换位思考。

但我无论如何也找不到类似这样的文档或例子。我想象有一种做事的方法(如果不是Quarkus就不会存在)。我想,当你用正确的方法去思考的时候,你必须找到doc,但是当你不知道去哪里的时候,就比较复杂了。我没有找到,是因为我不知道自己要找什么。

我想我必须封装JPA调用,它产生一个Uni或Multi,被处理器消耗,处理器将实体转化为DTO,然后传送到资源休息层,资源休息层将DTO转化为Response,JPA调用必须能够产生错误,处理器也是,资源层也是。

因此,在每一步都需要捕捉到这些错误,通过Uni或Multiple来传播。

但是怎么做呢?

答案

这是种知识 羔羊座 当它涉及到简洁和第一期望时,仅仅提供了限制。羔羊座 实现(或方法引用)作为方法调用参数。

同时,它可以通过围绕预期的 功能界面在你的情况下,它将是 Supplier<T>,它将捕获任何**检查**的异常并抛出一个 不加选择 一。

/**
 * A Supplier sub-interface that catches any thrown exception
 * and translates to an unchecked one.
 *
 * <p>This is a functional interface whose functional method is
 * @link #getChecked().
 */
@FunctionalInterface
public interface CheckedSupplier<T> extends Supplier<T> 

    @Override
    default T get() 
        try 
            return getChecked();
         catch (final Exception e) 
            // Your common exception handling logic here..
            throw new RuntimeException(e);
        
    

    /**
     * Gets a result.
     *
     * @return a result
     * @throws Exception
     */
    T getChecked() throws Exception;

注意: 功能界面签名 不再 #get() 不过 #getChecked(). 但这对编译器来说没有任何区别,编译器会尝试检查 功能签名 基于预期的,而这是。

一个返回T类型对象的方法

然后您可以简单地使用新的 CheckedSupplier 接口,只用一个显式的 铸造Supplier<T> (或类似的)是预期的。

Uni.createFrom().item((CheckedSupplier<DataType>) MutinyTest::findOne)
      .onItem()
      .apply(i-> Response.ok(i))
      .onFailure()
      .apply(e-> Response.status(555, e.getMessage()));
另一答案

我修改了myService方法,让它返回一个Supplier并处理异常。

   public Supplier<List<String>> myService (String arg)
      return () -> 
         try 
            //my code
            return result;
          catch (Exception e) 
            throw new RuntimeException(e);
         
      ;
   

我就这么叫它

Uni.createFrom().item(myService("sample")))
.onItem().apply(data -> Response.ok(data))
.onFailure().recoverWithItem(err -> Response.status(600, err.getMessage()))
.onItem().apply(ResponseBuilder::build)
.emitOn(Infrastructure.getDefaultExecutor())

以上是关于quarkus: IllegalStateException: 你试图对一个IO线程进行阻塞操作。这是不允许的,因为阻塞IO线程的主要内容,如果未能解决你的问题,请参考以下文章

如何更新使用的quarkus版本

Quarkus 系统日志消息格式

如何增加 Quarkus 中的事务超时?

Quarkus+Apache Camel+Swagger ui

Quarkus:面向Java开发人员的云原生开源框架

Quarkus:面向Java开发人员的云原生开源框架