kagamihogeの日記

kagamihogeの日記です。

gradleの複数プロジェクトで共通設定をpluginでまとめる

単一プロジェクト内のsubproject間の共通設定をpluginにまとめる方法はgradle initでプロジェクト作ればそこに例があるし、自分のblogだと gradle initの複数subproject構成を見る(6.8.3)にまとめている。

ここでは複数プロジェクト間の共通設定をpluginにまとめるやり方について。基本的には、大規模プロジェクト構成例の公式リファレンス https://docs.gradle.org/current/userguide/structuring_software_products.html のサンプルコード https://docs.gradle.org/current/samples/sample_structuring_software_projects.html から対象部分を抜粋した形となる。

やり方の概要としては、まずnaming conventionを行うgroovy-gradle-pluginで記述しpluginディレクトリに配置、includeBuildでそのディレクトリをincludeし、plugins { id '...'}でそのpluginを使用する、といったところ。

環境

  • java 11
  • gradle 7.2

ソースコード

ファイルのレイアウトはおおむね以下となる。

  • build-logic - pluginディレクトリとなる、共通設定を記述するpluginファイルの配置箇所。下の例だとcom.example.commons.gradleがpluginの実体。
  • project1 - プロジェクトその1。下の例だとsubprojectにappを持っている。
  • project2 - プロジェクトその2
build-logic
 settings.gradle
 commons
  build.gradle
  src/main/groovy
   com.example.commons.gradle
project1
 settings.xml
 app
   build.gradle
project2
 settings.xml
 ...

build-logic

このディレクトリの名前自体は何でもよいが、gradleのサンプルプロジェクトの名前をそのまま使用している。

settings.gradle

dependencyResolutionManagement {
    repositories {
        gradlePluginPortal()
    }
}

rootProject.name = 'build-logic'

include('commons')

一般的なプロジェクト例同様にinclude('commons')commonsディレクトリをincludeする。

gradlePluginPortal()のところは今回くらいシンプルだと要らないけど大抵は必要になると思う。

commons/build.gradle

plugins {
    id('groovy-gradle-plugin')
}

pluginはnaming conventionを使用して記述するので、そのためのgroovy-gradle-pluginを記述する。

src/main/groovy/com.example.commons.gradle

groovy-gradle-pluginの形式に従いsrc/main/groovyディレクトリにplugin-name.gradleを記述する。後述する通りplugin-nameというidで参照可能になる。

println '### com.example.commons.gradle'

中身はデバッグ用のprintfだけ。

project1

settings.xml

pluginManagement {
    includeBuild('../build-logic')
}

rootProject.name = 'project1'

include('app')

最初のincludeBuild('../build-logic')でpluginディレクトリをincludeする。includeBuildディレクトリというかプロジェクトまるごと取り込むのがポイント。

app/build.gradle

最後にアプリケーションのプロジェクトで対象のpluginを使用する。

plugins {
    id('com.example.commons')
}

com.example.commons.gradleという名前なのでid('com.example.commons')で使用できる。

実行時の様子

>gradlew build

> Configure project :app
### com.example.commons.gradle

plugin内のprintが実行されてるのが分かる。

バリエーション

その他使いそうなplugin定義方法のメモ。

同一ディレクトリ内のplugin使用

例えば、以下のときにcom.example.commons.gradleからsample.gradleを参照したい場合。

commons/src/main/groovy
 com.example.commons.gradle
 sample.gradle

単純にpluginの名前で参照できる。

plugins {
  id 'sample'
}

println '### com.example.commons.gradle'

別のディレクトリを参照する

例えば、以下のようにcommonsfoobarがあり、前者から後者を参照したい場合。

build-logic
 commons
 foobar

まずbuild-logic/settings.xmlfoobarを追加する。

include('foobar')
include('commons')

foobarの中身はほとんどcommonsと同じなので省略。次にbuild-logic/foobar/src/main/groovy/foo.bar.gradleという名前のpluginファイルを作成した、とする。

commons/build.gradlefoobarを取り込む。

plugins {
    id('groovy-gradle-plugin')
}

dependencies {
    implementation(project(':foobar'))
}

gradle公式のサンプル見るとspring-bomはimplementation(platform(...))を使ってる。このへん公式サンプル読み込めてないないんだが取り込む対象の種類によって使い分ける必要があるのだと思う。

最後にcom.example.commons.gradlefoo.bar pluginを使用する。

plugins {
  id 'sample'
  id 'foo.bar'
}

println '### com.example.commons.gradle'

ハマりどころ

apply pluginは使えない

