« 2022年9月 | トップページ | 2022年11月 »

2022年10月

2022/10/21

Javaのモジュールシステムの考え方をまとめてみた

Javaのモジュールシステムの理解が深まったのでメモ。
Java初心者のラフなメモ書き。

【1】モジュールシステムはなぜJavaで必要なのか?

異なるJarであっても、同一パッケージ名が衝突する問題があった。
モジュールは、パッケージを区別するための仕組み。
パッケージはクラスを包み込み、モジュールはパッケージを包み込む。

Javaはオブジェクト指向言語なので、機能追加したい場合、開放閉鎖原則に従って、既存クラスは修正せず新規クラスを追加する。
Rubyのオープンクラスみたいなもの。
すると、クラスがどんどん増えるので、パッケージでクラスを分類しようとする。
そして、パッケージをまとめたJarを配布して、開発者に利用してもらうようにする。

しかし、Jarファイルもどんどん増えてしまって、異なるJarなのに同一パッケージで衝突する場合がある。
Mavenでこういう依存ライブラリのJarを管理するけれど、名前衝突が多くなるのだろう。

【2】なぜ、無名モジュール、自動モジュールは必要なのか?

Java9以後はモジュールシステムを使う必要があるが、以前のJara8のJarファイルはモジュールに対応していない。
Java8のJarファイルを利用できるような環境としてモジュールが導入された。

基本は、Classpathにある無名モジュールが一般的だが、modulepathにないので、名前付きモジュールから無名モジュールを読み込めない。
そこで、modulepathにJarファイルを置いて、自動モジュールに変更して、名前付きモジュールから自動モジュールを読み込めるようにした。

実際の現場を見ると、Java8までで止まっているWebシステムは割と多いように感じる。
たぶん、Java9以後のモジュールシステムに対応するように、移植するのは難しい場面があるからだろう。

【3】無名モジュール、自動モジュールとは何か?

無名モジュールはJava9以前のJarで、Classpathにある。
以前のコマンドみたいに、java -cp **.jarみたいに使う。

なお、無名モジュールのJarはclasspathにあるので、名前付きモジュールから読み込めない。

自動モジュールはJava9以前のJarで、ModulePathにある。
java --module-path **.jar とか、java -p **.jarみたいに使う。

名前付きモジュール--> 自動モジュール、自動モジュール --> 名前付きモジュールの両方で読み込める。
なぜならば、modulepathに名前付きモジュールも自動モジュールも両方配置されているから。

なお、無名モジュールも自動モジュールも、パッケージのクラスは全て公開されているから、モジュールシステムのように公開の制限はできない。

無名モジュールはJDK9以前のライブラリ。
module-info.javaもMETA-INF/MANIFEST.MFもない。
ClasspathにJarを配置していると、java --module-path **.jarが使えない。

自動モジュールは、META-INF/MANIFEST.MFにAutomatic-Module-Name属性が指定されている or jarファイル。
JDK9以後は、java -p **.jarで実行する。

自動モジュールはできるだけMETA-INF/MANIFEST.MFにAutomatic-Module-Name属性を指定する。
なぜならば、Jarファイル名は書き換えられやすいので間違いやすい。
META-INF/MANIFEST.MFに記述すれば、Jarファイル名が書き換えられても呼び出されるJarは同じになるので安全。

【4】jlinkはなぜ必要なのか?

専用のランタイム用アプリを作りたい。
JDK9以後は、JREがないから。

さらに、クラウドのサーバーレス環境でアプリを実行する時、コンパイルしたアプリのサイズを小さくできる。
クラウドのリソースを抑えられるし、アプリの起動時間(ロード時間)も短くできるメリットが出てくる。
つまり、AWS lambdaみたいに、イベント駆動で多数のプロセスを並行起動するような場面では、アプリサイズが小さいほど性能も良くなるし、デプロイもやりやすい。

たぶん、クラウドの開発に特化するようにJavaも進化してきているのだろう。

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

【5】jdeps --jdkinternal はなぜ必要なのか?

JDKの内部APIでクラスレベルの依存関係を検索するためのコマンド。
古いJava8のJarファイルがどんなJDKライブラリを使っているか調べるために使う。
Java9以後は公開されていないJDKライブラリは排除していくべきという考え方。

Java9のモジュールへ移行する時や、jlinkコマンドで小さい専用ランタイムアプリを作りたい時に利用できるだろう。

【6】なぜServiceLoaderは必要なのか?

