Как выполнить удаленный поиск JNDI из Spring Boot Client на сервере GlassFi sh? - PullRequest
0 голосов
/ 01 марта 2020

Я начинаю с работающего приложения Spring Boot, использующего последнюю версию Spring Boot и встроенный Tomcat. Он содержит HomeController с индексным методом, сопоставленным с соответствующим jsp в каталоге веб-приложения.

@RequestMapping(value={"/", "/home", "/home/index"})
public ModelAndView index() {
    ModelAndView mv = new ModelAndView("/home/index");
    return mv;
}

Моя цель - создать удаленный JNDIlookup для сервера glassfi sh для доступа к EJB Singleton Service. Ранее я с помощью простого настольного клиента проверял, что удаленный поиск JNDI на моем сервере Glassfi sh работает отлично.

Я следовал этому руководству для WildFly, перепрофилировал его для Glassfi sh: https://www.baeldung.com/spring-ejb

Казалось, достаточно просто. Вместо клиентского модуля WildFly я бы импортировал Glassfi sh, а вместо свойств WildConly InitialContext я бы использовал Glassfi sh.

Поэтому я обновил свой pom. xml следующим образом (я также добавил зависимость, содержащую удаленные интерфейсы):

 <dependency>
      <groupId>org.glassfish.main.appclient</groupId>
      <artifactId>gf-client</artifactId>
      <version>5.1.0</version>
 </dependency>

Обновлен McvConfig. java вот так (мой базовый порт для GlassFi sh равен 8000, и он добавляет 37 для порта JNDI):

 @Bean
 public Context ejbInitialContext() {
      InitialContext initialContext = null;
      try {
           Properties jndiProps = new Properties();
           jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.enterprise.naming.impl.SerialInitContextFactory");
           jndiProps.put(Context.STATE_FACTORIES,
            "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
           jndiProps.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
           jndiProps.put("org.omg.CORBA.ORBInitialHost", "localhost");
           // optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
           jndiProps.put("org.omg.CORBA.ORBInitialPort", "8037");
           initialContext = new InitialContext(jndiProps);
      } catch (NamingException e) {
      } 
      return initialContext;
 }

И обновил HomeController следующим образом:

@Autowired
Context ejbInitialContext;

@RequestMapping(value={"/", "/home", "/home/index"})
public ModelAndView index() {
    ModelAndView mv = new ModelAndView("/home/index");
    ServiceRemote service = (ServiceRemote) ejbInitialContext.lookup("java:global/core/Service");
    mv.addObject("Hello", service.hello());
    return mv;
}

Я запустил сервер GlassFi sh, а затем попытался запустить мое приложение Spring Boot. Журналы загрузки Sprint не отображаются, и через некоторое время я получил это (Полный журнал здесь: https://pastebin.com/E11xLmFN):

 org.omg.CORBA.COMM_FAILURE: FINE: 00410001: Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: localhost; port: 3700  vmcid: OMG  minor code: 1  completed: No
 ...
 Caused by: java.lang.RuntimeException: java.net.ConnectException: Connection refused: connect
 ...
 Caused by: java.net.ConnectException: Connection refused: connect

Я попытался получить доступ к localhost, и он просто сказал:

This site can’t be reached

Я немного повозился с ним и сделал несколько выводов:

  1. Добавление новой зависимости - все, что нужно, чтобы сломать Spring MVC и убери мой веб-сервис.
  2. Spring пытается интегрироваться с GlashFi sh, потому что трассировка стека включает это:

    в org.springframework.jndi.JndiTemplate.lambda $ поиск $ 0 (JndiTemplate. java: 157) в org.springframework.jndi.JndiTemplate.execute (JndiTemplate. java: 92) в org.springframework.jndi.JndiTemplate.lookup (JndiTemplate. java): 1064 * org.springframework.jndi.JndiTemplate.lookup (JndiTemplate. java: 179)

  3. Spring полностью игнорирует мой Bean и использует по умолчанию GlassFi sh InitialContext, потому что номер порта в логах еще 3700, по умолчанию для GlassFi sh, но я зр ecified 8048.

Spring каким-то образом обнаруживает клиентский модуль и периодически пытается подключиться к Glassfi sh. Проблема в том, что я абсолютно не знаю, как сказать Spring, чтобы использовать мои собственные свойства InitialContext.

Я искал решение в Интернете. Большинство подобных вопросов были заданы не очень хорошо и не получили ответов, а другие были конкретно о DataSource, который слишком специфичен для меня c, так как я пытаюсь разместить весь слой Service на сервере Jakarta EE.

1 Ответ

0 голосов
/ 02 марта 2020

Nevermind. Я просто понял, что делать. Если вы посмотрите на трассировку стека, она начинается в начале приложения Spring Boot: SpringApplication.run (App.class, args);

Spring Boot буквально инициализирует GlassFi sh AppClient внутри своей собственной инициализации. Это было ясно, когда я написал этот вопрос.

Оказывается, единственный способ сделать это - поместить те же свойства из InitialContext в свойства системы, как показано ниже:

@SuppressWarnings("unused")
private static ApplicationContext applicationContext;
public static void main( String[] args ) throws NamingException
{
    Properties props = System.getProperties();   
    jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.enterprise.naming.impl.SerialInitContextFactory");
    jndiProps.put(Context.STATE_FACTORIES,
        "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
    jndiProps.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
    jndiProps.put("org.omg.CORBA.ORBInitialHost", "localhost");
       // optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
    jndiProps.put("org.omg.CORBA.ORBInitialPort", "8037");
    System.setProperties(props);
    applicationContext = SpringApplication.run(App.class, args);
}

Сначала нужно взять начальные свойства системы и добавить перед перезаписью системных свойств новым набором свойств, иначе вы все сломаете.

Это также необходимо сделать перед запуском SpringApplication, потому что именно там происходит инициализация.

Самое последнее, что мне нужно было сделать, это переместить вышеупомянутый GlassFi sh AppClient под все зависимости Spring в pom. xml. Находясь в самом верху, создавал NoClassDefFoundError для класса Connector, который, как мне кажется, находился на самом сервере Tomcat.

<dependency>
  <groupId>org.glassfish.main.appclient</groupId>
  <artifactId>gf-client</artifactId>
  <version>5.1.0</version>
</dependency>

После этого я открыл свою веб-страницу и тестовый текст, созданный внутри EJB Singleton, живущего на моем Сервер GlassFi sh был передан через мой клиент Spring Boot в мой браузер. Проверка работоспособности системы.

...