EJB客户端如何在没有URL的情况下定位EJB服务器?


问题内容

我是Java EE的新手。目前,我正在阅读Sun Microsystems 的Java EE 6教程第1卷(Basic Concepts Beta)
。为了不时地摆脱单调的阅读,我很少玩别人编写的Java EE项目/代码。

我来自SE。我的头仍然充满SE。在SE( 两层 应用程序)中,我使用

DATABASE_URL = "jdbc:mysql://something.db_server.com/db_name"

这就是我的客户端知道数据库服务器在哪里的方式。

在一个Java EE示例中,我看到了

// Access JNDI Initial Context.

Properties p = new Properties();

p.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
p.put("java.naming.provider.url","jnp://localhost:1099");
p.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");

InitialContext ctx = new InitialContext(p);

// Change jndi name according to your server and ejb

HelloRemote remote = (HelloRemote) ctx.lookup("HelloBean/remote");

msg = "Message From EJB --> " + remote.sayHello();

这我明白。该代码具有url和端口号。有这条线

p.put("java.naming.provider.url","jnp://localhost:1099");

客户端通过url知道服务器在哪里以及要敲哪个端口。我认为代码是在Java EE 5时编写的。

今天,我发现了另一个使用Netbeans 7,Java EE 6和GlassFish 3的示例。客户端代码

@EJB
private static MySessionRemote mySession;

/**
 * @param args the command line arguments
 */

public static void main(String[] args) {
    JOptionPane.showMessageDialog(null, 
            "result = " + mySession.getResult());
}

这是链接
http://netbeans.org/kb/docs/javaee/entappclient.html

没有提供网址和端口号。

*David R. Heffelfinger *用Netbeans 7 进行 Java EE 6开发
在第7章中有一个类似的示例。作者没有在书中解释它是如何完成的。我认为他已经做到了,但我可能错过了……

我的问题是客户端如何在没有url的情况下找到服务器?是在那些xml文件之一中说明的吗?客户可以在加利福尼亚,GlassFish
Server可以在纽约。谁能给我解释一下,或者指向任何可以找到答案的教程/博客/文章?

谢谢。


问题答案:

这里有两件事。

第一件事是Java EE中未指定获取对远程EJB的引用的方式。您无法确定单个供应商认为应该如何完成。

尽管JNDI是为此目的使用的事实上的标准,但即使此本身也不是强制性的。

示例:JBoss直到AS7

在直到AS 7的JBoss AS中,使用以下序列获取远程引用:

Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://myserver.example.com:1099");
InitialContext context = new InitialContext(env);

Bean bean = (Bean) context.lookup("myear/MyBean/remote");

在此,将远程服务器的URL提供给初始上下文,并从该上下文中检索Bean。 (请注意,您必须 NOT
:这里的前缀,否则将通过JNDI被拦截和就地解决,尽管做了查找在远程情况下加入著名的“/ JAVA”)

由于如上所述该方法不是标准化的,因此单个供应商可以在实施版本之间完全更改它。即使是针对相同Java EE版本的实现。

示例:JBoss AS7

在JBoss AS
7中,JBoss希望脱离JNDI(因为未指定必须使用JNDI),现在它大致以下列方式发生

首先,您需要jboss-ejb-client.properties使用以下上下文将文件放在类路径中:

endpoint.name = client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED = false
remote.connections = default
remote.connection.default.host = myserver.example.com
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS = false

并使用如下代码:

Properties env = new Properties();
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(env);

Bean bean = (Bean) context.lookup("ejb:/myear/mymodule/MyBean!com.example.Bean");

因此,从代码中看,似乎没有给出URL,但是它静态地隐藏在配置文件中。


应用程序客户端容器

今天,我发现了另一个使用Netbeans 7,Java EE 6和GlassFish 3的示例。客户端代码[…]

这是另一回事。所展示的是所谓的“ 应用程序客户端容器” (又名ACC)。

这与上面的示例不同,在上面的示例中,Java SE应用程序使用JNDI与远程服务器联系。在Java
EE中,应用程序客户端容器有点晦涩难懂。这个想法似乎是您从服务器(如Applet或Java Web
Start应用程序)动态下载客户端代码,然后神奇地“知道”其起源。在主类中,对(静态)注入的支持非常有限,您可以使用它直接注入远程bean。

应用程序客户端容器是Java
EE早期的想法,据我所知,它从来没有受到太多关注。这些年来,它在最初构想之后从未取得太大进步。由于它仍然需要完成大量特定于供应商的工作,因此我认为大多数人都不会为它而烦恼,而只是使用JNDI。