あれから4年

このブログを最後に書いてから4年が経った。


当時はまだ20代。
周りにいるSEから頭一つ抜けた技術力を身につけたいと思い、テクニカル一辺倒だった。


会社でも技術を専門にする部署に所属し、フレームワークの開発やアプリケーションサーバ、チューニングにのめり込んでいた。
JavaOneでもスピーチする機会があったし、技術ではその辺のエンジニアに負けるつもりはなかった。
海外でも通用するソフトウェアエンジニアを目指し、英語も必死で勉強していた。


最後にこのブログを書いてから、ベンチャーに転職。

今の立場は開発リーダー。
10名程度のチームを持っている。


転職当初は大部分のコアロジックを自分で書いていたが、今では自分でコードを書くことはほぼない。
10人メンバがいると、全員の力を出し切ることに注力しないと、すぐに仕事がショートする。
一定の余裕を持ちながらも、一定の速度を出し、一定のクオリティを担保する。
とにかく仕事の流れを止めない。
如何に効率よく仕事を回すかが最大の関心事。


いつの間にか社内で最も困難で最も要求が厳しいプロジェクトを担当するチームとなった。
でも土日はきちんと休むし、平日もブログを書く時間くらいはある。


テクノロジーより、人間やビジネスについて考える時間が圧倒的に増えた。
仕事のやり方もずいぶん変わった。


システムエンジニア10年で経験したことを綴ってみようと思う。

JBossとGeronimoの違いは?

ここ最近Geronimo1.0リリースのニュースを良く見かけます。


RDBMSであれば各製品、機能や特性が異なるので住み分けがされていますが、J2EEの場合は機能が標準化されているので違いが分かりにくくなっています。
しかし、システム開発においては、ステークホルダーが納得する選定基準で、1つの製品に決定する必要があります。


Geronimoについては他のBlogにお任せするとして、ここではJBossについて考えてみたいと思います。


機能については、ユーザーとしての視点では、ほぼ同じ、もしくは差があってもすぐに埋めらる程度か、代替手段があると考えて大きな問題はないと思います。


機能以外の点では、JBossのキャッチフレーズの「Professional Open Source」という言葉に表されているように、資本主義とオープンソースの融合をこれまで以上に進めている点と考えます。
海外のメディアでは、しばしばLinuxApache、Bindなどを第1世代オープンソースJBossMySQLなどエンタープライズ用途のミドルウェアを第2世代オープンソースとカテゴライズしています。
第1世代オープンソースは、基本的にボランティアベースで開発されます。商用サポートが提供されることはあっても、ソフトウェア自体とは関係が薄いことが特徴です。
第2世代オープンソースは、中心的な開発者がサポートを提供する企業を設立する、開発者を社員として雇うなど、より積極的にビジネスとして展開しています。更には、JBossWebサービスの分散トランザクション技術買収に見るように、必要な技術を買収してオープンソースとして公開するといった動きまであります。オープンソースの開発モデルを取り入れた商用製品と考えた方が自然かもしれません。


Geronimoは、IBMの資本注入を受けていますが、第1世代オープンソースと同じピュアなオープンソース開発モデルを志向しているように見受けられます。Apache Foundation自体、利益追求を目的としていないことも考慮にいれる必要があります。


方針の違いであり、どちらが良いといった事は一概に言えませんが、企業の一員としては、商用製品の開発速度と信頼性、オープンソースのユーザー参加型開発と開発プロセスのオープン性がうまく組合わされば、すばらしいと思います。

Windows + Norton Internet Securityでエラーが出る場合

Windows + Norton Internet Securityで、JBoss起動時にネットワーク関連のエラーが出る時は、FireWallの設定を疑って下さい。
[ファイアウォール] - [設定] - [プログラム制御] - [手動プログラム制御]でjava.exeに「すべてを遮断」が設定されていると、ソケットを作成できなくなるため、色々なサービスが立ち上がらなくなります。

パフォーマンス・チューニング

Java/J2EEだけで見ても、パフォーマンス上気を付けなければならない点は沢山存在します。
しかし現実的には、システムとしてのパフォーマンスのトラブルに対処しなければならないことが多く、ボトルネックを切り分けるためには、OS、ネットワークレベルで診断した方が早くて確実です。その上でアプリケーションサーバであることが判明すればJava/J2EE技術者の仕事になりますし、他の原因であればインフラ担当者やDBAにディスパッチします。


