2012年5月31日

[Solaris] Remote Development With Solaris Studio

原文はこちら。
https://blogs.oracle.com/run/entry/remote_development_with_solaris_studio

新しい技術記事がOTNにUpされました。
How to Develop Code from a Remote Desktop with Oracle Solaris Studio
by Igor Nikiforov
http://www.oracle.com/technetwork/articles/servers-storage-dev/howto-use-ide-desktop-1639741.html
この記事では、Oracle Solaris Studio IDEのリモートデスクトップ機能と、この機能を使ったコンパイル、実行、デバッグ、リモートサーバ上で実行しているコードのプロファイリングをする方法を説明しています。
Introducing the IDE Desktop Distribution
Determining Whether You Need the Desktop Distribution
Creating the Desktop Distribution
Using the Desktop Distribution
See Also
About the Author
IDE Desktop版の概要
Solaris Studio 12 Update 1 はユニークなリモート開発機能を有しており、この機能を使うと、IDEの1インスタンスを実行するだけで、複数のサーバやプラットフォームと連係させることができます。例えば、Oracle Linuxを実行しているx86ベースのラップトップやデスクトップでIDEを動かし、Oracle Solaris 10で動いているSPARCベースのサーバを使ってコンパイル、テスト実行、デバッグ、コードのプロファイルが可能なのです。あたかもOracle Solarisが自身のラップトップやデスクトップにあるかのごとく、IDEがシームレスに動作します。

以後は原文をどうぞ。
http://www.oracle.com/technetwork/articles/servers-storage-dev/howto-use-ide-desktop-1639741.html

[Solaris] Solaris Web Magazine JP へようこそ

原文はこちら。
https://blogs.oracle.com/solarisweb/entry/solaris_web_magazine

今回からSolaris Web Magazineは、Oracle Blogsで提供されるようになりました。
日本語ですので、ご興味ある方は是非どうぞ。

2012年5月28日

[JavaFX] Best Practices for JavaFX 2.0 Enterprise Applications, Part Two

原文はこちら。
https://blogs.oracle.com/java/entry/best_practices_for_javafx_21

Java ChampionでOracleのJava Evangelist、そしてJavaFXのエキスパートであるJim Weaverが、"Best Practices for JavaFX 2.0 Enterprise Applications"の第2部をOTNに寄稿しています。
Part1はこちら。
https://blogs.oracle.com/java/entry/best_practices_for_javafx_2http://orablogs-jp.blogspot.jp/2012/04/best-practices-for-javafx-20-enterprise.html
Weaver が新技術やベストプラクティスに焦点を当てて、引き続きTweetBrowserアプリケーションの可能性を調査します。
  • JavaFXのCSSを使う
  • UIでspringsとstrutsを実装する
  • バインディング式で三項演算子を使う
  • JavaFXプロパティを定義する
  • Popupを使ってダイアログボックスを実装する
  • WebViewを使ってWebページを表示する
Weaverが強調するように、JavaFXアプリケーションで利用できる技術やベストプラクティスがたくさん詰まっています。例えば、
  • JavaFXのカスケードスタイルシート(CSS)を使うと、ユーザーがアプリケーションの外観を変更することができます。
  • springsstrutsのコンセプトを使い、水平方向を固定(struts)にしたり、可変(spring)にして、シーンの大きさやプラットフォームの種類にかかわらず、開発者の意図通りにアプリケーションを表示できます。
是非JavaFXの2.0とエンタープライズアプリケーションの豊富な可能性の詳細を学んで下さい。
Best Practices for JavaFX 2.0 Enterprise Applications (Part Two)
http://www.oracle.com/technetwork/articles/java/javafxbest2-1634274.html

[Network] Advance Routing for Multi-Homed Hosts

原文はこちら。
https://blogs.oracle.com/networking/entry/advance_routing_for_multi_homed

以前マルチホームホストと呼ばれる、異なるネットワークやサブネットへ参加するホストについて説明しました。今回はLayer-3のルーティングについてお話します。今回は2個のシナリオ、シンプルなパターンとちょっと複雑なパターンに分けて説明します。

