繁体   English   中英

如何从 Spring Boot Client 到 GlassFish Server 进行远程 JNDI 查找?

[英]How to do a remote JNDI lookup from Spring Boot Client to GlassFish Server?

我从一个可用的 Spring Boot 应用程序开始,使用最新版本的 Spring Boot 和嵌入式 Tomcat。 它包含一个 HomeController,其 index 方法映射到 webapp 目录中相应的 .jsp。

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

我的目标是对 glassfish 服务器进行远程 JNDIlookup 以访问 EJB 单例服务。 我之前已经使用一个简单的桌面客户端验证过,对我的 Glassfish 服务器的远程 JNDI 查找工作正常。

我遵循了 WildFly 的本教程,将其重新用于 Glassfish: https ://www.baeldung.com/spring-ejb

看起来很简单。 我会导入 Glassfish 的而不是 WildFly 的客户端模块,并且我会使用 Glassfish 的而不是 WildFly 的 InitialContext 属性。

所以我用这个更新了我的 pom.xml(我还添加了一个包含远程接口的依赖项):

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

像这样更新 McvConfig.java(GlassFish 的基本端口是 8000,它为 JNDI 端口增加了 37):

 @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;
}

我运行了 GlassFish 服务器,然后尝试运行我的 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

我尝试访问本地主机,它只是说:

This site can’t be reached

折腾了一会,总结了几点:

  1. 添加新的依赖项就是破坏 Spring MVC 并关闭我的 Web 服务所需的全部。
  2. Spring 正在尝试与 GlashFish 集成,因为堆栈跟踪包括以下内容:

    在 org.springframework.jndi.JndiTemplate.lambda$lookup$0(JndiTemplate.java:157) 在 org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:92) 在 org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.lookup(JndiTemplate. java:157) 在 org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)

  3. Spring 完全忽略了我的 Bean 并使用默认的 GlassFish InitialContext,因为日志中的端口号仍然是 3700,GlassFish 的默认值,但我指定了 8048。

Spring 以某种方式检测客户端模块并定期尝试连接到 Glassfish。 问题是我完全不知道如何告诉 Spring 使用我的自定义 InitialContext 属性。

我在网上到处寻找解决方案。 大部分类似的问题都没有问的很好,也没有得到答案,还有一些是专门关于DataSource的,这对我来说太具体了,因为我试图把整个Service层放在一个Jakarta EE服务器上。

没关系。 我只是想知道该怎么做。 如果您查看堆栈跟踪,它从 Spring Boot 应用程序的开头开始: SpringApplication.run(App.class, args);

Spring Boot 就是在它自己的初始化中初始化 GlassFish 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 之前完成,因为这是初始化发生的地方。

我必须做的最后一件事是将前面提到的 GlassFish AppClient 移到 pom.xml 中所有 Spring 依赖项下。 让它靠近顶部是为我认为在 Tomcat 服务器本身中的连接器类创建一个 NoClassDefFoundError 。

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

之后,我打开了我的网页,在我的 GlassFish 服务器上的 EJB Singleton 中创建的测试文本通过我的 Spring Boot 客户端传递到我的浏览器中。 证明系统按预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM