В результате того, что «функциональный поезд» продолжает развиваться, и мы не поддерживаем наш программный стек в актуальном состоянии, наша команда оказывается в незавидном положении при переходе:
- JBoss 4.2.3 для AS 7.1.x (в настоящее время глядя на 7.1.1)
- EJB 2.1 до EJB 3.1
- Hibernate 2 до Hibernate 3 или 4
в быстрой моде. Я имею в виду, кто хочет выпустить новую версию с программным обеспечением 8-10 лет, а не я! Следующее является результатом некоторых исследований, которые я проводил, глядя на обновление с JBoss 4.2.3 с EJB 2.1 до AS 7.1.x с EJB 3.1. Я уверен, что будет больше
сообщения, связанные с этой миграцией в ближайшем будущем, но эта связана с изменениями в области именования JNDI.
В прошлом / настоящем
В нашем текущем коде именование JNDI было очень простым:
- Мы объединили «ejb /» с именем удаленного интерфейса Session Bean в дескрипторе развертывания, чтобы указать имя, с которым должна быть связана служба.
- В коде мы используем следующий код для обработки поиска JNDI. Действительно хорошая часть заключалась в том, что один и тот же код мог использоваться удаленными клиентами И на сервере, внутри контейнера.
Текущий код
1
2
3
4
5
6
|
Hashtable properties = new Hashtable(); properties.put( "java.naming.factory.initial" , "org.jnp.interfaces.NamingContextFactory" ); properties.put( "java.naming.factory.url.pkgs" , "org.jboss.naming:org.jnp.interfaces" ); properties.put( "java.naming.provider.url" , "jnp://localhost:1099" ); Context ctx = new InitialContext(properties); Object ref = ctx.lookup(jndiName); |
AS7 и EJB 3.1
Спецификация EJB 3.1 внесла некоторые изменения в мандат переносимых имен JNDI для EJB, и вы наследуете это в AS 7.1.1. Другая хитрость, которую я обнаружил, заключалась в том, что я больше не мог использовать точно такой же код поиска от наших удаленных клиентов и сервера.
AS 7 теперь имеет две опции для удаленного вызова EJB . Информацию, которая вам нужна, можно найти в документации JBoss, она просто не поразила меня! После нескольких дней борьбы с этой проблемой я решил создать небольшую программу, которая поможет сделать различия (надеюсь) очень ясными. Ниже приведена программа, которую я создал для вызова сессионного компонента без сохранения состояния с удаленного клиента. Я развернул пример « ejb-remote» из примеров быстрого запуска 7.1. Код пытается загрузить удаленный сервис, используя оба удаленных метода. Ожидается, что для первого набора поисков первый поиск будет успешным, а второй с использованием формата именования «ejb: /» завершится неудачно. Затем я добавляю свойство Context.URL_PKG_PREFIXES со значением «org.jboss.ejb.client.naming» к свойствам jndi, переданным конструктору InitialContext, и повторяю поиск. Теперь оба поиска должны быть успешными. Я включил все свойства JNDI в код, а не полагался на копию « jboss-ejb-client.properties » или « jndi.properties », полученную из пути к классам.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.Hashtable; public class EJBClient { private static String[] JNDINAME = { "jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator" , "ejb:/jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator" }; private Hashtable jndiProps; public EJBClient() { // setup 'base' jndi properties - no jboss-ejb-client.properties being picked up from classpath! jndiProps = new Hashtable(); jndiProps.put( "java.naming.factory.initial" , "org.jboss.naming.remote.client.InitialContextFactory" ); jndiProps.put(InitialContext.PROVIDER_URL, "remote://localhost:4447" ); jndiProps.put( "jboss.naming.client.ejb.context" , true ); // needed for remote access - remember to run add-user.bat jndiProps.put(Context.SECURITY_PRINCIPAL, "client" ); jndiProps.put(Context.SECURITY_CREDENTIALS, "password" ); } public void doLookups() { // the 'exported' namespace for ( int i = 0 ; i < JNDINAME.length; i++) { lookup(JNDINAME[i]); } // This is an important property to set if you want to do EJB invocations via the remote-naming project jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming" ); // now with the ejb for ( int i = 0 ; i < JNDINAME.length; i++) { lookup(JNDINAME[i]); } } private void lookup(String name) { System.out.println( "Lookup name=" +name); Context ctx = null ; try { ctx = new InitialContext(jndiProps); Object ref = ctx.lookup(name); System.out.println( "...Successful" ); } catch (NamingException e) { System.out.println( "...Failed" ); //System.out.println(e.getMessage()); e.printStackTrace(); } finally { if (ctx != null ) { try { ctx.close(); } catch (NamingException e) {} } } } public static void main(String[] args) throws Exception { EJBClient client = new EJBClient(); client.doLookups(); System.out.println( "Done!" ); } } |
AS7 на стороне сервера
Теперь простая часть, выполнение поиска JNDI на сервере, очень похожа на старый способ, за исключением того, что вам все еще нужно отформатировать имя JNDI в соответствии с новыми спецификациями, а фабрика имен больше не является версией jnp!
1
2
3
4
|
Hashtable jndiProps = new Hashtable(); jndiProps.put( "java.naming.factory.initial" , "org.jboss.as.naming.InitialContextFactory" ); ctx = new InitialContext(jndiProps); Object ref = ctx.lookup(jndiName); |
Вывод
Как я уже говорил ранее, информация была / есть в документации JBoss, но я, вероятно, читал ее несколько раз. Я искал пример, показывающий загрузку EJB-компонентов как с клиента, так и с сервера.
Надеюсь это поможет!