シンプルな場合
4個のNICを持ち、それぞれ一意のLayer-3のサブネットを持つホストを考えます。3個のサブネットはプライベートLANで、4番目はより大きなWANです。小さなネットワークは管理、開発、テスト用で管理の目が行き届く環境ですが、大きなネットワークはインターネットもしくはイントラネットゆえ、ホストやサービスの個数が把握しづらい環境です。この大きなネットワークをさらに多くのネットワークに分割され、ほとんどの場合そこにはルータが存在します。ご存知のようにルータの主要な役目は異なるブロードキャストサブネット間のトラフィックをルーティングすることです。
マルチホームホストには大きなネットワークやWANへのデフォルトゲートウェイがあります。既知のネットワーク外との通信が発生する場合、この通信をデフォルトゲートウェイに転送します。このデフォルトゲートウェイはルータとも呼ばれます。簡単に説明しましょう。
ホストのネットワーク参加要件は以下の通りです。
eth0  - 201.19.23.128 / 24  with gateway IP 201.19.23.1
bond0 - 192.168.10.1  / 24  with no gateway requirements
bond1 - 10.214.28.101 / 24  with no gateway requirements
bond2 - 172.23.7.128  / 24  with no gateway requirements
このマシンは社内ネットワークと eth0 (201.19.23.1)とだけ通信すればよいように思えます。問題解決ですね。このデフォルトゲートウェイを /etc/sysconfig/networking というファイルか、もしくは /etc/sysconfig/network-scripts/ifcfg-eth0 に設定すればよいのです。

ちょっと複雑な場合
上のシナリオから同じホストで、大きなネットワークへの接続が一つでない場合を考えると、同じような2個の接続ができあがります。一つは本当のインターネットに向いており、もう一つは企業内のWANを向いていることが考えられます。そして、その他に2個の管理用および内部用の通信を維持しています。この標準的な方法を使ってデフォルトゲートウェイを構成し続ける場合、2個の大きなネットワークのうち、一つしかアクセスできなくなってしまいます。それはデフォルトゲートウェイがインターフェースやLayer3サブネットにバインドされているからです。

ホストのネットワーク参加要件は以下の通りです。
eth0  - 201.19.23.128 / 24  with gateway IP 201.19.23.1
bond0 - 192.168.10.1  / 24  with no gateway requirements
bond1 - 10.214.28.101 / 24  with gateway IP 10.214.28.1
bond2 - 172.23.7.128  / 24  with no gateway requirements
ここでeth0とbond1が各々デフォルトゲートウェイを必要としていることがおわかりになるかと思います。bond1とbond2はデフォルトゲートウェイを必要としていません。単にLayer3サブネットに接続するだけです。

単純にデフォルトルートを追加すると、1個のデフォルトゲートウェイしか有効にできません。

問題点
私の問題文の形で上記の議論を言い換えてみましょう。
どうすれば、マルチホームホストが様々なルータを通して1個以上のネットワークとアクセスできるようにできるでしょうか。

解決策
Linuxにはiproute2というツールを使って高度なルーティングが可能です。これを使うと、一つ以上のデフォルトゲートウェイやルータアドレスを指定することができます。Oracle Enterprise Linux 5ベースのサンプル構成をご覧に入れますが、これは他のディストリビューションであっても適用は容易かと考えています。
基本的に、ルールとルーティング先検索のためのルーティングテーブルを作成します。一意のテーブルIDが必要ですが、今回は224と225を使うことにしています。
これらのテーブルIDは以前に使われていてはいけないため、以下のようなコマンドで確認します。
ip rule list
最初の列を見ると、出力は224でも225でもないはずです。そうで無ければ、別の番号を使って下さい。

eth0用に以下のファイル2個を作成します。

vi /etc/sysconfig/network-scripts/rule-eth0
from 201.19.23.128/32 table 224
to 201.19.23.128 table 224
vi /etc/sysconfig/network-scripts/route-eth0
201.19.23.0/24 dev eth0 table 224
default via 201.19.23.1 dev eth0 table 224
bond1用に以下のファイル2個を作成します。

vi /etc/sysconfig/network-scripts/rule-bond1
from 10.214.28.10/32 table 225
to 10.214.28.10 table 225
vi /etc/sysconfig/network-scripts/route-bond1
10.214.28.0/24 dev bond1 table 225
default via 10.214.28.1 dev bond1 table 225
これでネットワークを再起動し、これらの新しい設定を反映することができますが、この操作により、ホストへのアクセスが中断されるため、無計画に実施すべきではありません。
また、ランタイム実行のためにipコマンドを使用することができます。これで終わりです。これでホストは、両方のルータ間でアクセスできるはずです。

