JEP 330
Jonathan Gibbons
jonathan.gibbons at oracle.com
Tue Jun 5 14:54:11 UTC 2018
On 6/5/18 1:11 AM, Peter Levart wrote:
> Hi,
>
> On 06/03/2018 09:45 PM, Jonathan Gibbons wrote:
>>> As an idealist, I might want Class.getResourceAsStream to return
>>> the contents of a side file to the script file. But it's more
>>> likely to
>>> return null, given the strategy of compiling the script into a
>>> temporary
>>> artifact in an undisclosed location.
>> Class.getResourceAsStream will find items on the classpath used by
>> the VM.
>
> ...this will find the "content" of items on the classpath. If one
> wants to find the "location" (i.e. URL) Class.getResource() will
> return it.
>
> But in the context of java launcher executing a "source" file,
> searching for location of the executing class would return some URL
> pointing to "memory" where the source was compiled to, wouldn't it?
> Not something that could be used to locate "side" files - files in the
> same directory as source/script file.
I was intending to imply that because Class.getResource[AsStream] will
find items on the classpath used by the VM, if you set -classpath
appropriately you will be able to locate side files that way. I agree
that you will not be able to locate side files relative to the location
of the compiled classes.
>
> I know that the main purpose of this JEP is to provide a stepping
> stone for beginners in the Java world. But the experienced will always
> find it also as a means to write executable scripts in Java. For the
> later it is important that the feature allows writing scripts that are
> as portable as possible. I see one obstacle to achieve that. The
> location of java launcher executable is not standardized across
> platforms (even UNIX platforms). So hard-coding absolute path in the
> shebang script is bound to create non portable script. Locating the
> java launcher using PATH would be much more portable. Java, if
> installed properly, is usually added to PATH. The standard way to
> locate script interpreters using PATH is by indirection through
> /bin/env utility:
>
> #!/bin/env java
>
> public class Cmd {
> public static void main(String ...args) {
> ...
> }
> }
>
>
> While this works and passes script arguments to java executable as
> intended, it does not work when combined with additional options
> passed to script interpreter (like "--source 11") in the script itself:
>
> #!/bin/env java --source 11
>
> public class Cmd {
> public static void main(String ...args) {
> ...
> }
> }
>
>
> At least on Linux, env tries to locate executable called "java
> --source 11" on the PATH and bails out with:
>
> /bin/env: ‘java --source 11’: No such file or directory
Yes, that is a property of the Linux support for shebang files.
>
>
> So the best bet here is a hybrid script that starts as a bash script
> which "computes" the environment and paths and then executes java
> launcher with all required arguments. One way to do that is using
> "here" documents. Stuart Marks provided an example:
>
> #!/bin/bash
> exec java --source 11 /dev/fd/3 "$@" 3<<EOF
> public class Hello {
> public static void main(String[] args) {
> String name = System.console().readLine("Please enter your
> name: ");
> System.console().printf("Hello, %s!%n", name);
> }
> }
> EOF
>
> This script uses an OS feature where special file /dev/fd/N when
> opened, provides a file handle dup-ed from the file handle N. I don't
> know how portable this is across UNIX-es. Linux and Mac at least do
> have it and use same paths. What about other UNIX-like OS-es where
> OpenJDK is built? If for some OS the feature is not available, then
> java launcher could help here by interpreting a special syntax of file
> specified as "/dev/fd/N" and executing the necessary dup itself on
> such OS.
>
>
> What do you think?
I agree that for maximum flexibility and portability, using "here"
documents such as you describe is a good way to go, and this is now
listed as one of the "Alternatives" in the JEP. However, while it is
reasonable to disable the filename check in situations like this, to
_allow_ the use of /dev/fd/N where it is available, IMO it would be a
step too far to have the Java launcher conditionally _implement_ support
for "/dev/fd/N" on platforms that did not otherwise provide it.
-- Jon
>
> Regards, Peter
>
More information about the compiler-dev
mailing list