ちょうど、リクエストを発行しても、行ったきり帰ってこない(^^;というトラブルに対応しているので、以下の書籍で復習中。


Unixシステムパフォーマンスチューニング 第2版

Unixシステムパフォーマンスチューニング 第2版

Solarisベースですが、パフォーマンスチューニング、キャパシティプランニングの基本的な考え方が説明されています。アプリケーションサーバのチューニングにはこの本に書かれている内容まで知らなくてもいいかもしれませんが、コンピュータの動作を深く理解することができます。
第2版ではLinux向きの説明も追加されています。


Linuxパフォーマンスチューニング

Linuxパフォーマンスチューニング

Linuxでチューニングする場合の具体的な手順の説明が中心です。
最近はLinuxが多いのでこちらも参考に。こちらの方が取っ付き易いです。


データベースはOracleなのでSQLTraceでSQLの実行時間を取りますが、PostgreSQLMySQLの場合該当する機能はなさそうです。JMXをサポートするアプリケーションサーバであれば、少し手を加えればJBossのStatisticsCollectorが使えそうですが。

Entity Inheritance

前回気になった所をSpecで調べてみた。


継承階層のマッピング戦略は1階層1テーブルのみか?


Java Persistence API 2.1.10 Inheritance Mapping Strategiesより、


Specでは3つの戦略が規定されている。


Single Table per Class Hierarchy Strategy

  • 1継承階層1テーブル
  • 継承階層の型を横断する、つまりpolymorphicな処理をするクエリがある場合にGood
  • クラスの型を識別する“discriminator column”が必要


Table per Class Strategy

  • 1クラス1テーブル
  • polymorphicな処理に弱い
  • 継承階層の各型を扱うのに、SQLのUNIONに相当する処理を行う必要がある


Joined Subclass Strategy

  • 継承階層のルートに1テーブル
  • 各子には、追加されたプロパティとプライマリキーを持つテーブルを割り当て
  • 子テーブルのプライマリキーは親テーブルへのプライマリキーへの外部キーになる
  • polymorphicな処理も可能だが、子クラスの取得にjoinが必要。継承階層が深い場合パフォーマンス悪化の原因になる


上記のうち、実装することが定められているのは、Single Table per Class Hierarchy Strategy


DiscriminatorColumn、discriminatorValueのデフォルト値は?


DiscriminatorColumn
9.1.27 DiscriminatorColumn Annotationより、"TYPE"


discriminatorValue
9.1.24 Inheritance Annotationより、Persistence Provider依存

Entity Inheritance

JBossEJB3.0 TrailBlazerによると、EJB3.0ではEntityBeanに継承が使えるようになった。
これもPOJOベースになったことによるメリットだろう。

継承階層をリレーショナルモデルにマッピングするための戦略として、階層の各クラスを別のテーブルにマッピングする方法があるが、TrailBlazerでは一つのテーブルにマッピングする方法を説明している。

@Entity
@Table(name = "record")
@Inheritance(discriminatorValue="B")
@DiscriminatorColumn(name="record_type")
public class Record {
    // ... ...
}
@Entity
@Inheritance(discriminatorValue="T")
public class TimedRecord extends Record {

  private Timestamp ts;

  // ... ...

  public Timestamp getTs () {
    return ts;
  }

  public void setTs (Timestamp ts) {
    this.ts = ts;
  }

}


上が親クラス、下が子クラスになる。
親クラスのオブジェクトか、子クラスのオブジェクトかの違いは、
@DiscriminatorColumnで指定したカラムに設定される値で区別する。
@InheritanceのdiscriminatorValueで指定した値が設定され、
親クラスの場合は"B"が設定され、子クラスでは"T"が設定される。


Javaの世界では、親子を識別したい時はinstance ofで十分可能だと思う
が、上記のカラムは他に使いどころがあるのだろうか?
コンテナがデータベースからオブジェクトを生成する時には必要になり
そうだ。一つのテーブルに親子が格納されている場合、子で追加された
カラムは親では値が設定されないが、それだけで親子を判別することは
危険だからだ。
コンテナのためのカラムか?

なぜEJBを使うか?

Spring + Hibernateがあるのに、なぜ今更EJB3.0か?


技術的な優位性のみで考えれば、Spring+Hibernateに軍配が上がるのもやむを得ないだろう。EJB3.0の源流である上、これからもJavaEEの標準化とは別にどんどん進歩していくだろうから。


しかし、EJB、というかJavaEEの根底に流れている考え方は標準化であり、開発者のみならず、ソフトウェアに携わる様々な人にメリットがある。


[オーナーの視点]
・ベンダロックインの排除
あくまでリスクの話だが、企業でサードパーティ製品使う場合には、開発元の戦略が急に変わったり、倒産してしまう事態も考えなくてはならない。
標準化された機能を使うことによって、アプリケーションが特定の開発元に依存することを避けることができる。


・企業への導入障壁の引き下げ
お堅いユーザーにSpring、Hibernateを使います!っていったらなにそれ?と言われる場面でも、J2EEアプリケーションサーバの標準機能であれば、通りやすいだろう。


[開発ベンダの視点]
アプリケーションサーバベンダによるサポート
標準APIであれば、当然アプリケーションサーバベンダがサポートを提供する。
Struts、Spring、Hibernate等独自ライブラリは、プロジェクト内にこれらに精通したエンジニアが必要となる。


[開発者の視点]
・開発者の負荷軽減
汎用機時代は、ハードから言語、開発環境まですべて独自仕様であり、これがプログラマ35歳定年説の根拠でもあった。
案件が変われば別のプラットホームになるのは当たり前だが、J2EE標準であれば、開発者から見れば、JBossだろうがWebLogigcだろうが変わりは無い。結果的に開発者の寿命も延びることになる。


先鋭的な技術者には、不満が残るかもしれないが、標準化の考え方がJava/J2EEの採用を推進してきたこともまた事実である。もし、JavaがSunだけの技術だったら、ServletApacheやBEAだけの技術だったら今の状況はないだろう。標準化がオープンとプロプライエタリの絶妙なバランスを作り上げている。
そもそも標準とは良いものだと周知の事実になった事を順次取り込んでいくものであり、実験的要素があるプロダクトの特定の機能だけを見て、標準に噛み付くのは意味を成さないと思う。