静的ルーティング

さて、なぜ今まで静的ルートについては何も言及していないのか、と疑問に思ってらっしゃる方がいるかもしれません。私は忘れてはいません!静的ルートの利用は先のシナリオ両者の間のシナリオです。ルーター越しのwell-knownサブネットがある場合、確かにそのサブネット用の静的ルートを追加する必要があります。例えば、bond1ネットワークに接続されたマシンの1つが別のネットワークを知っていて、ルーティング機能がある場合、そのネットワークを通じて静的ルートを使用することができます。
OK、これでこのエントリは終わりです。いつものように、皆さんからのコメント大歓迎です。ありがとう!

[misc] How to enable anti-aliasing font

知っている人は知っている、IDEでのアンチエイリアスの有効化に関するお話です。
NetBeans、JDeveloper、SQL Developer、Oracle Data Integrator 11gの開発環境で、アンチエイリアスを有効化するためのオプションはほぼ同じです。

NetBeans
<NetBeansインストールディレクトリ>/etc/netbeans.conf のnetbeans_default_optionsに以下の設定を追加します。
-J-Dawt.useSystemAAFontSettings=on | lcd | gasp
onはJavaのアンチエイリアス、lcdは液晶ディスプレイ向けのアンチエイリアス(厳密には、サブピクセルのアンチエイリアス)です。gaspは小さい文字ではアンチエイリアスを行わない設定です。特にWindowsでご利用になる方はご注意下さい。

JDeveloper
<JDEV_Install_Home>/jdeveloper/jdev/bin/jdev.conf で、以下の設定を追加します。
AddVMOption -Dawt.useSystemAAFontSettings=on | lcd | gasp
NetBeansと同じく、gaspを指定すると、小さい文字ではアンチエイリアスを行いません。

NetBeansとJDevloperでは、設定箇所や設定方法がちょっと違うだけで、同じ内容を設定していますね。


SQLDeveloper、およびOracle Data Integratorの開発環境(Studio)でも、JDeveloperとほぼ同じ設定でアンチエイリアスが有効になります。

SQL Developer
<SQLDeveloper_Install_Home>/sqldeveloper/bin/sqldeveloper.conf に、以下の設定を追加します。
AddVMOption -Dawt.useSystemAAFontSettings=on | lcd | gasp
注意点はJDeveloperと全く同じです。
設定すべきファイルが違うだけで、JDeveloperと全く同じ設定ですね。

ODI Studio
<ODI_Home>/oracledi/client/odi/bin/odi.conf に、以下の設定を追加します。
AddVMOption -Dawt.useSystemAAFontSettings=on | lcd | gasp

2012年5月27日

[VM] example of transcendent memory and oracle databases

原文はこちら。
https://blogs.oracle.com/wim/entry/example_of_transcendent_memory_and

Transcendent Memory(以下TMEM)を使って、Oracle Database 11gR2とswingbenchを組み合わせたテストをやってみました。結果のグラフは下記の通りです。この意味を説明していきましょう。
Oracle VM 3をdom0の起動時に変更を施し(ブートプロンプトに追加パラメータを入れた状態)、UEK2をゲストカーネルとしてVMで利用する場合、autoballoonを利用できます。下図のグラフでわかることは非常にシンプルで、水平軸はVMの実メモリの利用量/必要量を時系列に並べたものです。36GBのOracle VMサーバ上で動作する3個の16GBのVMを作成しました(サーバで利用可能な物理メモリよりも多くのメモリがVMに割り当てられている状態です)。16GBのVMを起動したときに(縦軸)ゲストのLinuxは、すぐにサイズが約700MBにまで縮みます。ページを不要なハイパーバイザに自動的に解放し、それ以外の場合は自由に使える空きメモリです。4GBをSGAに割り当ててデータベースを起動すると、おわかりのように、DBを立ち上げてすぐにVMは4GB以上のサイズにまで大きくなります。そしてswingbenchを25、50、100、500、1000ユーザで実行します。そのような実行が開始されるたび、メモリ利用量が増え、swingbenchを停止するとメモリ利用量が減ります。最後に、1000ユーザで最後のテストを実行した後、データベースのインスタンスをシャットダウンし、メモリ使用量が700MBにまで減ります。
swingbenchとデータベースを使って3個のゲストOSを個々に実行し、動的なバルーニング、ゲストとハイパーバイザーの緊密な連携により、私は3個すべての16GBのVMを起動することができ、しかもパフォーマンスへの影響はありませんでした。ハイパーバイザ内に空きメモリがあったときに、cleancacheが動き、ゲストはそのメモリを利用しました(ページの圧縮なども含みます)。
ご自身で実験したいという場合、このコマンドをdom0で実行すると、セットアップからの統計を取得できます。
xm tmem-list --long --all | /usr/sbin/xen-tmem-list-parse
このコマンドで、圧縮率、キャッシュ率などがわかります。こうした統計情報を使って以下のグラフを作成しました。これはいつ、どうやってハイパーバー座とゲストOSを制御し、強調させることができるかという一例です。ブラックボックスのVMの管理よりも良い、より興味深い結果を得ることができます。


