Как клиент EJB находит сервер EJB без url-адреса?

Я новичок в Java EE. В настоящее время я прохожу через учебник Java EE 6, Том 1 (Основные понятия Beta) на "Сан майкросистемз". Чтобы избежать монотонного чтения время от времени, я играю с несколькими проектами/кодами Java EE, написанными другими.

Я пришел из SE. Моя голова все еще заполнена SE. In 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

url и номер порта не указаны.

разработка Java EE 6 с Netbeans 7 Дэвид Р. Heffelfinger есть подобный пример в главе 7. Автор не объяснил, как это делается в книге. Я думаю, что он сделал это, но я, вероятно, пропустил это...

мой вопрос в том, как клиентская сторона находит сервер без url-адреса? Это указано в одном из этих XML-файлов? Клиент может будьте в Калифорнии, а сервер GlassFish может быть в Нью-Йорке. Может ли кто-нибудь объяснить мне это или указать на любой учебник/блог/статью, где я могу найти ответ?

спасибо.

2 ответов


здесь происходит две вещи.

во-первых, способ получения ссылки на удаленный EJB не указан в Java EE. Вы находитесь во власти того, как отдельный поставщик думает, что это должно быть сделано.

хотя JNDI является де-факто стандартом, используемым для этого, даже это само по себе не является обязательным.

пример: JBoss до AS7

в JBoss как до 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 удаленного сервера предоставляется исходному контексту, и из этого контекста извлекается компонент. (обратите внимание, что вы должны не добавьте здесь известный префикс" java:/", иначе он будет перехвачен JNDI и разрешен локально, несмотря на выполнение поиска в удаленном контексте)

поскольку этот метод, как уже упоминалось, не стандартизирован, один поставщик может полностью изменить его между выпусками реализации. Даже для реализаций для той же версии Java EE.

пример: на JBoss КАК7

в JBoss как 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. Идея заключается в том, что вы загружаете клиентский код динамически с сервера (например, апплет или Java Web Start app), и что он затем волшебным образом "знает", откуда он взялся. Очень ограниченная поддержка для (статической) впрыски в основном классе, который вы можете использовать для того чтобы впрыснуть удаленные фасоли сразу.

Приложения Клиентский контейнер-это идея с первых дней Java EE и, насколько я знаю, никогда не получал большого внимания. После всех этих лет она так и не продвинулась далеко после своего первоначального зачатия. Поскольку для этого все еще требуется тонна конкретных вещей поставщика, я думаю, что большинство людей не беспокоятся об этом и просто используют JNDI.


должен быть jndi.properties файл с данными конфигурации в нем. Клиент не может волшебным образом узнать сервер для подключения, даже если ему нужно будет подключиться к серверу, работающему на том же хосте, что и клиент - их может быть несколько.

пример очень странный, хотя-аннотация EJB указывает, что он должен работать в контейнере Java EE, а не как клиентское приложение.

Я также хотел бы отметить, что вызов EJBs в клиентских приложениях на самом деле это не так часто; его больше технология на стороне сервера. Если вы хотите предоставить интерфейс клиентским приложениям, его намного проще и более портативно использовать, например, веб-службы RESTful через JAX-RS.