ServiceLoaderは、Java9以前で依存性注入(DI)を実現する方法に過ぎない。
たとえば、Sampleインターフェイスだけ公開して、SampleImpl実装クラスは呼び出さないように実装したい。
META-INF/servicesに、実装クラスを記載したテキストファイルを作って、ServiceLoaderが読み込んで動的に切り替える仕組みにしただけ。

Java9のモジュールシステムでは、ServiceLoaderを利用する場合、module-info.javaにprovides~with~でIFを書いて公開する。

「公開IFの提供」をmodule-info.javaで宣言する => provides 公開IF with 実装クラス(SPIを実装)
「公開IFの利用」をmodule-info.javaで宣言する => uses 公開IF名(SPIとして使う)

ServiceLoaderはJDBCドライバの実装にも使われているので、わりと一般的。

【7】Javaのモジュールシステムは、Javaの進化でどのような意義を持つのか?

モジュールシステムは、Javaをクラウド開発に適用したり、デプロイしたモジュールやライブラリの移植性を高めるために必要なのだろう。
しかし、Javaは過去の遺産が多すぎるために、どんどん仕様が複雑になってきていると思う。

実際、Jarの依存性のエラーメッセージの種類が多くなっているために、問題解決するのは大変だろうと想像する。

Javaのモジュールシステムは複雑性をより増している: プログラマの思索

一方、Javaはオブジェクト指向言語だけでなく、関数型言語の一面も持つ。
実際、OptionalやStreamなどのモナドのAPIはまさに関数型言語そのものだ。

Javaが関数型言語の特徴を持つようになった理由の背後には、クラウド上で多数のプロセスを並行で動かす時に、MapReduceの仕組みがあれば、負荷分散をより活用できるメリットを活かしたいからだろう。

Javaはオブジェクト指向言語ではなく関数型言語だった~「[増補改訂]関数プログラミング実践入門」はお勧めの本だ: プログラマの思索

Javaはなぜ関数型言語になろうとしているのか: プログラマの思索

JavaSilverの感想~Javaはオブジェクト指向と関数型言語の2つの性格を持つ: プログラマの思索

そんなことを考えると、20年前にUMLやJavaを使って、オブジェクト指向設計に熱狂していた時代はもう古くなっている。
そういう価値観はもはや終わったように思える。
そして、時代は更に進化しているわけだ。

一方、その進化はどんどんソフトウェアの複雑性を増やす。
ソフトウェアの本質は複雑性にあるが、その複雑性をどのように手懐けてコントロールすべきなのか?
今も昔もソフトウェア開発はこの問題から逃れられない。

| | コメント (0)

astah* Mermaid Pluginが公開された

astah* Mermaid Pluginがあるらしいのでメモ。

【参考】
astah* Mermaid Pluginをリリースしました! | astah in 5 min

Mermaid記法の書き方(Markdownテキストでチャート・グラフが描ける) - NotePM

Markdownでシーケンス図とかが書けるMermaid記法で業務フローを書いたら意外とイケたので自分なりのコツを紹介してみる | DevelopersIO

mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.

astahにMermaidプラグインを入れてみたら、既存のクラス図やシーケンス図から簡単にMermaid のソースを抽出できた。
Mermaid のソースはPlantUMLみたいに簡単。
直感的に読める。

Mermaid はUMLだけでなく、ER図やガントチャートも書ける。
つまり、設計書の図はMermaid で代用できるし、ガントチャートもMermaid で書いてしまえばいい。

なぜならば、Excel設計書は重たいし、修正に手間取るし、共有しにくいからだ。
設計書はMarkdownとPlantUMLやMermaidだけで、全てテキスト化すべきだろう。
そうすれば、Githubにソースコードと一緒に放り込んで、いつでもマニュアルとしてビルドして納品することも可能だ。
以前、そのようなアイデアも書いた。

PlantUMLを使ってExcel設計書をテキスト化するアイデア: プログラマの思索

仕様書にもExcel脱却が求められている: プログラマの思索

astahには、PlantUMLプラグインも既にある。
Mermaidも一緒に使うと便利かもしれない。

astahとPlantUMLを行き来できるastah* PlantUML Pluginが面白い: プログラマの思索

| | コメント (0)

2022/10/16

クラウド上の開発がJavaに与えた影響は何なのか

クラウド上の開発がJavaに与えた影響は何なのだろうか。
考えがまとまっていないがラフなメモ。
自分はAWSも知らないし、Go言語も知らないので、間違っていたら後で直す。

【参考】
Javaがサーバレスに至るまでの道のり

