Menu

#577 Invalid generic signature in the output jar

v5.2
closed-fixed
None
7
2017-06-27
2015-07-13
No

When working on the android gradle plugin, we encountered an issue ( http://b.android.com/175579 ) that I believe boils down a bug in ProGuard. I reduced it to a minimal repro scenario that you can find here:

https://github.com/benol/proguard-bug-repro

In short, for a Guava class with a non-trivial generic signature, ProGuard produces this signature in the output jar "Lcom/google/common/collect/AbstractMapBasedMultimap<tk;tv;>.com/google/common/collect/AbstractMapBasedMultimap$WrappedCollection;Ljava/util/Set<tv;>;" The part after the dot is a fully-qualified name and causes a parse error at runtime.</tv;></tk;tv;>

I checked the problem occurs on Linux and OS X, JDK 1.8.0_45.

Discussion

  • Eric Lafortune

    Eric Lafortune - 2015-07-29

    Thanks for your detailed report and sorry for the delay. I can reproduce the problem. Adding the following at line 317 in file src/proguard/shrink/ClassShrinker.java should fix it:

    else if (classEnumeration.isInnerClassName())
    {
        className = className.substring(className.lastIndexOf(ClassConstants.INNER_CLASS_SEPARATOR)+1);
    }
    

    It's not very pretty, but then again, neither are these generic signatures. I'll include this fix (with some documentation) in the upcoming ProGuard 5.3.

     
  • Eric Lafortune

    Eric Lafortune - 2015-07-29
    • status: open --> open-fixed
    • assigned_to: Eric Lafortune
    • Priority: 5 --> 7
     
  • Ashwin Agrawal

    Ashwin Agrawal - 2015-08-06

    Even I face similar issue where I get an exception if I enable "-dontobfuscate", if I remove this line from my proguard configuration, exception is gone. I tried above sugested fix, However, the issue is not resolved. Can you please help. The exception log is as below:

    Any clue/help will be appreciated.

     Caused by: java.lang.reflect.GenericSignatureFormatError
            at libcore.reflect.GenericSignatureParser.expect(GenericSignatureParser.java:473)
            at libcore.reflect.GenericSignatureParser.parseClassTypeSignature(GenericSignatureParser.java:332)
            at libcore.reflect.GenericSignatureParser.parseFieldTypeSignature(GenericSignatureParser.java:289)
            at libcore.reflect.GenericSignatureParser.parseForField(GenericSignatureParser.java:218)
            at java.lang.reflect.Field.initGenericType(Field.java:115)
            at java.lang.reflect.Field.getGenericType(Field.java:196)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:141)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:83)
            at com.google.gson.Gson.getAdapter(Gson.java:359)
            at com.google.gson.Gson.fromJson(Gson.java:809)
            at com.google.gson.Gson.fromJson(Gson.java:775)
            at retrofit.converter.GsonConverter.fromBody(GsonConverter.java:63)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:367)
    

    at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265)
                at retrofit.RxSupport$2.run(RxSupport.java:55)
                at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
                at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                at retrofit.Platform$Android$2$1.run(Platform.java:142)
                at java.lang.Thread.run(Thread.java:841)

     

    Last edit: Ashwin Agrawal 2015-08-06
    • Eric Lafortune

      Eric Lafortune - 2015-08-11

      Ashwin, could you find out which generic signature is triggering the problem? Perhaps a sample that allows me to reproduces the exception?

       
  • Eric Lafortune

    Eric Lafortune - 2016-10-23
    • Status: open-fixed --> closed-fixed
     
  • Yohann Roussel

    Yohann Roussel - 2017-06-27

    I'm still able to reproduce with Proguard 5.3.3 and the attached project.

    The problematic signature is "Lp/a<tt;>.p/b<tv;>;"</tv;></tt;>

    you can reproduce with
    javac p/*.java
    jar cvf ../generic.jar .
    proguard.sh -injars ../generic.jar -outjars ../proguarded.jar @p/proguard.flags -libraryjars $JAVA_HOME/jre/lib/rt.jar
    java -cp ../proguarded.jar p.Main

    Tested to fail on java 1.8.0_45 with
    Exception in thread "main" java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' or '.', got '/'.
    Remaining input: /b<tv;>;
    at sun.reflect.generics.parser.SignatureParser.error(SignatureParser.java:124)
    at sun.reflect.generics.parser.SignatureParser.parseSimpleClassTypeSignature(SignatureParser.java:367)
    at sun.reflect.generics.parser.SignatureParser.parseClassTypeSignatureSuffix(SignatureParser.java:378)
    at sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature(SignatureParser.java:312)
    at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:289)
    at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:283)
    at sun.reflect.generics.parser.SignatureParser.parseTypeSignature(SignatureParser.java:485)
    at sun.reflect.generics.parser.SignatureParser.parseTypeSig(SignatureParser.java:188)
    at sun.reflect.generics.repository.FieldRepository.parse(FieldRepository.java:52)
    at sun.reflect.generics.repository.FieldRepository.parse(FieldRepository.java:42)
    at sun.reflect.generics.repository.AbstractRepository.<init>(AbstractRepository.java:74)
    at sun.reflect.generics.repository.FieldRepository.<init>(FieldRepository.java:48)
    at sun.reflect.generics.repository.FieldRepository.make(FieldRepository.java:66)
    at java.lang.reflect.Field.getGenericInfo(Field.java:105)
    at java.lang.reflect.Field.getGenericType(Field.java:247)
    at java.lang.reflect.Field.toGenericString(Field.java:329)
    at p.Main.main(Unknown Source)</init></init></tv;>

     

Log in to post a comment.