Bundled app launcher changes

Mike Swingler swingler at apple.com
Fri Feb 10 22:42:42 PST 2012

On Feb 10, 2012, at 10:05 PM, Igor Nekrestyanov wrote:

> On 2/10/12 9:29 PM, Mike Swingler wrote:
>> On Feb 10, 2012, at 8:48 PM, Igor Nekrestyanov wrote:
>>>> I agree that implementing deep copy sounds straightforward, at first. So do you specify copying from one origin root to another destination root? Do you want inclusion or exclusion rules? How do you specify app bundle relative paths? Will you want macro expansion? Do you want to specify one-off resources from inside or outside the project to be copied to arbitrarily paths in the target bundle? Does it matter which parts of the hierarchy exist first, or are copied in which order? And for each path in a hierarchy do you implicitly or explicitly exclude or include them from the classpath? Actually answering these questions takes time (writing them off the top of my head sure did), and implementing them takes even more time. 
>>> Well, i think it is easier than you may think.
>>> Ant has it. Just allow developers to use standard fileset and resourcesets to define bundle content.
>>> This is partially what i was trying to explain - proposed any task look like reinventing the wheel.
>>> It does solve new problem (producing the bundle) but it does not follow usual ant approach to produce other type of "bundles"
>>> (e.g. jar, zip, copy, etc.). IMHO, right way to implement it would be to extend and customize existing tasks.
>> What syntax do you propose to take a fileset (which could contain multiple files or directories with no common root in the filesystem), and copy them into the $JAVAROOT of the bundle?
> I had it in my sample code earlier in the thread. Something along the lines:
>     <resources>  <!-- default type are "app" resources -->
>         <!-- includes both jar and native libs -->
>         <!-- e.g. we could have SwingSet.jar, lib/one.jar, lib/two.jar, docs/README.html, lib/macosx/something-native.dylib -->
>         <fileset basedir="${dist.dir}" includes="**"/>
>     </resources>
>     <!-- optional additional resources -->
>     <resources>
>         <fileset basedir="${other.dir}" includes="**"/>
>     </resources>
> Where <resources> could be an extension of ant <copy> task. It only predefine destination directory to value derived from bundle root defined in the outer element 
> and MacOSX specifics (i.e. set it to bundleRoot/Contents/Resources)
> And then you can easily can add support for frameworks by supporting one more attribute:
>     <resources type="framework">
>         <fileset basedir="Sparkle.src" includes="**"/>
>     </resources>
This model does feel like more "native ant", but as Greg is implementing this, I'd leave it up to him if he felt that this could be quickly implementable by subclassing the built-in ant copy task classes.

>> If all elements of the fileset were to be copied to the $JAVAROOT flat (and performing a straight copy of directories), how would you specify which individual files or fileset groups should be included on the classpath?
> In fact, you do not need this.
> Java has support for classpath in the manifest. we should expect that whatever we bundle can start as 
>     "java -jar main.jar"
> I.e. expect executable jar file with classpath in the manifest.
> This is what any Java IDE or packaging tool (ant, maven, etc.) can produce easily.

I would like to hear others opinion about using the Manifest as the authoritative source for the classpath.

AFAIK, there isn't any code in the native launching stub today that will pick apart any of the jars to dig around and parse out the Manifest. Perhaps there is a way to make use of the JLI_* helper functions? This also raises another point - how do you specify which .jar is the "primary" out of a file set? Simply specifying the main class won't work - so then, should you be able to specify a (perhaps Mac-specific) main class, and still read the classpath information from the Manifest?

> If we preserve the directory structure then no changes to manifest are needed.
> And if application has flat directory structure we keep it flat. 
> We can keep it simple - if it worked before we "bundle" it then it will work as bundled. 
> IMHO, bundling tool should not restructure the application. It is just not its role to alter the application.
> But if developer choose to flatten his directory structure at the bundle time (e.g. by specifying existing "flatten" attribute on the resource task)
> then it is his choice and if his app rely on the classpath set then he need to use (existing) jar task to update the manifest in the man     jar.
> IMHO, specific of "bundle for mac" task is 
>    a) knowledge of typical bundle structure (Contents, MacOS, folders, location of icon, plist file)
>    b) native launcher to add
>    c) ability to embed runtime
> This is unique contribution and would be nice to make it simple yet flexible.
> Other parts are already supported and we better reuse it unless we have good reason to reinvent 
> (e.g. how to set classpath, how to copy files, etc.).

I'm not convinced that the Manifest is a good place to define the classpath, since it cannot be (easily) augmented per-platform, but perhaps others have more experience deploying apps like this, and would offer their opinion if this matters or not.

Mike Swingler
Apple Inc.

More information about the macosx-port-dev mailing list