How to drain your laptop battery using Jigsaw

Jesse Glick jesse.glick at oracle.com
Wed Dec 21 14:23:44 PST 2011


My colleague Yarda Tulach had investigated module systems supporting version ranges, and wrote up a formal proof [1] that picking one version of each of several modules 
in a repository such that all dependencies are satisfied is in general NP-complete. I decided to verify that Jigsaw suffers from this problem.

The attached program, run against a recent Jigsaw build (8c6429c279e7), starts consuming many seconds of CPU time per round (effectively hanging) somewhere around 9 
variables (depending on the random seed), mostly running in Resolver.resolve according to a profiler. The randomized nature of the test and the clause count is designed 
to stress the system, of course.

Possible resolutions to this problem include:

1. Drop the requirement that module dependencies may include version ranges or otherwise permit incompatible changes to be marked, so that a dependency is always on some 
version or later. This seems unsatisfactory.

2. Drop the requirement that the module system pick a version of each module to load such that all dependencies are satisfied. For example: just try to load the newest 
available version of each module, and if any dependencies are in fact unsatisfied, report an error and ask the user to override one or more module versions manually.

3. Rewrite Resolver using something like SAT4J, or even leave it as it is, and just document that pathological cases can result in unbounded execution time.

4. Require that a new release of any module which uses an incompatible version of some dependency (even if used only internally) is itself marked incompatible. This seems 
unsatisfactory since it breaks encapsulation - I should not be forced to label my new widely used graphics toolkit 2.0 rather than 1.1 merely because I started to use a 
refactored version of some math library after 1.0 was released. Also it is unclear how you would enforce this constraint so long as Jigsaw assigns no semantics to version 
numbers except that they are totally ordered.

5. Permit multiple versions of a module to be loaded so long as class spaces remain consistent - resolving such configurations when needed - and only require that a new 
release of a module whose public signature refers to an incompatible version of some dependency is itself marked incompatible. (Whether 'requires public' is used does not 
matter.) More palatable than #4 but still forces a cascade of incompatibility, even when the incompatible change in the dependency is unrelated to this module's usage of 
it. Like #4, enforcement would require stronger version semantics.

Yarda please step in if I misrepresented any of these options.


[1] http://wiki.apidesign.org/wiki/LibraryReExportIsNPComplete


More information about the jigsaw-dev mailing list