2012年5月25日

[SOA] OSB Web Service Response Caching by Service Operation

原文はこちら。
https://blogs.oracle.com/bwb/entry/osb_web_service_response_caching

Oracle Service BusにはOracle Coherenceを使ったBusiness ServiceのResult Cache機能が組み込まれています。 しかし、Business Serviceが複数のオペレーションをサポートしている場合や、キャッシュのキーとして保存可能な、全てのオペレーションに共通するパラメータがない場合はどうなのでしょうか。
幸運にも、まさにこうしたシナリオに対するソリューションがあります。このエントリでは、サービスの各オペレーションで異なるキャッシュキー式を指定する方法をご紹介します。

OSB Web Service Response Caching by Service Operation
Oracle Service BusにはOracle Coherenceを使ったBusiness ServiceのResult Cache機能が組み込まれています。 詳細は以下のドキュメントをご覧下さい。
Oracle® Fusion Middleware Administrator's Guide for Oracle Service Bus 11g Release 1 (11.1.1.6.2)
Improving Performance by Caching Business Service Results
http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/configuringandusingservices.htm#CHDDCGEE
Oracle® Fusion Middleware Oracle Service Bus管理者ガイド 11g リリース1 (11.1.1.6.0)
ビジネス・サービスの結果のキャッシュによるパフォーマンスの改善
http://docs.oracle.com/cd/E28389_01/admin.1111/b61436/configuringandusingservices.htm#CHDDCGEE
Business Service毎に、リクエスト/レスポンスを識別するために使う一意のキーとしてキャッシュトークンを定義します。

キャッシュトークンは、XPath式から導出された文字列値です。このキャッシュトークン式は、以下のようにビジネスサービスの[詳細設定]で定義することができます。

しかし、ビジネスサービスが複数のオペレーションをサポートされている場合や、キャッシュのキーとして使用できるすべての操作に共通するパラメータがない場合はどうでしょう?

どうすれば、各オペレーションに固有のキャッシュキー式を設定することができるのでしょうか?
幸いにも、まさにこのシナリオのためのソリューションがあります。以下のリンクで説明されているように、キャッシュトークンは実行時に設定できます。
Oracle® Fusion Middleware Administrator's Guide for Oracle Service Bus 11g Release 1 (11.1.1.6.2)
Message Handling Configuration Page
http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/business_services.htm#i1141909
Oracle® Fusion Middleware Oracle Service Bus管理者ガイド&nbsp;11g リリース1 (11.1.1.6.0)
「メッセージ処理構成」ページ
http://docs.oracle.com/cd/E28389_01/admin.1111/b61436/business_services.htm#i1141909
キャッシュトークンの値をProxy Serviceのパイプラインの$outbound/ctx:transport/ctx:request/ctx-cache-token 要素に設定することができます。

キャッシュトークンの値を実行時に設定する

