2

我一直无法从我在 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

我真的迷路了。我一直有很多问题要让这件事继续下去,我必须得到所有 glassfish 罐子(库和模块)才能InitialContext()打电话,但现在我不确定这是否仍然是罐子问题或配置问题或它是什么。

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

所以问题是为什么会出现这个异常?

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

4

1 回答 1

2

错误是您尝试使用 grails 中的 tomcat 插件运行您的 Web 应用程序(使用命令 grails run-app)。问题是,当您尝试创建 InitialContext ( com.sun.enterprise.naming.SerialInitContextFactory) 时,如果您使用的是 GF 3.1 的客户端库,groovy 会在转换某些类型时出错。(我知道这是问题所在,但我真的不知道这是什么原因。因为理论上这应该可行)

如果生成 .war 文件并部署在 AppServer 中,则可以毫无问题地连接到 EJB。如果你将它部署在另一个 GF 服务器上,你就不必导入任何客户端 jars。

这将在生产环境中完美运行,唯一的问题是您必须在 GF 服务器上编译和部署您的应用程序,每进行一点更改,这在开发中有点烦人。

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

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 控制台和 grails run-app 命令,必须修改配置文件 $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
于 2013-04-30T14:40:07.987 回答