David Darby <email@hidden> wrote:
>I am trying to implement the same functionality on Mac for an existing
>Windows (java) application that has two states -admin (default) and -client
>which are determined by the command line option following the application
>(eg MyApp) path. The client state is crippled in some ways.
Exactly how is that functionality represented on Windows? That is, how are
the two possible application states presented to the desktop-based Windows
user?
Are there two separate double-clickable icons? Two documents and an app?
Or is only one state double-clickable and the other only obtainable by
command-line? Or are they both command-lines only?
Exactly how do you want the two possible states presented to the
desktop-based Mac OS X user?
>There were minor compile errors only and I created the jar file (eg
>MyApp.jar) using ant and the windows compatible build.xml script. The
>client version worked just fine when invoked from a shell using "java
>MyApp.jar -client". I then needed to create a double clickable Mac-like
>bundle with the appropriate icon etc. This was easy using jarbundler
>additions to the xml.build script (jar bundler is cool). But, then I could
>not work out how to invoke the bundled application using the -client
>option. Hence, my posts to this august list.
Double-clicked apps on different platforms have different requirements and
expectations. In general, a Mac OS X bundled app is entirely
self-contained and self-starting. It does not require additional
command-line args.
Another way of saying this is that a Mac OS X double-clicked app gets no
command-line args, so it should default as appropriate. In your case, if
there are no args, the program should default to the same state as
"-client". You can do this with Info.plist, or in pure Java.
Referring to the 1.4 Info.plist properties:
<http://developer.apple.com/documentation/Java/Reference/Java14JavaDict/index.ht
ml>
I suggest using the Arguments key under the Java dictionary, with "-client"
as the Arguments value. This should have the effect of running your app in
client-mode when the app-bundle is double-clicked. I think that's the
simplest answer to at least part of what you want (client-mode launch).
In pure Java, you simply create a small class like the following, and then
use it as the Main-Class of the app-bundle:
public class ClientMain
{
private static String[] clientArgs = { "-client" };
public static void main( String[] args )
{ MyApp.main( clientArgs ); }
}
Since any Java class can have a main() method, this strategy makes it easy
to have different entry-points that result in different states or
behaviors. The different entry-points can even be classes you've added to
a third-party program, that make it do the things you want in the way you
want them.
Also, I frequently use system properties in lieu of command-line args,
because they are a little easier to manage in Info.plist, and easier to set
up defaults for in Java. In some cases, absence of an arg causes retrieval
of an equivalent property-name (e.g. "app.mode" in absence of -client or
-admin arg), with appropriate fallback. Or it can go the other way, with
an arg causing my code to set a property for other parts of the app to read.
I think of args as positional parameters, and properties as named
parameters, so circumstances and convenience determine how they all
interact.
>I tried to avoid using shell scripts and Terminal at all, by creating a
>small java application that would call the shell directly using
>Runtime.exec(). I planned to put this small application in the same
>directory as MyApp and let the client users make an alias of it anywhere on
>their network which could be double clicked to start it in client mode.
Why wouldn't the double-clicked app-bundle alone just do that? Why is
there a "small application" at all? It seems like an unnecessary
complication.
I still don't understand all of what you're trying to do, except that you
want to start a double-clicked app in "client" mode, and have some other
way to start the same app in "admin" mode. For example, do you want admin
mode to be double-clickable, or is that only supposed to be achievable by
other means (e.g. scripted)?
The goal you seek may not lie on the path you are following. It seems to
me like you're accreting excessive flexibility, which is adding complexity,
which prevents things from working at all, or only with a complex or
convoluted solution. I think you should concisely state your final goal,
without presuming a particular solution, rather than continuing to add
layer upon layer of hackage.
In particular, your initial post premised various shells and Java apps as
inter-related components of a solution:
>I'm trying to write a double clickable java application (Mac OS version
>only required) that will send a command to the shell to start a bundled
>java application using a command line option (in this case it's over a
>network to run in "client" rather than the default "admin" mode).
Don't describe the How, just describe the What of the final user experience.
>Unfortunately I failed to get this working. Runtime.exec() either did
>nothing or returned errors. Note that the release application name actually
>contains a space (which is an added complication, as in "My App"). I
>suspect the problems were due to incorrect syntax (eg escaping of spaces in
>my application's name in the path).
The problem was in how you invoked exec(). You didn't break down the
command-line into individual args. The exec() methods are not command-line
interpreters. The String[] versions in particular do no additional parsing.
>I then managed to get it running quite
>easily with an AppleScript application which is double clickable and solved
>my problem (though it has an AppleScript icon at present). I posted this
>code because it took me a while to work out how to get the currently active
>application's path in a useable format. Applescript is also cool.
When a shell-script is the CFBundleExecutable of an app-bundle, it is
launched with its own full pathname as "$0". From that, one can derive the
full pathname to the app-bundle itself. One way is the 'dirname' command,
however, it may not be installed. The other way is a shell-variable form:
selfDir="${0%/*}"
There may be an equivalent csh-style expression, I don't know. The above
is for Bourne-type shells.
To see more about how to use the above, see:
<http://www.amug.org/~glguerin/howto/More-open-files.html>
>public void run_client_app() {
>
>String scriptpath = "<path to
>MyApp>/MyApp/Contents/MacOS/JavaApplicationStub -client";
>
>String cmdarray[] = new String[]{"sh", scriptpath};
You either need to quote the args you pass to 'sh', or you need the
following form, with each distinct arg as a separate String. Either way,
you also need the ".app" suffix on the app-bundle name:
String cmdarray[] = {
"/path to app/My App.app/Contents/MacOS/JavaApplicationStub",
"-client" };
You can accomplish the same thing using:
a) an Info.plist with "Arguments" key of "-client".
b) a Java main() entry-point that needs no overt "-client" arg.
c) a Java main() taking mode in a property, + "Property" key in Info.plist
d) a CFBundleExecutable of a shell-script, which executes the 'java' command.
Any one of those is simpler than a Java program that runs 'sh' to run a
JavaApplicationStub that runs another Java program.
>This leads to the following print out in the console window:
>Picked up _JAVA_OPTIONS: -Xdebug -Xnoagent
>-Xrunjdwp:transport=dt_local,server=y,address=8007
>-[NSJavaVirtualMachine initWithClassPath:] cannot instantiate a Java
>virtual machine
>sh
>/Users/ddarby/Documents/Projects/DgD_CPP_Applns/Qt_Stuff/
>CogStateApplns/ConcussionSentinelClient/Sentinel/mac_dist/
>ConcussionSentinel.app/Contents/MacOS/JavaApplicationStub
>Process exit code: 126
The first arg to JavaApplicationStub should be a -psn arg, which is
normally supplied by LaunchServices (via Finder or via the 'open' command).
See my HowTo article on "More Open Files", and play around with the
contents of the prelude shell-script, to see exactly what an app-bundle is
launched with when double-clicked or when run via 'open'. The 'echo "$@"'
command may still be in the downloadable example.
Your error message makes me think you're somehow running a Cocoa-Java app,
but that's just a guess.
-- 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