cannot access class jdk.internal.misc.Unsafe(java9的模块概念)

现象
java11的本地环境,服务中使用到netty。启动后,服务无法访问,查看日志,有提示:
cannot access class jdk.internal.misc.Unsafe ... because the module java.base not export jdk.internal.misc to unnamed module

解决办法
stackoverflow给了原因以及解决办法。
在这里插入图片描述

--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
-Dio.netty.tryReflectionSetAccessible=true

到了这里就完了。但是为什么呢?他还指出了是java9的module概念。

作为一个刨根问底的程序员,当然要去看看。

Understanding Java 9 Modules
里面介绍了java9的概念,语法。大概一看,就是为了让Java环境更小、强封装等。

在这里插入图片描述

环境更小
好理解,只为设备安装需要的module。
强封装是什么东西?
在这里插入图片描述

其中语法open提到了,以前反射可以访问各种类、成员变量,不管它是public还是private的。实际上破坏了封装。
现在,只能访问export的模块

在这里插入图片描述
允许runtime期间在目标module访问某个package
opens package to comma-separated-list-of-modules

–add-opens等同于open to命令
```–add-opens module/package=target-module(,target-module)*``
在这里插入图片描述
因此我们的--add-opens java.base/jdk.internal.misc=ALL-UNNAMED命令就是让无法访问的jdk.internal.misc允许任何未命名的模块访问。

至于tryReflectionSetAccessible
官网说是告诉netty使用反射。
在这里插入图片描述

其他的,不看了, 还要加班呢。😕

参考
https://stackoverflow.com/questions/57885828/netty-cannot-access-class-jdk-internal-misc-unsafe
https://github.com/netty/netty/issues/7769
https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE
https://www.oracle.com/corporate/features/understanding-java-9-modules.html
https://segmentfault.com/a/1190000013409571

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是因为在Java程序中,尝试将一个类加载器(classloader)转换为另一个类加载器时出现了问题。具体来说,这个错误是因为尝试将一个名为“jdk.internal.loader.classloaders$appclassloader”的类加载器转换为“java.net.URLClassLoader”的类加载器时出现了问题。 这个错误通常是由于代码中的类型转换错误引起的。要解决这个问题,您需要检查代码中的类型转换,并确保它们是正确的。您还可以尝试使用不同的类加载器来加载您的类,以避免这个问题。 ### 回答2: 这个问题看起来是一个类型转换的错误。出现这个错误可能的原因是,代码中尝试将一个 JDK 内部的加载器 `jdk.internal.loader.classloaders$appclassloader` 强制转换为标准的 `java.net.URLClassLoader` 类型。这两个类虽然都是 Java 类加载器,但是它们之间有着一些区别和限制。 `jdk.internal.loader.classloaders$appclassloader` 类型的加载器是 JDK 内部实现的,通常用于加载应用程序所需的基本类和库。这个类加载器会尽可能地从本地磁盘或者网络中的已知位置获取类文件,以快速地完成加载请求。另一方面,`java.net.URLClassLoader` 类型的加载器是 Java 标准库中提供的,它可以通过 URL 地址动态地加载远程代码和库。它支持从标准的 `file://`、`http://` 等协议地址获取类文件或者 jar 包文件,并将它们加载到 JVM 中。 由于这两个类型的加载器有着不同的实现方式和加载机制,所以它们之间并不是互相兼容的。如果我们在代码中尝试将 `jdk.internal.loader.classloaders$appclassloader` 类型的加载器强制转换为 `java.net.URLClassLoader` 类型,就会触发一个 `ClassCastException` 异常。这是因为 `jdk.internal.loader.classloaders$appclassloader` 类型的对象无法转化为 `java.net.URLClassLoader` 类型,所以在转换时会抛出异常。 解决这个问题的方法,就是检查代码中的类型转换操作是否正确。如果确实需要使用 `java.net.URLClassLoader` 类型的加载器,就要使用正确的方式创建或者获取这个对象,而不是尝试强制转换一个不兼容的类加载器。如果不需要使用 `java.net.URLClassLoader` 类型的加载器,那么就应该避免通过强制转换的方式访问它们的方法和属性。 ### 回答3: 这个问题出现的原因是因为在代码中对类加载器进行了强制类型转换,但是由于使用了不同的类加载器,这个类型转换是不合法的。 具体来说,jdk.internal.loader.classloaders$appclassloader是Java 9及以上版本中的类加载器,而java.net.URLClassLoader是Java 8及以下版本中的类加载器。由于它们不是同一个类加载器,因此将一个转换为另一个是不可行的。 解决这个问题的方法是使用 instanceof 运算符来进行类型检查,然后再根据不同的类加载器做出相应的操作。例如: ClassLoader classLoader = MyClass.class.getClassLoader(); if (classLoader instanceof java.net.URLClassLoader) { java.net.URLClassLoader urlClassLoader = (java.net.URLClassLoader) classLoader; // 对URLClassLoader进行操作 } else if (classLoader instanceof jdk.internal.loader.classloaders.AppClassLoader) { jdk.internal.loader.classloaders.AppClassLoader appClassLoader = (jdk.internal.loader.classloaders.AppClassLoader) classLoader; // 对AppClassLoader进行操作 } else { // 其他类型的类加载器 } 在这种情况下,我们可以根据实际情况用不同的方式处理不同的类加载器。这样就可以避免出现类型转换异常的错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值