0

Supposedly jjs is the Java 8 version of nashorn, ready for shell-scripting. However when I write a file with execute permission as:

#!/usr/bin/jjs
arguments.forEach(function(v,i,a){print(v);});

Running it produces some not so ideal shell-scripting behavior:

$./file.js
$./file.js one two
java.io.IOException: one is not a file
$./file.js -- one two
one
two
$./file.js file.js -- one two # what were they thinking
one
two
one
two
$

So, I don't ever want this script I'm writing to allow for the arbitrary interpretation of a file after it runs, maybe I should use -- in the shebang like:

#!/usr/bin/jjs --
arguments.forEach(function(v,i,a){print(v);});

But this gets less useful:

$./file.js
jjs>^D
$./file.js one two
jjs>^D
$./file.js -- one two
jjs>

Yes, being dropped into a REPL prompt is exactly what I thought should not happen.

How am I supposed to make it possible to execute a script with arguments that are passed directly and not interpreted by jjs itself such that I can get behavior like:

$./file.js one two
one
two
$
dlamblin
  • 43,965
  • 20
  • 101
  • 140
  • I can't find where they claim it can be used as shell script? The docs do mention a jrunscript though. – Rob Audenaerde May 08 '16 at 06:58
  • 1
    @RobAu I guess I didn't link the blog post I read that claimed it, and it may not be clear that `jjs` is an addition to `jrunscript` that has extensions when using the flag `-scripting` enabling `$ARG`, `$ENV`, heredocs, backticks, and some more scripting conveniences. – dlamblin May 08 '16 at 07:57

2 Answers2

2

The example works as expected in the JDK 9 version of Nashorn. I'll take care of backporting the required patches so they can appear in one of the upcoming 8u releases.

Update: the required changes are backported to the 8u stream, but it is not clear at what point there will be a release. The early access releases of JDK 9 available from https://jdk9.java.net/download/ have the shebang feature, and also other extensions, such as piping support for the $EXEC builtin.

haupz
  • 226
  • 2
  • 5
  • You will? That'd be great! Thank you. Feel free to update this post with any link to a bug tracking this or whatever the right way to go about requesting it would be. I take it you mean that in JDK 9 one of the two versions of `file.js` I showed behave as in the last "behavior like" block of my question. If so, is it the one with or without the `--` in the shebang? – dlamblin May 10 '16 at 21:18
  • Post is updated. The `--` does not need to be mentioned in the shebang line for your example to work. – haupz May 18 '16 at 05:49
1

While waiting for the changes to be backported, I wrote a script to overcome the problem. My jvm is installed in the folder /usr/lib/jvm/jdk1.8.0_101, so I created the following script:

/usr/lib/jvm/jdk1.8.0_101/bin/jjs/bin/jjs-cp.sh:

#!/bin/bash
CP=
if [[ $1 = "--lib="* ]]; then
    LIB_FOLDERS=${1:6}
    shift

    LIB_FOLDERS=$(echo $LIB_FOLDERS | tr ":" "\n")
    for FOLDER in $LIB_FOLDERS; do
        if [[ $FOLDER = "!"* ]]; then
            CP="$CP:${FOLDER:1}"
        else
            if [ -d $FOLDER ]; then
                JARS=$(find "$FOLDER" -type l -o -type f -name "*.jar")
                for JAR in $JARS; do
                    CP="$CP:$JAR"
                done
            fi
        fi
    done
    if [ -n $CP ]; then
        CP=${CP:1}
    fi
fi
SCRIPT_FILE="$1"
shift
if [ -n $CP ]; then
    /usr/lib/jvm/jdk1.8.0_101/bin/jjs -cp "$CP" $SCRIPT_FILE -- $@
else
    /usr/lib/jvm/jdk1.8.0_101/bin/jjs $SCRIPT_FILE -- $@
fi

Then, in my test.js script I can write:

#!/usr/lib/jvm/jdk1.8.0_101/bin/jjs-cp.sh --lib=!.:<full path to classpath folder 1>:<full path to classpath folder 2>
var console = {
    log: function(msg) {
        java.lang.System.out.println(msg);
    }
};

console.log('Hello, world!');
arguments.forEach(console.log);

var MyClass = Java.type('com.acme.MyClass'); // load a class from a jar in the classpath
console.log(MyClass.class); // prints "class com.acme.MyClass"

And I can execute my script with this command line:

~$ ./test.js one two
MscG
  • 366
  • 2
  • 15