title: How to tell proguard to keep enum constants and fields
body: <p>I've try obfuscate our web application which use spring, jaxb and relies on annotations, and reflection heavily.
  I apply many recipes found in internet to keep some classes, attributes, annotations and enumerations.
  But with enumerations still have problem. I've able preserve enum constants apply configuration from <a href="http://proguard.sourceforge.net/manual/examples.html#enumerations" rel="noreferrer">http://proguard.sourceforge.net/manual/examples.html#enumerations</a>:</p>
  
  <pre><code>-keepclassmembers,allowoptimization enum * {
      public static **[] values();
      public static ** valueOf(java.lang.String);
  }
  </code></pre>
  
  <p>At first glance it looks like working solution and constant preserved, so (<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getEnumConstants--" rel="noreferrer">Class.getEnumConstants()</a>) return correct list of values.
  But I got NoSuchFieldException when I try retrieve field by any of that by name.</p>
  
  <p>Problem come from <a href="http://grepcode.com/file/repo1.maven.org/maven2/com.sun.xml.bind/jaxb-impl/2.1.11/com/sun/xml/bind/v2/model/nav/ReflectionNavigator.java#ReflectionNavigator.getEnumConstants%28java.lang.Class%29" rel="noreferrer">jaxb reflection navigator</a>, please look at code:</p>
  
  <pre><code>public Field[] getEnumConstants(Class clazz) {
      try {
          Object[] values = clazz.getEnumConstants();
          Field[] fields = new Field[values.length];
          for (int i = 0; i &lt; values.length; i++) {
              fields[i] = clazz.getField(((Enum) values[i]).name());
          }
          return fields;
      } catch (NoSuchFieldException e) {
          // impossible
          throw new NoSuchFieldError(e.getMessage());
      }
  }
  </code></pre>
  
  <p>I fall exactly into "impossible" branch. I think it will be easy understandable to look at debug session screenshot (there also listed <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getEnumConstants--" rel="noreferrer"><strong>constants</strong></a>):
  <a href="https://i.stack.imgur.com/LjbCv.png" rel="noreferrer"><img src="https://i.stack.imgur.com/LjbCv.png" alt="Screenshot of debug session1"></a></p>
  
  <p>And if I try obtain <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getFields--" rel="noreferrer"><strong>fields</strong></a>, they are listed obfuscated as a, b, c, d, e, f:
  <a href="https://i.stack.imgur.com/vAz1Z.png" rel="noreferrer"><img src="https://i.stack.imgur.com/vAz1Z.png" alt="Screenshot of debug session2"></a></p>
  
  <p>My proguard configuration now look like (strip out some library listing and kipp particular classes, fields and methods about proguard complain):</p>
  
  <pre><code>-injars  core-3.15.rc5.6.jar
  -outjars core-3.15.rc5.6.proguard.jar
  
  -libraryjars &lt;java.home&gt;/lib/rt.jar
  
  -libraryjars ... # Other libs listed, strip out for shortness
  
  -printmapping core-3.15.rc5.6.proguard.map
  
  -keep public class ru.rlh.egais.portal.backend.controller.rest.**
  -keep public class ru.rlh.egais.portal.backend.integration.soap.service.**
  
  # http://midgetontoes.com/blog/2015/06/26/tips-for-using-proguard-with-spring-framework
  -optimizations !class/marking/final
  
  -adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF,META-INF/spring.*,spring/*
  
  -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
  # Also tried:
  # -keepattributes **
  
  -allowaccessmodification
  -dontshrink
  -dontoptimize
  -dontusemixedcaseclassnames
  -keepdirectories
  -keep @org.springframework.transaction.annotation.Transactional class *
  -keep @org.springframework.stereotype.Service class *
  -keep @org.springframework.stereotype.Repository class *
  -keep @org.springframework.stereotype.Controller class *
  -keep @org.springframework.stereotype.Component class *
  -keep @org.springframework.beans.factory.annotation.Autowired class *
  -keep @org.springframework.web.bind.annotation.ResponseBody class *
  -keep @org.springframework.web.bind.annotation.RequestMapping class *
  -keep @org.springframework.stereotype.Repository class *
  -keep @javax.annotation.Resource class *
  -keep @org.springframework.cache.annotation.EnableCaching class *
  -keep @org.springframework.context.annotation.Configuration class *
  
  -keepclassmembers class * {
      @org.springframework.beans.factory.annotation.* *;
      @org.springframework.beans.factory.annotation.Qualifier *;
      @org.springframework.beans.factory.annotation.Value *;
      @org.springframework.beans.factory.annotation.Required *;
      @org.springframework.context.annotation.Bean *;
      @javax.annotation.PostConstruct *;
      @javax.annotation.PreDestroy *;
      @org.aspectj.lang.annotation.AfterReturning *;
      @org.aspectj.lang.annotation.Pointcut *;
      @org.aspectj.lang.annotation.AfterThrowing *;
      @org.aspectj.lang.annotation.Around *;
  }
  
  -keepclassmembers enum * {
      public static **[] values();
      public static ** valueOf(java.lang.String);
  }
  </code></pre>
  
  <p>So, my question how I could fully keep public enums from obfuscation? In both cases - use its constants (<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getEnumConstants--" rel="noreferrer">class.getEnumConstants()</a>) and fields (<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getFields--" rel="noreferrer">class.getFields()</a>).</p>