On 5 Jul 2011, at 20:47, Sam Berlin wrote: > Thanks for looking into this, Stuart! Some replies inline.. > > On Tue, Jul 5, 2011 at 3:20 PM, Stuart McCulloch <[email protected]> wrote: > Hi folks, > > Background: > > The Guice project tree used to include a sub-set of Guava source code, > manually refactored under "core/src/com/google/inject/internal/util". Guava > is an internal implementation detail, just like CGLIB and ASM, which is why > it is embedded under an internal package inside Guice. Recently this code was > removed and replaced with a dependency to guava-r09.jar whose classes are now > refactored and shrunk by jarjar at build time. Unfortunately, because of a > limitation in jarjar (see an earlier discussion under > http://code.google.com/p/google-guice/issues/detail?id=264) it has trouble > shrinking Guava down to the subset of classes which are strictly required by > Guice. This means that the current Guice jar built from trunk is now just > over 1Mb compared to just under 700Kb for Guice 3, which might not be an > issue for most desktop developers but could be a concern for mobile > developers. > > Enter ProGuard: > > There are several jar shrinking tools around, one of the better ones being > ProGuard http://proguard.sourceforge.net/ However it doesn't appear to have > the capability to preserve the classname when you ask it to refactor > packages, instead it renames them to short names such as A, B, etc. which > isn't good for debugging. The best solution seems to be a combination of > ProGuard (for shrinking) and jarjar (for package refactoring) and with a bit > of tweaking I can get the Guice jar down to around 830kb (still not as good > as when we manually copied in the subset of Guava source, but not bad). > > I haven't messed around with ProGuard much, but looking at the reference page > @ http://proguard.sourceforge.net/index.html#/manual/refcard.html shows a few > options that seem like they'd get the job done for not renaming: --keepnames > (and a few others with that prefix), --dontoptimize, --dontobfuscate, > --keeppackagenames, --keepparameternames.
yeah, those either keep the entire name (ie. package + simple name) or let you relocate classes to a different package but doesn't keep the simple class name I've not (yet) found a ProGuard option that can match what jarjar does, which is relocate the package but retain the simple name (which helps when debugging) > > > Fragility Concerns: > > While adding ProGuard to my prototype Guice build I ran into a couple of > cases where extensions and tests relied on Guava methods that weren't used in > Guice core. Because ProGuard (and jarjar) operate on Guice core before the > tests or extensions are built, it has no knowledge that these methods should > be retained, which leads to odd test failures. While I can add explicit > instructions to tell ProGuard to keep these methods and classes around, I'm > concerned that this makes the build much more fragile. An extension developer > could easily depend on a new method in Guava (since it's on the project > classpath) and this new method wouldn't be repackaged inside Guice unless the > ProGuard instructions were updated (or unless Guice core just happened to > also use the same method). > > Note this wasn't an issue when we manually included the sub-set of Guava > source code, because the extensions built against the classes under > "core/src/com/google/inject/internal/util" and not against the whole of Guava. > > Possible Options? > > 1) Do nothing (and live with the larger jar size where we basically embed > all of Guava) > > If we need to, I think this is a valid choice. The jar for mobile folks will > be smaller anyway, since it won't include cglib or asm. Also, the only bits > of Guava that are kept are any referenced (transitively) classfiles. In > practice, that ends up as most of com.google.common.base & > com.google.common.collect, plus a few scattered com.google.common.io classes. > For the non-mobile version, it's about a ~400k increase the main jar size. > > > 2) Add ProGuard to the core build (and live with having to update the > instructions when extensions use new Guava methods) > > IMO, this is the best option. The extensions aren't updated all that often, > and it would be rare that one needs to use a method/class that the core isn't > using. An alternative here would be to make the extensions ProGuard/jarjar > their own Guavas. That would slightly increase the size of extensions that > use them, but not by much. > > > 3) Revert to including the sub-set of Guava source code (harder to update, > but perhaps more manageable / less fragile?) > > Definitely -1 here. Pointing to Guava gives us a lot of nice things, such as > making it a whole lot easier to update when new Guava releases come out (such > as the soon-to-be-shipped r10 which removes FinalizableReferenceQueue > entirely, fixing issue 288 for us just by dropping in a new jar). > > > 4) Build Guice core + extensions without any jarjar'ing or ProGuard'ing, > only do that as a final distribution / packaging step > > This sounds like an an implementation detail and we'd still have to resolve > #2 or #3... and I'd very much like to avoid people accidentally building > against the wrong version. > > > 5) Make Guava an external dependency, since a lot of people already use > Guava (leads to potential versioning issues) > > I'm -0.5 on this, because I don't really want to be tied to Guava versions. > Depending on it directly is kind of like making it part of the public API, > and I'd rather not do that. > > sam > > > Note option 4) would be moving more towards the model where everything is > built as simple Java projects and we only apply jarjar, etc. to get a > "nodeps" binary (to borrow the phrase from CGLIB) at the end. The downside of > this approach is that the unit tests would run against the un-jarjar'd > binaries, but there's no reason why we couldn't do an extra round of tests > against the final jarjar'd artifact. The other worry is that people might > take the interim jars which haven't been jarjar'd by mistake (but then again > there have been requests in the past from users to produce such artifacts, > see http://code.google.com/p/google-guice/issues/detail?id=289). > > Would like to hear people's thoughts on these options, since I don't think > there's an obvious "correct" choice* > > -- > Cheers, Stuart > > (* of course if everyone used OSGi then we wouldn't need to worry about > embedding and could just declare we needed the appropriate versions of > ASM/CGLIB/Guava ;) -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
