EJB Corba 编组异常

问题描述

我们使用包含两个应用程序(app1 和 app2)的 Websphere 集群。我可以从 Intellij-Idea 的本地 Spring Boot 中的两个应用程序调用 EJB。

当我将 spring boot 应用程序部署到公司的私有 openshift 云时,与 websphere 应用程序之一通信的两个服务之一(客户端)出现编组异常。

@Service
public class App1BookingsManagementService implements EjbService<DomainFacade> {

    private static final String DOMAINFACADE_EJB_NAME = "ejb/org/company/app/DomainFacade";

    private static final Logger LOG = LoggerFactory.getLogger(App1BookingsManagementService.class);

    @Autowired
    private InitialContext initialContext;

    public List<BookingDaTarow> getBookingsToday() {
        DomainFacade domainFacade = null;
        try {
            domainFacade = createEjbStub();
            BookingSelektionskriterien selektionskriterien = new BookingSelektionskriterien();
            selektionskriterien.setTerminFrom(valueOf(Now()));
            selektionskriterien.setTerminUntil(valueOf(Now().plusDays(1)));
            ResultList<BookingDaTarow> resultList = domainFacade.sucheBookingsDaTarows(selektionskriterien);
            if (resultList == null) {
                LOG.warn("Error in EJB {} from APP1 returned null. ",DOMAINFACADE_EJB_NAME);
            }
            LOG.info("Calling EJB sucheBookingsDaTarows returned {} results. ",resultList.getList().size());
            return resultList.getList();
        } catch (NamingException | CreateException | remoteexception | DomainException e) {
            LOG.error("Error in calling EJB {} from APP1: {},{}",DOMAINFACADE_EJB_NAME,e.getClass().getName(),e.getMessage());
        } finally {
            if (domainFacade != null) {
                try {
                    domainFacade.remove();
                } catch (remoteexception | RemoveException e) {
                    LOG.error("Could not remove ejb {}",e);
                }
            }
        }
        return Collections.emptyList();
    }

    public DomainFacade createEjbStub() throws NamingException,remoteexception,CreateException {
        Object stub = initialContext.lookup(DOMAINFACADE_EJB_NAME);
        DomainFacadeHome facadeHome = (DomainFacadeHome) PortableRemoteObject.narrow(stub,DomainFacadeHome.class);
        return facadeHome.create();
    }

}

这里的配置:

@Configuration
public class CorbaConfig {

    @Value("${corba-location}")
    private String corbaLocation;
    @Value("classpath:sas.client.props")
    private Resource sasClientProps;

    @Bean
    public InitialContext corbaContext() throws NamingException,IOException {
        Hashtable<String,Object> env = new Hashtable<>();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
        env.put(PROPS.HOSTNAME_norMALIZER,PROPS.HOSTNAME_norMALIZER_NONE);
        env.put("com.ibm.CORBA.ConfigURL",sasClientProps.getInputStream());
        env.put(Context.PROVIDER_URL,corbaLocation);
        return new InitialContext(env);
    }

    @Bean
    public MBeanServer mbeanServer() {
        MBeanServerfactorybean factory = new MBeanServerfactorybean();
        factory.setLocateExistingServerIfPossible(true);
        factory.afterPropertiesSet();
        return factory.getobject();
    }
}

这是我在 openshift 中看到的错误

2021-02-04 08:14:53,714 [ERROR] P=891120:O=0:CT appname=app-ejbcall corid= c.s.n.e.s.App1BookingsManagementService: Error in calling EJB ejb/org/company/app/DomainFacade from APP1: java.rmi.MarshalException,CORBA MARSHAL 0x4942f89a No; nested exception is: 
    org.omg.CORBA.MARSHAL: 
    >> SERVER (id=431c9d95,host=was.company.org) TRACE START:
    >>    org.omg.CORBA.MARSHAL: Unable to read value from underlying bridge : Default data must be read first  vmcid: IBM  minor code: 89A  completed: No
    >>   at com.ibm.rmi.iiop.CDRReader.read_value(CDRReader.java:1644)
    >>   at com.ibm.rmi.iiop.EncoderInputStream.read_value(EncoderInputStream.java:970)
    >>   at org.company.app.Domain.ejb.facade._EJSRemoteStatelessDomainFacade_a1729579_Tie.sucheBookingenDaTarows(UnkNown Source)
    >>   at org.company.app.Domain.ejb.facade._EJSRemoteStatelessDomainFacade_a1729579_Tie._invoke(UnkNown Source)
    >>   at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:638)
    >>   at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:508)
    >>   at com.ibm.rmi.iiop.ORB.process(ORB.java:613)
    >>   at com.ibm.CORBA.iiop.ORB.process(ORB.java:1584)
    >>   at com.ibm.rmi.iiop.Connection.doRequestWork(Connection.java:3190)
    >>   at com.ibm.rmi.iiop.Connection.doWork(Connection.java:3051)
    >>   at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:64)
    >>   at com.ibm.ws.giop.threadpool.WorkQueueElement.dispatch(WorkQueueElement.java:174)
    >>   at com.ibm.ws.giop.filter.GiopFilterChain.processMessage(GiopFilterChain.java:203)
    >>   at com.ibm.ws.giop.threadpool.PooledThread.handleRequest(PooledThread.java:81)
    >>   at com.ibm.ws.giop.threadpool.PooledThread.run(PooledThread.java:102)
    >>   at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892)
    >> SERVER (id=431c9d95,host=was.company.org) TRACE END.
  vmcid: IBM  minor code: 89A  completed: No

在本地与同一个 websphere 服务器通信没有问题。一种猜测是 RMI 存根不一样,但在本地也会出现问题,不是吗?

应用 1 应用 2
在IDE中运行本地Spring Boot 好的 好的
在 Openshift Cloud 中部署 好的 不同意

解决方法

问题是我使用 jdk-8 配置了构建,但在运行时 jre 设置为版本 11。

所以我必须找到正确的 docker 文件的内部配置才能使用 java 8。