Handle the Apple Event “open” within a bash shell script using osascript command

applescriptbashjavaplist

I use a bash script (myJavaBash.sh) within an Application Bundle (myJavaJar.app), that starts "java -jar myJarFile.jar" with additional JVM arguments (which works fine so far). My goal is to pass a file name as argument to the application, too, whenever the user opens a file via "open with … myJavaJar.app".

Edit: to clarify: I do not pass arguments to the bash script. I want the bash script to get filenames from wherever it can so it can pass the first of them to myJarFile.jar.

I tried to implement OpenFilesHandler in the java application and to copy an AppleScript-scpt-file into the bundle that calls myJavaBash.sh without success.

Last thing I tried just for the sake of testing every possibility was to call osascript within the bash

#!/bin/bash

#test: set command line args
MY_TITLE="Launching myJavaJarApp"
ARGS_MSG="command line args: "

osascript <<-EndOfScript
    set arguments to ""
      on open theFiles
            repeat with anItem in theFiles
               set arguments to arguments & space & (quoted form of POSIX path of anItem)
            end repeat
      end open
    display dialog "$ARGS_MSG" & arguments with title "$MY_TITLE"     
EndOfScript

Did not work out, the dialog just states $ARGS_MSG an no arguments, when I open a file with the myJavaJar.app.

Seems to me that setting the bash-script as CFBundleExecutable "consumes" all AppleEvents.

Or is there a way?

Edit:
This is the complete bash script. I got the first version from Sri Harsha Chilakapati's YouTube video "Bundling Java JAR files into Mac Applications" and edited it so it finds out the installed Java versions and chooses the most fitting. It also starts the JVM with additional parameters if Java version is > 1.8 to bind JAXB classes.

#!/bin/bash

# Constants
JAVA_MAJOR=1
# treat Java 1.8 other than Java 9
JAVA_MINOR=8
JAVA_MINOR_A=9
# Java higher than 10.x doesn't have java.xml.bind any more
JAVA_MAJOR_MAX=10
java_supported_versions=(1.8 9 10)
LIB_EXEC="/usr/libexec/java_home -v"
APP_JAR="myJarFile.jar"
APP_NAME="Setrok's Java Application"
APP_ICNS="myIcons.icns"
# different arguments for Java 1.8 than 1.9
VM_ARGS=""
VM_ARGS_A="--add-modules=java.xml.bind"

# Set the working directory
DIR=$(cd "$(dirname "$0")"; pwd)

#test: set command line args
MY_ARGS="$1"
ARGS_MSG="command line: $MY_ARGS"

osascript <<-EndOfScript
      set arguments to ""
      on open theFiles
             repeat with anItem in theFiles
               set arguments to arguments & space & (quoted form of POSIX path of anItem)   
             end repeat
      end open 
      display dialog "$ARGS_MSG" & arguments & "$MY_ARGS" with title "$ERROR_TITLE"
EndOfScript
#end test

# Error message for NO JAVA dialog
ERROR_TITLE="Cannot launch $APP_NAME"
ERROR_MSG="$APP_NAME requires Java version $JAVA_MAJOR.$JAVA_MINOR up to $JAVA_MAJOR_MAX to run."
DOWNLOAD_URL="https://www.oracle.com/java/technologies/javase-jre8-downloads.html"

# Is Java installed?
if type -p java; then
    _java="java"
