タイトルのままです。
Android版World of Gunsをインストールしようとしていたのですが、何故か初回起動時の更新データ読み込みが終わらない症状が出ました。
具体的には以下のような症状でした。
- ダウンロードに異常な時間がかかる
- アプリが落ちる
- アプリがフリーズする
以下を試した結果最終的に手くいったのですが、最後に試したのが通知の許可でした。
- 端末再起動
- 言語選択で英語を選択
- 通知を許可
他の要因が無かったか切り分けできていませんが、一応残しておきます。
タイトルのままです。
Android版World of Gunsをインストールしようとしていたのですが、何故か初回起動時の更新データ読み込みが終わらない症状が出ました。
具体的には以下のような症状でした。
以下を試した結果最終的に手くいったのですが、最後に試したのが通知の許可でした。
他の要因が無かったか切り分けできていませんが、一応残しておきます。
7年目もやっていきます。
wrongwrong163377.hatenablog.com
今年は8月以降仕事が異常に忙しくなり、休日がほぼ潰れる状況になっていました。
自由な開発もOSS活動もできず、非常にフラストレーションの溜まる日々が続いています(しかも状況は改善せず、年末年始から来年1, 2月も同じ勢いになりそう……)。
特にOSS周りは、最低限プロジェクトを死なせないための活動だけやっているような状況で申し訳ありません。
OSS関係今年の活動で最も大きな成果となったのは、jackson-module-kotlinにおけるStrictNullChecksオプションの性能改善でしょうか(手法確立自体は2024年以前だった気もしますが)。
従来のjackson-module-kotlinにおいて、型パラメータ上非null指定のCollectionに対するnullチェックはデフォルト無効でした。
理由は、大幅な性能低下を伴うためです。
これに対して、ほぼオーバーヘッド無しでのnullチェックを確立することができました。
加えて、この改善により、Jackson 3.0からはStrictNullChecksオプションをデフォルトでONとすることができました。
デフォルト挙動として、非nullを指定したはずのCollectionへnullが入った場合読み出し側でnull/ヌルポとなるのは大きな罠であったため、改善できたことは非常に嬉しかったです。
この他に個人的に気に入ってる改善としては、value class関連処理へのMethodHandle適用による性能改善が有ります。
MethodHandle化単体では誤差レベルの改善でしたが、久々にMethodHandleに触れて勉強になりました。
github.com wrongwrong163377.hatenablog.com
その他としては、主にJackson 3.0に向けた対応、Jackson絡みの細々としたバグ修正・改善をやっていました。
今年は33本で、去年よりも増やすことができました。
要因は、スプレッドシートを弄るのにハマったことと、久々に自作PCをやったことです。
8月頃までは割と調子良く稼げてたので、仕事で時間が潰れてなければ40本は書けたと思うんですが……残念でした(ガッツリ書きたいネタも有ったんですがね、、、)。
今年は年の初めに2回ほど軽く登壇してきました。
8月位までも色々有ったはずなんですが、後半の修羅場のせいでとにかく仕事がやばい印象しか残らない1年でした。
アウトプットしたいネタは結構溜まってるんですが、それぞれ実行できない状態となっていて非常に辛いです。
祝日は諦めてもせめて土日くらいは空いて欲しい……。
来年頭は人生初の確定申告に望まなければならないのですが、その辺りすら目処が立っていない状況です。
何とか1つ1つ片付けていかねば。
Java 21化後、Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK.という警告が出るようになりました。
当該プロジェクトではMockitoを利用していなかったため、除外することにしました。
また、当該プロジェクトはSpringBootのマルチモジュールプロジェクトで、一々個別のbuild.gradleへ除外を指定するのは手間なので、ルートに1発で指定する方法を探しました。
ChatGPTに聞いた所以下の方法を提示されました。
このプロジェクトはルートにコードが無かったですが、ルートにもコードが有る場合はallProjectsに指定する方が良いかもしれません。
subprojects {
configurations.configureEach {
exclude(group = "org.mockito")
}
}
一応、誤ってMockito関係の内容が利用されていた箇所にコンパイルエラーが出たため、これで機能していると思われます。
jackson-module-kogera 2.19.0-beta25にて、value classのシリアライズ / デシリアライズに関連する処理でMethodHandleを使うように変更しました。
この記事では、変更の効果が最低でどの程度かを確認した結果を紹介します。
value class関連処理をMethodHandle化する理由Jacksonでvalue classを違和感なく処理できるようにするため、value class関連処理は多くのリフレクション呼び出しが必要であり、リフレクション呼び出しが連続することもしばしば有るためです。
例えばデシリアライズ時は、最低でも「プライマリコンストラクタ呼び出し -> box化呼び出し」と2回のリフレクション呼び出しが必要です。
プロパティが非nullの場合、更にunbox化呼び出しも追加で必要です。
シリアライズの場合も、box化呼び出しとunbox化で2回のリフレクション呼び出しが必要です。
これらはMethodHandle化することで多くの改善が期待できます。
以下のリポジトリを使って比較を行いました。
MethodHandleで効果的に高速化するためには、型を明示することが重要です。
jackson-module-kogera 2.19.0-beta25では、ラップされる型がInt, Long, String, (Java)UUIDのいずれかだった場合に関して、型を明示的に扱うことによる最適化を行っています。
よって、この最適化の有無を比較する必要が有ります。
また、ベンチマーク内容は、Jacksonによる処理の量をなるべく減らし、今回の高速化に関する効果が表れやすいようにする必要が有ります。
以上を考慮し、ベンチマーク内容は以下のようにしました。
JSON構造value classは、Intをラップしたもの(= 型明示による最適化有り)と、Shortをラップしたもの(= 型明示による最適化無し)最適化の効果はvalue classの数が増えた分だけ高まるため、このベンチマークからは、value classに関する処理が最低でどれだけ改善されたかが分かります。
8ad900dをまとめたものです。
比が1より大きいほど改善されています。
シリアライズ
10/12ケースで改善が確認できました。
最も基本的なケースであるunbox.IntBenchmark.wrapped(シンプルなvalue classをプロパティに持つクラス)に関しては、約10%のスループット向上を記録しました。
key.jsonKey.ShortBenchmark.benchmarkとunbox.ShortBenchmark.directに関しては劣化が確認されましたが、それぞれ1%未満であり、誤差の範疇です。
| 2.19.0-beta24 | 2.19.0-beta25 | 2.19.0-beta25 / 2.19.0-beta24 | |
|---|---|---|---|
| key.jsonKey.IntBenchmark.benchmark | 1777332.255594 | 1817286.155664 | 1.022479702 |
| key.jsonKey.ShortBenchmark.benchmark | 1831096.322124 | 1819773.928008 | 0.9938166038 |
| key.unbox.IntBenchmark.benchmark | 1548940.949888 | 1557133.079293 | 1.005288858 |
| key.unbox.ShortBenchmark.benchmark | 739703.867427 | 760804.578200 | 1.028525889 |
| jsonValue.IntBenchmark.direct | 2892679.151030 | 2912412.745928 | 1.006821909 |
| jsonValue.IntBenchmark.wrapped | 1663825.635318 | 1866756.436996 | 1.121966387 |
| jsonValue.ShortBenchmark.direct | 2811182.009216 | 2904066.732081 | 1.033041163 |
| jsonValue.ShortBenchmark.wrapped | 1670737.423967 | 1832761.453181 | 1.096977554 |
| unbox.IntBenchmark.direct | 3179525.595621 | 3225851.588935 | 1.014570096 |
| unbox.IntBenchmark.wrapped | 1874000.549577 | 2057832.237266 | 1.098095856 |
| unbox.ShortBenchmark.direct | 3137818.450200 | 3135692.306827 | 0.9993224135 |
| unbox.ShortBenchmark.wrapped | 1631790.050848 | 1727636.426984 | 1.058736953 |
デシリアライズ
8/10ケースで改善が確認できました。
最も基本的なケースであるbyPrimaryConstructor.IntBenchmark.wrapped(シンプルなvalue classをプロパティに持つクラス)に関しては、約7%のスループット向上を記録しました。
byJsonCreator.ShortBenchmark.directとbyPrimaryConstructor.IntBenchmark.directに関しては、それぞれ約4%の劣化が確認されました。
ただし、これらはvalue classを直接デシリアライズする稀なケースです。
| 2.19.0-beta24 | 2.19.0-beta25 | 2.19.0-beta25 / 2.19.0-beta24 | |
|---|---|---|---|
| KeyBenchmark._int | 628928.592524 | 642907.263310 | 1.022226165 |
| KeyBenchmark._short | 536357.711456 | 555365.450802 | 1.03543855 |
| byJsonCreator.IntBenchmark.direct | 1784708.471187 | 1850169.260039 | 1.036678701 |
| byJsonCreator.IntBenchmark.wrapped | 916055.903594 | 958713.142722 | 1.046566196 |
| byJsonCreator.ShortBenchmark.direct | 1880281.625663 | 1809603.994811 | 0.9624111463 |
| byJsonCreator.ShortBenchmark.wrapped | 921136.345195 | 935274.268244 | 1.01534835 |
| byPrimaryConstructor.IntBenchmark.direct | 2147950.142659 | 2057745.453727 | 0.9580042911 |
| byPrimaryConstructor.IntBenchmark.wrapped | 995537.946778 | 1064727.840156 | 1.069500006 |
| byPrimaryConstructor.ShortBenchmark.direct | 1691792.929911 | 1739138.397988 | 1.02798538 |
| byPrimaryConstructor.ShortBenchmark.wrapped | 904488.697510 | 963217.354551 | 1.064930228 |
比が1より小さいほど改善されています。
シリアライズ
11/12ケースで劣化、劣化しなかったケースもほぼ差が有りませんでした。
最も基本的なケースであるunbox.IntBenchmark.wrappedに関して、劣化は2%未満でした。
| 2.19.0-beta24 | 2.19.0-beta25 | 2.19.0-beta25 / 2.19.0-beta24 | |
|---|---|---|---|
| key.jsonKey.IntBenchmark.benchmark | 184.561424 | 195.296498 | 1.058165318 |
| key.jsonKey.ShortBenchmark.benchmark | 187.364271 | 194.738718 | 1.039358875 |
| key.unbox.IntBenchmark.benchmark | 192.471979 | 192.413958 | 0.9996985483 |
| key.unbox.ShortBenchmark.benchmark | 185.425115 | 186.525809 | 1.005936057 |
| jsonValue.IntBenchmark.direct | 172.408964 | 176.969350 | 1.02645098 |
| jsonValue.IntBenchmark.wrapped | 286.545790 | 295.294399 | 1.030531277 |
| jsonValue.ShortBenchmark.direct | 175.135014 | 175.543538 | 1.002332623 |
| jsonValue.ShortBenchmark.wrapped | 282.984258 | 295.457164 | 1.044076325 |
| unbox.IntBenchmark.direct | 175.688984 | 177.968913 | 1.012977074 |
| unbox.IntBenchmark.wrapped | 292.981319 | 297.085654 | 1.014008862 |
| unbox.ShortBenchmark.direct | 176.957803 | 177.437413 | 1.002710307 |
| unbox.ShortBenchmark.wrapped | 281.099359 | 288.922695 | 1.027831213 |
デシリアライズ
7/10ケースで劣化、劣化しなかったケースもほぼ差が有りませんでした。
最も基本的なケースであるbyPrimaryConstructor.IntBenchmark.wrappedに関して、劣化は2%少しでした。
| 2.19.0-beta24 | 2.19.0-beta25 | 2.19.0-beta25 / 2.19.0-beta24 | |
|---|---|---|---|
| KeyBenchmark._int | 281.434946 | 280.577312 | 0.9969526386 |
| KeyBenchmark._short | 277.767897 | 286.769142 | 1.032405635 |
| byJsonCreator.IntBenchmark.direct | 269.644305 | 270.065927 | 1.001563623 |
| byJsonCreator.IntBenchmark.wrapped | 305.317364 | 307.809560 | 1.008162641 |
| byJsonCreator.ShortBenchmark.direct | 270.556615 | 275.870427 | 1.019640296 |
| byJsonCreator.ShortBenchmark.wrapped | 308.366190 | 306.834562 | 0.9950330871 |
| byPrimaryConstructor.IntBenchmark.direct | 275.885608 | 278.743274 | 1.010358155 |
| byPrimaryConstructor.IntBenchmark.wrapped | 302.336269 | 309.165245 | 1.022587353 |
| byPrimaryConstructor.ShortBenchmark.direct | 272.375393 | 269.656569 | 0.9900180998 |
| byPrimaryConstructor.ShortBenchmark.wrapped | 297.234643 | 316.185681 | 1.063757837 |
スループットに関しては、想定通り基本的なケース全般で改善を確認できました。
特にシリアライズは10%、デシリアライズは7%程度と、Jacksonに関するその他処理が有る中ではそれなりの改善量が得られたことは良かったです。
ただし、恐らくベンチマーク負荷が軽すぎたため、型明示による最適化有無の差はそれ程確認できませんでした(これに関しては、逆に「何が何でも最適化しなければならないほどの差は無い」とも言えるでしょうか)。
シングルショットに関しては、初期化処理の量自体は増えているため、想定通りほぼ劣化となりました。
ただ、全体を通しても劣化幅は10%未満であるため、それ程酷くならなかった点は安心しました。
data classとの差についてdata classと比較した際のスコアは、残念ながらMethodHandle化後も大きいままでした。
経験上、恐らくLambdaMetaFactoryを使った方が高速ですが、以下の理由からJacksonではLambdaMetaFactoryを使わない方針となっているため、試していません。
ベンチマーク結果は以下に格納してあります。
一応比較用テンプレートも用意しているため、ローカルでの実行結果比較も可能です。
※2025/06/25時点の話なので、将来的には変わってるかもしれません。
JetBrainsの方より、クレジットを使い切ってしまった場合の対処は以下を参照するよう案内を頂きました。
Junieのクラウドクレジットは、ライセンスアクティベートから30日単位でリセットされる
これはFAQに記載が有りました。
When your monthly cloud quota is used up, cloud-powered features are paused until the quota resets.
The reset occurs every 30 days from the date you first activated your JetBrains AI license — whether free or paid — which may not necessarily coincide with the start of your billing cycle. Local features remain unaffected.
AI Ultimate契約の場合、サポートに相談できるらしい
これはメール問い合わせの返答からです。
This message is AI-generated based on our knowledge base, FAQ, and other similar requests. If it doesn't answer your question, please reply to this message.
ユーザー様
Junieのクラウドクレジット(AIクォータ)の管理についてお問い合わせいただき、ありがとうございます。
Junieのクラウドクレジットは月単位で管理されており、毎月初めにクォータがリセットされます。この月ごとのリセットは、月額契約・年額契約のいずれの場合でも適用されます。未使用分のクレジットは翌月に繰り越されず、また、将来の月からクレジットを前借りすることもできません。
月間クォータを使い切った場合、Junieを含むクラウドベースの機能は、翌月のリセットまで一時停止されます。AI Ultimateをご利用の場合、月間クォータを使い切った際にはサポートまでご相談いただけますが、追加クレジットの付与は保証されておらず、個別に対応させていただきます。
詳細はJetBrains AI FAQおよび価格ページをご参照ください。
ご不明点やご質問がございましたら、お気軽にお問い合わせください。
以下の記事から、週末のOSS開発でAI Proプランを使ってました。
開発出来なかった週も有った位なのに30日でクレジットを使い切ったので、業務レベル利用ならAI Ultimateプラン必須な感強いです(あるいは、クレジット節約術を探るべきなのか、、、)。
Intellijのプロジェクト設定だった(元から壊れているものが顕在化した)Project StructureからJDKを設定すれば直るはずだが、自分の場合何故か直らなかった.idea配下のファイルを弄って直した
pullし直した方が早いかも?プロジェクトのJDKを17 -> 21に更新した直後からビルドが通らなくなりました。
CIや他の方のローカルでは動いていたので、おま環と特定しました。
このような場合、基本的にはProject Structure -> Project -> SDKから適切なJDKを設定すれば直るはずです。
また、これがダメでも、Project Structure -> Modulesから、個々のモジュールのLanguage levelを設定する(Project defaultに合わせる)ことで直るはずです。
ただ、自分の環境ではこれをやっても直りませんでした。
確認していた所、プロジェクトの何かが壊れているようでした(gradle上ではJava 21になっているのに、従来のJava 17や、今使っていないはずのJava 18が指定されている状態だった)。
本来であればプロジェクトをcloneし直すとか、.idea配下を全消しした上でリロードすべきな気もしますが、消えてほしくないものが色々有ったため、手動での修復を試みました。
以下のような変更を行った後にIDEの再起動を行うことで、一旦テストは通るようになりました。
.idea/compiler.xml
<component name="CompilerConfiguration">配下のJavaバージョン設定削除.idea/gradle.xml
GradleProjectSettings配下のJavaバージョン設定削除.idea/workspace.xml
"jdk.selected.JAVA_MODULE": "corretto-18",の削除ただ、対処後も一部変なバージョンが残ってしまうなどの問題が有ったため、手動でもう少し直すことが必要でした。
環境はIntellij IDEA(Ultimate) in Windowsです。
PluginsからJunieのプラグインをインストールして始めました。
一応無料枠が有りました。
ただし、ちょっと触っただけなのに一瞬で使い切ったので、正直フリー状態で出来ることはほぼ無い感が強いです。
この記事執筆時点でAI Proを契約してましたが、週末OSS開発(しかも開発できなかった週有り)ですらクレジット使い切りました。
ガチで使う場合はちゃんとAI Ultimateを契約した方が良さそうです。
wrongwrong163377.hatenablog.com
具体的には以下のPRです。
既存と同じテストケースを、別の型に対して適用しています。
期待する変更内容としては、ファイル毎に分かれているものと、1ファイル内でのケース追加が有りました。
parameterSizeに関するケース(4ファイル・合計4千行弱)は生成できませんでしたが、他の17ファイルは期待通り生成できました。
生成できなかったケースは、恐らく元になるファイルがデカすぎてコンテキストウィンドウに収まらなかったものと思われます(タスクの進め方とかを指定したらやれたのかも……?)。
また、「このパッケージ内全体で適切に生成して」的な指示の出し方だと、深い階層にあるテスト?が無視されてしまい、追加で指示が必要となるケースが有りました。
具体的には以下のPRです。
この変更は以下のような手順で生成させました。
特に「既存ケースをベースにしたテストケース拡充②」の3で、自分でも発見できていなかったケースが生成されたことが非常に嬉しかったです。
他にも、単調で面倒なテスト作成作業をワクワクしながら進めることが出来て良かったです。
モチベ的な意味で作業速度が上がったのはいいことでした。
また、テストを実行しながら開発してくれるのは安心感が有って良かったです。
あまり長く触れていないので、まだ使いこなせていない・どこまでやれるか把握できていない感は強いです。
特に、指示後にPlanを吐いてくれるので、その辺りをもっとちゃんと確認すれば、より良い結果を得られるような気がしています。
IntellijのCopilot Chatも利用しましたが、コード編集に関する安心感はJunieの方が良く感じました(これに引っかかってまともに使えてないというのも有りますが……)。