EJB客户端如何不用任何client jar去动态调用远程服务器的EJB?

08-03-16 zxp8088
我现在的项目遇到一个这样的问题,希望高手能给与解答。万分感谢!

客户端调用stateless EJB,客户端Classpath没有ejb client jar以及ejb的任何类。试图通过反射来解决,
但是一直没有成功。使用如下代码,发现依然需要导入home接口才能运行。无法满足不导入任何接口的要求。

//REFLECT EJB..REFLECT..

import javax.ejb.*;
//no-need to import anything..!!
public Class client_ejb_reflection {

public static void main(String args[]){
//1. create initial context
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory" );
env.put(Context.PROVIDER_URL, "jnp://192.168.66.66:1099" );
env.put("Java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");Context c = new InitialContext(env);
//2. look-up home
Object home = ctx.lookup(JNDI_NAME);
EJBHome theHome =(EJBHome) PortableRemoteObject.narrow(home, EJBHome.class)

//3. create the remote

EJBMetaData md =
this.theHome.getEJBMetaData();
Class homeClass =
md.getHomeInterfaceClass();
EJBObject theRemote = (EJBObject)
this.invoke(homeClass,theHome,"create");

//4. use the remote
Class remoteClass =
md.getRemoteInterfaceClass();
String message =
this.invoke(remoteClass,theRemote,"getMessage");
}

static Object invoke(Class c,Object obj,String mname){

Method[] methods = c.getMethods();
String name=null;
Object r= null;
try {
for(int i = 0; i <methods.length ;i++) {
name = methods.getName();
if(name.startsWith(mname)) {
r = methods.invoke(obj,null);
}
}
} catch(Exception e){
e.printStackTrace();

}
return r;
}
}

如果不导入home接口,就会报如下错误:

javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: com.rchema.GET_CUSTOMERHome (no security manager: RMI class loader disabled)]
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.rchema.EJBClientDynamic.dynamic_invoke(EJBClientDynamic.java:73)
at com.rchema.EJBClientDynamic.main(EJBClientDynamic.java:52)

banq
2008-03-17 21:33
可以参考Jdon框架中这部分代码,但是客户端最后使用时,可能要EJB的接口的,否则无法使用

zxp8088
2008-03-18 12:46
banq大哥,还有一个思路解决此问题,就是通过使用Corba,不知道是否可行。通过EJB container的Naming port,获取一个CORBA Object。类似于这样的代码:


ORB orb = ORB.init((String[])null, props);
//corbaname: iiop:<hostName>:<port>/<root>name
org.omg.CORBA.Object obj = orb.string_to_object(corbaName);
if (obj instanceof ObjectImpl) {
ObjectImpl objectImpl = (ObjectImpl)obj;
org.omg.CORBA_2_3.portable.InputStream in = null;
org.omg.CORBA.portable.OutputStream out = objectImpl ._request("create", true);
org.omg.CORBA_2_3.portable.InputStream in = (org.omg.CORBA_2_3.portable.InputStream)objectImpl ._invoke(out);
Object remoteStub = in.read_Object(_Remote_Stub.class);
}

通过上面的方式得到remote interface stub,然后再调用业务方法。
我测试了一下,使用jboss服务器,连接naming port为1098,但是orb.string_to_object(corbaName)返回结果为
null.有点晕。:(