Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass compiler options when running a single-file source-code Java program?

I'd like to use JEP 330 to run a single-file source-code program with Java (>= 11).

Doing so, I'd like to pass options understood by the compiler (javac) but not the runtime (java), e.g. -XDsuppressNotes. This causes e.g. the following invocation to fail:

java --enable-preview --source=12 -XDsuppressNotes Test.java

Unrecognized option: -XDsuppressNotes
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

How can I specify such compiler-specific option in this case?

like image 390
Gunnar Avatar asked Dec 15 '18 21:12

Gunnar


1 Answers

How can I specify such compiler-specific option in this case?

Short answer: you can't.

The goal of this JEP is not to replace javac! It is merely to make it more convenient, especially in the context of beginning programming to achieve the goal of "run this program".


JEP-330 has a set of limitations in comparison to standard javac -> java chain. Quotes from the JEP itself:

As of JDK 10, the java launcher operates in three modes: launching a class file, launching the main class of a JAR file, or launching the main class of a module. Here we add a new, fourth mode: launching a class declared in a source file.

...

In source-file mode, the effect is as if the source file is compiled into memory, and the first class found in the source file is executed. For example, if a file called HelloWorld.java contains a class called hello.World, then the command

java HelloWorld.java

is informally equivalent to

javac -d <memory> HelloWorld.java

java -cp <memory> hello.World

Any arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed. For example, if a file called Factorial.java contains a class called Factorial to calculate the factorials of its arguments, then the command

java Factorial.java 3 4 5

is informally equivalent to

javac -d <memory> Factorial.java

java -cp <memory> Factorial 3 4 5

In source-file mode, any additional command-line options are processed as follows:

  • The launcher scans the options specified before the source file for any that are relevant in order to compile the source file. This includes: --class-path, --module-path, --add-exports, --add-modules, --limit-modules, --patch-module, --upgrade-module-path, and any variant forms of those options. It also includes the new --enable-preview option, described in JEP 12.

  • No provision is made to pass any additional options to the compiler, such as -processor or -Werror.

...


In other words, there are certain limitations the one should keep in mind while running single-file source-code Java programs:

  • No outside classes, Single-File Programs only - you may not invoke any other classes in files other than the file you are executing.

  • No class files available - the invocation of the java tool in this manner does not produce any *.class files you can see in your working directory.

  • If existing class file exists in classpath, you’re forced to use it - For a file, say SampleClass.java, should an existing class file, say, SampleClass.class exist, you may not invoke the java tool to run your source file in source-file mode.

  • File name, not class name - the java tool considers the name of the file and NOT the name of the class in executing source files.

  • First class in the file, not matching file-class names - the class loader no longer determines the class to be executed by matching file name and class name. The first class in the file is the one that will be run,

  • No limits on public files in a source file - While javac cares about the amount of public classes in a source file, java couldn’t care less.

  • You may not pass certain compiler specific arguments - the arguments like -Werror or -nowarn that you can pass to javac, may not be passed (or recognized for that matter) by the java tool.

like image 181
Mikhail Kholodkov Avatar answered Sep 25 '22 05:09

Mikhail Kholodkov