目的
Libertyで実行するEJBにtWASからアクセスするテストをしたときの備忘録です。
EJBの作り直し
ThinClientでも実行したいので、EJBの作り直しをしました。
EclipseのEJBプロジェクトでSession BeansをNewして作成します。
以下のような画面にしてRemote interfaceを用意します。
Hello.javaにメソッドを追加します。
package pdprof.ejb;
import javax.ejb.Remote;
import javax.ejb.RemoteHome;
import javax.ejb.Stateless;
import pdprof.ejb.view.HelloRemote;
import pdprof.ejb.view.HelloRemoteHome;
/**
* Session Bean implementation class Hello
*/
@Stateless(mappedName = "ejb/Hello")
@Remote(HelloRemote.class)
@RemoteHome(HelloRemoteHome.class)
public class Hello implements HelloRemote {
/**
* Default constructor.
*/
public Hello() {
// TODO Auto-generated constructor stub
}
public String hello() {
return "Hello!!";
}
}
作成したメソッドをEJBのメソッドとして使えるようにPromoteします。
そうするとHelloRemote.javaにhello()メソッドが追加されています。
Annotationを手書きで追加を試みましたが、うまくいかず結果としてGUIで作成する方法が簡単でした。一度作成することで同じような構成をGUIを使わずに真似してかけるようになるかと思います。
ServletのEJBアノテーションでJNDIのLookupが失敗する
EJBの定義が変わってしまったことでサーブレットのEJBアノテーションの指定ではJNDIのLookupが失敗してしまうので修正しました。Hello から HelloRemoteに変更です。Business Interface作成の影響と思われます。
@EJB
HelloRemote hello;
launchClient で tWASにアクセス
順に構成をためしていくので、アクセスが問題ないと考えられる組み合わせから試します。
tWAS上のEJBはdumpNameSpace.sh で確認できます。
[was@17c043663791 ejb-ear.ear]$ /opt/IBM/WebSphere/AppServer/bin/dumpNameSpace.sh -username wsadmin -password passw0rd | grep Hello
18 (top)/nodes/DefaultNode01/servers/server1/pdprof.ejb.view.HelloRemote
18 pdprof.ejb.view.HelloRemote
49 (top)/nodes/DefaultNode01/servers/server1/pdprof.ejb.view.HelloRemoteHome
49 pdprof.ejb.view.HelloRemoteHome
66 (top)/nodes/DefaultNode01/servers/server1/ejb/ejb-ear/ejb-lib.jar/Hello#pdprof.ejb.view.HelloRemoteHome
66 pdprof.ejb.view.HelloRemoteHome
67 (top)/nodes/DefaultNode01/servers/server1/ejb/ejb-ear/ejb-lib.jar/Hello#pdprof.ejb.view.HelloRemote
67 pdprof.ejb.view.HelloRemote
108 (top)/applications/com.ibm.ws.AppNameSpaces/ejb-ear/root/ejb-lib/Hello!pdprof.ejb.view.HelloRemoteHome
108 pdprof.ejb.view.HelloRemoteHome
109 (top)/applications/com.ibm.ws.AppNameSpaces/ejb-ear/root/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
109 pdprof.ejb.view.HelloRemote
132 (top)/applications/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
132 pdprof.ejb.view.HelloRemote
133 (top)/applications/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemoteHome
133 pdprof.ejb.view.HelloRemoteHome
Lookupさせるのは
- java:global/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
- java:app/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
- ejb/ejb-ear/ejb-lib.jar/Hello#pdprof.ejb.view.HelloRemote
- Lookupのもとが /nodes/DefaultNode01/servers/server1 であるためその先
- java:comp/env/twas/ejb/Hello
- 上のものを application-client.xml と ibm-application-client-bnd.xml に書いて参照
LaunchClientはサーバーにデプロイ後に以下の手順で実行しました。更新してデプロイする度に実行することになるので、コピーするものを準備しておくと作業が早くなります。
cd /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/config/cells/DefaultCell01/applications/ejb-ear.ear
/opt/IBM/WebSphere/AppServer/bin/createEJBStubs.sh ejb-ear.ear
mkdir unzip;cd unzip;unzip ../ejb-ear.ear;cd ..
/opt/IBM/WebSphere/AppServer/bin/launchClient.sh ejb-ear.ear -CCclasspath=$PWD/unzip/ejb-lib.jar
ThinClientでtWASにアクセス
前までに実行していた createEJBStubs.sh が忘れやすい処理なので、ThinClient動かすなら必要なことを残して置きます。
WAS同梱のJavaを使ってThinClientとしてtWASにアクセスします。
WASの環境なので
com.ibm.SSL.ConfigURL
com.ibm.CORBA.ConfigURL
が使えます。
/opt/IBM/WebSphere/AppServer/java/8.0/bin/java \
-classpath /opt/IBM/WebSphere/AppServer/runtimes/com.ibm.ws.ejb.thinclient_9.0.jar:$PWD/unzip/ejb-lib.jar:$PWD/unzip/ejb-client.jar \
-Djava.naming.provider.url=iiop://localhost:2809 \
-Dcom.ibm.SSL.ConfigURL=file:///opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props \
-Dcom.ibm.CORBA.ConfigURL=file:///opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/sas.client.props \
Main
launchClientでLibertyにアクセス
次にLibertyにアクセスします。コンテナー間での通信をしたいので、networkを作成することにしました。
$ podman network create pdprof-network
pdprof-network
$ podman network inspect pdprof-network
[
{
"name": "pdprof-network",
"id": "418c96d79ef374bb42fd7e6e66ba8eac59860da30f9290dc1aaf40890af15440",
"driver": "bridge",
"network_interface": "podman1",
"created": "2024-11-25T01:29:41.803460871+09:00",
"subnets": [
{
"subnet": "10.89.0.0/24",
"gateway": "10.89.0.1"
}
],
"ipv6_enabled": false,
"internal": false,
"dns_enabled": true,
"ipam_options": {
"driver": "host-local"
}
}
]
podman start の時に --network pdprof-network で同じネットワークになり、コンテナ名での名前解決が出きるようになります。
Liberty側の通信を受け入れる設定を追加するのに iiopEndpoint を指定しました。
<iiopEndpoint id="defaultIiopEndpoint" host="ejb-jndi" iiopPort="2809">
<iiopsOptions iiopsPort="9402" sslRef="defaultSSLConfig"/>
</iiopEndpoint>
<orb id="defaultOrb">
<serverPolicy.csiv2>
<layers>
<authenticationLayer establishTrustInClient="Never"/>
</layers>
</serverPolicy.csiv2>
</orb>
providerURLの接続先を変えてアクセスする。
- launchClient
/opt/IBM/WebSphere/AppServer/bin/launchClient.sh ejb-ear.ear \
-CCclasspath=$PWD/unzip/ejb-lib.jar \
-CCproviderURL=corbaloc:iiop:ejb-jndi:2809
JNDIのLookup先の一部は成功しているので、動作していることが確認できる。
ThinClientでLibertyにアクセス
java.naming.provider.url=iiop://ejb-jndi:2809 の部分で接続先を変更して実行する。
- ThinClient
/opt/IBM/WebSphere/AppServer/java/8.0/bin/java \
-classpath /opt/IBM/WebSphere/AppServer/runtimes/com.ibm.ws.ejb.thinclient_9.0.jar:$PWD/unzip/ejb-lib.jar:$PWD/unzip/ejb-client.jar \
-Djava.naming.provider.url=iiop://ejb-jndi:2809 \
-Dcom.ibm.SSL.ConfigURL=file:///opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props \
-Dcom.ibm.CORBA.ConfigURL=file:///opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/sas.client.props \
Main
ThinClientではこれまでのすべてのJNDI Lookupが失敗してしまったので、Lookup先の追加が必要になります。ログを確認すると
CNTR0167I: The server is binding the pdprof.ejb.view.HelloRemote interface of the Hello enterprise bean in the ejb-lib.jar module of the ejb-ear application.
The binding location is: ejb/ejb-ear/ejb-lib.jar/Hello#pdprof.ejb.view.HelloRemote
とでているので1つは問題なさそうなだが失敗してしまいます。
を確認し
Object found = c.lookup("ejb/global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface");
となっていたので、ejb/global/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemote を lookupさせます。これで、ThinClientでもLibertyに接続できるのが確認できました。ここでLookup先に
- ejb/global/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
- java:comp/liberty/ejb/Hello
- 上のものを application-client.xml と ibm-application-client-bnd.xml に書いて参照
を追加しました。
試しに実行すると、dumpNameSpace.sh -host ejb-jndi -root default で確認出来ました。
/opt/IBM/WebSphere/AppServer/bin/dumpNameSpace.sh -host ejb-jndi -root default
Getting the initial context
Getting the starting context
==============================================================================
Name Space Dump
Context factory: com.ibm.websphere.naming.WsnInitialContextFactory
Provider URL: corbaloc:iiop:ejb-jndi:2809
Requested root context: default
Starting context: (top)=WebSphere Name Tree Root
Formatting rules: jndi
Time of dump: Mon Nov 25 16:11:35 UTC 2024
==============================================================================
==============================================================================
Beginning of Name Space Dump
==============================================================================
1 (top)
2 (top)/ejb com.ibm.ws.naming.jndicos.CNContextImpl
3 (top)/ejb/global com.ibm.ws.naming.jndicos.CNContextImpl
4 (top)/ejb/global/ejb-ear com.ibm.ws.naming.jndicos.CNContextImpl
5 (top)/ejb/global/ejb-ear/ejb-lib com.ibm.ws.naming.jndicos.CNContextImpl
6 (top)/ejb/global/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemoteHome
6 org.omg.stub.java.rmi._Remote_Stub
7 (top)/ejb/global/ejb-ear/ejb-lib/Hello!pdprof.ejb.view.HelloRemote
7 org.omg.stub.java.rmi._Remote_Stub
==============================================================================
End of Name Space Dump
==============================================================================
ThinClientをIBM Java以外で動作させる
WASのJavaで動作させているので、それ以外のJavaでも動作させるようにします。前にも見たページなのだけど、
と、WASについていた ssl.client.propsを見ながら以下のようにして /tmp/ssl.client.propsとして保管します。
user.root=/opt/IBM/WebSphere/AppServer/profiles/AppSrv01
com.ibm.ssl.alias=DefaultSSLSettings
com.ibm.ssl.protocol=TLSv1.2
com.ibm.ssl.trustManager=SunX509
com.ibm.ssl.keyManager=SunX509
com.ibm.ssl.contextProvider=SunJSSE
com.ibm.ssl.keyStoreType=PKCS12
com.ibm.ssl.keyStoreProvider=SUN
com.ibm.ssl.keyStore=${user.root}/etc/key.p12
com.ibm.ssl.keyStorePassword={xor}CDo9Hgw=
com.ibm.ssl.trustStoreType=PKCS12
com.ibm.ssl.trustStoreProvider=SUN
com.ibm.ssl.trustStore=${user.root}/etc/trust.p12
com.ibm.ssl.trustStorePassword={xor}CDo9Hgw=
Javaは tWASの環境にOSデフォルトのjavaを導入することにします。podmanでrootでbashを起動して導入します。
podman exec -u 0 -it was90-ejb bash
dnf -y install java-1.8.0
でうまくいくはずなのですが、container起動時に指定したネットワークが違うせいか、外部ネットワークに接続できていないので、build時に導入できるようにDockerfileを書きます。
Javaの導入ディレクトリを確認します。OSファイルの変更もするので、-u 0 で動かす必要があります。
# ls -l /usr/bin/java
lrwxrwxrwx. 1 root root 22 Nov 25 15:32 /usr/bin/java -> /etc/alternatives/java
# ls -al /etc/alternatives/java
lrwxrwxrwx. 1 root root 71 Nov 25 15:32 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.432.b06-2.el8.x86_64/jre/bin/java
# cd /usr/lib/jvm
# ls -al
total 0
drwxr-xr-x. 3 root root 183 Nov 25 15:32 .
dr-xr-xr-x. 1 root root 160 Nov 25 15:32 ..
drwxr-xr-x. 3 root root 17 Nov 25 15:32 java-1.8.0-openjdk-1.8.0.432.b06-2.el8.x86_64
lrwxrwxrwx. 1 root root 21 Nov 25 15:32 jre -> /etc/alternatives/jre
lrwxrwxrwx. 1 root root 27 Nov 25 15:32 jre-1.8.0 -> /etc/alternatives/jre_1.8.0
lrwxrwxrwx. 1 root root 35 Nov 25 15:32 jre-1.8.0-openjdk -> /etc/alternatives/jre_1.8.0_openjdk
lrwxrwxrwx. 1 root root 49 Oct 13 19:16 jre-1.8.0-openjdk-1.8.0.432.b06-2.el8.x86_64 -> java-1.8.0-openjdk-1.8.0.432.b06-2.el8.x86_64/jre
lrwxrwxrwx. 1 root root 29 Nov 25 15:32 jre-openjdk -> /etc/alternatives/jre_openjdk
細かいバージョンが変わってもいいようにパスの指定は必要そうだけど、今回は
cd /usr/lib/jvm/jre/lib/
mkdir endorsed
cp /opt/IBM/WebSphere/AppServer/runtimes/endorsed/endorsed_apis_9.0.jar .
にします。-classpathに/opt/IBM/WebSphere/AppServer/runtimes/com.ibm.ws.orb_9.0.jarを追加して、-Dcom.ibm.SSL.ConfigURL=file:///tmp/ssl.client.props のようにSSLの指定も変更します。
/usr/bin/java \
-classpath /opt/IBM/WebSphere/AppServer/runtimes/com.ibm.ws.ejb.thinclient_9.0.jar:/opt/IBM/WebSphere/AppServer/runtimes/:/opt/IBM/WebSphere/AppServer/runtimes/com.ibm.ws.orb_9.0.jar:$PWD/unzip/ejb-lib.jar:$PWD/unzip/ejb-client.jar \
-Djava.naming.provider.url=iiop://ejb-jndi:2809 \
-Dcom.ibm.SSL.ConfigURL=file:///tmp/ssl.client.props \
-Dcom.ibm.CORBA.ConfigURL=file:///opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/sas.client.props \
Main
これで動くようになります。ThinClientで動作するはずのLookupでもcom.ibm.ssl.protocolの指定が原因でSSL接続が失敗してしまうことも起きてしまったので、例外を確認しながら対応をすすめます。
発生した例外
Caused by: org.omg.CORBA.COMM_FAILURE: CAUGHT_EXCEPTION_WHILE_CONFIGURING_SSL_CLIENT_SOCKET Exception=java.lang.IllegalArgumentException: Unsupported protocolTLS vmcid: 0x49421000 minor code: 112 completed: No
at com.ibm.ws.security.orbssl.WSSSLClientSocketFactoryImpl.createSSLSocket(WSSSLClientSocketFactoryImpl.java:248)
at com.ibm.ws.orbimpl.transport.WSSSLTransportConnection.createSocket(WSSSLTransportConnection.java:258)
at com.ibm.CORBA.transport.TransportConnectionBase.connect(TransportConnectionBase.java:353)
at com.ibm.ws.orbimpl.transport.WSTransport$1.run(WSTransport.java:503)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.orbimpl.transport.WSTransport.getConnection(WSTransport.java:500)
at com.ibm.CORBA.transport.TransportBase.getConnection(TransportBase.java:182)
at com.ibm.rmi.iiop.TransportManager.get(TransportManager.java:98)
at com.ibm.rmi.iiop.GIOPImpl.getConnection(GIOPImpl.java:134)
at com.ibm.rmi.iiop.GIOPImpl.locate(GIOPImpl.java:230)
at com.ibm.rmi.corba.ClientDelegate.locate(ClientDelegate.java:1740)
at com.ibm.rmi.corba.ClientDelegate._createRequest(ClientDelegate.java:1765)
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1050)
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1135)
... 20 more
このエラーは com.ibm.ssl.protocol=TLS の指定が原因で起きていて、TLSv1.2を指定することで接続ができました。
Liberty clientから Libertyに接続する。
Liberty clientで動かす Application ClientのMaiクラスは @EJBが使えて、このアノテーションがあるとlaunchClientやThinClientではエラーになってしまったので、別のEnterprise Applicationを作成してApplication Clientだけ違うものをパッケージするように構成しました。
パッケージの時の参照構造は以下でどちらも同じejb-ear.earとしてexportする。アプリケーション名が変わってしまうとJNDI名が変わってしまうので、同じ名前で動作させる方が問題になりにくい。
- ejb-ear (tWAS用 Enterprise Application)
- ejb-client
- ejb-hello
- ejb-lib
- ejb-liberty-ear (Liberty用 Enterprise Application)
- ejb-liberty-client
- ejb-hello
- ejb-lib
接続先のLibertyサーバーの指定は
<orb id="defaultOrb" nameService="corbaname::localhost:2809">
<clientPolicy.clientContainerCsiv2>
<layers>
<authenticationLayer user="wsadmin" password="passw0rd" />
</layers>
</clientPolicy.clientContainerCsiv2>
</orb>
で指定します。認証情報も指定します。java.naming.provilder.url システムプロパティを指定して動作しませんでした。
まとめ
今回は launchClient, Thin Client, Liberty Client からLiberty ServerのEJBにアクセスするため、試した内容を備忘録として残しました。構成や手順もまとまってきたので、次は自動化して手順を忘れてしまっても環境が構築できるようにします。