読者です 読者をやめる 読者になる 読者になる

kagamihogeの日記

kagamihogeの日記です。

jBatch(JSR-352) on GlassFish 4.0でhello world的なことやる

Java GlassFish jBatch

準備

GlaffFish 4.0をダウンロードして、Eclipseから起動できるようにGlassFish Toolsプラグインを入れて、archetypeにwebapp-javaee7が使えるように設定をする。
参考:GlassFish 4さわる - kagamihogeの日記

コード

つくるものはjBatch(JSR-352) on Java SEでhello world的なことやる - kagamihogeの日記と同じで、batchletを一つだけ持つごくごくカンタンなジョブを作る。

全体的にはこんな感じ。
f:id:kagamihoge:20140403120713p:plain

pom.xml

jbatchの依存性を追加する。実装自体はGlassFish 4.0に含まれているのでAPIだけで良い。

        <dependency>
            <groupId>javax.batch</groupId>
            <artifactId>javax.batch-api</artifactId>
            <version>1.0</version>
            <scope>compile</scope>
        </dependency>
ジョブXML

META-INF\batch-jobs\sample-job.xmlを作成する。

<?xml version="1.0" encoding="UTF-8"?>
<job id="sample-job"
     xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     version="1.0">
     
     <step id="sample-batchlet">
         <batchlet ref="kagamihoge.glassfish4.javaee7.jbatchsample.batch.SampleBatchlet" />
     </step>
</job>

META-INF\batch-jobs\sample-job-named.xmlでは、クラス名書くのがだるいので@Namedを使用した場合のも作る。

<?xml version="1.0" encoding="UTF-8"?>
<job id="sample-job-named"
     xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     version="1.0">
     
     <step id="sample-batchlet">
         <batchlet ref="myBatchlet" />
     </step>
</job>
batchlet

ref 属性には CDI の Named で設定した名前も指定できる とのことなので、CDI用のアノテーションを付与したbatchletをつくる。

このエントリのサンプルの場合、sample-job-named.xmlでmyBatchletという名前で下記のクラスを参照している。

@Dependent
@Named("myBatchlet")
public class SampleBatchlet implements Batchlet {

    @Override
    public String process() throws Exception {
        System.out.println("## start");
        return null;
    }

    @Override
    public void stop() throws Exception {
        System.out.println("## stop");
    }
}
jobの開始

適当なServletをこさえて、ジョブのエントリーポイントを作る。

@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public TestServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        JobOperator job = BatchRuntime.getJobOperator();

        long id = job.start("sample-job", null);
        System.out.println("id = " + id);

        long id2 = job.start("sample-job-named", null);
        System.out.println("id2 = " + id2);
    }
}

http://localhost:8080/jbatchsample/TestServlet にアクセスして、コンソールに何かしら表示されればOK

管理コンソールからの確認

GlasFishの管理コンソールからジョブの実行結果などが確認できるので、見てみる。

http://localhost:4848/ で管理コンソールにアクセスする。
f:id:kagamihoge:20140403120812p:plain

左側のTreeのserver (Admin Server)をクリックする。
f:id:kagamihoge:20140403120825p:plain

右側のタブのBatchをクリックする。サンプルのジョブを実行しまくったので、COMPLETEDなのが幾つか見て取れる。
f:id:kagamihoge:20140403120837p:plain

Arquillian

オマケ。Java EEなんだからArquillianから起動することもできるよね、ってことでやってみた。

pom.xmlに依存性を追加する。

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.1.3.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-glassfish-remote-3.1</artifactId>
            <version>1.0.0.CR4</version>
            <scope>test</scope>
        </dependency>

JUnitのコードを書く。

@RunWith(Arquillian.class)
public class JBatchTest {

    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class)
            .addClasses(SampleBatchlet.class)
            .addAsResource("META-INF/batch-jobs/sample-job.xml")
            .addAsResource("META-INF/batch-jobs/sample-job-named.xml")
            ;
    }
    
    @Inject
    public SampleBatchlet batchlet;
    
    @Test
    public void testBatchlet() {
        try {
            batchlet.process();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void testBatch() {
        JobOperator job = BatchRuntime.getJobOperator();
        
        long id = job.start("sample-job-named", null);
        System.out.println("id = " + id);
    }

}

batchletをinjectして(単体で動かせる作りでなければならないが)overrideしてるメソッド直接呼ぶとか、ジョブ実行するとかして、Arquillianからjbatchを呼ぶことは出来た。