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

かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

共有ライブラリを管理するために Sonatype の Nexus Repository Manager OSS を使用する ( その8 )( build.gradle に 1.0-SNAPSHOT のバージョンで記述している時にライブラリを更新するとすぐに反映されるのか? )

概要

共有ライブラリを管理するために Sonatype の Nexus Repository Manager OSS を使用する ( その7 )( ksbysample-library-simpleutils ライブラリをアップロードし直した時の挙動と、1.0-SNAPSHOT で呼び出せるのかを確認する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • 前回の記事で build.gradle に ksbysample-library-simpleutils ライブラリのバージョン番号を 1.0-20160716.025552-1 → 1.0-SNAPSHOT に変更しても1日反映されないことがあったと書きました。
    • ksbysample-library-simpleutils ライブラリを更新して、すぐに ksbysample-webapp-demo プロジェクトから利用できるようになるのか疑問に思ったので確認します。

参照したサイト・書籍

  1. (o1, o2) -> o1 - o2 なんて呪文はもうやめて! - Java8でのComparatorの使い方
    http://qiita.com/tag1216/items/50ecf6a7bc10218ee889

    • Stream API で文字列長でソートする方法を参照しました。
  2. use latest snapshot version from the remote repo
    http://stackoverflow.com/questions/22372508/use-latest-snapshot-version-from-the-remote-repo

  3. How can I force gradle to redownload dependencies?
    http://stackoverflow.com/questions/13565082/how-can-i-force-gradle-to-redownload-dependencies

  4. 51.9.3. 依存関係キャッシュ制御の微調整 http://gradle.monochromeroad.com/docs/userguide/dependency_management.html#sec:controlling_caching

    • Gradle のマニュアルです。キャッシュの制御方法が記載されています。

目次

  1. ksbysample-library-simpleutils ライブラリの StringListUtils クラスにメソッドを追加する
    1. StringListUtils クラスに maxLengthString メソッドを追加する
    2. テストを作成して動作確認する
    3. Nexus にアップロードする
    4. アップロード後の Nexus の登録状況を確認する
  2. ksbysample-webapp-demo プロジェクトで StringListUtils::maxLengthString メソッドが呼び出せるか確認する
  3. ksbysample-library-simpleutils ライブラリの StringListUtils クラスにメソッドを追加する(2回目)
    1. StringListUtils クラスに minLengthString メソッドを追加する
    2. テストを作成して動作確認する
    3. Nexus にアップロードする
    4. アップロード後の Nexus の登録状況を確認する
  4. ksbysample-webapp-demo プロジェクトで StringListUtils::minLengthString メソッドが呼び出せるか確認する(前回の更新から1時間以内に試す)
  5. 反映されない理由とは?
  6. ksbysample-library-simpleutils ライブラリの最新版が反映されるようにするには?
    1. いろいろ試してみる
    2. 結論

手順

ksbysample-library-simpleutils ライブラリの StringListUtils クラスにメソッドを追加する

StringListUtils クラスに maxLengthString メソッドを追加する

  1. ksbysample-library-simpleutils プロジェクトを開きます。

  2. リストの中で最も文字列長が長い文字列を返す maxLengthString メソッドを追加します。src/main/java/ksbysample/library/simpleutils の下の StringListUtils.javaリンク先のその1の内容 に変更します。

テストを作成して動作確認する

  1. src/test/groovy/ksbysample/library/simpleutils の下の StringListUtilsTest.groovy を リンク先のその1の内容 に変更します。

  2. テストを実行します。def "maxLengthString(#stringList) --> #result"() メソッド名の左側の矢印アイコンをクリックしてメニューを表示した後、「Run 'maxLengthString(#s...()'」メニューを選択します。

    テストが実行され、全て成功することが確認できました。

    f:id:ksby:20160723143346p:plain

Nexus にアップロードする

  1. Gradle projects View の uploadArchives タスクをダブルクリックして登録します。

    f:id:ksby:20160723143534p:plain

アップロード後の Nexus の登録状況を確認する

  1. Nexus の管理画面を見ると、maven-snapshots repository の下に以下の画像の状態で登録されていました。1.0-20160723.053434-4 が追加されています。

    f:id:ksby:20160723143851p:plain

ksbysample-webapp-demo プロジェクトで StringListUtils::maxLengthString メソッドが呼び出せるか確認する

  1. ksbysample-library-simpleutils プロジェクトを閉じて ksbysample-webapp-demo プロジェクトを開きます。

  2. Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

  3. Project View から ksbysample-library-simpleutils ライブラリの StringListUtils クラスをダブルクリックして開くと maxLengthString メソッドが追加されていることが確認できました。

    f:id:ksby:20160723144718p:plain

ksbysample-library-simpleutils ライブラリの StringListUtils クラスにメソッドを追加する(2回目)

StringListUtils クラスに minLengthString メソッドを追加する

  1. ksbysample-webapp-demo プロジェクトを閉じて ksbysample-library-simpleutils プロジェクトを開きます。

  2. リストの中で最も文字列長が短い文字列を返す minLengthString メソッドを追加します。src/main/java/ksbysample/library/simpleutils の下の StringListUtils.javaリンク先のその2の内容 に変更します。

テストを作成して動作確認する

  1. src/test/groovy/ksbysample/library/simpleutils の下の StringListUtilsTest.groovy を リンク先のその2の内容 に変更します。

  2. テストを実行します。def "minLengthString(#stringList) --> #result"() メソッド名の左側の矢印アイコンをクリックしてメニューを表示した後、「Run 'minLengthString(#s...()'」メニューを選択します。

    テストが実行され、全て成功することが確認できました。

    f:id:ksby:20160723150120p:plain

Nexus にアップロードする

  1. Gradle projects View の uploadArchives タスクをダブルクリックして登録します。

    f:id:ksby:20160723150249p:plain

アップロード後の Nexus の登録状況を確認する

  1. Nexus の管理画面を見ると、maven-snapshots repository の下に以下の画像の状態で登録されていました。1.0-20160723.060157-5 が追加されています。

    f:id:ksby:20160723150406p:plain

ksbysample-webapp-demo プロジェクトで StringListUtils::minLengthString メソッドが呼び出せるか確認する(前回の更新から1時間以内に試す)

  1. ksbysample-library-simpleutils プロジェクトを閉じて ksbysample-webapp-demo プロジェクトを開きます。

  2. Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。前回の更新が 14:40頃、今回の更新が 15:09 で1時間以内です。

  3. Project View から ksbysample-library-simpleutils ライブラリの StringListUtils クラスをダブルクリックして開くと minLengthString メソッドがありませんでした。。。

    f:id:ksby:20160723151157p:plain

    やっぱり短時間での更新は反映されないようです。

反映されない理由とは?

stackoverflow のこの QA を見ると、Gradle ではモジュールが 24時間キャッシュされると書かれていました。それであれば、1) 修正しても当日中には反映されなかった、2) 翌日になったら反映された、という挙動も理解できます。

