D Oracle Business Rulesのトラブルシューティング
Oracle Business Rulesの使用時に発生する問題の回避策および解決方法。
D.1 非表示のgetterメソッドとsetterメソッド
ルール・デザイナでは、Java Beanプロパティをサポートしているメソッドは選択リストに表示されません。Beanプロパティのみが表示されます。たとえば、Y
という名前のプロパティを持つJava Beanには、少なくとも1つのgetterメソッドgetY()
が必要で、setterメソッドsetY(y-type-param)
が存在する場合もあります。
Java FactTypeを表示すると、すべてのプロパティとメソッド(プロパティを構成するgetterおよびsetterを含む)が表示されます。選択リストには、Javaクラスのプロパティ(getterおよびsetterメソッドは含まない)のみが表示されます。プロパティの表示を制御しようとする場合は、プロパティの表示フラグを使用するのが最善の方法です。getterまたはsetterメソッドを非表示にマークしても、選択リストからプロパティが削除されない場合もあります。
D.2 プロパティのsetterのみを使用したJavaクラス
Javaでは、Java Beanイントロスペクタに書込み専用プロパティが組み込まれています。Oracle RLでは、ルール内で判断できないため、Beanのようなプロパティは組み込まれません。
したがって、Oracle RLでJavaファクト・タイプのBeanプロパティに正しくアクセスするには、getterおよびsetterの両方が必要です。setterがあってgetterのないプロパティ、つまり書込み専用プロパティは、Oracle RLの新しい構文では許可されません。
たとえば、Bean Foo
のメソッドがsetProp1(int i)
のみの場合、Oracle RLでは次を使用できません。
Foo f = new Foo(prop1: 0)
D.3 実行時のNoClassDefFoundエラー
XMLファクトの使用中に、エラーを受信することがあります。
次のような形式のメッセージを受信する場合があります。
Exception in thread "main" java.lang.NoClassDefFoundError:
java.lang.NoClassDefFoundError
の原因は、必須クラスがCLASSPATHにないことである可能性があります。次をチェックしてみてください。
-
実行時にCLASSPATHに
xml.jar
を追加します。 -
生成済でコンパイル済のJAXBクラスが置かれるディレクトリをCLASSPATHに追加します。
D.4 RL固有のキーワード・ネーミング競合エラー
Oracle Business Rulesでは、ルール・デザイナからRLを生成する際、RL固有のキーワードがエスケープされます。
ほとんどの場合、RL固有のキーワードはエラーなしで使用できます。ただし、クラス名としてキーワードを使用する場合は例外です。規則では、Javaクラスは大文字で始まり、RL固有のキーワードはすべて小文字であるため、これはJavaクラスにはほとんどありません。
D.5 ビジネス・ルール・サービス・ランタイムからのjava.lang.IllegalAccessError
エラーがある可能性があります
問題: 次のようなエラーが送信されます。
java.lang.IllegalAccessError: tried to access class com.sun.xml.bind.v2.runtime.reflect.opt.Const from class:...
理由: これは、floatが必要な場合の不正な文字のアンマーシャリングで引き起こされるJAXB 2.1.6の問題490が原因である可能性があります。
回避策: この問題の回避策は、図D-1および図D-2に示すように、値を適切な要素に割り当てることです。図D-2では、approvalRequired
にデフォルト値false()
が割り当てられています。
スクリーン・ショットは、前のバージョンを反映していますが、内容は現在のリリースにも当てはまります。
D.6 JAXB 1.0ディクショナリとRLのMultipleInheritanceException
10.1.3から移行したディクショナリでは、JAXB 2.0ではなくJAXB 1.0が使用されます。これは、Oracle Fusion Middleware 11gリリース1 (11.1.1)ディクショナリのデフォルトです。このJAXB 1.0の使用により、移行されたディクショナリには要素タイプが含まれていない場合があります。ディクショナリの要素タイプが表示にマークされている場合、生成したRLによってMultipleInheritanceException
をスローされることになります。
この問題の解決策は、要素ファクト・タイプを参照不可としてマーク付けするか、データ・モデルから削除することです。ルールの記述にはJAXBで生成されたタイプのクラスのみを使用する必要があるため、要素タイプを削除しても機能が損なわれることはありません。
D.7 アンダースコアを持つXMLスキーマでJAXBコンパイルに失敗するのはなぜですか。
JAXBの定義済の動作では、'_'
+ 数字という形式の名前が見つかったら、エラーになります。この場合、JAXBはこの文字列から明白なJavaクラス名を生成できません。JAXBのデフォルト動作では、'_'
+ 文字は単語の境界として処理されます(underscoreBinding="asWordSeparator"
)。つまり、アンダースコアが外されて、文字はUpperCamelCasedになります。たとえば、_fooBar
はFooBar
にマップされます。
この問題を解決するには、違う方法で名前を生成するように、直接JAXBのスキーマをカスタマイズする必要があります。underscoreBinding
のデフォルト値は"asWordSeparator"
に指定され、名前の先頭にアンダースコアを使用することはできません。
グローバルな注釈underscoreBinding="asCharInWord"
を使用すると、クラス名および番号の後の先頭が大文字のキャメル・ケースで'_'
が保持されます。
<xsd:annotation><xsd:appinfo> <jaxb:globalBindings underscoreBinding="asCharInWord" /> </xsd:appinfo></xsd:annotation>
このグローバルな注釈を使用すると、_1foo_bar_baz
のマッピングは_1Foo_Bar_Baz
となります。
D.8 デシジョン・サービスの入力と出力の要素タイプはどのように制限されますか。
デシジョン・サービスを使用して、入力を定義するXMLスキーマを含むビジネス・ルールを実行すると、XMLスキーマ・ファイルFoo.xsd
内の任意のcomplexType
tFoo
の場合、タイプtFoo
のXMLスキーマ要素foo
を1つのみ含めることができます。
デシジョン・サービスでは、同じタイプ"tFoo
"の2つの要素"foo
"および"bar
"を使用することはできません。
D.9 デシジョン・サービスの入力と出力のスキーマはどのように制限されますか。
デシジョン・サービスを使用する場合、スキーマでcomplexType
を定義するか、complexType
を定義する別のスキーマをインポートする必要があります。
次に示すような、complexType
を定義しないスキーマは使用できません。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.org" targetNamespace="http://www.example.org" elementFormDefault="qualified"> <xsd:element name="count" type="xsd:int"/> </xsd:schema>
D.10 インポートしたファクト・タイプ内のJava予約名はどのように処理したらよいですか。
Oracle Business Rulesでは、Java言語に同じ名前があるファクト・タイプ・プロパティをインポートすると、予約語が除外されます。
Javaの予約語の一覧は、次のページを参照してください。
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
回避策として、除外されるプロパティを作成するgetterおよびsetterメソッドのペアの名前を変更することがあげられます。これらのメソッド名を変更できない場合、メソッドが、プロパティではなくルール内で使用されているということです。
たとえば、continue
という名前のプロパティが除外された場合は、プロパティを使用するかわりに、getContinue()
およびsetContinue()
メソッドを使用するルールを作成できます。このためには、パターンをリライトします。たとえば、次を置換します。
fact IncrCount ic && ic.continue == "foo"
置換後:
fact IncrCount ic && ic.getContinue() == "foo"
別の例では、アクションで、次のように置換します。
[assert new] IncrCount(continue:"bar")
置換後:
[assign new] IncrCount ic = new IncrCount( ) [call] ic.setContinue("bar") [assert] ic