5.12. EJB クライアントコードの移行

5.12.1. JBoss EAP 7 での EJB クライアントの変更

JBoss EAP 7 ではデフォルトのリモートコネクターおよびポートが変更になりました。この変更の詳細は リモート URL コネクターおよびポートの更新 を参照してください。

migrate 操作を使用してサーバー設定を移行した場合は、旧設定は保持されるため以下の変更を行う必要はありません。しかし、新しい JBoss EAP 7 のデフォルト設定で実行する場合は以下の変更を行う必要があります。

5.12.1.1. デフォルトのリモート接続ポートの更新

jboss-ejb-client.properties ファイルのリモート接続ポートの値を 4447 から 8080 に変更します。

以下は、前リリースと本リリースの jboss-ejb-client.properties ファイルの例になります。

例: JBoss EAP 6 の jboss-ejb-client.properties ファイル

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

例: JBoss EAP 7 の jboss-ejb-client.properties ファイル

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

5.12.1.2. デフォルトコネクターの更新

新しい JBoss EAP 7 設定で実行している場合、デフォルトのコネクターは remote から http-remoting に変更になりました。この変更は、使用するライブラリーと接続するサーバーの JBoss EAP リリースが異なるクライアントに影響します。

  • クライアントアプリケーションが JBoss EAP 6 の EJB クライアントライブラリーを使用し、JBoss EAP 7 サーバーへ接続する場合、8080 以外のポートで remote コネクターを公開するようサーバーを設定する必要があります。その後、そのクライアントは新しく設定されたコネクターを使用して接続する必要があります。
  • JBoss EAP 7 の EJB クライアントライブラリーを使用し、JBoss EAP 6 サーバーへ接続するクライアントアプリケーションは、サーバーインスタンスによって http-remoting コネクターは使用されず、remote コネクターが使用されることを認識する必要があります。これは、新しいクライアント側接続プロパティーを定義することで実現されます。

    例: remote 接続プロパティー

    remote.connection.default.protocol=remote

5.12.2. リモートネーミングクライアントコードの移行

新しいデフォルトの JBoss EAP 7 設定で実行している場合、新しいデフォルトのリモートポートおよびコネクターを使用するようクライアントコードを変更する必要があります。

以下の例は、リモートネーミングプロパティーが JBoss EAP 6 のクライアントコードでどのように指定されていたかを示しています。

java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=remote://localhost:4447

以下は、JBoss EAP 7 のクライアントコードでリモートネーミングプロパティーを指定する方法の例になります。

java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory
java.naming.provider.url=http-remoting://localhost:8080

5.12.3. JBoss EAP 7.1 に導入された EJB Client のその他の変更