では、3個のオペレーションを持つDepartment FinderというWebサービスについて考えます(このWebサービスは以前のエントリで紹介した手順に従って作成できます)。
以前のエントリとは…Create a simple Web Service from Java Code using JDeveloper
https://blogs.oracle.com/bwb/resource/webservices/Create_a_simple_Web_Service_from_Java_Code_using_JDeveloper.html
Webサービスとして公開されるJavaのメソッドは以下のようなものです。
public DepartmentDetails getDepartmentDetails(String deptNumber) throws DepartmentFinderFault
public DepartmentDetails getDepartmentByMgrEmailId(String mgrEmailId) throws DepartmentFinderFault
public List<String>  getDepartments()
3個のメソッドにはキャッシュキーとして利用できる共通のパラメータはありません。
では、ブランチノードを持つDepartmentFinderProxyから取りかかりましょう。

ブランチノードの各ブランチには、対応するオペレーションを呼び出す1つのルートアクションが含まれています。

上図でgetDepartmentDetailsリンクを選択すると、OSBはgetDepartmentDetailsブランチを表示します。

ブランチにはRouteNode2というルートノードが含まれています。

ルートノードでは、リクエストアクションを追加してキャッシュのキーとして利用するパラメータを取得し、リクエストメッセージ中に設定します。上のRouteNode2アイコンをクリックすると、OSBはルートノードの設定画面を表示します(下図)。

新しくリクエストメッセージのインサートアクションを追加し、<tp:cache-token>要素を$inboundコンテキスト変数のリクエストの箇所に追加します。既存の<tp:headers>要素の後ろに<tp:cache-token>要素を追加するように設定します。
トークン要素の値を正しいパラメータをリクエストメッセージから取り出すXPath式で定義します。
実行時に、XPath式はクライアントから送られたdeptNumberの値を取得し、この値をキャッシュ目的でキャッシュトークンの一意の値として利用します。

この手順を各ブランチ毎に繰り返し実施します。例えば、次のブランチはgetDepartmentByMgrEmailIdブランチです。

ここにはRouteNode3というルートノードが含まれています。

The Insert action in the getDepartmentByMgrEmailIdルートノードのインサートアクションはgetDepartmentDetailsルートアクションとほぼ同じです。
mgrEmailIdをリクエストメッセージから取得するようにXPath式を修正し、この値をキャッシュトークンの値として利用します。

3個目のオペレーションであるgetDepartmentsにはパラメータがないので、同じキャッシュトークンの値に全ての結果をキャッシュすることができます。
他のオペレーションのキャッシュキーと衝突しない限り、キャッシュトークン式は任意の値に解決することができます。例えば、string型(AllDepartments)のキャッシュトークン式が'AllDepartments'という文字列リテラル値に解決します。

    string(AllDepartments)


各ブランチオペレーションのルートノードを構成したら、テストしましょう。

トレースの例
実行時のトレースの例です。
クライアントはgetDepartmentDetailsオペレーションを2という部門IDで呼び出しています。リクエスト・レスポンスは以下の通りです。

トレースから、リクエストメッセージに<tran:cache-token>要素に2という値が入っていることがわかります。これはクライアントから送信された部門IDです。
この値はサービス名とオペレーション名(このエントリのはじめに最初の図にあったもの)に紐づけられ、リクエストメッセージの一意のキーとなり、レスポンスをキャッシュします。

最終的に、トレースの最後で$outboundコンテキスト値が更新されて部門2の詳細に対するリクエストが完了しますが、これはキャッシュからのレスポンスではありません。

次のテストでの部門2の詳細の問い合わせでは、キャッシュが完了させています(下図)

この例ではBusiness Serviceのキャッシュトークンを実行時に設定することをご説明しました。このやり方で様々なXPath式を使ってサービスの各オペレーション用にキャッシュキーの値として生成することができます。

このエントリのサンプルは以下の環境でテストしました。
  • Oracle Service Bus Version: [Oracle Service Bus 11.1 Wed Apr 20 04:25:20 EDT 2011 1400736]
  • Oracle Weblogic Server Version: [WebLogic Server 10.3.5.0 Fri Apr 1 20:20:06 PDT 2011 1398638 ]

[Java] SonOfAnException Handling in Try Multi-Catch?

原文はこちら。
https://blogs.oracle.com/binkyscave/entry/sonofanexception_handling_in_try_multi

