Keep on moving

あんまりまとまってないことを書きますよ

Gradle で「詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください」と表示されたときの対処(for build.gradle.kts)

レアキャラです。今回は久々なので小ネタです。

software version
Java 11.0.9.1
Gradle 7.3.3

Gradle で「詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください」と表示される時があります。 build.gradleの時は以下の記事を参照。

qiita.com

ただ、この書き方だとbuild.gradle.kts(kotlinで書く方のやつ)だと動きません。 ではどう書くかというと以下のような感じになります

tasks {
    withType<JavaCompile> {
        options.compilerArgs.add("-Xlint:unchecked")
    }
}

先人に感謝

参考

https://discuss.gradle.org/t/what-is-xlint-deprecation-and-how-to-use-it/40270

Gradle+KotlinでのJavaのtarget versionの指定のしかたをまとめた

software version
gradle 7.2
Kotlin 1.5.30

Gradle+ Kotlinの環境でライブラリを書いていたらいつの間にか以下のようなwarningが出るようになってしまいました。

% ./gradlew test  

> Task :compileKotlin
'compileJava' task (current target is 11) and 'compileKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.

> Task :compileTestKotlin
'compileTestJava' task (current target is 11) and 'compileTestKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.

TL;DR

Gradleに以下の設定を入れる。以下はJava8の場合で KotlinDSLを使う場合の例

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

// こちらの書き方でもOK
// java {
//    toolchain.languageVersion.set(JavaLanguageVersion.of(8))
// }

val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions.jvmTarget = "1.8" // javaの方とversionをあわせる

ググってみた

stackoverflow.com

どうもJavaのtarget versionとKotlinでのjvmTargetの値を両方指定しないといけないらしい。

toolchainの話が出てきたので調べてみたところどうもGradle 6.7から追加された概念らしい(後でもうちょい調べてみよう)

Gradle 6.7 で追加された Toolchain サポート - A Memorandum

Gradleはjava_homeで指定されているバージョンを使おうとするので私はadoptopenjdk11を使っていることもありtarget versionの互換性が〜〜〜というエラーが出るようになった様子。

というわけでこういう書き方をするようにbuild.gradle.ktsを書き直したところビルド時にwarningが出なくなりました。

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

// こちらの書き方でもOK
// java {
//    toolchain.languageVersion.set(JavaLanguageVersion.of(8))
// }

val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions.jvmTarget = "1.8" // javaの方とversionをあわせる

余談

ちなみに 私はm1 macを使っているせいか toolchain.languageVersion.set(JavaLanguageVersion.of(8)) と書くと adoptOpenJDKから aarch64版のopenjdk8をダウンロードしてくれようとするのですが、adoptopendjdkでは提供していないため ビルドしようとするとエラーになってしまうので toolchainを使っていません

Gradleで条件によってdependencyを変える

こんにちは, 僕です。

近頃 Apache Beam にたまにパッチを送るのを趣味で行っているのですが、そこで学んだtipsを紹介します。 今回のテーマはGradleを使っていて条件によってdependencyを変えたい的な要件です。

ちなみにGradleのバージョンは6以降が対象です。

TL;DR

github.com

条件によってGradleのdependencyを切り替える。

Gradleだとできそうだなーと思って調べたら結構簡単に見つかりました。

stackoverflow.com

こんな感じでgradleの実行時引数をとって分岐することができるとのこと。

$ gradle -Pgson dependencies --configuration implementation

これを利用すると呼び出しもとのgradleファイル内で変数を参照することも可能でした。 以下のような感じです。