JBoss EAP 7.0 には JBoss EJB Client 2.1.4 が同梱されていましたが、JBoss EAP 7.1 以上には JBoss EJB Client 4.0.x が同梱され、API に複数の変更が追加されました。

  • 以下の新しいメソッドに org.ejb.client.EJBClientInvocationContext クラスが追加されました。

    方法タイプ説明

    isBlockingCaller()

    boolean

    この呼び出しによって呼び出しているスレッドが現在ブロックされているかどうかを判断します。

    isClientAsync()

    boolean

    メソッドがクライアント非同期 (client-asynchronus) としてマークされているかどうかを判断します。 マークされていると、サーバー側のメソッドが非同期であるかどうかに関わらず、呼び出しは非同期になります。

    isIdempotent()

    boolean

    メソッドが冪等 (idempotent) としてマークされているかどうかを判断します。 マークされていると、メソッドは追加の効果なしで複数回呼び出されることがあります。

    setBlockingCaller(boolean)

    void

    この呼び出しによって呼び出しているスレッドが現在ブロックされているかどうかを確定します。

    setLocator(EJBLocator<T>)

    <T> void

    呼び出し先のロケーターを設定します。

  • org.ejb.client.EJBLocator クラスは以下の新しいメソッドに追加されました。

    方法タイプ説明

    asStateful()

    StatefulEJBLocator<T>

    ある場合、このロケーターをステートフルロケーターとして返します。

    asStateless()

    StatelessEJBLocator<T>

    ある場合、このロケーターをステートレスロケーターとして返します。

    isEntity()

    boolean

    これがエンティティーロケーターであるかどうかを判断します。

    isHome()

    boolean

    これがホームロケーターであるかどうかを判断します。

    isStateful()

    boolean

    これがステートフルロケーターであるかどうかを判断します。

    isStateless()

    boolean

    これがステートレスロケーターであるかどうかを判断します。

    withNewAffinity(Affinity)

    abstract EJBLocator<T>

    このロケーターのコピーを新しいアフィニティーで作成します。

  • 特権のある EJB 操作へのアクセスを制御するために、java.security.Permission のサブクラスである新しい org.ejb.client.EJBClientPermission クラスが導入されました。

    • 以下のコンストラクターを提供します。

      • EJBClientPermission(String name)
      • EJBClientPermission(String name, String actions)
    • 以下のメソッドを提供します。

      方法タイプ説明

      equals(EJBClientPermission obj)

      boolean

      2 つの EJBClientPermission オブジェクトが等値であるかをチェックします。

      equals(Object obj)

      boolean

      2 つの Permission オブジェクトが等値であるかをチェックします。

      equals(Permission obj)

      boolean

      2 つの Permission オブジェクトが等値であるかをチェックします。

      getActions()

      String

      アクションを文字列として返します。

      hashcode()

      int

      この Permission オブジェクトのハッシュコード値を返します。

      implies(EJBClientPermission permission)

      boolean

      指定パーミッションのアクションが、この EJBClientPermission オブジェクトのアクションによって 暗示 されたかどうかをチェックします。

      implies(Permission permission)

      boolean

      指定パーミッションのアクションが、この Permission オブジェクトのアクションによって 暗示 されたかどうかをチェックします。

  • 特定の EJB メソッドを見つけるために、新しい org.ejb.client.EJBMethodLocator クラスが導入されました。

    • 以下のコンストラクターを提供します。

      • EJBMethodLocator(String methodName, String…​ parameterTypeNames)
    • 以下のメソッドを提供します。

      方法タイプ説明

      equals(EJBMethodLocator other)

      boolean

      このオブジェクトが別のオブジェクトと等しいかどうかを判断します。

      equals(Object other)

      boolean

      このオブジェクトが別のオブジェクトと等しいかどうかを判断します。

      forMethod(Method method)

      static EJBMethodLocator

      指定のリフレクションメソッドのメソッドロケーターを取得します。

      getMethodName()

      String

      メソッド名を取得します。

      getParameterCount()

      int

      パラメーターの数を取得します。

      getParameterTypeName(int index)

      String

      指定インデックスのパラメーターの名前を取得します。

      hashCode()

      int

      ハッシュコードを取得します。

  • 失敗したケースに対して、org.jboss.ejb.client.EJBReceiverInvocationContext.ResultProducer.Failed クラスが新たに導入されました。

    • 以下のコンストラクターを提供します。

      • Failed(Exception cause)
    • 以下のメソッドを提供します。

      方法タイプ説明

      discardResult()

      void

      結果を破棄し、使用されないことを示します。

      getResult()

      オブジェクト

      結果を取得します。

  • 即座に結果を得るために、org.jboss.ejb.client.EJBReceiverInvocationContext.ResultProducer.Immediate クラスが新たに導入されました。

    • 以下のコンストラクターを提供します。

      • Failed(Exception cause)
    • 以下のメソッドを提供します。

      方法タイプ説明

      discardResult()

      void

      結果を破棄し、使用されないことを示します。

      getResult()

      オブジェクト

      結果を取得します。

  • URI アフィニティーを指定するために、org.jboss.ejb.client.Affinity のサブクラスである org.jboss.ejb.client.URIAffinity クラスが新たに導入されました。

    • これは、Affinity.forUri(URI) を使用して作成されます。
    • 以下のメソッドを提供します。

      方法タイプ説明

      equals(Affinity other)

      boolean

      別のオブジェクトがこのオブジェクトと等しいかどうかを示します。

      equals(Object other)

      boolean

      別のオブジェクトがこのオブジェクトと等しいかどうかを示します。

      equals(URIAffinity other)

      boolean

      別のオブジェクトがこのオブジェクトと等しいかどうかを示します。

      getURI()

      URI

      関連する URI を取得します。

      hashCode()

      int

      ハッシュコードを取得します。

      toString()

      String

      オブジェクトの文字列表現を返します。

  • org.jboss.ejb.client.EJBMetaDataImpl クラスによって以下のメソッドが非推奨になりました。

    • toAbstractEJBMetaData()
    • EJBMetaDataImpl(AbstractEJBMetaData<?,?>)