でも自分で構築した repository manager に入れている SNAPSHOT バージョンのコンポーネントは、おそらく頻繁に更新することもあるのでキャッシュ無効にして欲しいところです。

ksbysample-library-simpleutils ライブラリの最新版が反映されるようにするには?

いろいろ試してみる

上記のページに記載されていることを試してみます。

configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')

    compile('ksbysample.library:ksbysample-library-simpleutils:1.0-SNAPSHOT')
}

まずは build.gradle に configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } の設定だけ入れて Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新しましたが、反映されませんでした。

configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')

    compile('ksbysample.library:ksbysample-library-simpleutils:latest.integration')
}

次に sample-library-simpleutils ライブラリのバージョンを 1.0-SNAPSHOTlatest.integration に変更して更新しましたが、反映されませんでした。

configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')

    compile('ksbysample.library:ksbysample-library-simpleutils:1.0-SNAPSHOT') { changing = true }
}

sample-library-simpleutils ライブラリのバージョンを 1.0-SNAPSHOT に戻して { changing = true } を追加して更新しましたが、反映されませんでした。

コマンドプロンプトから gradlew.bat build --refresh-dependencies コマンドを実行してみます。

f:id:ksby:20160723200259p:plain

1.0-20160723.060157-5 を Download した出力が出ているのですが、IntelliJ IDEA で StringListUtils クラスを Decompile してみるとソース内に minLengthString メソッドがありませんでした。

