gpt4 book ai didi

java - Gson 类中的VerifyError

转载 作者:行者123 更新时间:2023-11-30 02:52:32 25 4
gpt4 key购买 nike

我使用以下代码对一个类进行 rebase :

DynamicType.Unloaded unloaded = new ByteBuddy().with(TypeValidation.DISABLED).rebase(typeDescription,
ClassFileLocator.Simple.of(className, classBytes,
ClassFileLocator.ForClassLoader.of((ClassLoader) classLoader))).method(
ElementMatchers.isPackagePrivate().and(ElementMatchers.not(ElementMatchers.isAbstract()))).intercept(
MethodDelegation.to(PackagePrivateInterceptor.class)).transform(
MethodTransformer.Simple.withModifiers(Visibility.PUBLIC)).make();
return new ClassPair(unloaded.load((ClassLoader) classLoader,
ClassLoadingStrategy.Default.INJECTION.withProtectionDomain(
classLoader.getClass().getProtectionDomain())).getLoaded(), unloaded.getBytes());

加载类时class com.google.gson.internal.ConstructorConstructor

它会遍历构造函数,直到最后到达 com.google.gson.internal.LinkedTreeMap 的类初始值设定项。

在初始化期间,我收到一个VerifyError:

1:24:20.227 [main] ERROR   [io.hakansson.dynamicjar.core.main.Bootstrap] - java.lang.RuntimeException: java.lang.VerifyError: Illegal type at constant pool entry 195 in class com.google.gson.internal.LinkedTreeMap$1Exception Details:  Location:    com/google/gson/internal/LinkedTreeMap$1.thenComparing$accessor$vT023QbO(Ljava/util/function/Function;)Ljava/util/Comparator; @2: invokespecial  Reason:    Constant pool index 195 is invalid  Bytecode:    0x0000000: 2a2b b700 c3b0                             at io.hakansson.dynamicjar.core.api.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:52)    at io.hakansson.dynamicjar.core.main.Bootstrap.main(Bootstrap.java:42)Caused by: java.lang.VerifyError: Illegal type at constant pool entry 195 in class com.google.gson.internal.LinkedTreeMap$1Exception Details:  Location:    com/google/gson/internal/LinkedTreeMap$1.thenComparing$accessor$vT023QbO(Ljava/util/function/Function;)Ljava/util/Comparator; @2: invokespecial  Reason:    Constant pool index 195 is invalid  Bytecode:    0x0000000: 2a2b b700 c3b0                             at com.google.gson.internal.LinkedTreeMap.classInitializer$oNOjADym(LinkedTreeMap.java:40)    at com.google.gson.internal.LinkedTreeMap.(LinkedTreeMap.java)    at com.google.gson.internal.ConstructorConstructor$13.construct$original$gt92dwVY(ConstructorConstructor.java:207)    at com.google.gson.internal.ConstructorConstructor$13.construct$original$gt92dwVY$accessor$lof1omy8(ConstructorConstructor.java)    at com.google.gson.internal.ConstructorConstructor$13$auxiliary$oB71rVyd.call(Unknown Source)    at io.hakansson.dynamicjar.nestedjarclassloader.PackagePrivateInterceptor.intercept(PackagePrivateInterceptor.java:29)    at com.google.gson.internal.ConstructorConstructor$13.construct(ConstructorConstructor.java)    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:167)    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read$original$ZTjOtCtb(ReflectiveTypeAdapterFactory.java:116)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read$original$ZTjOtCtb$accessor$WgRdwpwl(ReflectiveTypeAdapterFactory.java)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1$auxiliary$41HBhnNS.call(Unknown Source)    at io.hakansson.dynamicjar.nestedjarclassloader.PackagePrivateInterceptor.intercept(PackagePrivateInterceptor.java:29)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read$original$bOjIYDn5(TypeAdapterRuntimeTypeWrapper.java:40)    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read$original$bOjIYDn5$accessor$hMWEZRZS(TypeAdapterRuntimeTypeWrapper.java)    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper$auxiliary$U1tyihKy.call(Unknown Source)    at io.hakansson.dynamicjar.nestedjarclassloader.PackagePrivateInterceptor.intercept(PackagePrivateInterceptor.java:29)    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java)    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read$original$ZTjOtCtb(ReflectiveTypeAdapterFactory.java:116)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read$original$ZTjOtCtb$accessor$WgRdwpwl(ReflectiveTypeAdapterFactory.java)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1$auxiliary$41HBhnNS.call(Unknown Source)    at io.hakansson.dynamicjar.nestedjarclassloader.PackagePrivateInterceptor.intercept(PackagePrivateInterceptor.java:29)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)    at com.google.gson.Gson.fromJson(Gson.java:879)    at com.google.gson.Gson.fromJson(Gson.java:817)

