Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 验证Gson类中的错误_Java_Bytecode_Byte Buddy - Fatal编程技术网

Java 验证Gson类中的错误

Java 验证Gson类中的错误,java,bytecode,byte-buddy,Java,Bytecode,Byte Buddy,我使用以下代码重新设置类的基础: DynamicType.Unloaded unloaded = new ByteBuddy().with(TypeValidation.DISABLED).rebase(typeDescription, ClassFileLocator.Simple.of(className, classBytes, ClassFileLocator.ForClassLoader.of((Class

我使用以下代码重新设置类的基础:

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.constructor

它经过构造函数,最后到达
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$1 Exception 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$1 Exception 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) 编辑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());

这确实是一个Buddy中的bug。问题是您正在Java 8虚拟机上重新设置Java 6类的基础,
Comparable
接口正在实现几个默认方法。您可以指示Byte Buddy重写这些方法,还可以指示库从重写的实现中调用这些默认方法。这对于Java 6类文件是不合法的,即使VM正在运行Java 8

如果我能让你的匹配者:

not(isPrivate().or(isAbstract()).or(isDefaultMethod()))
错误消失了。我将在Byte Buddy的未来版本中修复此问题

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


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

您能否重新生成该错误?通常情况下,这种情况不应该发生,我无法创建此错误。Byte Buddy在后台使用ASM,它负责处理整个常量池,因此我假设库中存在问题。方法代码为
aload_0 aload_1 invoke,特别是[195]areturn
,看起来很合理,即没有垃圾。所以问题是,常量池发生了什么,它应该在索引
195
处包含一个方法描述符。也许发布unload.getBytes()的
结果(作为十六进制转储)会有帮助…@RafaelWinterHalter,我已经尝试了一个干净的娱乐,但问题没有出现。很明显,这是我做的事情,但问题是我不做任何字节或任何操作。我将调查并尝试看看触发此错误的确切原因。@Holger,这是
com/google/gson/internal/LinkedTreeMap
的hexdump:我对字节码一无所知,因此非常感谢您的帮助。您是否编写了自定义组件?在我看来,你注册了某种形式的自定义转换器或Java代理,它会破坏你的类文件。工作起来很有魅力!非常感谢。所以我认为这是我的一个错误,在ASM/ByteBuddy中触发了一个bug。添加isDefaultMethod时,它会起作用。但是,我不能更新到最新版本的ByteBuddy,因为这会引发新的问题,但我会发布另一个关于这个问题的问题。关于另一个问题,没关系,它显然在1.4.13中解决了。这是因为找不到泛型类型“E”。
not(isPrivate().or(isAbstract()).or(isDefaultMethod()))