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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13643127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:29:07  来源:igfitidea点击:

How does the EJB client locate the EJB server without url?

javajakarta-eeejbjndi

提问by S A

I am new to Java EE. At present I am going through The Java EE 6 Tutorial, Volume 1 (Basic Concepts Beta)by Sun Microsystems. To escape from monotonous reading time to time I play with few Java EE projects/codes written by others.

我是 Java EE 的新手。目前,我正在阅读Sun Microsystems 的The Java EE 6 Tutorial, Volume 1(Basic Concepts Beta)。为了摆脱单调的阅读,我偶尔会玩一些其他人编写的 Java EE 项目/代码。

I came from SE. My head is still filled with SE. In SE (two tierapplication) I use

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

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

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

This is how my client knows where the database server is.

这就是我的客户如何知道数据库服务器在哪里。

In one Java EE example I saw

在我看到的一个 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();

This I understand. The code has url and port number. There is this line

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

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

Client side knows where is the server by the url and which port to knock. I think the code was written at the time of Java EE 5.

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

Today I have found another example where Netbeans 7, Java EE 6, and GlassFish 3 are used. The client side code

今天我发现了另一个使用 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());
}

Here is the link http://netbeans.org/kb/docs/javaee/entappclient.html

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

No url and port number are given.

没有给出 url 和端口号。

Java EE 6 Development with Netbeans 7by David R. Heffelfinger has a similar example in chapter 7. The author did not explain how it is done in the book. I think he has done it but I probably missed it…

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

My question is how the client side locate the server without url? Is it stated in one of those xml files? Client can be in California and the GlassFish Server can be in New York. Can anyone explain it to me or point to any tutorial/blog/article where I can find the answer?

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

Thank you.

谢谢你。

采纳答案by Arjan Tijms

There are two things that are going on here.

这里有两件事情正在发生。

The first thing is that the way in which to obtain a reference to a remote EJB is not specified in Java EE. You are at the mercy of how an individual vendor thinks it should be done.

首先,Java EE 中没有指定获取远程 EJB 引用的方式。您受制于单个供应商认为应该如何完成。

Although JNDI is the de facto standard used for this, even this itself is not mandated.

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

Example: JBoss up till AS7

示例:JBoss 直到 AS7

In JBoss AS up till AS 7, the following sequence was used to obtain a remote reference:

在直到 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");

Here, the URL of the remote server is provided to the initial context and from that context a bean is retrieved. (Note that you must NOTadd the well known "java:/" prefix here, or else it will be intercepted by JNDI and resolved locally, despite doing the lookup on a remote context)

在这里,远程服务器的 URL 提供给初始上下文,并从该上下文中检索 bean。(请注意,您不能在此处添加众所周知的“java:/”前缀,否则它会被 JNDI 拦截并在本地解析,尽管在远程上下文中进行查找)

Since this method was as mentioned not standardized, a single vendor can change it completely between releases of implementations. Even for implementations for the same Java EE version.

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

Example: JBoss AS7

示例:JBoss AS7

In JBoss AS 7, JBoss wanted to move away from JNDI (because it was not specified that JNDI had to be used) and now it happens in approximately the following way:

在 JBoss AS 7 中,JBoss 想要摆脱 JNDI(因为没有指定必须使用 JNDI),现在它以大约以下方式发生

You'll first need to put a jboss-ejb-client.propertiesfile on your classpath with the following context:

您首先需要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

And use code as the following:

并使用如下代码:

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");

So from the code it looks like no URL is given, but it's statically hidden in a config file.

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



Application Client Container

应用程序客户端容器

Today I have found another example where Netbeans 7, Java EE 6, and GlassFish 3 are used. The client side code [...]

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

This is yet another thing. What's demonstrated there is a so-called Application Client Container(aka ACC).

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

This is different from the example above, where a Java SE application used JNDI to contact the remote server. The Application Client Container is a bit of an obscure thing in Java EE. The idea seems to be that you download the client code dynamically from the Server (like an Applet or Java Web Start app), and that it then magically 'knows' where it originated from. There is very limited support for (static) injection in the main class, which you can use to inject remote beans directly.

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

The Application Client Container is an idea from the early days of Java EE and as far as I know has never gotten much attention. After all these years it has never advanced much after its initial conception. Since it still requires a ton of vendor specific things to be done, I think most people don't bother with it and just use JNDI.

Application Client Container 是 Java EE 早期的一个想法,据我所知,从未受到太多关注。经过这么多年,它在最初的构想之后从未取得太大进展。由于它仍然需要完成大量特定于供应商的事情,我认为大多数人不会为此烦恼而只使用 JNDI。

回答by Gimby

There would need to be a jndi.propertiesfile with the configuration data in it. A client can't magically know the server to connect to even if it would need to connect to a server running on the same host as the client - there can still be multiple.

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

The example is very odd though - the EJB annotation would indicate it is supposed to run in a Java EE container, not as a client application.

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

I would also like to note that invoking EJBs in client applications is not really that common; its more a server side technology. If you want to provide an interface to client applications its far easier and more portable to use for example RESTful webservices through JAX-RS.

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