Search code examples
ejb-3.0jndiapache-tomee

Configuring Tomee to allow WebSphere JNDI Lookups


We are currently developing an application intended for deployment on a WebSphere server. The application should use an in-house Service Provider, that provides access to services implemented as remote EJBs. The Service Provider bean has some hard-coded jndi-names to use.

Now during development we are using Tomee and in general all is working nicely. All except one thing: The ServiceProvider does a jndi-lookup of "cell/persistent/configService". Now I tried to create a mock ear that contains mock EJBs for these services. I am able to deploy them, and I am able to access them from the application using jndi-names like: "java:global/framework-mock-ear-1.0.0-SNAPSHOT/framework-mock-impl/ConfigServiceMock" but it seems to be impossible to access them using a jndi lookup of: "cell/persistent/configService" ... now I added an openejb-jar.xml file to my mock implementation containing:

<openejb-jar>
    <ejb-deployment ejb-name="ConfigServiceMock">
        <jndi name="cell/persistent/configService"
              interface="de.thecompany.common.services.config.ConfigService"/>
    </ejb-deployment>
</openejb-jar>

And I can see during startup, that the bean seems to be registered correctly under that name:

INFORMATION: Jndi(name=cell/persistent/configService) --> Ejb(deployment-id=ConfigServiceMock)

But I have now idea how to make the other ear be able to access this bean using that name.

The Service Provider part is given and we are not able to change this at all, so please don't suggest to change the hard-coded jndi names. We surely would like to do so, but are not able to change anything.


Solution

  • Ok ... to I wasted quite some time on this. Until I finally came up with a solution. Instead of configuring Tomee and OpenEJB to find my beans, I hijacked the InitialContext and rewrote my queries.

    package de.mycompany.mock.tomee;
    
    import org.apache.naming.java.javaURLContextFactory;
    
    import javax.naming.Context;
    import javax.naming.NamingException;
    import java.util.Hashtable;
    
    public class MycompanyNamingContextFactory extends javaURLContextFactory {
    
        private static Context initialContext;
    
        @Override
        public Context getInitialContext(Hashtable environment) throws NamingException {
            if(initialContext == null) {
                Hashtable childEnv = (Hashtable) environment.clone();
                childEnv.put("java.naming.factory.initial", "org.apache.naming.java.javaURLContextFactory");
                initialContext = new MycompanyInitialContext(childEnv);
            }
            return initialContext;
        }
    
    }
    

    By setting the system property

    java.naming.factory.initial=de.mycompany.mock.tomee.MycompanyNamingContextFactory
    

    I was able to inject my MycompanyInitialContext context implementation:

    package de.mycompany.mock.tomee;
    
    import org.apache.openejb.core.ivm.naming.IvmContext;
    import org.apache.openejb.core.ivm.naming.NameNode;
    
    import javax.naming.NamingException;
    import java.util.Hashtable;
    
    public class MycomanyInitialContext extends IvmContext {
    
        public MycomanyInitialContext(Hashtable<String, Object> environment) throws NamingException {
            super(environment);
        }
    
        @Override
        public Object lookup(String compositName) throws NamingException {
            if("cell/persistent/configService".equals(compositName)) {
                return super.lookup("java:global/mycompany-mock-ear-1.0.0-SNAPSHOT/mycompany-mock-impl/ConfigServiceMock");
            }
            if("cell/persistent/authorizationService".equals(compositName)) {
                Object obj = super.lookup("java:global/mycompany-mock-ear-1.0.0-SNAPSHOT/mycompany-mock-impl/AuthServiceMock");
                return obj;
            }
            return super.lookup(compositName);
        }
    
    }
    

    I know this is not pretty and if anyone has an idea how do make this easier and prettier, I'm all ears and this solution seems to work. As it's only intended on simulating production services during development, this hack doesn't induce any nightmares for me. Just thought I'd post it, just in case someone else stumbles over something similar.