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。