For reference, the interceptor basically just manually checks for package-private access (since package private methods were made public) and then just calls superCall.call(). I don't believe the issue lies there.

Any ideas?

EDIT:Here's the PackagePrivateInterceptor: public class PackagePrivateInterceptor {

@RuntimeType
@BindingPriority(1)
public static Object intercept(@SuperCall Callable<?> superCall, @Origin Class targetClass, @Origin String method) throws
Exception
{

Class callingClass = new InternalSecurityManager().getCallingClass();
String targetPackage = targetClass.getPackage().getName();
if (!callingClass.getPackage().getName().equals(targetPackage)) {
throw new IllegalAccessError(callingClass + " cannot access method " + method + " of Class " + targetClass);
}

//Default:
return superCall.call();
}

private static class InternalSecurityManager extends SecurityManager {
Class getCallingClass() {
Class[] classContext = getClassContext();
for (Class current : classContext) {
if (current.getName().startsWith("java.") ||
current.getName().equals(PackagePrivateInterceptor.class.getName()) ||
current.getName().equals(InternalSecurityManager.class.getName()))
{
continue;
}
return current;
}
throw new IllegalStateException("Failed to find calling Class");
}
}

编辑2:以下代码不会触发该问题:

//Only package-private methods should be proxied.
DynamicType.Unloaded unloaded = new ByteBuddy().with(TypeValidation.DISABLED).rebase(typeDescription,
ClassFileLocator.Simple.of(className, classBytes,
ClassFileLocator.ForClassLoader.of((ClassLoader) classLoader))).method(
ElementMatchers.isPackagePrivate().and(ElementMatchers.not(ElementMatchers.isAbstract()))).intercept(
MethodDelegation.to(PackagePrivateInterceptor.class)).transform(
MethodTransformer.Simple.withModifiers(Visibility.PUBLIC)).make();
DynamicType.Loaded loaded = unloaded.load((ClassLoader) classLoader,
ClassLoadingStrategy.Default.INJECTION.withProtectionDomain(
classLoader.getClass().getProtectionDomain()));
if (className.equals("com.google.gson.internal.LinkedTreeMap"))
System.out.println(DatatypeConverter.printHexBinary(loaded.getBytes()));
return new ClassPair(loaded.getLoaded(), unloaded.getBytes());

但以下情况确实如此:

//All non-private methods should be proxied
//TODO: Actually, the class itself should be made visible and still only package-private methods should be proxied.
DynamicType.Unloaded unloaded = new ByteBuddy().with(TypeValidation.DISABLED).rebase(typeDescription,
ClassFileLocator.Simple.of(className, classBytes,
ClassFileLocator.ForClassLoader.of((ClassLoader) classLoader))).method(
ElementMatchers.not(ElementMatchers.isPrivate()).and(
ElementMatchers.not(ElementMatchers.isAbstract()))).intercept(
MethodDelegation.to(PackagePrivateInterceptor.class)).transform(
MethodTransformer.Simple.withModifiers(Visibility.PUBLIC)).make();
return new ClassPair(unloaded.load((ClassLoader) classLoader,
ClassLoadingStrategy.Default.INJECTION.withProtectionDomain(
classLoader.getClass().getProtectionDomain())).getLoaded(), unloaded.getBytes());

最佳答案

这确实是Byte Buddy的一个bug。问题在于您正在 Java 8 VM 上重新构建 Java 6 类,其中 Comparable 接口(interface)正在实现多个默认方法。您指示 Byte Buddy 覆盖这些方法,还指示库从覆盖的实现中调用这些默认方法。即使 VM 运行 Java 8,这对于 Java 6 类文件也是不合法的。

如果我将您的匹配器更改为:

not(isPrivate().or(isAbstract()).or(isDefaultMethod()))

错误消失。我将在 Byte Buddy 的 future 版本中修复此问题。

此错误当前未被 Byte Buddy 或 ASM 捕获,从而产生奇怪的错误消息。

更新:该错误现已在版本 1.4.13 中得到解决。

关于java - Gson 类中的VerifyError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38199849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com