しおしお

IntelliJ IDEAのことなんかを書いてます

Oracle11gR2からはlikeのパターン一致文字に全角が含まれなくなったもよう

ドキュメントにこんな注意書きが増えてた。。。

f:id:sioiri:20151120075118p:plain

Oracle12cで試してみたら、全角はパターン一致文字にならなかった。全く把握できてなかった(´・ω・`)

SQL>  select * from test where value like 'ほ_';

ID VALUE
-- ----------
 1 ほげ

SQL>  select * from test where value like 'ほ_';

レコードが選択されませんでした。

jax-rsなリソースクラスをArquillianを使ってテストしてみた

Arquillian REST Extension 1.0.0.Alpha3 Released · Arquillian Blog を見ながらやるとかなり簡単にできた。

テスト対象のリソースクラス

シンプルなこんな感じのリソースクラスをテスト対象に。。。

public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get() {
        return "hello";
    }
}

build.gradleに必要なライブラリを追加

  testCompile 'org.jboss.arquillian.junit:arquillian-junit-container:1.1.9.Final'
  testRuntime 'org.jboss.arquillian.container:arquillian-glassfish-embedded-3.1:1.0.0.CR4'
  testRuntime 'org.glassfish.main.extras:glassfish-embedded-all:4.1'
  testRuntime 'org.jboss.arquillian.extension:arquillian-rest-client-impl-jersey:1.0.0.Alpha3'

テストクラス

テストメソッドにテスト対象のリソースクラスをinjectすることができるので、あとはテスト対象メソッドを呼び出して結果をアサートするだけ。

@RunWith(Arquillian.class)
public class HelloResourceTest {

    @Deployment
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "hoge.war")
                .addClass(HelloResource.class);

    }

    @Test
    public void test(@ArquillianResteasyResource HelloResource resource) throws Exception {
        System.out.println("resource = " + resource);
        assertThat(resource.get(), is("hello"));
    }
}

テスト実行結果

実行できました。
f:id:sioiri:20150930150217p:plain

おわり。

JSR352-Batch Applicationを試してみた(ジョブの停止-Chunk)

Chunckステップ実行中にバッチジョブを停止する方法。

基本的な考え方やステータスの遷移は、Batchletの停止と同じ。違いは、Chunkの場合はBatchletのような停止用の実装を行う必要はないこと。

Chunkの場合は、Writerが処理中の場合はWriterの処理が終わり次の塊のデータを読み込んだあとにジョブが停止される。*1

もし、chunkのそれぞれの処理(readerやwriter、processorなど)が終わらない場合、ジョブの停止要求を出しても自動的にジョブは終わらないので、それぞれの処理が終わらない原因を取り除く必要がある。
例えば、データベースのロック待機などで永遠にクライアントに処理が戻ってこない場合には、停止要求を出してもジョブは停止しない。

ItemReadListenerで動きを確認してみる

ItemReadListenerでは、Itemリード後のコールバック処理でリードしたitemの内容とジョブのステータスを標準出力に書き込んでいる。

  @Inject
  lateinit val jobContext:JobContext

  override fun afterRead(item: Any?) {
    item?.let {
      println("read item = ${item}, job status = ${jobContext.batchStatus}")
    }
  }

Chunkのitem-countを5で実行した場合で、4件目のレコードを読込中のジョブの停止命令を出した場合のログの内容。4件目のレコードを読み込んだあとのジョブのステータスは停止中を表すSTOPPINGになり、5件目のレコードは読み込まずに今まで読み込んだitemがwriterに渡され処理されているのがわかる。

23:09:27,474 INFO  [stdout] (Batch Thread - 1) read item = 1, job status = STARTED
23:09:32,485 INFO  [stdout] (Batch Thread - 1) read item = 2, job status = STARTED
23:09:37,487 INFO  [stdout] (Batch Thread - 1) read item = 3, job status = STARTED
23:09:42,491 INFO  [stdout] (Batch Thread - 1) read item = 4, job status = STOPPING
23:09:42,500 INFO  [stdout] (Batch Thread - 1) it = 1
23:09:42,500 INFO  [stdout] (Batch Thread - 1) it = 2
23:09:42,500 INFO  [stdout] (Batch Thread - 1) it = 3
23:09:42,501 INFO  [stdout] (Batch Thread - 1) it = 4

ジョブ停止後のジョブリポジトリの状態

Chunkステップ処理中にジョブを停止すると、ジョブリポジトリ(step_executionテーブル)にステップの処理状態が記録される。
以下のように、何件目まで正常に処理できたかなどが記録される。この情報は、停止したジョブをリスタートした場合の再開ポイントとして利用される。
f:id:sioiri:20150925145845p:plain

おわり。

*1:jberetの場合

JSR352-Batch Applicationを試してみた(ジョブにパラメータを指定する)

JSR352-Batch Applicationを試してみた(ジョブの停止-Batchlet) - しおしおの続編。今回は、ジョブにパラーメータを渡す方法を試してみた。

ジョブ起動時にパラメータを指定する方法

以下のコードのように、JobOperator#startの2番めの引数にジョブ起動時のパラメータを指定する。

final Properties jobParams = new Properties();
jobParams.put("param1", "value1");
jobParams.put("param2", "100");

final JobOperator operator = BatchRuntime.getJobOperator();
final long executionId = operator.start(jobId, jobParams);

ジョブパラメータを受け取る

ジョブパラメータは、BatchletやChunk関連の実装クラス、リスナーなどにBatchPropertyとしてインジェクションする。自動的にインジェクションされるわけではないので、ジョブXMLでジョブパラメータをBatchPropertyにセットする設定が必要となる。

ジョブパラメータを使用する実装サンプル

@Dependent
@Named
public class JobParameterSampleBatchlet: AbstractBatchlet() {
  
  @Inject
  @BatchProperty
  var param:String? = null

  override fun process(): String {
    log.info("param: {}", param)
    return "success"
  }

  companion object {
    val log:Logger = LoggerFactory.getLogger(javaClass<JobParameterSampleBatchlet>())
  }

}

ジョブパラメータを設定するジョブXMLのサンプル
ジョブパラメータを設定するには、以下の例のように#{jobParameters['パラメータ名']}というEL式を使用する。
この例では、ジョブ起動時に指定されたパラメータの中で、パラメータ名がjob-paramの値を、paramプロパティに設定する。

<job id="jobParameter" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
  <step id="myStep">
    <batchlet ref="jobParameterSampleBatchlet">
      <properties>
        <property name="param" value="#{jobParameters['job-param']}" />
      </properties>
    </batchlet>
  </step>
</job>

実行すると
こんなパラメータを設定してと

Properties properties = new Properties();
properties.put("job-param", "パラメータ");

ログにジョブパラメータが出力されたので、パラメータがBatchletに設定されているのがわかる。

13:34:13,554 INFO  [siosio.batchlet.JobParameterSampleBatchlet] (Batch Thread - 1) param: パラメータ

おわり

GradleのjarタスクでMANIFEST.MFにgit情報を書き込むプラグイン作ってみた

Gradleのjarタスクで、gitのどのリビジョンをベースに作成したかをMANIFEST.MFに書き込むGradleプラグインを作ってみた。

作った理由

最近、社内のMavenリポジトリに古いソースコードベースのartifactが頻繁にアップされてかなりハマったので。。。
jarがどのリビジョンベースで作られたのかサクッとわかると、個人的にはわりと便利な気がしたので作ってみた感じです。*1

使い方

こんな感じにプラグイン適用するだけな感じです。

buildscript {
  repositories {
    mavenLocal()
  }
  dependencies {
    classpath 'siosio:add-git-info-to-manifest:+'
  }
}

apply plugin: 'AddGitInfoToManifest'

プラグインのコード

siosio/add-git-info-to-manifest · GitHubに上げてみてます。

おわり

*1:同じようなことできるプラグインあるんだろうけど探せなかった・・・

JSR352-Batch Applicationを試してみた(ジョブの停止-Batchlet)

JSR352-Batch Applicationを試してみた(Chunkステップ編) - しおしおの続編で、今回は実行中のジョブの停止を試してみる。

実行中ジョブの停止方法

JobOperator#stopを呼び出すことで実行中のジョブが停止する。
sotpメソッドの引数には、停止対象のジョブ実行を識別するためのexecutionIdを指定します。executionIdは、ジョブの起動時に戻される値です。

stopメソッドを呼び出して、ジョブの停止要求を受け付けると、ジョブのステータスは停止処理中であることを示すSTOPPINGに変更されます。実行中のステップの処理を停止し、ジョブが停止されるとステータスはSTOPPEDに変更されます。

ジョブを停止させるサンプルコード

    val jobOperator = BatchRuntime.getJobOperator()
    jobOperator.stop(executionId)

Batchletの処理を安全に中止する

ジョブの停止要求があると、Batchlet#stopがコールバックされるので、Batchlet#processの処理を安全に中断する必要がある。

サンプルコード

このバッチレットでは、processで処理の長いSQLが実行される。stop処理では、SQL文の実行をキャンセルするために、Statement#cancelを実行する。

  override fun process(): String {
    // 処理の長いSQL文を実行する
    dataSource!!.use {
      statement = it.createStatement()
      statement.execute("select pg_sleep(30)")
    }
    return "OK"
  }

  override fun stop() {
    LOGGER.info("ジョブを停止します..... execution id={}, step={}, status={}",
        jobContext!!.getExecutionId(), stepContext!!.getStepName(), stepContext!!.getBatchStatus())
    statement.cancel()
  }

Batchletの全コード

実行結果ログ

ステータスが実行中(STARTED)から、中断を示す(STOPPED)に変わっています。

01:53:16,310 INFO  [siosio.listener.LogStepListener] (Batch Thread - 4) step start... job=stoppable-batchlet, step=batchlet, status=STARTED
01:53:20,483 INFO  [siosio.batchlet.StoppableBatchlet] (default task-15) ジョブを停止します..... execution id=120, step=batchlet, status=STOPPING
01:53:20,511 INFO  [siosio.batchlet.StoppableBatchlet] (Batch Thread - 4) ステップの処理がキャンセルされました。 step=batchlet, status=STOPPING
01:53:20,514 INFO  [siosio.listener.LogStepListener] (Batch Thread - 4) step end... job=stoppable-batchlet, step=batchlet, status=STOPPED

ジョブの状態を格納するテーブル上でも、バッチのステータスがSTOPPEDになっている。
f:id:sioiri:20150725015600p:plain

stopメソッド実装しなかったらどうなる?

stopメソッドを実装しないと、Batchlet#processの処理が終わるのを永遠と待ち続ける。stop要求時に即処理を停止したいなら、stopメソッドを実装する必要がある。

おわり。

UpsourceのIntelliJ IDEAプラグインを使ってみた

JetBrainsのUpsource触ってみた(リポジトリブラウザ) - しおしお依頼久しぶりのUpsourceネタ。
お仕事系プロジェクトで使ってみようかなと思って久しぶりに触って見てたら、IntelliJ IDEA用のプラグイン出てたのでプラグインの使い方を少し整理してみた。

プラグインの入れ方

設定画面のPluginsからインストールします。プラグイン名は、Upsource Integrationです。
f:id:sioiri:20150627014648p:plain

プラグインの設定

Upsourceサーバの設定を行い、テスト接続をしておきます。テスト接続の途中で、Upsourceの認証画面が開くので、アカウント情報を入力して、IntelliJ IDEAのプラグインからのアクセスを許可しておきます。
f:id:sioiri:20150627015126p:plain

レビューを依頼する

レビューの依頼はVersion Controlのコミットログ画面から行います。下の画像のようにレビューしてほしいコミットを選択してコンテキストメニューからレビューを作ります。
f:id:sioiri:20150627020305p:plain

新しいレビューを作るか、既存のレビューに選択したコミットを追加するかを効かれます。
とりあえず、新しいレビューを作りたいのでCreate・・・の方を選択します。
f:id:sioiri:20150627020619p:plain

次のレビューのタイトルやレビューする人を選びます。
レビューする人の追加や削除は右側の「+」や「ー」ボタンから行います。
f:id:sioiri:20150627020732p:plain

レビューの作成が完了するとReviewsウィンドウからレビュー対象などが確認できるようになります。
f:id:sioiri:20150627021108p:plain

指摘をあげる

まずは、レビューしたいファイルの変更内容を確認します。画像のように、レビュー対象のコミットを選択して、コンテクストメニューからdiffを表示します。
f:id:sioiri:20150627021455p:plain

指摘を追加したい行にカーソルを移動または、指摘を追加したい部分を選択しメニューにある「+」をクリックします。
これで、指摘を追加するダイアログが表示されるので指摘を登録します。*1*2
f:id:sioiri:20150627021746p:plain

指摘を追加すると、こんな感じにdiff画面で指摘が見れるようになります。
f:id:sioiri:20150627022110p:plain

指摘をなおす

画像のようにIDE上から指摘一覧や、指摘箇所が確認できます。
f:id:sioiri:20150627023553p:plain

対応ができたら指摘に対してコメントを書いてあげたりします。
f:id:sioiri:20150627023758p:plain

コミットします。コミットの際には、今回にコミットをレビューに含めるようにしてあげます。
画像のように既存のレビューに追加する形でコミットを行います。
f:id:sioiri:20150627024154p:plain

こんな感じに自動的にコミットがレビューの中に追加されました。
あとは、プッシュして再レビューしてもらう感じですね。
f:id:sioiri:20150627024340p:plain

おわり。

*1:UIめっちゃわかりづらかった

*2:Macで指摘に日本語いれれなかった(´・ω・`)