在 jberet 实现下,CDI 无法与 Java EE Batch 一起工作

CDI not working with Java EE Batch under jberet implementation

我有一个 Java EE 批处理应用程序,使用部署在 WildFly 应用程序服务器上的 jberet 实现。此应用程序还公开了一个 REST api 来按需触发作业。

我有以下 class 创建要注入的 bean:

public class Factory {

    @Produces
    public JsonValidator getJsonValidator() {
        return JsonSchemaFactory.byDefault().getValidator();
}

在 REST 中注入上述 bean api 工作正常:

@Path("my-resource")
public class MyResource{

    @Inject
    private JsonValidator jsonValidator;

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public Response handleNotification(String notification) {
        // using jsonValidator here works fine..

然而,在 ItemReader 中使用相同的 bean 会抛出一个空指针异常,但是注入 JobContext 没有任何问题:

public class MyReader extends AbstractItemReader {

    @Inject
    private JobContext jobContext;

    @Inject
    private JsonValidator jsonValidator;

    @Override
    public Integer readItem() throws Exception {
        // using jsonValidator here throws a null pointer exception
        // however jobContext works fine

我的beans.xml在src/main/resources/META-INF下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

作业文件在src/main/resources/META-INF/batch-jobs/myjob.xml下:

<job id="myjob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> 
  <step id="mystep">
    <chunk item-count="1">
      <reader ref="myReader"/>
      <processor ref="myProcessor"/>
      <writer ref="myWriter"/>
    </chunk>
  </step>
</job>

src/main/resources/META-INF/batch.xml

下的批处理工件文件
<?xml version="1.0" encoding="UTF-8"?>
<batch-artifacts xmlns="http://xmlns.jcp.org/xml/ns/javaee">
    <ref id="myReader" class="com.my.app.MyReader" />
    <ref id="myProcessor" class="com.my.app.MyProcessor" />
    <ref id="myWriter" class="com.my.app.MyWriter" />
</batch-artifacts>

我的 pom.xml 如下所示:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.my.app</groupId>
    <artifactIdjava-batch</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>

    <name>java-batch</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <!-- JBoss dependency versions -->
        <version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>

        <!-- other plugin versions -->
        <version.compiler.plugin>3.7.0</version.compiler.plugin>
        <version.surefire.plugin>2.21.0</version.surefire.plugin>
        <version.war.plugin>3.2.0</version.war.plugin>

        <!-- maven-compiler-plugin -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>

        <version.org.jboss.spec.javax.batch.jboss-batch-api_1.0_spec>1.0.0.Final
        </version.org.jboss.spec.javax.batch.jboss-batch-api_1.0_spec>
        <version.org.jboss.spec.javax.ws.rs.jboss-jaxrs-api_2.0_spec>1.0.0.Final</version.org.jboss.spec.javax.ws.rs.jboss-jaxrs-api_2.0_spec>
        <version.org.jberet>1.3.0.Final</version.org.jberet>
        <version.javax.inject>1</version.javax.inject>
        <version.javax.enterprise>2.0</version.javax.enterprise>
    </properties>

    <build>
        <finalName>java-batch</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>${version.war.plugin}</version>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.spec.javax.batch</groupId>
                <artifactId>jboss-batch-api_1.0_spec</artifactId>
                <version>${version.org.jboss.spec.javax.batch.jboss-batch-api_1.0_spec}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.inject</groupId>
                <artifactId>javax.inject</artifactId>
                <version>${version.javax.inject}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.enterprise</groupId>
                <artifactId>cdi-api</artifactId>
                <version>${version.javax.enterprise}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>org.jberet</groupId>
                <artifactId>jberet-rest-api</artifactId>
                <version>${version.org.jberet}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jberet</groupId>
                <artifactId>jberet-rest-commons</artifactId>
                <version>${version.org.jberet}</version>
                <scope>runtime</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.jberet</groupId>
                        <artifactId>jberet-core</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.jberet</groupId>
                <artifactId>jberet-schedule-executor</artifactId>
                <version>${version.org.jberet}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jberet</groupId>
                <artifactId>jberet-schedule-timer</artifactId>
                <version>${version.org.jberet}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jberet</groupId>
                <artifactId>jberet-support</artifactId>
                <version>${version.org.jberet}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jboss.spec.javax.ws.rs</groupId>
                <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
                <version>${version.org.jboss.spec.javax.ws.rs.jboss-jaxrs-api_2.0_spec}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.jboss.spec.javax.batch</groupId>
            <artifactId>jboss-batch-api_1.0_spec</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-rest-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-rest-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-schedule-executor</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-schedule-timer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-support</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jberet</groupId>
            <artifactId>jberet-core</artifactId>
            <version>${version.org.jberet}</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.fge</groupId>
            <artifactId>json-schema-validator</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>LATEST</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>
</project>

我尝试了@Produce、@JobScoped (org.jberet.cdi.JobScoped) 的各种组合,并使用@JobScoped、@Default 和@ApplicationScoped 注入带注释的Class,但都产生相同的结果(NullPointerException 而使用注入的对象)。

我错过了什么?

尝试将 @Named 添加到您的 reader、处理器和编写器 类,并删除 src/main/resources/META-INF/batch.xml。这将使 CDI 发现批处理工件作为 CDI bean 并执行依赖注入。