5 回答
TA贡献1799条经验 获得超8个赞
我有同样的问题(但使用JDK 11):
找不到方法 'sun.misc.Unsafe.defineClass(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;'。
和你一样的版本gradle 4.7。
我的gradle-wrapper.properties文件是:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
为了解决这个问题,我使用参数更改为 4.9 版本的包装器distributionUrl:
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
并在没有任何错误的情况下重建项目。
TA贡献1765条经验 获得超5个赞
在jdk 9 中sun.misc.Unsafe.defineClass
已被替换为,在 jdk 11 中完全删除。java.lang.invoke.MethodHandles.Lookup.defineClass
sun.misc.Unsafe.defineClass
TA贡献1898条经验 获得超8个赞
由于 Java 后期版本的 sun.misc.Unsafe 中删除了 defineClass 方法,所以我们需要在内部 Unsafe 中调用该方法。由于默认情况下整个包是隐藏的,我们需要反射地调用所有内容。此代码从 java 17 开始工作
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe"),
f1 = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
f1.setAccessible(false);
Unsafe unsafe = (Unsafe) f.get(null);
int i;//override boolean byte offset. should result in 12 for java 17
for (i = 0; unsafe.getBoolean(f, i) == unsafe.getBoolean(f1, i); i++);
Field f2 = Unsafe.class.getDeclaredField("theInternalUnsafe");
unsafe.putBoolean(f2, i, true);//write directly into override to bypass perms
Object internalUnsafe = f2.get(null);
Method defineClass = internalUnsafe.getClass().getDeclaredMethod("defineClass",
String.class, byte[].class, int.class, int.class,
ClassLoader.class, ProtectionDomain.class);
unsafe.putBoolean(defineClass, i, true);
Class<?> newClass = (Class<?>) defineClass.invoke(internalUnsafe,
className, byteCode, offset, length,
Object.class.getClassLoader(), Object.class.getProtectionDomain());
} catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e);
}
我将逐步解释这是在做什么
使用反射直接访问 sun.misc.Unsafe 实例。
获取 sun Unsafe 字段的另一个副本,将其设置为不可访问
严格地遍历这两个实例中的字节,直到发现差异。这是 AccessibleObject 类中的变量“覆盖”,字段和方法用于确定它们是否可访问。
从 sun Unsafe 类中获取 internalUnsafe 字段,使用 sun Unsafe 实例将其设置为可访问(虽然我们可以获取字段对象,但 java 不会让我们将内部或反射包中的任何内容设置为可直接访问)
获取 internalUnsafe 实例,将其保存到 Object 指针,因为我们不能直接引用 internal.misc.Unsafe
从 internalUnsafe 反射性地获取 defineClass 方法
使用与太阳相同的偏移量将方法设置为可访问不安全
用我们的参数调用它
希望只要 Unsafe 保留在 jdk 中,它就可以继续工作。
TA贡献1865条经验 获得超7个赞
Gradle 中的 .gradle 文件中的依赖项存在问题。或 pom.xml 文件(如果您使用的是 Maven)。这可能有很多原因:版本冲突,或者两次声明相同依赖项的冲突。或者检查您添加到库中的 jar_file 版本。
添加回答
举报