下記のようにnot foundになる。もしかしたら何か方法があるかもしれないがそこまで調べてない。

* What went wrong:
A problem occurred evaluating project ':app'.
> Plugin with id 'com.example.commons' not found.

新型コロナウイルス ワクチン(モデルナ)接種2回目の記録

f:id:kagamihoge:20210725174335j:plain

40代・男性の新型コロナウイルス ワクチン(モデルナ)接種2回目の記録です。

時系列

接種日から数日後まで時系列に沿って、体調の変化やその対処およびその時の心境などを述べる。

7/21 接種日 - 約半日後に急激な発熱

正午頃に2回目の接種を終える。数時間後までは特に何も無く、次第に接種した腕に筋肉痛に似た痛みが増す。頭を洗うために腕を上げるのが苦しい程度の痛みで、1回目と同等程度の痛みが発生した。

約半日経過した23時頃に変化が生じる。22時頃に布団に横になってYouTubeをダラダラと見ていた。すると、23時過ぎ頃からなんとなく体に違和感を覚え始めると、一気に発熱が進み、0時頃には38度を超える。

しかし発熱は想定内なので落ち着いて就寝する。とはいっても、38度の発熱・悪寒・節々の痛みで全く眠れない。冷えピタをおでこ・首筋に張り付けると非常に気持ちが良い。発熱の苦しさで起きる、喉が渇いてポカリスエット飲む、トイレが近くなりまた起きる、の繰り返しで翌朝を迎える。

身体的には苦しいが精神的には落ち着いていた。事前準備はしていたし発熱の可能性が高いことは分かっていたので、まぁワクチンの副作用としてはこんなもんだよな、と納得しつつ朦朧と長い夜を過ごしていた。

7/22 接種日翌日 - 朝から夜になるにつれ高熱は微熱へ

ほとんど眠れずの翌朝を迎える。

引き続き38度台は維持しており倦怠感は相当なのに、不思議と食欲は旺盛だった。ただし、レトルトのおかゆをレンチンする事すら億劫だったため、ゼリー飲料を重宝した。朝食として1個食べた。2個しか買っていなかったので1つに留めたが、本音としてはもう1個食べたかった。

38度台は継続したまま昼食の時間帯を迎える。倦怠感はもとより空腹感が強くなる。ゼリー飲料を半分飲んでバファリンを服用、37度台に下がり体力に余裕を作った状態で、レトルトおかゆをレンチンして食べる。一袋ではやや物足りなくはあったが腹八分で満足して再び寝床に戻る。

夕方頃に37度台に熱が下がる。体力も余裕が出て食欲も出てくる。19時頃にカレーうどんを食べ、物足りずにチキンラーメンを追加で食べている。

シャワーを浴びて就寝。発熱の苦しさは大分収まったが、倦怠感は依然として残り、睡眠の質は前日ほどではないが悪かった。

7/23 接種日翌々日 - 微熱と頭痛

起床時は37度台。布団から起き上がってYouTubeをダラダラ見るくらいには余裕が出てくる。

しかし、頭痛が度々起き、その都度横になってウトウトする、を繰り返す一日となった。

昼食頃になると、頭痛は前述の通りで倦怠感はそこそこ、食欲はいつも通りとなった。昼・夜ともにコンビニ弁当を買いに出かける余力があり、かつ、完食している。ついでにおやつでスナック菓子一袋をあけている。

7/24 接種日から3日目 - 平熱だが頭痛

久々に一度も夜に起きず朝までぐっすり眠れる。気分爽快な目覚めだったのを良く覚えている。10時頃起床して余勢を駆って朝昼兼用の外食に出掛ける。体温も平熱に戻り特に気になる症状も無し。

しかし、その2,3時間後に頭痛がひどくなる。ソシャゲしたりYouTube見たりはギリギリ出来るが、小説など文字を追うのは困難な程度の頭痛。余暇を読書に充てる私にとってこの頭痛は大変に耐えがたく、頭痛回避のためにバファリンを合計2回服用している。

7/25 接種日から4日目

この文章は7/25の20時頃に書いている。今のところ特にこれといった副作用と思しき症状は発生していない。さすがにこれ以上は何も起きないだろう、と考えている。

事前準備

物資の余裕は精神の余裕を産む。前述の通り、発熱に対して身体的にはともかく精神的にはさほど動揺はしていなかったが、これは事前準備のたまものと言ってよい。以下に私が準備したものとその感想について述べる。

冷えピタ

これ自体に解熱効果は無いらしいが、冷感が大変に気持ちが良い。なるべく快適に発熱の時期を過ごすためには必須では無かろうか。

