Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Best folder structure for application + services



David Watson wrote:

I'm starting the process of packaging a Java-based application for MacOS, and I'm wondering what the "preferred" way of organizing jars, resources, etc. would be if you have more than just a standalone application bundle. In my case, the application includes some network services that run out of the same jars as the application itself.

It depends.

Different audiences might be better served with an arrangement suited to their needs and experience level. So it depends on your audience.

If your app depends on (i.e. requires) the network services, then bundling into a single integrated whole might be best. If your app doesn't depend on the services, i.e. it can run without the services active, then splitting them up might be best. If some users might use your app but not the services, or if the services and the app are aimed at different audiences, then completely separate structures (e.g. 2 or more distinct apps or launchables) might be best.

If your services can be run completely separate from your app, then you should make them completely separable. That is, if there's a reason why a user might run your services but never run your app, then that should be possible to do. If the services and app are separable, then the user should even be able to remove the app (MyApp.app) entirely, but still keep the services.

If the services can run per-user (i.e. as launch-agents instead of launch-daemons), you might consider a completely different placement for the services.

So briefly, it depends on your audience, on the relationship betwee your app and services, and the usage patterns of your audience for the app and services.


My options would seem to be:

1) Install everything into /Applications/MyApp. Thus I'd have / Applications/MyApp/MyApp.app, /Applications/MyApp/lib/ wholebunchofjars.jar, etc. The service configurations would go in / Library/LaunchDaemons. Upside: if the user moves the .app folder, things will still run, since the app and services will know to look in /Applications/MyApp/lib.

Exploit the structure of app-bundles.

First, /Applications/MyApp/MyApp.app would force users to have a hierarchical menu for your app. They might not want that.

Second, /Applications/MyApp/lib/wholebunchofjars.jar is gonna confuse all the users who have no idea that the lib folder next to MyApp.app is required to be there. And all the users who do know what it's for are gonna think it's sloppy or uninformed to slap that folder there when it could be perfectly well located inside the app-bundle. That's why an app-bundle is a self-contained directory tree: so it can be moved without leaving half its internal organs behind.

Third, if a user moves /Applications/MyApp/MyApp.app elsewhere, it's unlikely they will leave /Applications/MyApp/lib in place. The most logical reason for moving an app is to get it entirely out of its original location, so deleting /Applications/MyApp/lib is the most likely second step after moving the app. That will cause grave disorder in your launch daemon plists. Either embed the lib inside the app-bundle, or put it in a more stable location that users are unlikely to clean out.

Fourth, users might not want to put the app in /Applications. For example, there might be restrictions on that folder in a shared environment, or company policies against it, or just personal policy (like me). I never intentionally add apps to /Applications, and it really irks me when some app can ONLY be installed there.


2) Include everything except the launchd plist files in / Applications/ MyApp.app. This looks neater, but if the user moves the app bundle, the services will no longer run.

Agreed. This would be very bad. Don't do it.


3) Create a framework in /Library/Frameworks/MyApp.framework, and put all the libraries in there. Services and app will all look for their jars in the framework directory, and I can even version things if I want.

You can version things anywhere you put them, not just in /Library/ Frameworks/. There's no magic versioning you get by placing things in /Library/Frameworks/.


Also, you can't version things arbitrarily anyway if your services are running as a launch daemon. You have to stop the job, terminate the daemon, change the jar (versioned or not), then start the job again. Because it's a launch daemon, all that has to be done as root.

You also have to secure all the resources (jars, executables, etc) used by the launch daemon, so they can't be altered by anyone except root. I don't know what your experience in this area is, but it's not as simple as it might seem. If it's not necessary to run your services as root, then you should use an unprivileged launch agent instead.


With no other information about your app or services, I think Doug Zwick's suggestion is the best: use /Library/Application Support/ MyApp/. If you're running your services as root, you will still need to lock down all the resources used by the privileged launch daemon, including the path of parent dirs used to reach the resources. This is one reason why it's usually best to make daemons as self-contained as possible, even if it means replicating files for their exclusive use. Also remember that Unix has hard-links, and sometimes a hard- link isn't a security risk (NB. hard-link != symlink in this regard).


  -- GG

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden


Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.