Java17雑感
LTSとなるJava17が出ました。組織が今後もJavaを使っていけるかの試金石になるバージョンだと思います。
実際のとこLTSだから特別安定してるとかそんなことはないと思うし、6バージョン(3年)ごとにLTSにするってのもたぶんOracleさんが言ってみただけで、いろんなとこがそれに乗っかってるから、実質的に節目になってるに過ぎない。はず。 その程度のものなんだけど、私のようなのは乗っかりますし、たぶん多数派なんじゃないかなぁ……この派閥が運用で使うJavaのバージョンは8、11、17で、他のバージョンは評価に使うくらいでしょう。
11から17のジャンプになるんで、かなりたくさんの変更がありますが、業務アプリケーションの表層に関係するものはそこまで多くありません。パフォーマンスとかに影響のあるものは多々ありますが、基本的には早くなるはずで、問題になることは稀です。稀なことはよくあるんですが。
ということで、17にした時に業務アプリケーションの表層に影響のありそうなものを挙げて雑感を書いておきます。多分3ヶ月後くらいにはいうこと変わりますが。 JEPの名前とリンク、正式版として導入されたバージョンです。
- Text Block: JEP 378, Java15
- Switch Expression: JEP 361, Java14
- switch式です。
if式が欲しい - なんかswitchの強化多いんですよね。11以前はswitchなんて滅多に使わなかったけど、今後は見る機会が増えてくるかもしれません。
- とはいえ無理に使わなくてもいいと思います。いい感じに書けそうなら試す、くらいで。
- switch式です。
- Record: JEP 395, Java16
- 目玉。Java17を採用するなら使っていきたいかなーと。
- 私がよく見る「lombokを使いたい動機」のほとんどが消えます。Data以外にBuilderとか使い倒してたら引き続き出番はありますが。
- イミュータブルの強要、アクセサのメソッド名にgetがつかない、バインディングライブラリの対応状況など、地味なハードルはあります。
- とは言え無理に使わなくてもいいと思います。recordでなければできないことも今はないだろし。
- 2021-09-24追記: Recordを使ってく上で気にしとくこと 書いた。
- Sealed Class: JEP 409, Java17
- 他言語によく(?)あるSealedClassがJavaにもやって来ました。
- 挙げてはみたものの、今後の準備として入った程度の認識で良いかと。
- 使い方がこなれて、これを利用するものが増えてきてからでいいと思います。
- Pattern Matching for instanceof: JEP 394, Java16
- instanceofの後のキャストを書かなくて良くなります。
- ジェネリクス以降登場機会の激減したキャストさんの活躍場所がまた減った。
- 挙げてはみたものの、そもそもinstanceofを使う機会が少ないし、無理に使う必要は無いかと。
- 使える場面では喜んで使えばいいと思います。一行減るだけだけど。
五つだけ。まとめると「TextBlockをテストで使って、データクラスを新しく作るならRecordを使ってみる」くらいでしょうかねぇ。
コーディングにそう影響ないから挙げてないけど、個人的に一番嬉しいのはHelpful NullPointerExceptionsだったりします。下手にnullチェックして例外投げるくらいなら、チェックせずそのままNPE発生させる方が役立つ可能性まである気がしてたり。
細かいけど嬉しいの
String#formatted
Java12Stream#toList
Java16Collectors#teeing
Java12
ちょっと便利系。この辺のAPIはIDEが教えてくれるから、存在自体を知らなくても、使う機会が来たら使えると思います。
実際いつあげんの
- プロダクトはSpringBootがほとんどなんで、来週出るらしいJava17対応のSpringBoot2.5.5に乗っかる。
- 2021-09-24追記: Spring Boot 2.5.5 available now 出た。特別に17向けの何かはないけど、まぁ動いてる。
- その頃にはbuildpackも出るだろから乗っかってないのもいけるかなって。
- Java16で動かしてるものは軽い気持ちでコンパイルから全部17にあげる。
- Java11のは検証環境のランタイムだけ17にしてしばらく回してから。
そんな感じ。
まともな情報
- きしださんとこ の「Java XX新機能まとめ」シリーズ
- さくらばさんとこの「JEPでは語れないJava XX」シリーズ
- てらださんのJEP一覧
とりあえずSpringBootアプリケーションをherokuで公開する
手順の全て
mkdir {てきとうななまえ}
cd {てきとうななまえ}
curl -O https://start.spring.io/pom.xml -d dependencies=web -d javaVersion=8
- Applicationクラス作成(後述)
git init
git add .
heroku create
heroku git:remote -a {createで作られたもの}
git push heroku main
9ステップ。これでgit push
のレスポンスメッセージに出てるURLにアクセスしたらhello
と表示されます。目指せ5分!
説明
書きたいところを適当に書いていきます。あ、herokuアカウントの作成とコマンドラインツールのインストールは済ませといてください。私はbrew
で入れてます。
この記事は現在に対する局所最適なので、バージョンなどは割愛します。 未来にこの記事のバージョンに合わせて動かすより、やりたいときにその時点での最新のやり方でやるのがいいと思います。 どうせherokuの挙動変わったらバージョンなんぞ合わせられないし。
curl...
Spring Initializr です。ブラウザでも使えますけど私はもっぱら curl
で叩いてます。
詳しくは SpringBootのプロジェクトを作成する - 日々常々 とか。
普段はGradle使っていますが、今回はMavenを選択。
これは plain jar
がSpringBoot2.5からできるようになって、herokuのデフォルトだと *.jar
で起動しようとしてエラーになるため。
無効にするとかexecutable jar
を実行するように明示するとかすればいいんだけどステップが増えるので今回は回避しています。
-d dependencies=web
はこれがないとウェブアプリケーションにならないので。(webflux
でもいいんだろけど)
-d javaVersion=8
がポイントでherokuのデフォルトJavaバージョンは1.8だったりします。SpringInitializrデフォルトは11なんで、そのままじゃ動かない。
pom.xml
を修正したり、system.properties
(herokuが読む設定)に java.runtime.version=11
とか書いてもいいんだけど、今回は一番ステップが少なくなるの選びました。
普通は system.properties
書くことになると思います。書けばJava16も使えるよ。実際いくつかで使ってたりします。
Applicationクラス作成
コマンドだけで無理やり作るとこう。
% mkdir src/main/java/hoge % cat>src/main/java/hoge/Application.java package hoge; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @SpringBootApplication @RestController public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @RequestMapping String index() { return "hello"; } }
1クラスとはいえIDEで書くのがなんだかんだで早いと思う。importとか書いてられん。
(とはいえIDEで書くと後の git add .
が .
じゃ余計なものが入るので pom.xml
と Application.java
だけaddしなきゃになって若干面倒にはなる。些細な問題だけど。)
@Controller
でなく @RestController
なのはハンドラメソッドの戻りで文字列を直接返したいから。@Controller
だとテンプレート探しに行ってエラーになって /error
なくて404になっちゃう。@ResponseBody
とか書けばいいんだけど面倒だから @RestController
にしちゃった。
あとデフォルトパッケージにすると余計なものコンポーネントスキャンで食っちゃうので、適当でもいいんでパッケージはつけなきゃです。
heroku create
ログインしてないとこれ叩いたときに自動でログイン促されます。ブラウザが開く。
heroku create
は apps:create
の短縮。アプリ名を渡せるけど、指定しなかったら適当につけてくれる。今回はお任せ。
これだと salty-woodland-12925
ですね。(destroy済み)
次の heroku git:remote
は git remote add heroku {herokuのgitのURL}
を代わりにやってくれるコマンドです。git
コマンドを叩いても一緒なんでお好きな方でOK。gitのURLもcreate
時に出てますしね。
ここに push
したらherokuはビルドして動くようにしてくれます。
git push
ソースコードを投げ込むといい感じにビルドしてくれるのがbuildpack。
「pom.xml
があるからMavenだろ」「SpringBootだからこうだろ」みたいなのを雰囲気でやってくれます。
雰囲気でやってくれすぎて何がどうなってるか分からなくなる可能性がそこそこ。
わかりたかったら https://buildpacks.io/ とかで pack
コマンド使って手元でビルドして docker run
とかいじってみると、何かわかるかもしれない。わからないかもしれない。
git push
したらMavenのいつものjarダウンロードのログがダラダラ流れる。git push
でそんなん表示されるのに慣れてないと面食らうかもですね。
成功したらこんな感じ。
Released
とかの次の行の https://... を開いたら動いてる。はず。
今回はherokuのgitにpushしたけど、普段はGitHubからherokuに繋いで使ってます。この辺の連携も素直につながるのでいいですよね。
あとがき
適当にやろうとしたら地味なつまずきかたをしたので整理してみました。 ビルドは3分くらいで終わるんで、スムーズにできれば「ゼロから始めて5分でデプロイ完了」までいけると思います。ドラが鳴る前に終わることを祈る。
今回つまづいたのは
*-plain.jar
のおかげでGradleだと素直に動かない。build.gradle
のjar
タスク止めるか、Procfile
(herokuの設定ファイル)で動かすJar名を明示したらいける。普段は後者でやってる。
- デフォルトJavaバージョンの食い違い
pom.xml
とかbuild.gradle
のバージョン読んでくれるようにきっとそのうちなると信じてる。
……くらいかな? こういうの踏んだときに雰囲気で察しちゃったりするんだけど、「ここにこのログが出てる」と確認しておくのも大事で、そういうのがこの手の素振りの目的だったりもします。
herokuでMaven使った記憶はないんだけど、「どうせいけるだろ」みたいなノリで push
したらいけました。よかったよかった。
この「どうせいけるだろ」みたいな感覚って結構大事だと思ってたりします。たまに大外しするけど。
追記: タイムアタック結果
- start:
2021-08-05T11:20:11
- finish:
2021-08-05T11:22:08
コマンドのみの一発勝負。1分57秒でした。 mkdirから最後にcurlでhelloが返って来るところまで(curlのhello確認は上の手順にないですが。)で、全ログは gist に置いてます。 少し上で「ビルドは3分」とか書いてますが、herokuのご機嫌によりますね。
…… git init
がReinitialized
になってるな。空じゃなかったのか。🤔
似た記事
「ソースコードの公開まで」って感じですね。今回のは手元の動作確認すらしてないという・・・。
アームがないモニターアームを買ってみた、その後
ということです。
- 移動に自由度がない。上下移動するにはネジまわさなきゃで面倒。
- デッドスペース(10数センチ)を許容するには机が小さすぎる
- モニターの上下移動は使いづらい。上端、下端でとまらないからカーソルが行方不明になる。
あたりが理由。
ちなみに他のモニターアーム。
写真の通り、結局エルゴトロンにしてます。
マットブラックにしてみた。格好いい(黒が好きなアレです)。
台座はそこそこ大きいから複数並べると邪魔になるんだけど、追加モニターアームも売ってるし、1つ目の台座に2つのアームつけちゃってます。
追加用を買わなかったのは台座がほしくなることもありそうだから……値段も大差ないし。