元JavaエンジニアがGoに感じた「表現力の低さ」と「開発生産性」の話 - DMM inside

Ruby->Go->Scalaという習得順序がエンジニアの爆速の成長に最適である理由 - Qiita

Javaがサーバレスに至るまでの道のりの記事を読むと、いかに軽量のWebアプリケーションを実現するか、に注力しているように思える。

従来のWebアプリケーション開発では、PerlのCGIのようなプロセス指向ではなく、JavaのServletのようなマルチスレッドの方が無駄にリソースを食わず、効率が良いと歌われていた。

しかし、サーバーレス環境では、AWS Lambdaのようにアプリをキックするような仕組みなので、アプリの処理時間だけでなく、アプリのロード時間も短いほど優位だからだ。
サーバーレス環境では、アプリを常駐させて、マルチプロセスで動く。
そして、処理が終わり、無駄に多くなったプロセスはすぐに破棄される。

つまり、クラウドでは、DockerやK8sのようなコンテナのおかげで、アプリ環境を使い捨てにできるメリットがある。
アプリも、負荷分散に応じて必要なだけ常駐プロセスを増やして、不要になれば捨てればいい。

すると、アプリのビルド、デプロイの時間も短い方がいい。
さらに、「起動時間がレスポンスタイムに含まれる」ために、アプリの起動時間も短くできれば、サーバーレス環境ではレスポンスタイムをもっと短くできて、使い勝手が良くなる。

そういう発想がJavaにどんな影響を与えているのか?
クラウド上の開発がJavaに与えた影響は何なのか?

たまたま、Javaのモジュールシステムの話の中で、jlinkコマンドがなぜ必要なのか?という話があった。
JDK9以後は、JREが配布されないので、Javaファイルを実行できない。
そこでjlinkで実行ファイルを作る必要があるという話だったが、さらにもう一つ興味深い話があった。

Java Module System 入門 その1 - YouTube

Java Module System 入門 その2 - YouTube

jlinkコマンドを使うとランタイム専用アプリを作れるが、必要なJDKライブラリだけを読み込んで、Jarファイルを作成する。
すると、jlinkで作られたランタイム専用アプリのサイズは、従来のランタイム専用アプリのサイズよりもかなり小さくなる。
不要なライブラリを除いているからだ。
実際、デモ画面では200Mから30Mまで小さくできた例があった。

つまり、jlinkコマンドを使えば、クラウドのサーバーレス環境でアプリを実行する時、コンパイルしたアプリのサイズを小さくできる。
その分、クラウドのリソースを抑えられるし、アプリの起動時間(ロード時間)も短くできるメリットが出てくる。

すなわち、jlinkコマンドはクラウド上で配布するアプリに適合するように作られたものなのだろう。
Javaもクラウドに特化したアーキテクチャ設計を取り込んでいるのだろう。

そんな話を聞くと、サーバーレス環境のアプリでは、ランタイム専用アプリはバイナリファイルでサイズが小さいほど優位性が高いことになる。
マイクロサービスの実装言語はGoが主流であると聞くが、その理由は、Goで簡単にバイナリファイルが作れて、さらにそのサイズが小さいので、性能的にも優れている点があるのではないだろうか?
そして、Javaもそういう流れの設計手法を取り入れるために、jlinkコマンドのようなアーキテクチャが必要になってきたのではないだろうか?

ここで、クラウド上のシステム設計では、ドメインごとにアプリを細分化したマイクロサービスアーキテクチャが流行していて一般的になってきている。
マイクロサービスアーキテクチャが必要な理由は、普通のWebシステムでもクライアントからのアクセスがブラウザだけでなく、スマホだったりタブレットだったり、色んな端末に対応する必要があるので、公開APIを通じて制御できるよに、色々分割したほうが楽になる点があるだろう。
また、逆コンウェイ戦略のように、システム開発しやすいチーム組織の観点で設計すると、小さなコンポーネントの集まりになるようにシステムを分割して、マイクロサービスアーキテクチャで連携できるようにした方がよい点もあるだろう。

マイクロサービスアーキテクチャのそんな特徴を活かすには、おそらく、Go言語やjlinkコマンドのような実装言語やビルド方法も必要になってくるのだろう。

そんなことを考えると、クラウド上のシステム開発では、フロントWebシステムをRubyやJava、Pythonで作ったとしても、AWS lambdaやマイクロサービスの部分はGo言語やjlinkを使う、といったように、複数のプログラミング言語を適材適所に当てはめて開発する必要性があるのではないか。
つまり、クラウド上の開発は、単にコンテナ部分のアーキテクチャを使いこなすだけでなく、複数のプログラミング言語を適材適所で使い分けるノウハウも必要になってくるのだろう。