// aaa.gradle
spark_scala_version = '2.12'
// bbb.gradle
//      aaa.gradleから呼ばれる
dependencies {
  // ...
  if(project.property("spark_scala_version").equals("2.11")){
    runtimeOnly library.java.jackson_module_scala_2_11
  } else {
    runtimeOnly library.java.jackson_module_scala_2_12
  }
  // ...

こんな感じで、Javaのバージョンによって参照するライブラリのバージョン分けることも可能なようです。 先人に感謝

Kotlinで書いたアプリのMaven Central Repository への公開手順(Gradle KotlinDSL 版)

- version
Date 2021.02.13
OpenJDK OpenJDK Runtime Environment Zulu11.43+1017-CA (build 11.0.9.1+1-LTS)
kotlin 1.4.30
gradle 6.8.2

Kotlinで書いたアプリのMaven Central Repository への公開手順(Gradle(KotlinDSL)版)

TL;DR

  • bintrayに公開していたものを移行するのは割と簡単
    • sonatypeへの登録は初回だけちょいと面倒かも(JIRAでissue作ったりが必要)
    • singingの追加
      • pgp keyの登録が必要
    • maven-publish pluginを使っていればアップロード先をbintray -> maven-centralに変える
  • 僕が使っているbuild.gradle.ktsを共有

流れ

こちらのブログが素晴らしく良くまとまっているので参照すると良いと思います。

blog1.mammb.com

  1. sonatype の JIRA で issue を通してリポジトリ作成を依頼
  2. GnuPG で jar を署名できる環境を作成
  3. Gradle プラグインリポジトリへ登録
  4. Repository Manager で Maven Central Repository へリリース

Tips

いくつか捕捉しておくと良さそうなことを書いておきます。

windowsを使っている方向け

windowsで表題の件をやりたい場合はこちらでgpg keyを作成すると良いと思います。 https://www.gpg4win.org/

gnupgmacportsで入れる

sudo port install gnupg2 # XCodeが必要

RSA keys may be between 1024 and 4096 bits long

ここは (3072) [デフォルト]になったみたいです。

すでにbintrayに公開済みのjarをmavencentralに移行

jfrog.com

JVM言語界隈に激震が走ったこの件について。 bintrayにpublishしているものをmaven centralに移行したい方は以下の感じになります

  1. sonatype の JIRA で issue を通してリポジトリ作成を依頼
  2. GnuPG で jar を署名できる環境を作成
  3. Gradle プラグインを変更してリポジトリへ登録
  4. Repository Manager で Maven Central Repository へリリース

build.gradle.ktsの書き換えは以下のような感じになります。

github.com

抜粋すると

plugins {
    ...
    signing // signingを追加. bintrayではこれが必要なかった
}
...
//    repositories {
//        maven {
//            name = "bintray"
//            val bintrayUsername = "masahitojp"
//            val bintrayRepoName = "maven"
//            val bintrayPackageName = "com.github.masahitojp.bqdatamapper4k"
//            setUrl("https://api.bintray.com/content/$bintrayUsername/$bintrayRepoName/$bintrayPackageName/${project.version};publish=0;override=1")
//            credentials {
//                username = project.findProperty("bintray_user") as String?
//                password = project.findProperty("bintray_api_key") as String?
//             }
//    }
    repositories {
        maven {
            name = "MavenCentral"
            val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
            credentials {
                username = project.findProperty("sonatypeUsername")?.toString() ?: ""
                password = project.findProperty("sonatypePassword")?.toString() ?: ""
            }
        }
    }
// PGP署名(Mavenセントラルリポジトリに公開するのに必要な署名形式)の追加
signing {
    sign(publishing.publications["maven"])
}

私がよく使っているbuild.gradle.ktsGradle(KotlinDSL)

plugins {
    val kotlinVersion = "1.4.30"
    kotlin("jvm") version kotlinVersion
    id("org.jetbrains.dokka") version "1.4.20" // Docにはdokkaを使う(ここは自分の好きなのに入れ替えてよし)
    `maven-publish`
    signing
}

group = 'Your Group Id'
version = 'X.X.X'
val artifactID = "プロジェクト名"

repositories {
    mavenCentral()
    jcenter() // dokka dependency
}

dependencies {

    // Use the Kotlin JDK 8 standard library.
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")


   // 必要ならライブラリがあれば追加

    // Use the Kotlin test library.
    testImplementation("org.jetbrains.kotlin:kotlin-test")

    // Use the Kotlin JUnit integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}

// Configure existing Dokka task to output HTML to typical Javadoc directory
tasks.dokkaHtml.configure {
    outputDirectory.set(buildDir.resolve("javadoc"))
}

// Create dokka Jar task from dokka task output
val dokkaJar by tasks.creating(Jar::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Assembles Kotlin docs with Dokka"
    archiveClassifier.set("javadoc")
    // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka)
    from(tasks.dokkaHtml)
}

// Create sources Jar from main kotlin sources
val sourcesJar by tasks.creating(Jar::class) {
    description = "Assembles sources JAR"
    archiveClassifier.set("sources")
    from(sourceSets["main"].allSource)
}

artifacts {
    add("archives", sourcesJar)
    add("archives", dokkaJar)
}

val jar by tasks.getting(Jar::class) {
    manifest {
        attributes(
            "Implementation-Title" to project.name,
            "Implementation-Version" to project.version,
            "Implementation-Vendor" to "masahito.me",
            "Built-JDK" to "${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})",
            "Built-Gradle" to gradle.gradleVersion
        )
    }
}

val sonatypeUsername = project.findProperty("sonatypeUsername")?.toString() ?: ""
val sonatypePassword = project.findProperty("sonatypePassword")?.toString() ?: ""

publishing {
    publications {
        create<MavenPublication>("maven") {
            groupId = project.group.toString()
            from(components.findByName("kotlin"))
            artifact(sourcesJar)
            artifact(dokkaJar)
            pom {
                name.set(artifactId)
                description.set("BigQuery datamapper for Kotlin")
                url.set("https://github.com/masahitojp/bqdatamapper4k")
                licenses {
                    license {
                        name.set("Apache License, Version 2.0")
                        url.set("https://opensource.org/licenses/Apache-2.0")
                    }
                }
                developers {
                    developer {
                        id.set("Your ID")
                        name.set("Your name")
                        email.set("Your email address")
                    }
                }
                scm {
                    connection.set("scm:git:git@github.com:XXXXX.git")
                    developerConnection.set("scm:git:ssh://github.com:XXXXX.git")
                    url.set("https://github.com/XXXXX")
                }
            }
        }
    }
    repositories {
        maven {
            name = "MavenCentral"
            val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
            credentials {
                username = sonatypeUsername
                password = sonatypePassword
            }
        }
    }
}

signing {
    sign(publishing.publications["maven"])
}

まとめ

  • bintrayに公開していたものを移行するのは割と簡単
    • sonatypeへの登録は初回だけちょいと面倒かも(JIRAでissue作ったりが必要)
    • singingの追加
      • pgp keyの登録が必要
    • maven-publish pluginを使っていればアップロード先をbintray -> maven-centralに変える
  • 僕が使っているbuild.gradle.ktsを共有

上記をしました。すでにsonatypeにアカウントを作っていればそんなに大変なことはないと思います。 ちょっと古かったりしますがまとめ直してくれていたりする素敵なかたがたくさんいたので僕は1時間くらいで作業を終えることができました。 先人たちに感謝。

How to upgrade dokka version 0.10.x to 1.4.x

Kotlinではドキュメント生成ツール(KDoc JavaでのJavadoc的なもの)として Dokkaというツールがあります。 自作のライブラリでdokka 0.10.1を使っていたのですが、気づいたら1.4.xにアップデートしていました。1 Gradleでの書き方も変更があり、だいぶハマったのでまとめておきます。

TL;DR

chore: update dokka to 1.4.20 · masahitojp/bqdatamapper4k@a8a6933 · GitHub

dokka 1.4.xでの変更点

公式ドキュメントでまとまってます。

github.com

/* 0.10.x */    outputDirectory = "$buildDir/javadoc"
/* 1.4.x */     outputDirectory.set(buildDir.resolve("javadoc"))

こんな感じで = で設定していた箇所がsetter methodに変わったりしてるっぽい。 が、実際にコードで使ってるプロジェクトがなかなかなく,じゃーどう書き換えればいいかよくわかりませんでした。 というわけでGithub で検索してなんとなくわかってきました。

// 0.10.xでのjavadocフォルダにhtmlを出力する設定
val dokka by tasks.getting(DokkaTask::class){
    outputFormat = "html"
    outputDirectory = "$buildDir/javadoc"
}

// 1.4.xでの同じ書き方 htmlを出力したいのでdokkaHtmlを使う
tasks.dokkaHtml.configure {
    outputDirectory.set(buildDir.resolve("javadoc"))
}

// for 1.4.x [Option]  Gfm, javadoc, Jekyll向けの設定もある
tasks.dokkaGfm.configure {}
tasks.dokkaJavadoc.configure {}
tasks.dokkaJekyll.configure {}
// for 0.10.x
val dokkaJar by tasks.creating(Jar::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Assembles Kotlin docs with Dokka"
    archiveClassifier.set("javadoc")
    // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka)
    from(dokka)
}
// for 1.4.x
val dokkaJar by tasks.creating(Jar::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Assembles Kotlin docs with Dokka"
    archiveClassifier.set("javadoc")
    // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka)
    from(tasks.dokkaHtml) // ^でのtasksの設定を入れる
}

参考

github.com

関連ドキュメント

blog.jetbrains.com

先人に感謝。


  1. https://github.com/Kotlin/dokka/releases/tag/v1.4.20 version名にalphatついているのが気になるところ.リライトしたとのことなのでまだ安定版ではないアピール?

GitHub ActionsでGradle環境でCIを回してみる

こんにちは、yaml苦手っ子です。GitHub Actions+GradleでCIする方法をまとめます。

key value
Last Update 2020/07/06

Gradle

こちらを参考にすればOK.

docs.github.com

超シンプルに書くとこんな感じ。

name: Java CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: Build with Gradle
        run: ./gradlew test

Cacheを利用する

ここをみると以下のように説明されている。

依存関係をキャッシュしてワークフローのスピードを上げる - GitHub Docs

GitHubホストランナー上のジョブは、クリーンな仮想環境で開始され、依存関係を毎回ダウンロードしなければならず、ネットワークの利用率を増大させ、実行時間が長くなり、コストが高まってしまいます。

なるほど、というわけでキャッシュの使い方をまとめてみる。

actions/cacheを使う

actions cacheを使う方法。 github.com

A repository can have up to 5GB of caches. Once the 5GB limit is reached, older caches will be evicted based on when the cache was last accessed. Caches that are not accessed within the last week will also be evicted. どうやら5GiBの制限があるみたい

READMEにちゃんと設定が書いてある。例としては以下のような感じ

name: Run Gradle unit-test on Push
on: [pull_request, push]
jobs:
  gradle:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: 8
      - name: Cache Gradle packages
        uses: actions/cache@v2
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
          restore-keys: ${{ runner.os }}-gradle
      - name: Build with Gradle
        run: ./gradlew test

gradle pluginでcacheを使う

ちなみに eskatos/gradle-command-action@v1 でもcacheを使うことが可能だったりします。

github.com このActtionではcacheを以下の3つに分けてあるとのこと。(default でwrapper-cacheのみ有効.多分キャッシュの制限が原因)

wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true

以下のような感じになる

github.com

name: "CI"

on: [pull_request, push]


jobs:
  ci:
    name: "CI"
    runs-on: ubuntu-latest
    steps:

      - name: Checkout sources
        uses: actions/checkout@v2

      - name: Setup Java 11
        uses: actions/setup-java@v1
        with:
          java-version: 11

      - name: Build with Gradle
        uses: eskatos/gradle-command-action@v1
        with:
          dependencies-cache-enabled: true
          configuration-cache-enabled: true
          arguments: test

参考

GradleでのJavaのビルドとテスト - GitHub Docs

GitHub ActionsでGradleの自動ビルド/テストをする [再掲] | Qrunch(クランチ)

GradleでScalaのインクリメンタルコンパイラのバージョンを変える

|Gradle|4.3.1|

GradleのScala plugin 使うと Zinc Compiler がすでに有効になっていて インクリメンタルにコンパイルしてくれる(=== 全コンパイルしない)

https://docs.gradle.org/current/userguide/scala_plugin.html#sec:configure_zinc_compiler

ちなみにバージョンを上げたい場合は以下のようにdependencyに追加するだけ

dependencies {
    zinc 'com.typesafe.zinc:zinc:0.3.9'
}

ちなみに

Zinc 1.0系にはまだGradleでは対応してないようです

github.com

Gradleの方でもissue化されてる。インターフェースがコレまでと違うらしく違う名前(scala-plugin じゃない名前)になるかもとのこと。今後に期待

github.com