升级Java17时new InitialContext()触发InaccessibleObjectException求助
问题:Java 17下WebLogic JMS客户端初始化InitialContext抛出InaccessibleObjectException
原Java 8环境代码
public class Application { public static void main(String[] args) throws NamingException, JAXBException { Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL, "xxxxx" ); InitialContext initialContext = new InitialContext(env); ConnectionFactory connectionFactoryIn = (ConnectionFactory)initialContext.lookup("jms/xxxxxxxxx"); Destination destinationIn = (Destination)initialContext.lookup("jms/xxxxx"); ConnectionFactory connectionFactoryOut = (ConnectionFactory)initialContext.lookup("jms/xxxxxxxxxx"); Destination destinationOut = (Destination)initialContext.lookup("jms/xxxxxxx"); } }
升级Java 17后的异常信息
<Fri Oct 06 12:05:30 CEST 2023> <Debug> <RJVM> <WL-000517> <'java.io.ObjectInputStream.defaultDataEnd' field not initialized java.lang.reflect.InaccessibleObjectException: Unable to make field private boolean java.io.ObjectInputStream.defaultDataEnd accessible: module java.base does not "opens java.io" to unnamed module @1bce4f0a at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) at java.base/java.lang.reflect.Field.setAccessible(Field.java:172) at weblogic.rjvm.MsgAbbrevInputStream.getField(MsgAbbrevInputStream.java:135) at weblogic.rjvm.MsgAbbrevInputStream.<clinit>(MsgAbbrevInputStream.java:89) at weblogic.rjvm.ConnectionManager.getInputStream(ConnectionManager.java:2005) at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:555) at weblogic.rjvm.t3.client.MuxableSocketT3.dispatch(MuxableSocketT3.java:180) at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:397) at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:981) at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907) at weblogic.socket.JavaSocketMuxer.processSockets(JavaSocketMuxer.java:385) at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30) at weblogic.work.ExecuteRequestAdapter.execute(ExecuteRequestAdapter.java:21) at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147) at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119)
已尝试的无效方案
添加了如下module-info.java文件,但问题未解决:
module berichtenverkeer-utilities { requires java.base; requires java.reflect; requires java.naming; opens java.io; }
有效解决方案
方案1:升级WebLogic客户端库到Java 17兼容版本
旧版WebLogic客户端库(如wlfullclient.jar)针对Java 8及以下开发,依赖反射访问Java核心模块的私有字段,而Java 17的模块系统严格限制此类操作。需下载对应WebLogic版本的Java 17兼容客户端依赖包,替换原有库文件。
方案2:添加JVM启动参数开放模块访问
若暂时无法升级客户端库,可在启动JVM时添加以下参数,允许未命名模块访问java.base的java.io包:
--add-opens java.base/java.io=ALL-UNNAMED
该参数允许所有未命名模块(WebLogic客户端通常运行在此类模块中)反射访问java.io的私有成员,绕过模块系统的限制。
方案3:修正模块化项目配置
若项目采用模块化结构,之前的module-info.java存在错误——opens java.io;是尝试开放当前模块的java.io包,但该包属于java.base模块,并非当前模块所有。正确配置如下:
- 修正
module-info.java:
module berichtenverkeer-utilities { requires java.base; requires java.naming; // 声明依赖WebLogic JMS客户端模块(若为模块化库) requires weblogic.jms.client; // 若WebLogic需要反射你的业务类,开放对应包 opens com.your.package to weblogic.jms.client; }
- 添加JVM启动参数,针对性开放模块访问:
- 若WebLogic客户端为模块化:
--add-opens java.base/java.io=weblogic.jms.client - 若WebLogic客户端仍在未命名模块:
--add-opens java.base/java.io=ALL-UNNAMED
- 若WebLogic客户端为模块化:
内容的提问来源于stack exchange,提问作者wouter
相关产品推荐
相关产品推荐

