0

I have a java library project which contains a dependency to guava library. Guava has near 11k methods count, and I expect most of the users would came from the Android community. On Android there is a limit count method, it is 65k...

But the total count methods of my library is about 11.400, so my library's code is under 200 lines.

I was able to download and shrank a guava jar using proguard, reducing the count method number to 1k. But now the project needs to contain a reference to this shrank jar, instead a reference to the remote repository where the guava is hosted. But any jar added to the project would be discard by maven when it were published at any remote repository as an artifact, so the guava dependencies could not be resolved and the application client ultimately would crash.

Guava itself advices to not use proguard if your “application” is actually a library, and leave to the users of your library deal with this situation, using themselves proguard in order to shrank guava. But I don’t like this idea, because I would like to offer an easy configuration solution.

As far as I know, the output that proguard provides is some sort of executable (jar, apk, etc), so, If I shrank my own library, the final output would be a jar, and this jar, again, could not be published as an artifact, because it would be discarded (I tried it several times).

Is there any way of using proguard in my own java library project and pass the resulting output to the build chain in order to be published as a remote repository, not as a jar?

I’m using gradle by the way to build my project, but at this point I would be up to move to a maven one it that solves the problem.

Thanks.

Community
  • 1
  • 1
Víctor Albertos
  • 8,093
  • 5
  • 43
  • 71

1 Answers1

1

Do one of the followings:

  1. Use your shrank version of guava as separate maven artifact, publish it, and let your lib depend on it as on any other dependency
  2. Do not shrink the library and use multidex build - this is the method to solve 65K method limiation http://developer.android.com/tools/building/multidex.html

Anyway as for ease of configuration you should not use progruard on your library for a simple reason: User will have to add dependency to its project anyway. And what if in some cases users will start having ClassNotFound exception because you have truncated some of the code that you didnt expect it can be used?

If somebody is programing for Android he will sooner or later bang into ProGuard, and I think sooner is better.

So as for ease of configuration, I would rather suggest in the documentation, that if user wants to avoid 65k limitation because your library is already exceeding it, he can use proguard in provided example configuration.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • It’s your first approach what I tried to accomplish but I did not success. Because if I have this shrank version of guava as a jar, how can I publish as a maven artifact? I did not find any information about it, just this, and it did not work at all http://ufasoli.blogspot.com.es/2013/05/managing-system-scoped-jars-with-maven.html – Víctor Albertos Jan 16 '16 at 01:35
  • This is not a straightforward to do. You would have to create an empty project with guava as dependency and have Progruard enabled for it. You could build it and publish as "MyShrankGuavaDep". I suggest to not go that way, and leave library shrinking to the end user - maybe he will use guava in his project nad gradle/maven will not import it again because it will be imported as dependency to your library. If not, he can use proguard then. – Antoniossss Jan 16 '16 at 01:40
  • Maven scopes is different story (referencing to link u provided in comment). Simply speaking: You would have to build a project that uses Proguard to shrink its dependencies, and use that project as dependency to your library project. – Antoniossss Jan 16 '16 at 01:43
  • I tried that already. With different approaches indeed, and none of them worked out. https://github.com/VictorAlbertos/GuavaShrankRxCache. In the end I always have a jar, and I do not know how to publish this jar as an artifact, even in another complete maven project. – Víctor Albertos Jan 16 '16 at 01:48
  • It is all done by maven. Did you google "how to upload maven artifact to maven central" ?? Your case is no different https://maven.apache.org/guides/mini/guide-central-repository-upload.html – Antoniossss Jan 16 '16 at 01:49
  • If I did that, the guava jar dependency would be discarded because jars are not added to the classpath. If instead of that, I use guava as a maven repository dependency inside my project -not a jar, I don’t know how to use the output jar generated by proguard as the artifact. Because as you already said, maven does that automatically, so I don’t know how to tell maven, “this jar generated by proguard is what I want to use to create the artifact”. Said so, my knowledge of maven is pretty limited. – Víctor Albertos Jan 16 '16 at 02:00
  • OK ic what is the problem here, maven does not include another maven dependency into artifact (cuz why the hell he should? :)) The last resort would be to download the sources and use it in the project insteed of using maven dependency. This would be like you wrote everything yourself, nad the ProGuard would exclude required code. This way you would not need any dependency. However I am affraid that this can cause conflicts when somebody will use Guava ad dependency - there would be a class conflicts :( I think that you will have to leave your LIB without progruard :( – Antoniossss Jan 16 '16 at 02:10
  • And to avoid conflicts you would have to refactor whole package (eg. addint `victor` as a first suffix to every package in Guava lib. I think it is not worth of diggin, just make your lib with Guava as devendency and let the end user handle the rest. – Antoniossss Jan 16 '16 at 02:11
  • Even if I do that -use the original source code of guava in my own project- still I don’t know how to put proguard in the middle of the build chain. I mean, proguard generates a jar output, which is what you want when you project is a final product (like an apk), but my project is a library, so what do I do with this jar created by proguard. How can I tell maven “get this jar generated by proguard”? xD I’m going to take the second approach, in any case, it is the most safety. If in a few days if no one has given to me a solution I will accept your answer. Thanks a lot ;) – Víctor Albertos Jan 16 '16 at 02:21
  • 1
    I must admit that I never used proguard with maven (android projects only with gradle), You would probably have to use some kind of other publishing plugin... But to be honest, these are bounderies of my knowlage and I will not be able to help further :( The only thing left, is use the 2) approach. On the other hand bigger brains than us probably wanted to achieve that and concluded in "not recomending using proguard on lib projects". This is not much overhead for the enduser, but a hell of a work for you as you can see. So there is a reason for that. Leave Progruard to endusers with APKs :) – Antoniossss Jan 16 '16 at 02:31