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

问题描述 投票:-1回答:1

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

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

我的目标是对glassfish服务器进行远程JNDIlookup,以访问EJB Singleton Service。以前,我已经使用一个简单的桌面客户端验证了对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.java:157)在org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)

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

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

我在网上寻找解决方案。大多数类似的问题并没有很好地回答,也没有得到答案,还有其他一些问题是关于数据源的,这对我来说太具体了,因为我正试图将整个服务层放在Jakarta EE服务器上。

java spring spring-boot ejb jndi
1个回答
0
投票

没关系。我只是想出办法。如果查看堆栈跟踪,它是从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);
}

您必须先获取初始的System属性并将其添加,然后再用新的一组属性覆盖System属性,否则您将破坏整个过程。

也必须在运行SpringApplication之前完成,因为这是初始化的地方。

[我要做的最后一件事是将上述的GlassFish AppClient移动到pom.xml中所有Spring依赖项的下面。让它靠近顶部是为我认为在Tomcat服务器本身中的Connector类创建了NoClassDefFoundError。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.