I need to produce a jar file that contains some files rooted in multiple directories, and all of the contents of some set of other jar files in the project (no, they're not dependencies, sadly). In other words, the rough equivalent of the assembly plugin in maven.
I've been fiddling around with hooking leiningen.jar/filespecs and uberjar/write-components, with limited success.
On Mon, Oct 10, 2011 at 10:15 AM, Chas Emerick <cemer...@snowtide.com> wrote: > I need to produce a jar file that contains some files rooted in multiple directories, and all of the contents of some set of other jar files in the project (no, they're not dependencies, sadly). In other words, the rough equivalent of the assembly plugin in maven.
> Is there an obvious alternative that I'm missing?
No, right now all we've got is the single :resources-path config value. Are these things that need to be both on the classpath and in the jar, or just the latter?
On Oct 10, 1:24 pm, Phil Hagelberg <p...@hagelb.org> wrote:
> On Mon, Oct 10, 2011 at 10:15 AM, Chas Emerick <cemer...@snowtide.com> wrote:
> > I need to produce a jar file that contains some files rooted in multiple directories, and all of the contents of some set of other jar files in the project (no, they're not dependencies, sadly). In other words, the rough equivalent of the assembly plugin in maven.
> > Is there an obvious alternative that I'm missing?
> No, right now all we've got is the single :resources-path config
> value. Are these things that need to be both on the classpath and in
> the jar, or just the latter?
> -Phil
In this case, both. The REPL case is handled by :extra-classpath-dirs
(seems to work for jars in there as well as directory paths), but
that's less important to me at this point.
It's honestly a stupid scenario that I wouldn't expect project.clj to
support directly, but I did expect an API to be available for such
things (e.g. "make a jar out of this, that, and the other thing").
The copy-to-jar multimethod is going in the right direction. I'm
surprised that uberjar didn't build on top of that, actually.
> On Oct 10, 1:24 pm, Phil Hagelberg <p...@hagelb.org> wrote: >> On Mon, Oct 10, 2011 at 10:15 AM, Chas Emerick <cemer...@snowtide.com> wrote: >>> I need to produce a jar file that contains some files rooted in multiple directories, and all of the contents of some set of other jar files in the project (no, they're not dependencies, sadly). In other words, the rough equivalent of the assembly plugin in maven.
>>> Is there an obvious alternative that I'm missing?
>> No, right now all we've got is the single :resources-path config >> value. Are these things that need to be both on the classpath and in >> the jar, or just the latter?
>> -Phil
> In this case, both. The REPL case is handled by :extra-classpath-dirs > (seems to work for jars in there as well as directory paths), but > that's less important to me at this point.
> It's honestly a stupid scenario that I wouldn't expect project.clj to > support directly, but I did expect an API to be available for such > things (e.g. "make a jar out of this, that, and the other thing"). > The copy-to-jar multimethod is going in the right direction. I'm > surprised that uberjar didn't build on top of that, actually.
I've patched together a solution, though it's fugly. Take this as an experience report, or something. :-)
First, a :jar implementation of copy-to-jar for the curious:
The :when clause is unfortunate, but lein.jar doesn't have the same notion of duplicate entry skipping that lein.uberjar does.
Add the above with a hook on lein.jar/filespecs to inject the necessary :path and :jar entries, and I'm good…*except* when I run `clean` prior to `jar`. If I run `lein clean, jar`, the jar fn gets run twice — one with my hook, one without my hook, and I end up getting a duplicate jar entry exception. Leave off the `clean`, and all's well. I don't have a theory about why that is at the moment.
In general, it seems like lein.jar, lein.uberjar, and e.g. lein.ring.war all have bits and pieces of what would be a properly comprehensive zip/jar API, but none of them have them all in one spot (e.g. lein.jar is the only one that is openly extensible and attempts to get away from procedurally building archives, only uberjar does duplicate entry skipping, and ring.war is the only one that allows for re-rooting of content from 'filespecs').
I wonder if I'm the only one that has this impression, or if others are simply making do with other methods.
> In general, it seems like lein.jar, lein.uberjar, and e.g. lein.ring.war > all have bits and pieces of what would be a properly comprehensive zip/jar > API, but none of them have them all in one spot (e.g. lein.jar is the only > one that is openly extensible and attempts to get away from procedurally > building archives, only uberjar does duplicate entry skipping, and ring.war > is the only one that allows for re-rooting of content from 'filespecs').
> I wonder if I'm the only one that has this impression, or if others are > simply making do with other methods.
You're not the only one, I've had similar problems recently, and had to resort to ugly workarounds. It would be very nice if the code/APIs could be cleaned up and made more extensible.
On Mon, Oct 10, 2011 at 7:55 PM, Chas Emerick <cemer...@snowtide.com> wrote: > In general, it seems like lein.jar, lein.uberjar, and e.g. lein.ring.war all have bits and pieces of what would be a properly comprehensive zip/jar API, but none of them have them all in one spot (e.g. lein.jar is the only one that is openly extensible and attempts to get away from procedurally building archives, only uberjar does duplicate entry skipping, and ring.war is the only one that allows for re-rooting of content from 'filespecs').
This is exactly the kind of thing I hope to address in 2.0 when we have a chance to really break APIs, so I'm glad you brought it up. I'll make sure these issues are addressed.
On Oct 13, 2011, at 2:28 AM, Phil Hagelberg wrote:
> On Mon, Oct 10, 2011 at 7:55 PM, Chas Emerick <cemer...@snowtide.com> wrote: >> In general, it seems like lein.jar, lein.uberjar, and e.g. lein.ring.war all have bits and pieces of what would be a properly comprehensive zip/jar API, but none of them have them all in one spot (e.g. lein.jar is the only one that is openly extensible and attempts to get away from procedurally building archives, only uberjar does duplicate entry skipping, and ring.war is the only one that allows for re-rooting of content from 'filespecs').
> This is exactly the kind of thing I hope to address in 2.0 when we > have a chance to really break APIs, so I'm glad you brought it up. > I'll make sure these issues are addressed.
Good to know. :-)
If anyone's curious, they can look at what I ended up with: