Gleyzer両氏によって共同開発されました。2019で、同言語の発表を行いました。InfoQはPurdy氏に言語と、氏らが解決を目指した問題について聞きました。設計/アーキテクチャアジャイルマニュフェスト:ソフトウェアアーキテクトの視点ソフトウェアアーキテクトの役割と責任はアジャイルソフトウェア開発のためのマニフェストの価値と矛盾していると見えますが、優れたアーキテクトはアジャイル開発チームをサポートするテクニックを見つけています。Streamingは、ストリーミングデータのためのSQLライクなインターフェースを提供します。Streamsによって、Redisがストリーミングデータを複数のプロデューサとコンシューマの間で消費、保持、配信することができるようになります。ソフトウェア開発のマニフェストたゆまず息もつかずに市場に突進することで、会社を静かに消滅の崖っぷちへと追い込みます。それは設計してコードを書く方法を再考する時です。簡単さへの投資は、速さへの投資です。簡単さは知的財産の主鉱脈でもあります。競争上の優位性は、一度失ったら、もう一度手に入れることはほとんど不可能です。Buytaerts氏が過去10年間にわたって、企業がDevOps採用のハイプサイクルをくぐり抜け、変革に対する誤解を解消する過程を支援してきた経験について語ります。原文(投稿日:2009/09/23)へのリンクここ数年にわたって、Javaのモジュール化は活発に議論され続けている話題である。294にいたるまで、モジュール化はJavaの進化における必要なステップであるとみられている。ScalaのようなJVMベースの将来の言語でさえモジュール化について検討している。Javaに関する一連の記事の最初となるこの記事では、モジュール化とは何を意味し、なぜそんなことを気にしなければならないのか、について議論する。モジュール化とは何か?モジュール化は個々のモジュールを開発することができるようにする方法をソフトウェアの開発に対して適用する一般概念である。各モジュールは多くの場合、モジュールがやりとりをするための標準化されたインターフェースを持つ。実際のところ、オブジェクト指向言語におけるオブジェクト間の関心の分離のようなものは、その規模がより大きいことを除いてまったく同じ概念である。システムをモジュールに分解することによって、結合度を最小化することができ、それによりコードの維持管理をより容易にすることができる。関連スポンサーコンテンツJavaは(導入時にModula-3モジュールになぞらえたというpackage以外には)モジュールのことを念頭において設計されてはいなかったにもかかわらず、Javaコミュニティでは多くの事実上のモジュールが存在している。Log4JからHibernate、Tomcatにいたるまで、どんなJavaライブラリも事実上モジュールである。一般的に言って、オープンソースのアプリケーションもクローズドソースのアプリケーションもいくつかの外部ライブラリへの依存性を持っているはずであり、それによって結果的にさらに別のライブラリへの依存性を推移的に持つことになる。ライブラリもモジュールであるライブラリは暗黙的なモジュールである。ライブラリは必ずしもやりとりするための単一のインターフェースを持っているというわけではないだろうが、多くの場合(使われるためにあるべき)'パブリックな'APIとユースケースを文書化する'プライベートな'パッケージを持っている。それらのライブラリは(JMXやJMSといったライブラリへの)依存性をそれら自身持っている。この結果、自動依存性マネージャは、正確に必要としているよりもずっと多くのものを持ち込むことになる。Log4J-1.2.15の場合には、10以上の(javax.mailやjavax.jmsを含む)ライブラリ依存関係を持ち込むが、これらの多くはLog4Jを使用するプログラムではまったく必要とされないものである。いくつかの場合には、モジュールの依存関係は任意である。モジュールは依存モジュールを欠落させることで機能の一部のみを提供する。前述の例では、JMSが実行時クラスパス上に存在しなければ、JMSを使ったロギングは利用可能ではないが、他のメカニズムが利用可能になるだろう。(Javaはこのことを遅延リンクによって実現している。遅延リンクとはクラスがアクセスされるときまでに存在していればよく、依存ライブラリが見つからない場合には適切なClassNotFoundExceptionによって扱う仕組みである。他のプラットフォームには実行時チェックと全く同じものを提供する弱いリンクを持つものもある。)一般に、モジュールにはバージョン番号が割り当てられる。多くのオープンソースプロジェクトはlog4j-1.2.15.jarのように名付けられたリリースをつくる。これによって開発者は、実行時の手動検査によってではあるが、オープンソースライブラリの特定のあるバージョンが使われているかどうかをクラスパスを調査することによって決定することができる。プログラムは異なるバージョンのライブラリに対してコンパイルされていることが多い:暗黙の仮定はlog4j-1.2.3.jarに対してコンパイルしてlog4j-1.2.15.jarに対して動かしても挙動としては互換性がある、ということだ。2.0を作り出すことになった理由である)。これらの多くは一般的に制約よりもむしろ実行時に知ることができる規約をもとにしているのである。どんなときにモジュラリティが有効なのか?モジュラリティはアプリケーションを異なる部分に分解するための一般的概念として有用である。それによって、別々にテスト(そして進化)することができる。上述の通り、多くのライブラリはモジュールであるため、ライブラリを作り出す人にとってもライブラリを使う人にとっても、モジュラリティは理解すべき重要な概念である。pomやivy-moduleなど)にエンコードされており、ライブラリの利用方法の記述の中に明示的に文書化されている。上位のライブラリが下位のライブラリのバグの回避方法を組み込むことも珍しくなく、最新バージョンの下位ライブラリが修正されたとしても、上位レベルライブラリでの違和感のない使用感を提供するために組み込まれることもある。(時にこのことが微妙な問題を引き起こしうるけれど。)もしライブラリが他の人が利用するためにビルドされているならば、それだけで暗黙的にはモジュールである。World”モジュールも多くは存在しない。アプリケーションが十分に大きくなったとき(あるいは、十分にモジュール化されたビルドシステムで構築されたとき)にはじめて、アプリケーションを論理的に異なる部品に分割するという概念が効果を発揮する。モジュール分割の恩恵の一面はテストの側面である。(適切に定義されたAPIを持つ)小さなモジュールは一般に一枚岩のアプリケーションよりもテストがしやすい。このことは特にGUIアプリケーションであてはまり、GUI自身は簡単にテストすることができるわけではないかもしれないが、GUIが呼び出しているコードは比較的簡単にテストすることができる。一つの側面は進化の側面である。システムは全体としてバージョン番号を持つけれども、現実的には表には現れない複数のモジュールやバージョンが組み合わせられた製品である。結果的に、各モジュールはそのモジュールにあった方法で自由に進化することができる。他のモジュールに比べて早く進化するモジュールもあるし、その一方で長い期間変化する必要のないくらい安定なものもある。3.5にはorg.eclipse.core.bootがあるが、これは2008年2月から変更されていない。)プロジェクト管理もモジュール化から恩恵を受ける。一つのモジュールが公開APIを持って他の人がそれに対するコードを書くことができるようになれば、別のチームが別のモジュールを実装することが可能である。このことは、大きな規模のプロジェクトではどうしても避けられないことであり、サブチームに別のモジュールの納期に対して責任を持たせることができる。アプリケーションをモジュール化することは依存するライブラリのどのバージョンを利用しているかを明確に識別することを可能にし、大きなプロジェクト全体のライブラリの依存性の調和に役立つ。実行時vsコンパイル時Javaは一般に、コンパイル時か実行時かにかかわらずフラットなクラスパスを持っている。アプリケーションは普通クラスパス上にみつかるどんなクラスにたいしても、(少なくともオーバーラップのない前提では、つまり最初に見つかったものを採用する前提では)クラスパスでのエントリの順序にかかわらず完全な可視性を持っている。このことによってJavaでは動的リンクの機能が実現されている。クラスパスの前方からロードされたクラスは、クラスパスの後方のクラスの全ての参照を実際に必要とされるまで解決する必要がない。このことは、実装が実行時まで不明であるようなインターフェースの集合を機能させるために頻繁に利用されている。SQLユーティリティは一般的なJDBCパッケージに対してコンパイルされているが、実行時には(設定情報をいくつか加えて)正しいJDBCドライバをインスタンス化する。これは一般的には(事前に定義されたファクトリインターフェースか抽象クラスを実装する)クラス名を実行時にClass.forNameルックアップで与えることで実現している。その結果、コンパイル時のクラスパスがモジュールの実行時のクラスパスと(微妙に)異なることは起こりそうなものである。1.2に対してコンパイルされるというように)単独でコンパイルされるが、実行時には一つのパスの中に結合される(今回の例では、モジュールCのバージョン1.1か1.2のうちの任意に選ばれたどちらかだけを参照すること)ことも起こる。これは即座に依存性地獄につながり、特にそれが実行時クラスパスを形成するこれらの依存性の推移閉包である場合に起こる。MavenやIvyのようなビルドシステムはエンドユーザではなく開発者に対してモジュール化を可視化してくれる。Javaはクラスローダと呼ばれるそれほど賞賛されてはいない機能を持っていて、それによって、実行時のパスをさらに細分化することができる。一般には、全てのクラスはシステムクラスローダによってロードされる。実行時の空間を異なる複数のクラスローダに分けているシステムもある。良い例はTomcat(や他のサーブレットエンジン)であり、多くの場合一つのウェブアプリケーションに一つのクラスローダを持っている。これによって、ウェブアプリが普通に機能しながら、同じJVM助運の他のウェブアプリに寄って定義されたクラスを(偶然だろうとそれ以外の理由であろうと)見ることができないようになっている。これが機能するための方法は各ウェブアプリが独自のクラスローダでクラスをロードすることであり、(局所的な)ウェブアプリの実装は他のウェブアプリの実装と衝突するようなクラスをロードしないことである。このことが要求することは、どんなクラスローダチェーンに対してもクラススペースが一貫しているということだ。これは、一度に2つのクラスローダからロードされた2つのUtil.classを保持することが、もしそのクラスローダが互いに不可視であるならば、可能であるという意味である。(それはまた、サーブレットエンジンが再起動することなく変更を際デプロイすることができるようにしているものでもある。これはサーブレットエンジンが新しいクラスローダを作成して、実行時に新しいバージョンのクラスを再ロードすることを可能にしている。)隅から隅までモジュールモジュラーシステムを構築することは、まさにアプリケーションを(潜在的に)再利用可能なかたちのモジュールに分割する方法であり、モジュール間の結合を最小化することである。モジュールの要求を分断する方法である。IDEは一般的に(例えばjdt.uiとjdt.coreのように)GUIおよび非GUIコンポーネントにそれぞれ依存性を持つプラグインを備えている。このことによって、非GUIモジュールはIDE環境の外部で他の用途(ヘッドレスビルドや構文解析、エラーチェックなど)に利用することができる。モノリシックなrt.jar以外にも、いかなるシステムも一般に様々なモジュールに分解可能である。ここで問題が思い浮かぶ。その価値があるといえるか、ということだ。結果として、モジュールシステムとして開始して作業を進めた方が、モノリシックなシステムを分解してモジュールに切り分けるよりもずっと簡単なのだ。このことが一般的であるといえる理由の一つが、モジュール境界を越えたクラスの漏洩に対処することである。java.beansパッケージは論理的には、いかなるGUIコードに対する依存性をも持つべきではない。Beans.instantiate()で使われているjava.beans.AppletInitializerはAppletへの参照を保持しており、それによって当然のごとくAWT全体への波及的な依存性を持つ。そのためjava.beansは技術的にはAWTに対しては選択的な依存性を持つが、常識的にはそうであるべきではないことがわかる。仮にコアJavaライブラリ構築当初、もっとモジュラーな方法がとられていれば、このようなエラーはAPIが公開されるずっと前に捕まえられていたであろう。ある時点でモジュールはそれ以上サブモジュールに分解することができなくなる。時々関連する機能の組織化が容易であるという理由で同じモジュールの中に残され、必要となったときにだけさらに分解される、ということがある。JDTの一部であったが、(CDTのように)他の言語が一般的なリファクタリング機能を利用することができるために独自のモジュールとして引き出された。プラグイン多くのシステムはプラグインの概念を通して拡張可能である。このような場合には、ホストシステムはプラグインが適合しなければならない定義されたAPIと、プラグインを注入する方法を持っている。(ウェブブラウザやIDE、ビルドツールといった)多くのアプリケーションは正しいAPIを提供するプラグインを与えることによってアプリケーションをカスタマイズする方法を提供する。時に、これらのプラグインは制限されていて(オーディオやビデオをデコードするような)一般的操作を行うことしかできないが、(たとえばIDEのプラグインのように)それだけで同程度に十分複雑になり得る。ある時には、これらのプラグインはその振る舞いをさらにカスタマイズするための独自のプラグインを提供することがあり、それによってシステムをさらにカスタマイズ可能にする。(しかしながら、間接的なレベルの数が増大するにつれてシステムがどんどん理解しにくいものになる。)プラグインAPIは個々のプラグインが従わなければならない契約の一部を形成している。これらのプラグインはそれ自体モジュールであり、それを包含するシステムが提供する通常の依存連鎖やバージョニングの課題にぶつかる。(特定の)プラグインAPIの複雑さが増すにつれ、プラグインそのものも同じように複雑になる(か、後方互換性の振る舞いをメンテナンスしなければならなくなる)。ブラウザでのNetscapeプラグインAPIの成功の一つの理由は、その簡潔さにあった。片手で数えられるほどの機能だけが必要とされ、ホストブラウザがインプットを適切なMIMEタイプで変換することで、プラグインはその残りの処理を扱うことができる。IDEのようにもっと複雑なアプリケーションは一般にずっと密接に統合されたモジュールが必要であり、それゆえそれらのモジュールを扱うためのもっと複雑なAPIを必要とする。多くのモジュールシステムやプラグインインフラがJavaの世界に現状存在している。IDEは一般によく知られたものであり、IntelliJ、NetBeans、Eclipseはすべてその使い方をカスタマイズする方法として独自のプラグインシステムを提供している。AppleScriptを利用できるアプリケーション)はそのアプリケーションやシステムの主要な機能を拡張することができる、というやり方を独自に持っている。間違いないと言っていいだろうが、Javaにおける最も成熟したモジュールシステムはOSGiであり、Javaそのものとほぼ同じくらい長い歴史がある。291として承認された。OSGiはJARのMANIFEST.MFの中にメタデータを追加定義し、パッケージ単位での必要な依存関係を示すようにしている。これにより、モジュールが(実行時に)依存関係が適合しているかどうかをチェックすることが可能になり、加えて各モジュールが(モジュールごとにClassLoaderを持っているおかげで)独自のプライベートなクラスパスを持つことを可能にしている。このことによって、上述した依存性地獄の問題から救われるが、完全には防ぐことはできない。JDBC同様、OSGiは複数のオープンソース(と商用)実装をもつ仕様(現在はリリース4.2である)である。モジュールはどんなOSGiの特定のコードにも依存する必要がないので、多くのオープンソースライブラリは今やOSGiランタイムで使うためのマニフェストの中にライブラリのメタ情報を埋め込んでいる。ないものに対しては、bndのようなツールが既存のJARファイルを後処理して、実用にたえるデフォルト値を生成することができる。3.0がOSGiに移行したのは2004年であり、それ以前はプロプライエタリなプラグインシステムを利用していた。他のプロプライエタリなカーネルを持つシステム(JBoss、WebShepre、Weblogic)も後に続き、そのランタイムのベースをOSGiカーネルの上に構築している。最近になって、JigsawプロジェクトがJDKそのものをモジュール化するために開始された。7実装ではサポートされない可能性もあるが、JigsawをJDK外部で利用することは禁止されていない。294のリファレンス実装になる可能性もある。6やそれ以下で稼動するシステムでは一般には利用可能ではない、ということである。system提案について議論を続けている。(MavenリポジトリやApache.orgのようなところで見つかるような)Javaライブラリの作成者で、このグループにいる誰かがJigsawやOSGiシステムの両方から使用可能なメタ情報を提供するだろう。Java言語の少しの変更(もっとも注目すべきはmoduleキーワードの追加である)とあわせて、この情報は十分に先進的なコンパイラであればコンパイル時に生成することができるのではないだろうか。(JigsawやOSGiのような)ランタイムシステムはこの情報をインストールされたモジュールやその依存関係の検証にりようすることができるかもしれない。まとめこの記事ではモジュール化の一般的概念とそれがJavaシステムでどのように実現されているかを論じてきた。コンパイル時と実行時のパスは異なるかもしれないので、依存性地獄を引き起こすようなライブラリの一貫性のない要求がある可能性がある。プラグインAPIによって多くのタイプのコードがロードされるだろう。それらはホストの依存性解決の結果でなければならないし、一貫性の欠如に対する責任を増す。このことを防ぐために、OSGiのような実行時モジュールシステムは、アプリケーションが何も言わずに失敗したり、実行時に検出不可能な方法で失敗したりするのではなく正しく開始されるかどうかを決定する以前に要求を検証することができる。294メーリングリストにおいてJava言語のJava言語仕様全体で定義されることになるモジュールシステムを作る作業は進行中である。それによって、Java開発者は、エンコードされた依存性情報をもつバージョンづけられたモジュールを生成することができるようになる。その依存性情報は結果的にどんなモジュールシステムでも使われることになるだろう。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見るあなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。登録するとさまざまなことができます。アカウント登録をしてInfoQをお楽しみください。あなたの意見をお聞かせください。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見る様々なイノベーターとアーリーアダプターがお送りするテクノロジーの概要を見る。自分がまだ知らないことに気づいていないと知るあなたが興味のあるトピックスをいつでも最新な情報に。あなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。よい世界へ私たちが暮らす世界を大切に思い、よりよいものにしたいと考えています。人のためのソフトウェア開発を加速し私たちのミッションを実現することで、この思いを成し遂げようとしています。私たちは利益の1%をさまざまな慈善団体に寄付しています。会社として、また従業員として、そうしたことの価値を強く信じているからです。with.プライバシーBTあなたのプロファイルは最新ですか?プロフィールを確認してアップデートしてください。アドレス*Eメールを変更すると確認のメールが配信されます。会社名:現在の会社名をご入力ください。Other組織規模:現在の組織規模をご入力ください。2,501+国:現在の国を設定してください。Zimbabwe都道府県:現在の都道府県に設定してください。次の都道府県にアップデートする:ニュースレターを購読しますか?インダストリーメールを購読しますか?本Eメールに登録すると、以前より関心のあったトピックの関連情報をお送りする場合がございます。詳細はこちらのプライバシーポリシーをご覧ください。newsletter?新しいメールアドレスに確認用のメールを送信します。このポップアップ画面は自動的に閉じられます。