今月頭にJavaOne Indiaで講演していたところ、参加者からtry multi-catch構文について質問がありました。最初の質問は例外の処理順序に関する質問でしたが、その裏にある質問は、その例外が別の例外のサブクラスである場合はどうなるのか、また別の言い方をすれば、multi-catchは例外の息子を処理することができるのか、というものでした。
質問を受けたときに回答を持っていないのは嫌なので、ちょっと調べて正解を見つけました。明確にするため、以下のような状況について話しています。
try {
  throwAorSonOFA();
} catch(ExceptionA | SonOfExceptionA e) {
  ...
}
上記のような場合、ExceptionAが投げられるのでしょうか、それともtryの中でSonOfExceptionAが投げられる場合、SonOfExceptionAが捕獲されるのでしょうか。
答えはどちらでもありません。コンパイル中にコンパイル時エラーになってしまうのです。
答えを探すため、OpenJDK 7 Featuresに当たりはじめました。四分の一ほど進むと、Joe DarcyがリードしたSmall language enhancements(Project Coin)に関する記載があります。
JSR 334: Small language enhancements (Project Coin)
http://openjdk.java.net/projects/jdk7/features/#f618
Joseph D. Darcy's Oracle Weblog
https://blogs.oracle.com/darcy/
Joeのブログを見ていると、2011年5月24日のエントリにて、JDK 7 b143で実装されるProject Coinの機能のセマンティクスへのリンクがありました。
Project Coin: Documenation at Rampdown (Joseph D. Darcy's Oracle Weblog)
https://blogs.oracle.com/darcy/entry/project_coin_rampdown_documenation
Project Coin/JSR 334 Documentation v0.9375
http://cr.openjdk.java.net/~darcy/ProjectCoin/ProjectCoin-Documentation-v0.9375.html
この文書には、実装の背後にある理由がたくさん記載されています。具体的には、"Multi-catch and more precise rethrow"の構文セクションで以下のような文章があります。
A try statement may have catch clauses (also called exception handlers).
A catch clause must have exactly one parameter (which is called an exception  parameter); the declared type of the exception parameter can be a single 
class type or can be a union type (denoted with '|') between two or more 
class types (or alternatives). A catch clause with a union type parameter is called a multi-catch clause. For the purposes of type-checking, a union type D with alternatives D1, D2... Dn has type lub(D1, D2... Dn) (§15.12.2.7). It is a compile-time error if a union type contains two alternatives Di, Dj where Di is a subtype of Dj.
(tryステートメントにはcatch句(例外ハンドラと呼ばれることがあります)を含む場合があります。
catch句は厳密に一つのパラメータ(例外パラメータと呼ばれるものです)を持たなければなりません。例外パラメータの宣言型は単一のクラス型か、2個以上のクラス型のunion型(|を使って表記)をとることができます。
Union型を取るcatch句を、multi-catch句と呼びます。型チェックの目的のために、D1、D2...Dnという型のunion型Dはlub(D1, D2, ...Dn)という型を持ちます(§15.12.2.7)。
union型にDjとDjのサブタイプであるDiを含む場合、コンパイル時エラーになります。
)


15.12.2.7. Inferring Type Arguments Based on Actual Arguments
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7
しかし、このドキュメントをそのまま信じるわけにはいかないので、Java Language Specification, SE 7 Edition(Java言語仕様 SE 7版)の14章の第20節を当たってみました。
The Java™ Language Specification Java SE 7 Edition
http://docs.oracle.com/javase/specs/jls/se7/html/index.htmlChapter 14. Blocks and Statements - 14.20. The try statement
http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20
これはJava言語のバイブルですね。ここに太字で明確に書かれています。
It is a compile-time error if a union of types contains two alternatives Di and Dj (i ≠ j) where Di is a subtype of Dj (§4.10.2).
(DiがDjのサブタイプである場合、DiとDj(I≠j)という二つの選択肢を含んでいるとコンパイル時エラーになります)
あぁ、これですっきりしました。そして、元の質問に関連して、この行も見つけました。
If a value is thrown and the try statement has one or more catch clauses 
that can catch it, then control will be transferred to the first such catchclause.(値が投げられ、tryステートメントにその値を捕獲できる1個以上のcatch句がある場合は、最初のcatch句に制御が渡されます)
翻訳すると、例外を左から右への順序で試行します。一つわからなかったのは、mutli-catch例外処理がデフォルトでfinalである、ということです。仕様では、以下のようになっています。
An exception parameter of a multi-catch clause is implicitly declared final 
if it is not explicitly declared final. (multi-catch句の例外引数は、明示的にfinalで宣言しない場合、暗黙のうちにfinalで宣言されます)
そしてさらに少し下に、finalとして宣言したcatch句を使って同等のコードを表したmulti-catchの例があります。

まぁ、そんなわけですので、(少なくともmulti-catchに関する限り)例外のサブクラスを取り扱うことはありません。

2012年5月24日

[BPM] BPM 11g Deployment & Instance Migration

原文はこちら。
https://blogs.oracle.com/ateamsoab2b/entry/bpm_11g_deployment_instance_migration

新しいバージョンのプロセスを管理する方法や、旧バージョンから現行バージョンへのインスタンスの移行を確認する方法に関して、多くの問い合わせを最近よく頂きます。このエントリでは以下の2件について取り上げます。
  1. プロセスへの変更が大きな変更と見なされず、プロセスインスタンスが自動的に移行する場合
  2. プロセスに加えた変更がより複雑で、手作業によるプロセスインスタンスの移行が必要な場合
このエントリではBPM Studioを使って実行中のバージョン管理について、手順を追って説明しますが、他の方法でもデプロイメントに適用できます(例えばEnterprise Managerなどを使うこともできます)。

[注意]
インスタンスの移行はBPM PS4FP以後で利用可能です。PS4以前のバージョンで作成されたインスタンスをPS4FP以後のバージョンのインスタンスに移行することはできません。

プロセスの理解
簡単なプロセスです。3個の異なるフォームを持つ3個のHumanTaskがあります。その後ファイルへの出力が続きます。

単純なXMLスキーマです。3個のフォームを表す3個のComplex型があります。

サンプルの入力メッセージです。個々の要素で全ての引用文を形成しています。

フォーム1

フォーム2

フォーム3

出力ファイル

いくつかのインスタンスを作成します。各インスタンスはプロセスフロー中の様々なポイントで待機中です。


既存のシングルフォームのXMLスキーマに少々変更を施した場合
これは非常に標準的なユースケースです。お客様がフォームの不イールドを間違えた場合、下位のXMLスキーマを変更してフォームをデプロイし直す必要があります。BPMプロジェクト内のXMLスキーマでフォーム2を変更し、新しい要素を含めるようにします。

ビジネスオブジェクトやデータオブジェクトに即座に反映されていることに注目して下さい。

フォームのペイロードに関連するXMLスキーマの中は…

データコントロールを更新して、フォームの変更を反映する必要があります。関連するデータコントロール上で右クリックし、[定義の編集]を選択します。

すると、データコントロールが変更されます。



実際のフォームにこの変更を反映させる必要があります。
フォームを見ると、そのフィールドをどこに配置すべきかわかります。

というわけで、”Field21”を右クリックして「入力テキスト(InputText)」フィールドを追加します。

そして、データコントロールから新しいフィールドにドラッグ&ドロップします。

これでフォームは完成です。

通常の方法でこのフォームをWebLogic Serverにデプロイします。

テストを再実行してフォームが確かに変更されていることを確認しましょう。

BPMプロジェクトをデプロイします。実行中のインスタンスはそのまま生存させつつ、新しいバージョンにインスタンスを移行したと思っています。
BPMプロジェクトを同じRevision IDで「再デプロイ後にインスタンスの実行を続行します」を選択してデプロイしましょう(注意:PS5では、Revision IDが異なる場合にはインスタンスの移行はできません)。

BPM Workspaceの中では、[プロセストラッキング]タブの[保留中のコンポーネント]に、保留状態になっているプロセスインスタンスがないことに着目して下さい。

どうしてなのでしょうか?元のプロセスへの変更が手作業による移行が必要なほど顕著なものではないと判断されたため、すべてのインスタンスが新しいバージョンに自動的に移行されました。変更されたフォーム(フォーム2)を通過したインスタンス(つまりフォーム3で待機中のインスタンス)が正しいデータを持っているとどうやって確認するのでしょうか。そこで使えるのが、「Alter Flow」です。
[プロセストラッキング]タブで、フォーム3で待機中のインスタンスを選択します。

[Alter Flow & Suspend]アクションを選択します。

データオブジェクトに"Field20"がないことに注目して下さい。

表示されているXMLに直接値を追加して、現在のアクティビティを”Form3”として”再開”をクリックします(必要であれば、”Form2”にプロセスを戻し、データを再度入力することができます)。

関連するインスタンスに戻り、"Form3"を完成させます。ファイルの中身を見てみましょう。


新しいHumanTaskやスコープ内のフォームでXMLスキーマに大きな変更を加える
XMLスキーマに変更を加えます。

で、プロセスもこんな感じに変更します。

プロセスを作成して、このフォーム用に新しいUIプロジェクトを作成し、デプロイします。
BPMプロジェクトは以前と同様「再デプロイ後にインスタンスの実行を続行します」を選択します。

BPM Workspaceで、「保留中のコンポーネント」を見てみましょう。

新しくスコープを追加したので、インスタンスの自動移行はできません。移行するには2方法あります。
  1. インスタンス個々に移行するか、[プロセストラッキング]タブからまとめて移行する
  2. [保留中のコンポーネント]からまとめてインスタンスを移行する

個別に移行

フローもデータも変更できます。



グループで移行

フローのみ変更できます。データは変更できません。

保留しているコンポーネントから移行

フローの変更やデータの変更はできません。

スコープの削除
この場合、変更が重要なもので、インスタンスの移行が容易に実施できないとみなされます。Form0の周りのサブプロセスを取り除いて…

「実行中のインスタンスの保持」オプションを指定して再デプロイすると

以下のようなデプロイ時のログが出ます。

「回復できない非互換性」のためにデプロイが失敗しました。サブプロセス削除に伴う変更はかなり大きなものだった、という結果です。この事象が発生するプロセスへの変更内容の完全なリストは、以下の通りです(PS5現在)。
  • 排他または包含ゲートウェイ・ペアが削除される
  • 包含-複合ゲートウェイ・ペアが包含-包含ゲートウェイ・ペアに変更される
  • サブプロセスが削除されるか、そのループ特性が変更される
  • ユーザー・タスクがゲートウェイ・ペアの別のブランチまたはゲートウェイ・ペアの外部に移動される
  • アクティビティ・レベルが変更される。たとえば、アクティビティがサブプロセス内またはゲートウェイ構造内で移動される
  • サブプロセスまたはイベント・サブプロセスまたはコール・アクティビティが追加される
  • イベント・サブプロセスが連続しないタイプから連続するタイプに変更される
  • 境界イベントが連続しないタイプから連続するタイプに変更される
  • 境界イベントが追加される
  • ユーザー・タスクの実装が別のヒューマン・タスクを使用するように変更される 
では、どうやってこの事象を避ければよいでしょうか。回避策はあるのでしょうか。
現実には、このような変化であれば新しいRevision IDを使うべきで、その場合すべての古いインスタンスは古いRevisionで完了まで継続させ、新しいインスタンスでは新しいRevisionを使うべきでしょう。
代替策として、"composite.xml"ファイルに以下のように追記することで、強制的にコンポジットをデプロイすることができます。

コンポジットレベル(つまりコンポジット内のすべてのBPMプロセスに適用される)でoracle.bpm.bpmn.force.deploy=trueを指定することもできますし、個々のBPMプロセスレベルで設定することもできます。詳細は「モデリングおよび実装ガイド」をご覧ください。
Oracle® Fusion Middleware Oracle Business Process Managementモデリングおよび実装ガイド 11g リリース1 (11.1.1.6.2)
Oracle Business Process Management Workspaceでの実行中のプロセス・インスタンスの変更
http://docs.oracle.com/cd/E28389_01/doc.1111/b61409/alt_flw_mig_bpmpd.htm
Oracle® Fusion Middleware Modeling and Implementation Guide for Oracle Business Process Management 11g Release 1 (11.1.1.6.3)
Modifying Running Process Instances in Oracle Business Process Management Workspace
http://docs.oracle.com/cd/E23943_01/doc.1111/e15176/alt_flw_mig_bpmpd.htm 
この設定で、先ほどと同様に「実行中のインスタンスの保持」オプションを指定してデプロイすると、以下のようなログが出てきます。

BPM Workspaceの[プロセストラッキング]タブをみると、以前にみたのと同じような状況を目の当たりにすることができます。つまり、先ほど述べた「保留中コンポーネント」という状態になっています。