gpt4 book ai didi

jakarta-ee - CDI 注入(inject)和 Java 批处理 (JSR-352)

转载 作者:行者123 更新时间:2023-12-02 07:29:16 25 4
gpt4 key购买 nike

TLDR:在将 Web 配置文件示例迁移到完整的 EE 应用程序后,CDI 的行为并不像我预期的那样

首先让我说我是 CDI 的新手。我喜欢认为我理解这个概念,但实现的细微差别还有待克服。

我正在尝试 EJB 化并随后使用 RESTful API Java Batch (JSR-352) 进行包装。

首先,我采用了 Payroll 的 javaee7 示例,并将逻辑和工作规范提取到一个完整的 EE7 项目(ejb、web、ear 模块)中。

当我调用 RESTful 服务时,我最初遇到了这个问题(为了保持理智而缩短):

WARNING:   Caught exception executing step: java.lang.RuntimeException: com.ibm.jbatch.container.exception.BatchContainerRuntimeException: Tried but failed to load artifact with id: SimpleItemProcessor
Caused by: com.ibm.jbatch.container.exception.BatchContainerRuntimeException: Tried but failed to load artifact with id: SimpleItemProcessor
Caused by: java.lang.ClassNotFoundException: SimpleItemProcessor

请记住,应用程序的这一部分应该基本没有变化。 SimpleItemProcessor 定义相同,如下所示。