5.12.4. JBoss EAP 7 で必要な EJB クライアントの変更

JBoss EAP 7.2 では org.apache.santuario.xmlsec モジュールが 2.0.8 から 2.1.1 にアップグレードされ、PicketLinkSTS のリモーティングで回帰が発生します。この問題により以下のランタイム例外が発生します。

java.lang.IllegalArgumentException: ELY05131: Invalid ASCII control "0xA"

これは、アサーションの生成された SignatureValue のフォーマットの変更が原因です。これまでのリリースでは、生成された値は以下の例と似ていました。

<dsig:SignatureValue xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">cUNpFJIZlLYrBDZtQSTDrq2K6PbnAHyg2qbx/D5FuB4XMjdQ5oxQjkMejLyelnA7s4GFusoLhahlqlTOT8UrOyxrR4yYAmJ/e5s+f4gys926+tbiraT/3/wG8wM/Lvcjvk5Ap69zODuRYpypsWfA4jrI7TTBXVPGy8g4KUdnFviUiTuFTc2Ghgxp53AmUuLis/THyP28jE7+28//q8bi/bQrFwHC6tWX67+NK1duFCOcQ6IPIKeVrePZz55Ivgl+WWdkF6uYCz5IdMzurhzmeQ3K8DAMIxz/MG67VWJIOnuGNWF7nmdye5zd9AFcRsr1XadvZJCbGNfuc89AL5inCg==</dsig:SignatureValue>

JBoss EAP 7.2 では、生成された値に無効な非表示の ASCII 0xD キャリッジリターンおよび 0xD ラインフィード制御文字のインスタンスが含まれます。

<dsig:SignatureValue xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">cUNpFJIZlLYrBDZtQSTDrq2K6PbnAHyg2qbx/D5FuB4XMjdQ5oxQjkMejLyelnA7s4GFusoLhahl&#13;
qlTOT8UrOyxrR4yYAmJ/e5s+f4gys926+tbiraT/3/wG8wM/Lvcjvk5Ap69zODuRYpypsWfA4jrI&#13;
7TTBXVPGy8g4KUdnFviUiTuFTc2Ghgxp53AmUuLis/THyP28jE7+28//q8bi/bQrFwHC6tWX67+N&#13;
K1duFCOcQ6IPIKeVrePZz55Ivgl+WWdkF6uYCz5IdMzurhzmeQ3K8DAMIxz/MG67VWJIOnuGNWF7&#13;
nmdye5zd9AFcRsr1XadvZJCbGNfuc89AL5inCg==</dsig:SignatureValue>

上記のランタイム例外が発生した場合はクライアントコードを更新し、発生した非表示の ASCII 文字を返されたアサーション文字列から削除する必要があります。

たとえば、現在のコードが以下の例と同様であるとします。

WSTrustClient client = new WSTrustClient("PicketLinkSTS", "PicketLinkSTSPort",
                "http://localhost:8080/picketlink-sts/PicketLinkSTS", new WSTrustClient.SecurityInfo(username, password));
Element assertion = client.issueToken(SAMLUtil.SAML2_TOKEN_TYPE);

// Return the assertion as a string
String assertionString = DocumentUtil.getNodeAsString(assertion);
...
properties.put("remote.connection.main.password", assertionString);

コードを 1 行追加して、以下のように無効な非表示の ASCII 0xD キャリッジリターンおよび 0xA ラインフィード文字を削除する必要があります。

WSTrustClient client = new WSTrustClient("PicketLinkSTS", "PicketLinkSTSPort",
                "http://localhost:8080/picketlink-sts/PicketLinkSTS", new WSTrustClient.SecurityInfo(username, password));
Element assertion = client.issueToken(SAMLUtil.SAML2_TOKEN_TYPE);

// Return the assertion as a string, stripping the invalid hidden ASCII characters
String assertionString = DocumentUtil.getNodeAsString(assertion).replace(String.valueOf((char) 0xA), "").replace(String.valueOf((char) 0xD), "");
...
properties.put("remote.connection.main.password", assertionString);