f:id:ksby:20160723200702p:plain

この後で Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、やっと反映されました。Decompile したソースに minLengthString メソッドが表示されています。

f:id:ksby:20160723201131p:plain

結論

上で試しただけでは分からなそうだったので他にもいろいろ試してみた結果、以下の結論でした。

  • sample-library-simpleutils ライブラリを使う方のプロジェクトで build.gradle にバージョン番号を 1.0-SNAPSHOT で指定している場合、前回更新時から 24時間以内に Nexus にアップロードされた最新版を反映する方法は以下の方法だけでした。
    1. まずコマンドプロンプトから gradlew.bat build --refresh-dependencies コマンドを実行します。
    2. その後で Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
  • 24時間経過すれば、Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックするだけで反映されます。
  • build.gradle に以下の記述を追加してみましたが、全く関係ありませんでした。gradle のマニュアルや stackoverflow を見ていると、そうは思えないのですが動作が確認できませんでした。。。
    • configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } を追加する。
    • バージョンを 1.0-SNAPSHOTlatest.integration に変更する。
    • { changing = true } を追加する。

ソースコード

StringListUtils.java

■その1

package ksbysample.library.simpleutils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.Collections.reverseOrder;
import static java.util.Comparator.comparing;

public class StringListUtils {

    ..........

    static public Optional<String> maxLengthString(List<String> stringList) {
        Optional<String> result = Optional.empty();
        if (stringList != null) {
            result = stringList.stream()
                    .filter(s -> s != null)
                    .sorted(comparing(String::length, reverseOrder()))
                    .findFirst();
        }

        return result;
    }

}
  • maxLengthString メソッドを追加します。

■その2

package ksbysample.library.simpleutils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.Collections.reverseOrder;
import static java.util.Comparator.comparing;

public class StringListUtils {

    ..........

    static public Optional<String> minLengthString(List<String> stringList) {
        Optional<String> result = Optional.empty();
        if (stringList != null) {
            result = stringList.stream()
                    .filter(s -> s != null)
                    .sorted(comparing(String::length))
                    .findFirst();
        }

        return result;
    }

}
  • minLengthString メソッドを追加します。

StringListUtilsTest.groovy

■その1

package ksbysample.library.simpleutils

import spock.lang.Specification
import spock.lang.Unroll

class StringListUtilsTest extends Specification {

    ..........

    @Unroll
    def "maxLengthString(#stringList) --> #result"() {
        expect:
        StringListUtils.maxLengthString(stringList) == result

        where:
        stringList            || result
        null                 || Optional.empty()
        [null]               || Optional.empty()
        ["a"]                || Optional.of("a")
        ["テスト"]           || Optional.of("テスト")
        ["a", "ab", "abc"]  || Optional.of("abc")
        ["a", null, "abc"]  || Optional.of("abc")
    }

}
  • def "maxLengthString(#stringList) --> #result"() メソッドを追加します。Optional の戻り値を評価する時は Optional.of(...) を使用します。

■その2

package ksbysample.library.simpleutils

import spock.lang.Specification
import spock.lang.Unroll

class StringListUtilsTest extends Specification {

    ..........

    @Unroll
    def "minLengthString(#stringList) --> #result"() {
        expect:
        StringListUtils.minLengthString(stringList) == result

        where:
        stringList            || result
        null                 || Optional.empty()
        [null]               || Optional.empty()
        ["a"]                || Optional.of("a")
        ["テスト"]           || Optional.of("テスト")
        ["a", "ab", "abc"]  || Optional.of("a")
        ["abc", null, "a"]  || Optional.of("a")
    }

}
  • def "minLengthString(#stringList) --> #result"() メソッドを追加します。

履歴

2016/07/24
初版発行。