@Named("SimpleItemProcessor")
public class SimpleItemProcessor
implements ItemProcessor {

@Inject
private JobContext jobContext;


public Object processItem(Object obj) throws Exception {
Properties jobParameters = BatchRuntime.getJobOperator().getParameters(jobContext.getExecutionId());

PayrollInputRecord inputRecord = (PayrollInputRecord) obj;
PayrollRecord payrollRecord = new PayrollRecord();
payrollRecord.setMonthYear((String) jobParameters.get("monthYear"));

int base = inputRecord.getBaseSalary();
float tax = base * 27 / 100.0f;
float bonus = base * 15 / 100.0f;

payrollRecord.setEmpID(inputRecord.getId());
payrollRecord.setBase(base);
payrollRecord.setTax(tax);
payrollRecord.setBonus(bonus);
payrollRecord.setNet(base + bonus - tax);

return payrollRecord;
}

这个 SimpleItemProcessor 由它在 PayrollJob.xml 定义中的 CDI 名称引用(Batch 环境清楚地找到了它)。此规范也是工作 JavaEE7 示例的副本。

<job id="payroll" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="process">
<chunk item-count="3">
<reader ref="SimpleItemReader"></reader>
<processor ref="SimpleItemProcessor"></processor>
<writer ref="SimpleItemWriter"></writer>
</chunk>
</step>

如果我使用 SimpleItemProcessor (com.mycompany.SimpleItemProcessor) 的完全限定名称,它似乎可以工作。其他两个批处理组件(Reader 和 Writer)似乎不需要这个。

我的猜测是我在 CDI 领域遗漏了一些东西。

这一切都在 Glassfish 4 上运行。

我的 Web 模块的 WEB-INF 和 EJB 模块的 META-INF 中都有空的 beans.xml。

请告诉我您对此有何见解。我已经考虑了很长时间。

编辑:增加了引发异常的 Batch 组件的日志记录,并得到了一些有趣的东西,指向可能与 CDI 相关的东西。

FINER:   ENTRY Loading batch artifact id = SimpleItemReader
FINER: Delegating to preferred artifact factorycom.ibm.jbatch.container.services.impl.CDIBatchArtifactFactoryImpl@4ac13bc2
FINER: ENTRY Loading batch artifact id = SimpleItemReader
FINER: RETURN For batch artifact id = SimpleItemReader, loaded artifact instance: com.mycompany.SimpleItemReader@4862cec7 of type: com.mycompany.SimpleItemReader
FINER: ENTRY Loading batch artifact id = SimpleItemProcessor
FINER: Delegating to preferred artifact factorycom.ibm.jbatch.container.services.impl.CDIBatchArtifactFactoryImpl@4ac13bc2
FINER: ENTRY Loading batch artifact id = SimpleItemProcessor
FINE: Tried but failed to load artifact with id: SimpleItemProcessor, Exception = java.util.NoSuchElementException
FINER: RETURN For batch artifact id = SimpleItemProcessor, FAILED to load artifact instance
FINER: Preferred artifact factory failed to load artifact SimpleItemProcessor. Defaulting to batch.xml.
FINE: TCCL = EarClassLoader :

实现失败的 CDI 部分(bm.getBeans(id) 返回为空):

51  private Object More ...getArtifactById(String id) {
52
53 Object artifactInstance = null;
54
55 try {
56 InitialContext initialContext = new InitialContext();
57 BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");
58 Bean bean = bm.getBeans(id).iterator().next();
59 Class clazz = bean.getBeanClass();
60 artifactInstance = bm.getReference(bean, clazz, bm.createCreationalContext(bean));
61 } catch (Exception e) {
62 // Don't throw an exception but simply return null;
63 logger.fine("Tried but failed to load artifact with id: " + id + ", Exception = " + e);
64 }
65
66 return artifactInstance;
67 }

这是工作网络配置文件示例的相同日志记录:

FINER:   ENTRY
FINER: No preferred job xml loader is detected in configuration
FINER: Preferred job xml loader failed to load PayrollJob. Defaulting to META-INF/batch-jobs/
FINER: Loaded job xml with PayrollJob from META-INF/batch-jobs/
FINER: ENTRY Loading batch artifact id = SimpleItemReader
FINER: Delegating to preferred artifact factorycom.ibm.jbatch.container.services.impl.CDIBatchArtifactFactoryImpl@4ac13bc2
FINER: ENTRY Loading batch artifact id = SimpleItemReader
FINER: RETURN For batch artifact id = SimpleItemReader, loaded artifact instance: com.oracle.javaee7.samples.batch.api.SimpleItemReader@753908c of type: com.oracle.javaee7.samples.batch.api.SimpleItemReader
FINER: ENTRY Loading batch artifact id = SimpleItemProcessor
FINER: Delegating to preferred artifact factorycom.ibm.jbatch.container.services.impl.CDIBatchArtifactFactoryImpl@4ac13bc2
FINER: ENTRY Loading batch artifact id = SimpleItemProcessor
FINER: RETURN For batch artifact id = SimpleItemProcessor, loaded artifact instance: com.oracle.javaee7.samples.batch.api.SimpleItemProcessor@5376b860 of type: com.oracle.javaee7.samples.batch.api.SimpleItemProcessor
FINER: ENTRY Loading batch artifact id = SimpleItemWriter
FINER: Delegating to preferred artifact factorycom.ibm.jbatch.container.services.impl.CDIBatchArtifactFactoryImpl@4ac13bc2
FINER: ENTRY Loading batch artifact id = SimpleItemWriter
FINER: RETURN For batch artifact id = SimpleItemWriter, loaded artifact instance: com.oracle.javaee7.samples.batch.api.SimpleItemWriter@243e016c of type: com.oracle.javaee7.samples.batch.api.SimpleItemWriter

最佳答案

最近的一次搜索将我引导至此处,所以不管问题的年代如何,让我给出部分答案。

首先,对于背景知识,请快速阅读 CDI 的“bean 发现模式”,例如见here .

现在,在 1.0 XSD 级别存在空 beans.xml 将被 CDI 视为 ALL 模式,而完全不存在 beans.xml 将被视为默认 >注释 模式。

批处理工件对于 CDI 来说并不是特别特殊。因此,与任何类一样,它们将仅被视为 CDI 管理的 bean,并且只能通过 bean 名称(@Named 值)访问:

  • bean 发现模式 = ALL
  • bean 发现模式 = ANNOTATED 当工件另外包含一个 bean 定义注释(并且 @Dependent 确实是一个 bean 定义注释)。

我的猜测是,在重新打包时,Bean.xml 不再被 CDI 检测到,因此您有效地从 ALL 转移到 ANNOTATED 模式,需要 @Dependent bean 定义注释以按 bean 名称加载批处理工件。

(为什么会这样?OP 没有详细介绍,我敢肯定现在已经很好地进行了......所以没关系,我认为其余的答案仍然有值(value)) .

希望这对仍然有帮助的人!

关于jakarta-ee - CDI 注入(inject)和 Java 批处理 (JSR-352),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23872306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com