如何从grails独立客户端访问EJB服务

时间:2013-01-23 15:53:41

标签: web-services ejb grails-2.0

我在使用grails 2.0.3开发的独立客户端访问EJB服务时遇到了问题。 EJB服务部署在glassfish服务器(Java)上。我在netbeans测试器类上测试了这段代码来访问EJB:

    Properties p = new Properties();
    p.put("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
    p.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
    p.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
    p.setProperty("org.omg.CORBA.ORBInitialHost", INTEGRATION_IP);
    p.setProperty("org.omg.CORBA.ORBInitialPort", CORBA_PORT);
    ctx = new InitialContext(p);
    try {
        this.admAuth = (AdmAuthenticationRemote) this.ctx.lookup(Tester.AUTHENTICATION_SERVICE_JNDI);
    }catch(Exception e){
        ...
    }

Tester.AUTHENTICATION_SERVICE_JNDI是一个变量,它包含已部署服务的路径,在这种情况下类似于"java:global/...",表示正在请求的服务的地址。这种访问服务的方式完全可以从测试人员那里获得,但是当我尝试从grails中做同样的事情时,这种方法不起作用。我能够以相同的方式创建上下文,但是当我调用ctx.lookup()调用时,我得到一个例外:

Message: Lookup failed for 'java:global/...' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory, 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
Cause: javax.naming.NamingException: Unable to acquire SerialContextProvider for SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory, 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
[Root exception is java.lang.RuntimeException: Orb initialization erorr]

主要的例外是命名异常,这意味着它在ctx.lookup()中失败,但原因是orb初始化异常,它有另一个异常堆栈:

java.lang.RuntimeException: Orb initialization erorr
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set long field com.sun.corba.ee.impl.orb.ORBDataParserImpl.waitForResponseTimeout to java.lang.Integer
Caused by: java.lang.IllegalArgumentException: Can not set long field com.sun.corba.ee.impl.orb.ORBDataParserImpl.waitForResponseTimeout to java.lang.Integer

我真的迷失在这里。我一直有很多问题需要用grails,我必须得到所有的玻璃鱼罐子(库和模块)所以它可以进行InitialContext()调用,但现在我不确定这是不是仍然是一个jar问题或配置问题或它是什么。

我知道当你尝试在java中分配不兼容的类型时会出现IllegalArgumentException,但是我没有设置类似的东西,所以我假设它是一个内部方法初始化。

所以问题是为什么这个例外会出现?

是否有另一种方法可以从grails调用我的服务更好?

1 个答案:

答案 0 :(得分:2)

错误在于您尝试使用grails中的tomcat插件运行Web应用程序(使用命令grails run-app)。问题是,当您尝试创建InitialContext(com.sun.enterprise.naming.SerialInitContextFactory)时,如果您使用的是GF 3.1的客户端库,则groovy会为您提供一些错误。 (我知道这是问题,但我真的不知道这个的原因。因为理论上这应该有效)

如果生成.war文件并在AppServer中部署,则可以毫无问题地连接到EJB。如果您将其部署在另一台GF服务器上,则无需导入任何客户端jar。

这对于生产来说是完美的,唯一的问题是你必须在GF服务器上编译和部署你的应用程序,只需稍加改动,这在开发中有点烦人。

如果您想在GF之外工作并使用命令“grails run-app”,则必须修改远程服务器上的两个.jar GF 3.1,其中包含grails应用程序:

1- jar文件$ GLASSFISH_HOME / modules / glassfish-corba-omgapi.jar

您应该在网络上搜索班级com.sun.corba.ee.spi.orb.ParserImplBase,然后修改此部分

    Field field = getAnyField(name);
    field.setAccessible(true);
    field.set(ParserImplBase.this, value);

这个

if (name.equalsIgnoreCase("waitForResponseTimeout")) {
     Object newValue = new Long(1800000);
     Field field = getAnyField(name);
     field.setAccessible(true);
     field.set(ParserImplBase.this, newValue);
} else {
     Field field = getAnyField(name);
     field.setAccessible(true);
     field.set(ParserImplBase.this, value);
}

这应解决java.lang.IllegalArgumentException

2- jar文件$ GLASSFISH_HOME / modules / glassfish-corba-orb.jar

你必须删除这个库的javax.rmi.CORBA.PortableRemoteObjectClass类,因为这个类与grails插件使用的类有冲突

PS:     如果您不想在grails应用程序中安装GF客户端jar,可以在客户端计算机的类路径中添加以下库

$GLASSFISH_HOME/modules/ejb-container.jar
$GLASSFISH_HOME/modules/ejb.security.jar
$GLASSFISH_HOME/modules/management-api.jar

如果你使用带有grails run-app命令的grails控制台,必须修改配置文件$ GRAILS_HOME / conf / groovy-starter.conf whit this

   load $GLASSFISH_HOME/modules/ejb-container.jar
   load $GLASSFISH_HOME/modules/ejb.security.jar
   load $GLASSFISH_HOME/modules/management-api.jar
相关问题