0

How can you strip java or scala annotations programmatically?

One of the deliverables for my current project is my code, plus whatever dependencies my code relies on, as an uber-jar. We're building an SDK therefore any of the included dependencies need to be renamed as to not interfere with the SDK client's dependencies (meaning if we're using apache commons version X, and they're using version Y, there aren't any conflicts). We used sbt-assembly to rename the packages our code relies on. For example org.apache.* -> com.mycompany.org.apache.*

Our project is largely written in scala and we're using sbt to build. Recently I determined that shading causes problems with the ScalaSignature annotation. This in turn causes build problems when the uber-jar is used in the client's project.

I have determined that removing ScalaSignature resolves the problem. I used ProGuard to do this, however that tool is overkill for what we are trying to achieve. I'm just curious if anyone out there has found a tool that can strip specified annotations. Or even better, a tool that will rename the packages while preserving ScalaSignature in a way that scalac is happy with.

James Sheppard
  • 301
  • 1
  • 4
  • 15
  • Can you explain how you used Proguard to remove this annotation ? I *really* would like to do the same. – Jan Goyvaerts Feb 01 '16 at 15:33
  • I think by default you just let proguard do its thing. It will by default remove annotations as part of the obfuscation process. If you have -dontobfuscate, it appears that's when annotations are kept, or at least the @ScalaSignature annotation. If you want to keep other attributes (line number table, etc.) try adding the line `--keepattribute !*Annotation*`. This will keep everything except annotations. – James Sheppard Feb 01 '16 at 21:08
  • Well, that will be a problem ! Because we're using annotations for Spring & co. So, no option either. :-) – Jan Goyvaerts Feb 02 '16 at 09:10
  • Check the proguard documentation. I believe with `--keepattribute` you can specify which annotations you want to keep. Good luck! – James Sheppard Feb 03 '16 at 18:17

1 Answers1

1

You might want to check JavaAssist library, which clearly allows to get/add annotations dynamically.

Following that, it should be theoretically possible to use AnnotationsAttribute in the following way (haven't tried myself but let us know if the below has worked):

MethodInfo minfo = m.getMethodInfo();
AnnotationsAttribute attr = (AnnotationsAttribute)
     minfo.getAttribute(AnnotationsAttribute.invisibleTag);
Annotation[] annotations = attr.getAnnotations();
// ...remove the unnecessary annotation from array...
attr.setAnnotations(annotations);
mindas
  • 26,463
  • 15
  • 97
  • 154
  • Thank you for your response. I was looking for something more along the lines of a plugin that will do this as part of the build process as it seems @ScalaSignature is added as part of the compilation process. – James Sheppard Feb 01 '16 at 21:11