【问题标题】:Configuring Tomee to allow WebSphere JNDI Lookups配置 Tomee 以允许 WebSphere JNDI 查找
【发布时间】:2014-09-18 09:20:03
【问题描述】:

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

现在在开发过程中,我们正在使用 Tomee,总的来说一切都很好。除了一件事: ServiceProvider 对“cell/persistent/configService”进行 jndi 查找。现在我尝试为这些服务创建一个包含模拟 EJB 的模拟耳朵。我能够部署它们,并且可以使用 jndi 名称从应用程序中访问它们,例如:“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。

Service Provider 部分已给出,我们根本无法更改,因此请不要建议更改硬编码的 jndi 名称。我们当然愿意这样做,但无法改变任何事情。

【问题讨论】:

  • 尝试使用 {deploymentId}/{interfaceClassName} 作为 jndi 名称,看看是否可以查找 bean
  • 是的,确实有效,但正如我在帖子中所写,我无法更改名称,因为它们是我必须使用的已编译库的一部分。
  • 我的意思是在您的客户端/您的 EJB 中使用该名称进行查找。您在哪里进行查找?
  • 好吧,我让 Tomee 将 EJB 绑定到该名称(如您所见它输出绑定),但是当使用 JNDI 查找 bean 时,InitialContext 似乎只能找到具有前缀“java:”。但我找到了一个可行的解决方案,并将其作为答案发布。

标签: ejb-3.0 jndi apache-tomee


【解决方案1】:

好吧……我在这上面浪费了很多时间。直到我终于想出了一个解决方案。我没有配置 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);
    }

}

我知道这并不漂亮,如果有人知道如何使这更容易和更漂亮,我全神贯注,这个解决方案似乎有效。由于它仅用于在开发过程中模拟生产服务,因此这种 hack 不会给我带来任何噩梦。只是想我会发布它,以防其他人偶然发现类似的东西。

【讨论】:

    【解决方案2】:

    我知道这个答案会在问题发生几年后出现,但更简单的解决方案是简单地设置系统属性如下(比如在 catalina.properties 中):

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

    这允许您通过设置的名称查找 ejb,以及在启动期间显示在 tomee 日志中的名称,例如您的 '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/”以及该工厂来查找它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 2015-01-17
      相关资源
      最近更新 更多