配置Tomee以允许WebSphere JNDI Lookup

时间:2014-09-18 09:20:03

标签: ejb-3.0 jndi apache-tomee tomee

我们目前正在开发一个旨在在WebSphere服务器上进行部署的应用程序。应用程序应使用内部服务提供程序,该服务提供程序提供对作为远程EJB实现的服务的访问。 Service Provider bean有一些硬编码的jndi名称可供使用。

现在在开发过程中我们正在使用Tomee,总的来说一切都很好。除了一件事之外: ServiceProvider执行“cell / persistent / configService”的jndi查找。现在我尝试创建一个包含这些服务的模拟EJB的模拟耳朵。我能够部署它们,并且我能够使用jndi-names从应用程序访问它们,例如:“java:global / framework-mock-ear-1.0.0-SNAPSHOT / framework-mock-impl / ConfigServiceMock”但它似乎无法使用jndi查找来访问它们:“cell / persistent / configService”...现在我在我的模拟实现中添加了一个openejb-jar.xml文件,其中包含:

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

我可以在启动时看到bean似乎在该名称下正确注册:

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

但我现在已经知道如何让另一只耳朵能够使用该名称访问这个bean。

提供服务提供商部分,我们根本无法更改,因此请不要建议更改硬编码的jndi名称。我们当然希望这样做,但无法改变任何事情。

2 个答案:

答案 0 :(得分:0)

好的......我浪费了相当多的时间。直到我终于找到了解决方案。我没有配置Tomee和OpenEJB来查找我的bean,而是劫持了InitialContext并重写了我的查询。

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

}

通过设置系统属性

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

我能够注入MycompanyInitialContext上下文实现:

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

}

我知道这不是很漂亮,如果有人知道如何让这更容易和更漂亮,我全心全意,这个解决方案似乎有效。因为它只是用于在开发过程中模拟生产服务,所以这个黑客并不会对我产生任何噩梦。只是想我发布它,以防其他人偶然发现类似的东西。

答案 1 :(得分:0)

我知道这个问题会在几年后问世,但是一个更简单的解决方案是按照以下方式简单地设置系统属性(例如在catalina.properties中):

java.naming.initial.factory=org.apache.openejb.core.OpenEJBInitialContextFactory

这允许您通过设置的名称查找ejb,并在启动过程中在tomee日志中显示该ejb,例如来自您的“ cell / persistent / configService”

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

设置系统属性后,您可以按所需方式查找ejb

final Context ctx = new InitialContext();
ctx.lookup("cell/persistent/configService")

OpenEJBInitialContextFactory允许访问本地EJB和容器资源。

如果您不想设置系统属性(因为它会影响tomee中的所有应用程序),您仍然可以使用工厂以“标准”方式对其进行设置:

    Properties properties = new Properties();
    properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.OpenEJBInitialContextFactory");
    final Context ctx = new InitialContext(properties);
    ctx.lookup("cell/persistent/configService");

当然,您仍然可以使用全局“ java:global /”以及该工厂来查找它们。