バファリン(解熱剤)

薬局でたまたま目についたものを買ったが、より万全を期すには自分の体質に合う薬を買うべきであろう。

合計4回服用しており、目的別でみると高熱のためが2回、頭痛のためが2回。高熱も苦しかったが、私にとっては高熱が収まった後の頭痛も同じくらい苦しかった。

ポカリスエット

どちらかと言えばポカリスエット派なので900mlを2本用意した。翌々日頃に飲み切って1本追加したので3本買っておいても良かったか、と感じている。

理屈は不明だが冷蔵庫で冷やしたものを高熱状態では飲むのが辛かった。どのみち枕元に置きっ放しにしたのですぐ常温になり問題は無かったが、最初から取り出しておけば良かった。

ゼリー飲料

38度台での主要な食糧。食べやすいし腹にたまる感触も得られるしで非常に重宝した。私は2個買っておいたが、4,5個買って置けばよかったと思う。前述の通り、介助者がいるならともかく、38度台ではレンチンすら億劫になる。

レトルトのおかゆ

37度台での主要な食糧。

ゼリー・プリン・ヨーグルトなど

ずっと寝てる状態なので食事は一つの楽しみとなる。そのため、食べやすい食糧はバリエーションが豊かな事に越したことは無い。

寝室の清掃やシーツの交換

布団に長時間拘束されるため、なるべく快適に過ごすために寝室を整備しておくと良い。

肌着・寝巻きの準備

発熱と寝汗ですぐに服が不愉快な状態になる。これも、なるべく快適に過ごすためには、頻繁に着替えた方が良い。接種日に合わせて備蓄がマックスになるよう洗濯をしておきたい。

その他に買って置けばよかったもの

意外にも食欲があったので、もう少し食糧の質・量ともに増やしておけば良かった。たとえば、うどんなど麺類、しっとりめのクッキーなども食べられたかな、と思う。

感想

情報と物資の十分な準備が重要

基本的には以下2つが重要と考える。

  • ワクチン接種後に何が起きるかの情報収集
  • 発熱を見越した物資等の事前準備

前述の通り、身体的には中々にキツイ症状だが精神的にはそれほどの動揺は無かった。何が起きるか分かっており、かつ、先が見える苦しみはそこまで怖くはない。また、精神を下支えするのが物資である。「冷えピタ気持ち良いし、高熱が苦しくなればバファリン飲めばよい。ポカリスエット十分量あるし、落ち着いたらゼリー飲料とおかゆ食べよう」と考えられれば自然と心に余裕が生まれる。

www3.nhk.or.jp

余談:ある軽傷経験者の話

話は横道に逸れるが、ほぼ時を同じくして新型コロナウイルスに感染し軽傷(おそらく)を経験したゲーム実況者の話を取り上げたい。

www.youtube.com

この動画で軽傷の症状として「三日間に渡り38度以上の高熱と激しい頭痛、嗅覚・味覚障害」と述べている。私のワクチン接種後は主に高熱と頭痛でそれなりに共通点があるので、軽傷を更にマイルドにした状態を体験できたのだろうか? と素人ながらに感じている。

また「インフルエンザ等とは明らかに異質な高熱、二度と罹りたくない」とも述べてもいる。私はワクチンのそれですらまぁまぁキツかったのでその意見には強く頷ける。そしてワクチン接種を強く呼びかけている点も同意見である。

まとめ

  • 接種日プラス翌日の2日間できれば3日間は安静としたい。
  • 事前準備の余裕が精神の余裕を産む。

情報源

javaでextendsの階層を大量に深くする

javaでextendsの階層を深くしまくったらどうなるか? 理論的な裏付けは特に行わず、とりあえずやってみたら何が起きるか、を見る。

環境

  • java version "16" 2021-03-16

やったこと

こんな感じでひたすらextendsを重ねるクラスを生成し、コンパイルして実行してみる。

class A1 extends Object {
    public void m() {
        System.out.println("A1");
    }
}

class A2 extends A1 {
    public void m() {
        System.out.println("A2");
        super.m();
    }
}

//...(省略)

public class Main {
    public static void main(String[] args) {
        new A100().m();
    }
}

extendsが200で以下のようにStackOverflowErrorとなった。末尾最適利かないだろうから結果としては至極当然といったところか。

> java a.Main
Exception in thread "main" java.lang.StackOverflowError
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1010)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:855)

コンパイル時間は500で1分強、1000で数分。一気に60000は全く終わる気配が無くて途中であきらめた。

実行時間は、上記の事情があるので100しか試していないが、特に早いとか遅いとかは無かった。