Kohei Nozaki's blog 

別プロセスからリモートEJBを呼び出してみる


Posted on Sunday Feb 09, 2014 at 03:18PM in Technology


WildFly8にデプロイしてあるEJB(WARファイル内に存在)を、別のJavaプロセスからリモート呼び出ししてみる

環境

  • Eclipse Kepler SR1
  • WildFly8.0.0.CR1
  • Oracle JDK7u51

前提条件

WildFly8.0.0CR1でサーブレットを動かしてみる あたりでEclipseに加えた設定が終わっているものとする

準備

プロジェクトを作る

以下の3つを作ります

  1. リモートEJBインタフェースを含むプロジェクト(remoteejbif)
  2. リモートEJBの実装を含むプロジェクト(remoteejbwar)
  3. クライアント側プロジェクト(remoteejbclient)

リモートEJBインタフェースを含むプロジェクト(remoteejbif)

  1. 「remoteejbif」という名称のJavaプロジェクトを作る
  2. ソースを追加
package foo;


public interface HogeBean {

    String hoge();
}

リモートEJBの実装を含むプロジェクト(remoteejbwar)

  1. 「remoteejbwar」という名称のMavenプロジェクトをarchetype「javaee7-essentials」から作る
  2. プロジェクトの設定を開く
  3. Project Referencesでremoteejbifにチェックを入れる
  4. Java Build PathのProjectsタブでAddを押してremoteejbifを追加する
  5. Deployment Assembly→Add→Projectでremoteejbifを追加する。追加した後、再度設定内容を確認すると、追加されていなかったりするので注意(もう一度追加するとOKっぽい。なんだこれ)
  6. ソースを追加
  7. ソースを追加したらJava EE Perspective→Servers→WildFly→右クリック→Add and Removeからデプロイ
package foo;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(HogeBean.class)
public class HogeBeanImpl implements HogeBean{

    @Override
    public String hoge() {
        return "hoge from remote";
    }
}

クライアント側プロジェクト(remoteejbclient)

  1. 「remoteejbclient」という名称のJavaプロジェクトを作る
  2. プロジェクトの設定を開く
  3. Project Referencesでremoteejbifにチェックを入れる
  4. Java Build PathのProjectsタブでAddを押してremoteejbifを追加する
  5. Java Build PathのLibrariesタブでAdd External Jarsを押して$WILDFLY_HOME/bin/client/jboss-client.jarを追加する
  6. ソースを追加
package foo;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;

public class HogeBeanInvoker2 {

    public static void main(String[] args) throws Exception {
        Properties p = new Properties();
        p.put("remote.connections", "default");
        p.put("remote.connection.default.port", "8080");
        p.put("remote.connection.default.host", "localhost");
        p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", false);
        p.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        p.put("org.jboss.ejb.client.scoped.context", true);

        Context c = null;
        try {
            c = new InitialContext(p);
            HogeBean hogeBean = (HogeBean) c.lookup("ejb:/remoteejbwar//HogeBeanImpl!foo.HogeBean");
            System.out.println(hogeBean.hoge());
        } finally {
            c.close();
        }
    }
}

実行

「remoteejbclient」プロジェクトに作ったHogeBeanInvoker2を普通に実行する(右クリック→Run As→Java Application)。こんな感じの出力が出る。わりと速い

2 10, 2014 5:24:54 午後 org.xnio.Xnio <clinit>
INFO: XNIO version 3.2.0.Beta4
2 10, 2014 5:24:54 午後 org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.2.0.Beta4
2 10, 2014 5:24:54 午後 org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version (unknown)
2 10, 2014 5:24:54 午後 org.jboss.ejb.client.remoting.VersionReceiver handleMessage
INFO: EJBCLIENT000017: Received server version 2 and marshalling strategies [river]
2 10, 2014 5:24:54 午後 org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@1f1ee981, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection@2674241d,channel=jboss.ejb,nodename=kyle-no-macbook]} on channel Channel ID bb6edca7 (outbound) of Remoting connection 3aa7fab1 to localhost/127.0.0.1:8080
2 10, 2014 5:24:54 午後 org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.0.0.Beta5
hoge from remote

備考

デプロイ時に出力されるJNDI名は別プロセスからのリモート呼び出しには使えない

EJBをデプロイするとWildFlyの出力に以下のようなJNDI名が出力されるが、別プロセスからのリモート呼び出しでは使えなかった。別プロセスからlookupする場合は「ejb:」で始まるJNDI名を使わないといけないっぽい。詳細は参考文献を参照。

java:global/remoteejbwar/HogeBeanImpl!foo.HogeBean
java:app/remoteejbwar/HogeBeanImpl!foo.HogeBean
java:module/HogeBeanImpl!foo.HogeBean
java:jboss/exported/remoteejbwar/HogeBeanImpl!foo.HogeBean
java:global/remoteejbwar/HogeBeanImpl
java:app/remoteejbwar/HogeBeanImpl
java:module/HogeBeanImpl

同じAPサーバにデプロイされたアプリケーション間なら「java:global」で始まるJNDI名でlookup可能。

ユーザの作成は不要

参考文献を見るとユーザの作成が必要な旨の記述が多く見つかるが、どうやらこの環境では特に必要ない模様

standalone.xmlでOK

参考文献を見ると設定ファイルstandalone-full.xmlで起動している例が見つかるが、この記事のような単純なものの場合は特に必要ない模様。JMSとか使う場合に必要になるのかも

その他

レガシーでもはやなるべく使うべきではないと言われることもあるリモートEJB呼び出しだが、局面によっては依然使えると思われる

参考文献

  1. Tanmoy's Blog: WildFly: EJB invocations from a remote client
  2. java - WildFly: EJB invocations from a remote client - Stack Overflow
  3. EJB invocations from a remote client using JNDI - WildFly 8 - Project Documentation Editor
  4. JNDI Lookup Failing | Community
  5. Remote EJB invocations via JNDI - EJB client API or remote-naming project - WildFly 8 - Project Documentation Editor
  6. Java Web: Accessing remote EJB on JBoss AS 7.1 from web application
  7. JBoss EAP 6.2のリモートEJB呼び出し - nekopの日記