EJB客户端如何在没有url的情况下找到EJB服务器?

时间:2012-11-30 10:14:52

标签: java java-ee ejb jndi

我是Java EE的新手。目前,我正在阅读Sun Microsystems的 Java EE 6 Tutorial,Volume 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");

客户端通过网址知道服务器在哪里以及敲击哪个端口。我认为代码是在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在第7章中有类似的例子。

Java EE 6开发与Netbeans 7 。作者没有解释如何在书中完成它。我认为他已经做到了,但我可能错过了......

我的问题是客户端如何在没有网址的情况下找到服务器?是否在其中一个xml文件中声明了?客户可以在加利福尼亚州,GlassFish Server可以在纽约。任何人都可以向我解释或指向任何我可以找到答案的教程/博客/文章吗?

谢谢。

2 个答案:

答案 0 :(得分:9)

这里有两件事情。

首先,Java EE中未指定获取对远程EJB的引用的方式。您将受到个别供应商认为应该如何完成的摆布。

虽然JNDI是用于此的事实上的标准,但即使这本身也没有强制要求。

示例:JBoss直到AS7

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

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 在此处添加众所周知的“java:/”前缀,否则它将被JNDI拦截并在本地解析,尽管在远程上下文中进行查找)< / em>的

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

示例:JBoss AS7

在JBoss AS 7中,JBoss想要离开JNDI(因为没有指定必须使用JNDI),现在它大概发生在following way

首先需要在类路径中放置一个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联系远程服务器。 Application Client容器在Java EE中有点模糊。这个想法似乎是您从服务器(如Applet或Java Web Start应用程序)动态下载客户端代码,然后它神奇地“知道”它的来源。主类中对(静态)注入的支持非常有限,您可以使用它直接注入远程bean。

应用程序客户端容器是Java EE早期的一个想法,据我所知,从未引起太多关注。经过这么多年,它在最初构想之后从未取得过多进步。由于它仍然需要大量特定于供应商的事情,我想大多数人都不会为此烦恼而只是使用JNDI。

答案 1 :(得分:2)

需要一个包含配置数据的jndi.properties文件。客户端无法神奇地知道要连接的服务器,即使它需要连接到与客户端在同一主机上运行的服务器 - 仍然可以有多个。

这个例子很奇怪 - EJB注释表明它应该在Java EE容器中运行,而不是作为客户端应用程序运行。

我还要注意,在客户端应用程序中调用EJB并不常见;它更像是服务器端技术。如果您想为客户端应用程序提供一个接口,那么通过JAX-RS可以更轻松,更便携地使用RESTful Web服务。