I класс пересчитать динамические со следующим кодом:VerifyError в Gson классы
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$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)
Для справки, перехватчик в основном только вручную проверяет пакет-частного доступа (поскольку пакет частные методы были опубликованы), а затем просто вызывает superCall.call()
. Я не верю, что там лежит проблема.
Любые идеи?
EDIT: Вот PackagePrivateInterceptor
: общественный класс 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");
}
}
EDIT2: Следующий код не вызывает вопрос:
//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 использует ASM под обложками, которые заботятся обо всем постоянном пуле, поэтому я предполагаю, что в библиотеке есть проблема. –
Код метода: aload_0 aload_1 invokespecial [195] areturn', который выглядит разумным, т. Е. Не разбит. Итак, вопрос в том, что произошло с постоянным пулом, который должен содержать дескриптор метода в индексе '195'. Может быть, публикация результата 'unloaded.getBytes()' (как hex dump) может помочь ... – Holger
@RafaelWinterHalter, я пытался сделать чистый отдых, но проблема не возникает. Очевидно, это то, что я делаю, но дело в том, что я не делаю никаких манипуляций с байтами или чем-то еще. Я буду исследовать и попытаться выяснить, что именно я делаю, что вызывает эту ошибку. – erikh