我在使用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调用我的服务更好?
答案 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