我想编写一个有 2 个 EJB 的应用程序。该应用程序可以在 OpenEJB 和 WebLogic 10.3 中运行。这两个 EJB 都是 EJB 3.0。
我知道如何在 OpenEJB 和 WebLogic 中实现,但问题是我想使用相同的代码部署到这两个环境。我认为问题在于如何进行JNDI查找,因为WebLogic的Context.INITIAL_CONTEXT_FACTORY是weblogic.jndi.WLInitialContextFactory,但OpenEJB不是。
当前的想法是第一个 EJB 使用服务定位器来查找第二个 EJB,并且服务定位器将在 2 个环境中读取不同的 INI。还有其他建议吗?有没有一种解决方案,我可以只使用注释,而不需要使用外部 INI 文件。
这 2 个 EJB 位于一个容器中,但将来其中一个可能会移动到其他容器。
2011/10/06 更新
根据大卫的建议,我换了一些零钱。该代码是 POJO,而不是 JUnit 代码。它不使用@LocalClient和initialContext.bind(“inject”, this); (我将2代码放在我的JUnit代码中)
放入resources\META-INF\application-client.xml(仅包含 )
放入 resources\jndi.properties
jdbc/OrderDB = new://Resource?type=DataSource jdbc/OrderDB.JdbcDriver = oracle.jdbc.OracleDriver jdbc/OrderDB.JdbcUrl = jdbc:oracle:thin:@*.*.*.*:1521:test jdbc/OrderDB.JtaManaged = false jdbc/OrderDB.UserName = test jdbc/OrderDB.Password = test
查找代码
InitialContext ctx= new InitialContext(); ctx.lookup("jdbc/" + name);
以下是日志,OpenEJB为数据库创建JNDI。我还使用Eclipse Debug模式查看“ctx”的内容,并在MyProps中找到“jdbc/OrderDB”
INFO - Configuring Service(id=jdbc/OrderDB, type=Resource, provider-id=Default JDBC Database)
但最后还是查不到。我也尝试使用 ctx.lookup(name), ctx.lookup("java:comp/env/jdbc/"+ name) 结果是一样的。
javax.naming.NameNotFoundException: Name "jdbc/OrderDB" not found.
2011/10/12更新
根据 David 的评论,在 Java EE6 之前,我认为唯一的解决方案是使用服务定位器和一些配置来在 WebLogic 和 OpenEJB 之间使用不同的 JNDI。以下是测试结果。
数据库: WebLogic:OrderDB,OpenEJB:openejb:Resource/jdbc/OrderDB
事务管理器: WebLogic:javax.transaction.TransactionManager,OpenEJB:java:comp/TransactionManager
EJB:两者都只是查找没有任何前缀的EJB名称
最佳答案
更新中的问题是一个非常不同的问题,因此发布不同的答案。
Java EE 6 之前没有全局 JNDI
总而言之,在 Java EE 6 之前,没有全局 JNDI。因此,从字面上看,“x 的 JNDI 名称是什么”这个问题是一个无法回答的问题。每个 EJB 都有自己的私有(private) JNDI 命名空间,而“POJO”根本没有任何命名空间,它们使用任何 EJB 调用它的 JNDI 命名空间。因此,为了使“java:comp/env/myDataSource”尽可能全局化,您必须为应用程序中的每个 EJB 声明该引用。
这给用户带来的配置工作量是相当大的。在 Java EE 6 中,终于有了 Global JNDI 和三个新的标准命名空间:java:module
、java:app
和 java:global
。 Java EE 6 之前存在的任何全局 JNDI 功能都是特定于供应商的且不可移植。
在 OpenEJB 中针对给定名称进行全局 JNDI 查找的特定于供应商且不可移植的方法是查找 openejb:Resource/jdbc/OrderDB
实话实说
在 OpenEJB 中,我们故意不支持像某些供应商那样的 jdbc/OrderDB
或 java:jdbc/OrderDB
等非标准查找。 OpenEJB 中全局名称所需的前缀是 openejb:
。
JNDI 非常复杂且令人困惑,使不可移植的名称看起来像可移植的名称并不会给用户带来任何好处。如果某种命名风格不可移植并且会造成供应商锁定,那么它应该看起来像这样。因此,使用 openejb:
前缀,您可以在全局范围内访问您需要的任何内容,但至少可以清楚的是,您所做的事情是不可移植的,并且不应期望在不进行某些修改的情况下在其他平台上工作。
关于java - EJB调用WebLogic和OpenEJB中的EJB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7488109/