问题描述
我们使用包含两个应用程序(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。