使用proguard时出现MalformedParameterizedTypeException

时间:2013-11-24 21:16:21

标签: java reflection guice proguard

我正在使用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)

现在我被困住了;任何可以帮助我的建议都非常感谢。

1 个答案:

答案 0 :(得分:1)

这是Proguard 5.0中修复的已知错误。见https://sourceforge.net/p/proguard/bugs/518/