【问题标题】:ContextNotActiveException with Quarkus and JeneticsQuarkus 和 Jenetics 的 ContextNotActiveException
【发布时间】:2021-03-17 16:20:42
【问题描述】:

第一次使用 Quarkus,这可能是一个菜鸟问题,但我不知道如何解决。 我正在尝试设置一个应该运行遗传算法(由 Jenetics 制作)并返回结果的端点。 这是端点定义:

@Path("/items")
public class ItemResource {

    @Inject
    ItemService service;

    @GET
    public List<Item> getItems() {
        return service.getItems();
    }

}

端点要求执行到下面的服务类:

@ApplicationScoped
public class ItemService {

    @Inject
    ItemMapper mapper;

    @Transactional
    public List<Item> getItems() {
        int numOfItems = Math.toIntExact(Item.count());
        IntegerChromosome chromosome = IntegerChromosome.of(0, numOfItems - 1, 14);
        Factory<Genotype<IntegerGene>> factory = Genotype.of(chromosome);
        Engine<IntegerGene, Double> engine = Engine
                .builder(this::fitnessFunction, factory)
                .build();
        Genotype<IntegerGene> result = engine.stream()
                .limit(100)
                .collect(EvolutionResult.toBestGenotype());
        return mapper.toItems(result);
    }

}

最后这是映射器类:

@ApplicationScoped
public class ItemMapper {

    public List<Item> toItems(Genotype<IntegerGene> genotype) {
        List<Item> items = Item.listAll();
        return genotype.chromosome().stream()
                .map(IntegerGene::intValue)
                .map(items::get)
                .collect(Collectors.toList());
    }

}

当我运行上面的代码时,我得到以下异常:

Error handling 0d80baf3-12da-49ec-b8d0-e48472c801c9-1, org.jboss.resteasy.spi.UnhandledException: java.util.concurrent.CancellationException: javax.enterprise.context.ContextNotActiveException

代码在标准 Java 应用程序中完美运行,但不能在 Web 服务中运行。有什么想法吗?


Here you can find the stack trace.

【问题讨论】:

  • @Transactional移动到ItemResource是否有效?
  • 不,它会抛出同样的异常。
  • 你能添加堆栈跟踪吗? Item 是否包含数据库访问代码?计算的任何部分(在Item 或 Jenetics 中)是否异步 - 即在另一个线程上?
  • 默认情况下,Jenetics 使用ForkJoinPool.defaultPool() 同时评估适应度值。如果这是问题所在,您可以在构建引擎时显式设置使用的Executor。是的,完整的堆栈跟踪会很有用。
  • 有没有办法为 Jenetics 配置特定的线程池?

标签: java cdi quarkus jenetics


【解决方案1】:

您可以尝试设置不同的执行服务。

final Executor executor = Executors.newFixedThreadPool(10);
final Engine<EnumGene<WayPoint>, Double> engine = Engine.builder(...)
    .executor(executor)
    .build();

【讨论】:

  • 您很可能会收到与手工制作的执行器相同的ContextNotActiveException。如果是这样,请将ManagedExecutorService 注入为@Resource ManagedExecutorService managedExecutor 并使用它。
  • 通过将Executors.newFixedThreadPool(10) 设置为执行者,我确实收到了同样的异常。我愿意尝试@Resource ManagedExecutorService managedExecutor,但我找不到这个类,我应该以某种方式创建它吗?
  • 嗨@Andrea,我是javax.enterprise.concurrent.ManagedExecutorServicejavax.annotation.Resource。我不确定这是否适用于 Quarkus,尽管它适用于传统的 JEE。如果没有,您可以尝试 2 件事:(1) @Inject ManagedExecutorService 而不是 @Resource ... 和 (2) 使用 MicroProfile 的 ManagedExecutor,如 here 和安迪对 this question 的回答。
  • @NikosParaskevopoulos 显然 ManagedExecutorService 在 Quarkus 中不起作用,所以我尝试使用 @Inject ManagedExecutor executor。我得到了同样的例外,但有一个different stack trace
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 2016-11-06
  • 2016-08-09
  • 1970-01-01
  • 2021-11-15
相关资源
最近更新 更多