Menu

Problems getting Spring based application Running after obfuscation.

Help
2014-08-21
2014-08-22
  • Jason "JRSofty" Reed

    Hi, I'm trying to obfuscate our application that runs fine when not obfuscated. The application is built on the Spring framework, and apparently I'm having problems getting Spring and ProGuard to play nicely with one another.

    At this point I've told ProGuard to keep every thing about the offending class, but it still seems it feels the need to optimize even after telling it -dontoptimize. My big suspicion is that it has something to do with an optimization of a switch call. The output map shows the following:

    de.aeromaritime.messaging.roudistsrv.data.RdsDAO -> de.aeromaritime.messaging.roudistsrv.data.RdsDAO:
    long serialVersionUID -> serialVersionUID
    org.apache.log4j.Logger logger -> logger
    java.text.DateFormat AUTHINFO_DATE_FORMAT -> AUTHINFO_DATE_FORMAT
    javax.persistence.EntityManager em -> em
    boolean $assertionsDisabled -> $assertionsDisabled
    javax.persistence.EntityManager getEntityManager() -> getEntityManager
    java.util.List listMailbox(java.lang.String,de.aeromaritime.messaging.mail.Operator,de.aeromaritime.messaging.mail.type.MessageType,int,int,de.aeromaritime.messaging.mail.type.SortType,boolean,java.util.Map) -> listMailbox
    java.lang.String getColumnNameFromSortType(de.aeromaritime.messaging.mail.type.SortType) -> getColumnNameFromSortType
    de.aeromaritime.messaging.roudistsrv.st4406.service.som.MailStateExtraInfo getMailStateExtraInfoFromMessageId(java.lang.String) -> getMailStateExtraInfoFromMessageId
    java.util.List listMailbox(java.lang.String,de.aeromaritime.messaging.mail.Operator,java.util.Date,de.aeromaritime.messaging.mail.type.SortType,boolean) -> listMailbox
    de.aeromaritime.messaging.roudistsrv.data.schema.MessageHistory listTrashBox(java.lang.String) -> listTrashBox
    java.util.List getMessageHistory(java.lang.String,de.aeromaritime.messaging.mail.Operator,long) -> getMessageHistory
    java.util.List getMessageHistory(java.lang.String[],java.lang.String[],long) -> getMessageHistory
    boolean createINExpr(java.lang.StringBuilder,java.lang.String,java.lang.String[]) -> createINExpr
    java.lang.Long getMessageHistoryOID(de.aeromaritime.messaging.mail.Operator,de.aeromaritime.messaging.mail.IMail) -> getMessageHistoryOID
    de.aeromaritime.messaging.roudistsrv.data.schema.MessageHistory getMessageHistoryById(java.lang.Object) -> getMessageHistoryById
    de.aeromaritime.messaging.mail.IMail getMailById(java.lang.Object) -> getMailById
    java.lang.Long getMailOID(java.lang.String,int) -> getMailOID
    java.util.List getReportDestinations(java.lang.String) -> getReportDestinations
    de.aeromaritime.messaging.mail.Mail4406 getMessageForReport(de.aeromaritime.messaging.mail.Mail4406) -> getMessageForReport
    java.util.List getIPNDestinations(java.lang.String) -> getIPNDestinations
    de.aeromaritime.messaging.mail.Mail4406 getMessageForIPN(de.aeromaritime.messaging.mail.Mail4406) -> getMessageForIPN
    void persist(java.lang.Object[]) -> persist
    void save(java.lang.Object[]) -> save
    java.lang.Long saveMessageHistory(java.lang.String,java.lang.String,de.aeromaritime.messaging.mail.IMail) -> saveMessageHistory
    java.lang.Long saveMessageHistory(de.aeromaritime.messaging.mail.Operator,java.lang.String,de.aeromaritime.messaging.mail.IMail) -> saveMessageHistory
    void saveMessageHistory(de.aeromaritime.messaging.mail.Appointment,java.lang.String,de.aeromaritime.messaging.mail.IMail) -> saveMessageHistory
    boolean saveMessageAndHistory(java.util.Set,java.lang.String,de.aeromaritime.messaging.mail.IMail) -> saveMessageAndHistory
    boolean saveMessageAndHistoryDirect(java.util.Set,java.lang.String,de.aeromaritime.messaging.mail.IMail) -> saveMessageAndHistoryDirect
    de.aeromaritime.messaging.roudistsrv.data.schema.MessageHistory getMessageHistory(java.lang.String,java.lang.Object) -> getMessageHistory
    int deleteMessageHistory(java.lang.String,java.lang.Object) -> deleteMessageHistory
    boolean deleteMessage(java.lang.Object) -> deleteMessage
    boolean markMessageAsDeleted(java.lang.String,java.lang.Object) -> markMessageAsDeleted
    boolean moveToFolder(java.lang.String,java.lang.Object,java.lang.String) -> moveToFolder
    boolean isMessageReferenced(java.lang.Object) -> isMessageReferenced
    boolean markMessageRead(java.lang.Object) -> markMessageRead
    boolean markMessageRead(java.lang.String,java.lang.Object) -> markMessageRead
    java.util.Date getMessageRead(java.lang.String,java.lang.Object) -> getMessageRead
    java.lang.Long draftMessage(de.aeromaritime.messaging.mail.Operator,de.aeromaritime.messaging.mail.Appointment,de.aeromaritime.messaging.mail.IMail) -> draftMessage
    de.aeromaritime.messaging.mail.Mail rejectMessage(de.aeromaritime.messaging.mail.IMailHandle,java.lang.String,java.lang.String,java.lang.String) -> rejectMessage
    de.aeromaritime.messaging.mail.IMailHandle[] releaseMessage(de.aeromaritime.messaging.mail.IMailHandle,de.aeromaritime.messaging.mail.ICMailStore,java.lang.String,java.lang.String) -> releaseMessage
    boolean updateReleaser(java.lang.Object,java.lang.String,java.lang.String) -> updateReleaser
    boolean updateDrafter(java.lang.Object,java.lang.String) -> updateDrafter
    int getMailCount(de.aeromaritime.messaging.mail.Operator,java.lang.String,de.aeromaritime.messaging.mail.type.MessageType,boolean) -> getMailCount
    boolean markAllMessagesAsDeleted(java.lang.String) -> markAllMessagesAsDeleted
    boolean moveAllMessagesToFolder(java.lang.String,java.lang.String,java.lang.String,de.aeromaritime.messaging.mail.type.MessageType) -> moveAllMessagesToFolder
    void sendReleaseErrorNotification(de.aeromaritime.messaging.mail.MailCommon,java.lang.String) -> sendReleaseErrorNotification
    de.aeromaritime.messaging.roudistsrv.data.RdsDAO$1 -> de.aeromaritime.messaging.roudistsrv.data.RdsDAO$1:
    int[] $SwitchMap$de$aeromaritime$messaging$mail$type$SortType -> a
    

    My concern is with this de.aeromaritime.messaging.roudistsrv.data.RdsDAO$1 -> de.aeromaritime.messaging.roudistsrv.data.RdsDAO$1:
    int[] $SwitchMap$de$aeromaritime$messaging$mail$type$SortType -> a
    as this is not an internal class we're dealing with just a simple switch. Even stranger when I use a decompiler to view this a.class created here I find it basically empty. Just the standard class items. Now I have no idea if this is what it should look like or not but it looks wrong. The worse part is that I cannot get Spring to see this file or its annotations even though I've told ProGuard to -keep, -keepnames, -keepmembernames and as well as to -keepattributes Annotation.

    Any help to get this figured out would be most appreciated.

     
  • Eric Lafortune

    Eric Lafortune - 2014-08-22

    With -dontoptimize, the bytecode is left unchanged, but classes, fields, and methods may still be removed (if unused) or renamed (if possible).

    "de.....data.RdsDAO$1" is an anonymous inner class of RdsDAO. ProGuard has not renamed it, probably because you have a -keep option for it.

    "$SwitchMap$...$SortTyp" is a field of type "int[]" in this inner class. The javac compiler has added this synthetic field to implement a switch statement on an enum type "de.....type.SortTyp". ProGuard has renamed the field to "a". So in this context, "a" is not a class, just a field. You can preserve the class, its fields, and its methods, with their original names, with:

    -keep class de.aeromaritime.messaging.roudistsrv.data.RdsDAO$1 {
        *;
    }
    

    You can tweak the option to keep more or fewer classes, fields, and methods.

    Without details on the actual errors, I can't really tell if this is related to the problems with Spring. Spring uses a lot of reflection to access classes, fields, and/or methods, so you may need to preserve those. If you are using annotations, you indeed want to preserve those:

    -keepattributes *Annotation*
    

    For some frameworks, you need to preserve other attributes as well:

    -keepattributes *Annotation*,InnerClasses,EnclosingMethod,Signature
    
     
  • Jason "JRSofty" Reed

    Thanks, that moved me further. At least now I can get to the next error in the line :D.

    Any progress is good progress.