elif [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then
    _java="$JAVA_HOME/bin/java"
else
    osascript \
    -e "set question to display dialog \"$ERROR_MSG\" with title \"$ERROR_TITLE\" buttons {\"Cancel\", \"Download\"} default button 2" \
    -e "if button returned of question is equal to \"Download\" then open location \"$DOWNLOAD_URL\""
    echo "$ERROR_TITLE"
    echo "$ERROR_MSG"
    exit 1
fi

# Java version check
if [[ "$_java" ]]; then
    version=$("$_java" -version 2>&1 | awk -F '"' '/version/ {print $2}')

    # Is version too high or too low?
    # Are there other (supported) java versions installed?
    if [[ "$version" < "$JAVA_MAJOR.$JAVA_MINOR" ]] ||  [[ "$version" > "$JAVA_MAJOR_MAX" ]]; then
        for i in "${java_supported_versions[@]}";
        do
            java_other=$($LIB_EXEC "$i")
            _java="$java_other/bin/java"
            version=$("$_java" -version 2>&1 | awk -F '"' '/version/ {print $2}')
            if [[ "$version" < "$JAVA_MAJOR.$JAVA_MINOR" ]] ||  [[ "$version" > "$JAVA_MAJOR_MAX" ]]; then
                echo "Java Version does not match: $i"
            else
                break
            fi
        done
    fi

    ur_version="Your Java version is $version!"
    # Is version still too high or too low?
    if [[ "$version" < "$JAVA_MAJOR.$JAVA_MINOR" ]] ||  [[ "$version" > "$JAVA_MAJOR_MAX" ]]; then
        osascript \
        -e "set question to display dialog \"$ERROR_MSG $ur_version\" with title \"$ERROR_TITLE\" buttons {\"Cancel\", \"Download\"} default button 2" \
        -e "if button returned of question is equal to \"Download\" then open location \"$DOWNLOAD_URL\""
        echo "$ERROR_TITLE"
        echo "$ERROR_MSG"
        echo "$ur_version"
        exit 1
    fi
fi

# Run the application  -cp ".;$DIR;" -cp ".;$DIR;"
if [[ "$version" < "$JAVA_MAJOR.$JAVA_MINOR_A" ]]; then
    exec $_java $VM_ARGS -Dapple.laf.useScreenMenuBar=true -Dcom.apple.macos.use-file-dialog-packages=true -Xdock:name="$APP_NAME" -Xdock:icon="$DIR/../Resources/$APP_ICNS" -jar "$DIR/$APP_JAR"
else
    exec $_java $VM_ARGS_A -Dapple.laf.useScreenMenuBar=true -Dcom.apple.macos.use-file-dialog-packages=true -Xdock:name="$APP_NAME" -Xdock:icon="$DIR/../Resources/$APP_ICNS" -jar "$DIR/$APP_JAR"
fi

Edit: I forgot to give the Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>German</string>
    <key>CFBundleDisplayName</key>
    <string>Setrok's Java Application</string>
    <key>CFBundleIdentifier</key>
    <string>eu.gronos.myJavaJar</string>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>skktx</string>
            </array>
            <key>CFBundleTypeIconFile</key>
            <string>myIcons.icns</string>
            <key>CFBundleTypeName</key>
            <string>myJavaJar calculation</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSHandlerRank</key>
            <string>Owner</string> 
        </dict>
    </array>
    <key>CFBundleExecutable</key>
    <string>myJavaBash.sh</string>
    <key>CFBundleIconFile</key>
    <string>myIcons.icns</string>
    <key>CFBundleGetInfoString</key>
    <string>Setrok's Java Application (C) 2014-2020 (GPL)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>0.6.0</string>
    <key>CFBundleSignature</key>
    <string>xmmd</string>
    <key>CFBundleVersion</key>
    <string>0.6.0</string>
    <key>NSAppleScriptEnabled</key>
    <string>YES</string>
    <key>NSHumanReadableCopyright</key>
    <string>Setrok's Java Application (C) 2014-2020 (GPL)</string>
</dict>
</plist>

Best Answer

Arguments for a stand-alone osascript are passed as a list of strings to the AppleScript run handler, for example on run argv - see the osascript man page. If you are using osascript inside another script, you can just use the arguments you already have - expanding variables in a heredoc, for example.

The following example will use arguments from the command line, or if none, from an array defined in the shell script. The arguments are separated by a newline, which is used by the AppleScript to get the list:

#!/bin/bash

dialog_title="Command Line Argument Test"
dialog_header="Arguments:"

args=(
   argument1
   argument2
   "argument with spaces"
   argumentN
)

osascript <<-SCRIPT
   if "$@" is "" then -- use args array
      set arg_list to "$(printf '%s\n' "${args[@]}")"
   else -- use cli arguments
      set arg_list to "$(printf '%s\n' "$@")"
   end if
   set arguments to ""
      repeat with anArg in paragraphs of arg_list
         set arguments to arguments & return & tab & anArg
      end repeat
   display dialog "$dialog_header" & arguments with title "$dialog_title"
SCRIPT