【发布时间】:2013-11-24 21:16:21
【问题描述】:
我正在使用 proguard 来缩小阴影 jar 以用作命令行工具。阴影 jar 工作正常,但在运行 proguard 创建的 jar 时出现异常。该应用程序使用 Guice 注入,我添加了我在 SO 上找到的配置,主要是在 this answer。
这是例外:
Exception in thread "main" java.lang.reflect.MalformedParameterizedTypeException
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:60)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:95)
at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:140)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
at java.lang.Class.getGenericSuperclass(Class.java:696)
at com.google.inject.internal.MoreTypes.getGenericSupertype(MoreTypes.java:273)
at com.google.inject.TypeLiteral.getSupertype(TypeLiteral.java:257)
at com.google.inject.spi.InjectionPoint.hierarchyFor(InjectionPoint.java:755)
at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:635)
at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:356)
at com.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:151)
at com.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:585)
at com.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:543)
at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:529)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:847)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:772)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:256)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:205)
at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:853)
at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:133)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at com.acme.ui.cli.Main.main(Main.java:44)
这是产生它的配置:
-injars acme-cli-0.2.1-SNAPSHOT.jar
-outjars target/acme-cli-0.2.1-SNAPSHOT.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jce.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jsse.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/rt.jar
-dontobfuscate
-dontpreverify
-dontoptimize
-printmapping mapping.map
-ignorewarnings
-keepattributes *Annotation*,Signature
# Keep - Applications. Keep all application classes, along with their 'main' methods.
-keep public class com.acme.ui.cli.Main {
public static void main(java.lang.String[]);
}
# Keep Guice-related classes
-keep public class javax.inject.**
-keep class com.google.inject**
-keep class * extends com.google.inject.AbstractModule
# keeps all fields and Constructors annotated with @Inject and @AssistedInject
-keepclasseswithmembers class * {
@com.google.inject.Inject <fields>;
@com.google.inject.Inject <init>(...);
}
-keepclasseswithmembers class * {
@com.google.inject.assistedinject.AssistedInject <fields>;
@com.google.inject.assistedinject.AssistedInject <init>(...);
}
当我添加这个问题时,问题就消失了:
-keep class * {
<init>(...);
}
但它保留了更多的类,并使 jar 的大小增加了一倍。我正在使用 proguard 4.10 并尝试过 4.9。以下是我尝试过的一些似乎最相关的选项:
-keepattributes *
-keepparameternames
-keep class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl {
<init>(...);
}
由于它似乎与 Guice 相关并且保留所有构造函数可以解决问题,因此我还尝试了各种方法来配置保留选项而没有结果。但我必须说我并不完全理解它们。
我不确定它是否与问题有关,但看起来很奇怪的是 ParameterizedTypeImpl 类中唯一的构造函数具有这样的签名:private ParameterizedTypeImpl(java.lang.Class<?> aClass, java.lang.reflect.Type[] types, java.lang.reflect.Type type),但堆栈跟踪中的签名看起来像是在接受 ParameterizedTypeImpl 本身:ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53)。
现在我被困住了;非常感谢任何可以进一步帮助我的建议。
【问题讨论】:
-
你解决了这个问题吗?
-
我还发布了same question on the proguard forum,在那里我得到了回复。您可能可以使用一些建议,但罪魁祸首似乎是一个错误。我们还没有发布示例供 proguard 的维护者调查,可能还需要两周时间。
-
如果有用,我会在这里发布我们的发现。如果您在我们做之前发现任何有用的东西,您介意也分享一下吗?
标签: java reflection guice proguard