Bundled app launcher changes

Scott Palmer swpalmer at gmail.com
Fri Feb 10 19:33:24 PST 2012

On Fri, Feb 10, 2012 at 9:56 PM, Mike Swingler <swingler at apple.com> wrote:

> On Feb 10, 2012, at 6:16 PM, Scott Palmer wrote:
> > Why re-invent?  The standard Java mechanism is to provide the class path
> in the main jar's manifest.  Existing Ant tasks will already handle that.
> Why is anything more than pointing to the main jar needed?  The manifest in
> the main jar can be used to figure out what resources to bundle and the
> relative locations they need to be placed in.  While raw .class files in
> folders could be referenced, it is highly unusual for an application to be
> distributed that way.
> This means you'd have to intertwine process of creating a Manifest with
> the end deployment filesystem structure. This seems rational, however it
> does make adding/removing other classpath entries harder without
> reopening/repacking the main jar.
> Is this actually a common deployment practice? I'm no fan of duplicating
> classpath information, but I think there are often situations where you
> bring in different libraries based on the deployment platform (things like
> Quaqua come to mind).

I think it is common.  Ant and Maven are the most common means to build a
Java project (NetBeans being Ant-based by default and both NetBeans and
Eclipse have good support for working with Maven projects).  Both tools
have a means for manipulating the classpath in the jar's manifest.  If I
wanted to produce a build for the Mac that had a few extra jars I would
automate it in the Ant or Maven (or Gradle) code.   For something like
Quaqua there would be no harm in including it on other platforms anyway.
It would just take up space.  That wouldn't be significantly different from
the unused code in a "universal binary"

These days we try to have our builds entirely automated by our continuous
integration server (Hudson/Jenkins).  So the idea of opening up a bundle
and tweaking a couple jars and classpath entries manually would beoutof the
question.  When we want a new release that incorporates a new version of
some 3rd-party library we would update the information in the dependency
declaraions (pom.xml, ivy.xml, or build.gradle) and then press the
"Release" button on the CI server.

As far as "[intertwining the] process of creating a Manifest with the end
deployment filesystem structure" - presumably the standard layout of
dist/my_app.jar  and dist/lib/some_library.jar (or whatever relative paths
are in the manifest classpath of the main jar) would be equivalent to
$JAVAROOT/my_app.jar  $JAVAROOT/lib/some_library.jar, where as you wrote
$JAVAROOT would be (app)/Contents/Java.  The classpath info would
presumably get transformed into the Info.plist correctly by the app bundler
- if such a transformation is necessary. I was thinking that relative paths
in the manifest classpath would be relative to $JAVAROOT such that nothing
special needs to be done at all for it to "just work" by copying the main
jar to that location in the bundle as well as all of the jars mentioned in
the main jar's manifest classpath - preserving the relative folder
structure under $JAVAROOT.


Scott P.

More information about the macosx-port-dev mailing list