この辺りは妄想に近いかもしれないので間違っているかもしれない。
ただ、クラウドというアーキテクチャは、Webリソースをふんだんに使える富豪プログラミングを可能にしたからこそ、それに特化した設計手法がどんどん現れているのだろうと思う。

この発想が正しいのか、これから検証していく。

| | コメント (0)

2022/10/02

TwitterやFacebookは人力キュレーションツールとして使う

TwitterやFacebookの使い方がコロナ禍で変わったように思う。
TwitterやFacebookは人力キュレーションツールとして使うべきだ。
ラフなメモ。

【参考】
Twitterは最速のメディア: プログラマの思索

ビジネス特化SNS「Linkedin」から見えるもの~人脈はデータマイニングで作られる: プログラマの思索

Facebookはセルフブランディングの最強ツール: プログラマの思索

MEDIA MAKERSの感想: プログラマの思索

Clubhouseは路上ライブや朗読のためのツールかもしれない: プログラマの思索

「現代病「集中できない」を知力に変える 読む力 最新スキル大全」の感想: プログラマの思索

たとえば、コロナの情報を知るには、新聞やテレビ、書籍では不十分だ。
なぜなら、まだその知見や真実が最新論文にしか存在せず、それを解説する情報が新聞やテレビ、書籍にはないから。
だから、医療現場でコロナ患者に対応している医者、コロナワクチンを研究している医療研究者、コロナウイルスの流行を予測する疫学者から情報を収集すればいい。
すると、彼らはTwitterで情報を流しているので、彼らを特定してツイートを逐次読めばいい。

実際、武漢ウイルスからデルタ株、オミクロン株へ変異するうちに、コロナの毒性やかかりやすさもどんどん変化している事実が分かったし、mRNAワクチンのおかげで沢山の人が助かった事実もわかってきたわけだ。

また、Twitterのインフルエンサーのうち信頼できる人達を集めてみると、その分野で専門的知識や専門用語を正しく使えて、その専門知識を一般人にもわかりやすく説明できる能力を持っている傾向がある。
また、インフルエンサーで能力のある人は、他人をけなす言葉は言わないし、人格的な面が言葉に出てきている場合が多い。
僕も、専門知識を使えないインフルエンサーはできるだけ排除しようとしている。
つまり、SNSを集合知として扱うメリットがある。

Facebookの友達関係では、ビジネル上の人間関係から発生する事が多く、同じ業界や同じ興味を持つ仲間が多い。
その集団からの情報発信を集めることになる。
つまり、彼らの興味から発信した情報は、自分にも有用であるケースが多いから、Facebookは友人がわざわざ発信した情報を読むだけで最新情報を入手できる。

たとえば、IT業界にいれば、アジャイル界隈の人達とたくさんFacebookの関係を作っておけば、勝手にアジャイルの最新情報は入手しやすい。
税理士、行政書士、中小企業診断士のような士業も、Facebook上でコミュニティを作る場合が多いので、最新のセミナー情報や補助金、お仕事の情報を集めやすくなるメリットがある。

以前は、TwitterやFacebookなどのSNSは無駄な情報が多く、遊びでしか使っていないイメージが多かったが、今は違う。
そんな経緯を踏まえると、TwitterやFacebook、LinkedinなどのSNSは情報収集ツール、人力キュレーションツールとして使うべきだ。

換言すれば、SNS上の人間関係が深い人ほど、最新情報を入手できて、正しい意思決定により近づける可能性もあるのだろう。

| | コメント (0)

計量政治学と計量経済学の考え方の違い

経済セミナー2022年10・11月号 通巻728号【特集】いま、政治の問題を考えるを読んでいたら、計量政治学と計量経済学の考え方の違いの記事が面白かった。
以下はラフなメモ書き。

機械学習で反実仮想や自然実験が作れる: プログラマの思索

Pythonで微分積分や統計の基礎を理解しよう: プログラマの思索

経済学は信頼性革命や構造推定により大きく変貌している: プログラマの思索

経済学や心理学の実験で得られた理論は再現性があるのか?~内的妥当性と外的妥当性の問題点がある: プログラマの思索

Rによる計量経済学/計量政治学を読んでいる: プログラマの思索

【1】計量政治学と計量経済学の考え方の違い

政治学の方が特定地域のこだわりがある。
たとえば、NPO法人や政治家にインタビューするために、現地言語を習得したり、その国の文化に慣れる必要がある。
経済学はそこまでこだわらない。

一方、政治学は理論と計量をそこまで区別しない。
政治学は定性データを重視するし、時事問題を重視する。
たとえば、リーマン危機、ウクライナ戦争など。
しかし、経済学では、理論と計量を区別し、過去に蓄積してきた理論を使って、計量データを用いて、政策の効果を測定したりする。
だから、経済学では、理論の人は計量の論文を読め、計量の人は理論の論文を読め、と言われるらしい。

【2】計量政治学から得られた経験則

独裁者は暴力行使の利益とコストを勘案して多様な手法で大衆を制御しようとする。
ここに独裁者のジレンマがある。
権威主義的な国の選挙は実行がすごく難しい
選挙の不正がなければ、野党や反体制の人達がのさばり、自分たちの権力を脅かそうとする。
一方、選挙で不正を実施しすぎると、本当の支持率が分からないし、どこの地域が支持率が高く、どこの地域に反体制の人達が実は多いのか、分からない。
つまり、自発的な支持が得られないので、実は権力基盤が脆い事実を国民の皆が知っている。
だから、権威主義国の独裁者は実は裸の王様。
だから、独裁者は、自分の支持率はじつは高いのだ、というシグナルを国民に知らせる必要があり、あの手この手を使っている。

また、農業主体の国は人々が散在しており、組織化しにくい。
つまり、一体化して反抗しにくい傾向があるらしい。
すなわち、都市化した国の方が、民衆が組織化しやすく、一致団結しやすいので、民主化しやすい傾向があるらしい。

この話を読んで、フランス革命は実はパリ革命だった、という話を思い出した。
なぜなら、フランスは中央集権の王権国家であり、パリに人民も富も集中していたので、パリで体制変革されると全土にその余波が行き渡っていたから。

【3】民主化はいつどのように起きるのか?

色んな国の統計データを調査すると、与党と野党の間に、権力基盤の合意がある前提があるらしい。
つまり、信憑性のあるコミットメントが存在している。
だから、クーデターや内戦のような暴力行為による政権交代は必要なくなる。
たとえば、韓国や台湾、南アフリカなどがその事例に相当するだろう。

【4】計量政治学に機械学習や深層学習を用いて得られたノウハウ

権威主義国では統計データを不正に操作しているので信頼性が低い。
だが、夜間の光量データから経済活動の活発さを見る、という手法を取ることもできる。
その場合、衛星からの画像データをCNNに食わせて、計測アルゴリズムを作り出す、というやり方も取れる。

すると試行錯誤による発見的予測アルゴリズムの成果はどうだったのか?
4つある。

1つ目は、本来のアルゴリズムは藪の中。
真の因果関係を表すアルゴリズムは不明だった。
特に、深層学習の場合は、予測できたとしても説明可能性は低い。
正しいモデルアルゴリズムにこだわるのは不毛なことがある。

2つ目は万能なアルゴリズムは存在しないこと。

3つ目は、次元の恵みを活用せよ。
説明変数の次元が増えるほど、必要なデータ量は指数関数的に増えて計算できなくなる。
つまり、次元の呪いが発生する。

そこで、次元の呪いを解決するために、予測に必要な説明変数を絞り込む変数選択、過学習を防ぐ正則化などを用いる。
しかし、予測に使える変数は全て投入して、次元の恵みを最大限活用する方法もあるのでは、と。

4つ目は、予測可能性と説明可能性のジレンマがある。
深層学習は、予測性は高いが理屈は複雑で説明しにくい。
一方、線形回帰や決定木は、予測は微妙だが説明しやすく、因果関係を明確にしやすい。
そういうトレードオフがある。
つまり、政策介入の因果関係としての効果を測定することと、機械学習による予測は完全に調和しないのだ。

僕はこのトレードオフは、実際の政策を実行する上で、ハードルが高くなるリスクがあると思う。
たとえば、財政出動や補助金をばらまく政策を実行する時に、これだけの効果を予測できます、とアナウンスすることで、国民や利害関係者を納得させたいが、その効果の因果関係を説明できなければ、本当に効果があるのかと疑問に思う人も増えて、その制作に反対する人が増えてしまい、せっかく期待していた効果が実行しても得られないリスクが出てくるからだ。

経済学のルーカス批判のように、政治学でも自己予言的なリスクがあるのかもしれない。

| | コメント (0)

« 2022年9月 | トップページ | 2022年11月 »