Kevin Fernandez
Kevin Fernandez

Reputation: 21

How to access EJB services from a grails standalone client

I've been having problems to access to my EJB services from a standalone client i've developed on grails 2.0.3. The EJB services are deployed on a glassfish server (Java). I tested this code on a netbeans tester class to access the EJBs:

    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){
        ...
    }

This Tester.AUTHENTICATION_SERVICE_JNDI is a variable tha contains the path to the deployed service, in this case something like "java:global/..." that represents the address to the service that is being requested. This way of accessing the services works perfectly from the tester, but when i try to do the same from grails doesn't works. I am able to create the context the same way, but when i invoke the ctx.lookup() call i get an exception:

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]

The main exception is a naming exception, which means that it failed in the ctx.lookup(), but the cause is the orb initialization exception, which has another exception stack:

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

I'm really lost here. I've been having a lot of problems to get this going on grails, I had to get all glassfish jars (libs and modules) so it could make the InitialContext() call, but now i'm not sure if this is still a jar problem or a configuration problem or what it is.

I know that IllegalArgumentException occurs when u try to assign incompatible types in java, but i'm not setting anything like that, so i assume its an internal method initialization.

So the question is why is this exception coming up??

Is there another way to invoke my services from grails that works better??

Upvotes: 2

Views: 902

Answers (1)

Christian Delgado
Christian Delgado

Reputation: 21

The error is that you're trying to run your web application using the tomcat plugin in grails (using the command grails run-app). The problem is that when you try to create the InitialContext (com.sun.enterprise.naming.SerialInitContextFactory) groovy gives you an error casting some types if you're using the client libraries for GF 3.1. (I know that this is the problem, but I really don't know the reason for this. Because in theory this should work)

If you generate the .war file and you deploy in an AppServer, you can connect to your EJBs without problems. And if you deploy it on another GF server you don't have to import any of the client jars.

This will work perfect on production, the only problem is that you must compile and deploy your app on the GF server with every little change, and this is a bit annoying in development.

If you want to work outside of GF and using the command "grails run-app", you must modify two of the .jar GF 3.1 on your remote server, where you have the grails application:

1- The jar file $GLASSFISH_HOME/modules/glassfish-corba-omgapi.jar

You should search in the web the class com.sun.corba.ee.spi.orb.ParserImplBase, and modify this part

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

for this

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);
}

this should resolve the java.lang.IllegalArgumentException

2- The jar file $GLASSFISH_HOME/modules/glassfish-corba-orb.jar

you must delete the javax.rmi.CORBA.PortableRemoteObjectClass class of this library, because this class have conflicts with one used by the grails plugin

PS: If you do not want to have the GF client jars in your grails application, you can add to the classpath of your client machine the following libraries

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

If you use the grails console with the grails run-app command, must modify the configuration file $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

Upvotes: 2

Related Questions