JEP 330 describes a new feature in JDK 11 for launching single-file programs in Java. I've tried:
$ ./Example.java
but it doesn't work. What is the correct usage?
Short-version:
$ java Example.java data.txt
or (with #!):
$ ./example data.txt
Details:
Working example here.
Consider a single-file program to print the lines in a file:
import java.nio.file.*;
import java.util.stream.Stream;
public class ExampleJDK11 {
public static void main(String[] args) throws Exception {
// snip ... print file args[0]
}
}
Usage 1:
Assuming the code is in Example.java and that java is on the PATH, then usage is:
java Example.java data.txt
Note that there is no javac step (!)
Note that the filename need not match the classname.
Usage 2:
Assume the code is in a file, example, with a "shebang" line at the top:
#!/Users/measter/tools/jdk-11.jdk/Contents/Home/bin/java --source 8
import java.nio.file.*;
import java.util.stream.Stream;
// as above
Usage is:
./example data.txt
Though the answer by you includes correct information. Just trying to put this into simpler terms, a file can simply be executed using java from JDK11 onwards, for example on MacOS
.../jdk-11.jdk/Contents/Home/bin/java Sample.java
This would seek and execute the standard public static void main(String[] args) method. As one can notice(even beginners) that this method accepts args of type String, hence the arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed. Therefore the following command
.../jdk-11.jdk/Contents/Home/bin/java <file-name>.java arg1 arg2
would provide the string arguments arg1, arg2 during the execution phase.
Side note - If the file includes multiple classes with standard main methods, the first top-level class found in the source file which shall contain the declaration of the standard public static void main(String[]) method is executed.
Related
I wrote a Java program whose filename was (intentionally) different from the class I wrote inside the file. The javac command failed as expected on both CMD and WSL. The java command however worked and ran my print statement. I wrote the code intentionally this way so there is no way it was a previously compiled version of the code. The following code was written in a file called "explainJava.java" (notice the filename is different from the class name).
public class explain{
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
I've had to google this myself, but I think I've found an explanation in this article.
According to that source as of Java 11 java is capable of compiling a single source file into memory.
What I conclude from that: When the file is compiled into memory and not written to disk it obviously cannot have a file name. If there is no filename there is no such thing as a wrong filename, therefore the code executes.
Please also note that the restriction of having to name a file like the public class within that file is more of a design decision to make work for the compiler easier/ faster. It is not a physical restriction so to speak. Have a look at the following thread for more details.
If you put this code:
public class explain {
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
into a file named explainJava.java, and then compile it with this:
javac explainJava.java
you will get an error that correctly informs you that your filename ("explainJava") and the class defined inside that file ("explain") do not match:
explainJava.java:1: error: class explain is public, should be declared in a file named explain.java
public class explain{
^
1 error
If you run this command:
$ java explainJava.java
Java is weird
you see expected output, because you're skipping the explicit compilation step (that is, you aren't running javac first) and instead relying on behavior introduced in Java 11 that allows you to compile+run in a single step. Here's an explanation: Does the 'java' command compile Java programs?
So the answer is to either:
rename your file to match the class, so change the filename to "explain.java", or
rename the class to match the file, change public class explain to be public class explainJava
I'm a relative Java newbie so apologies if the question appears somewhat basic. I've googled high and low for an answer here and I'm not finding anything that's helping.
Problem:
Whilst I'm able to integrate external packages into my Java programs from an IDE environment, I am trying to do run a very basic program from the command line that calls on a separate, basic package file that I have written - and am simply doing all this as I want to have a bottom-up understanding of how package files are related to a main program by Java.
I have a program that sits on my desktop named MyProgram.java:
import org.somepackage;
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
Still on the Desktop, I then have another folder which I've named src, inside of which I have created the necessary subfolders corresponding to the package name, i.e. ./src/org/somepackage - and in this location, I have the Human.java file which defines the Human class with the following contents:
package org.somepackage;
public class Human {
public void scream() {
System.out.println("I exist!!");
}
}
I then created a classes folder, again on the Desktop, and ran the following compile command on the command line:
javac -d ./classes/ ./src/org/packagename/Human.java
This ran fine and created - as expected - the Human.class file within the ./classes/org/packagename/ location.
However, where I fall down is when I then try to compile MyProgram.java on the command line, i.e.
javac -cp ".:./classes/" MyProgram.java
As you'll see, my class path contains a reference to the current location (".") for the MyProgram.java file, and it contains a reference to the classes folder ("./classes/") which is the base location for the org.somepackage package inside whose subfolders (./classes/org/somepackage/) on can find the Human.class file.
At this stage, I was simply expecting the java engine to compile MyProgram.java into the program MyProgram.class - but, instead, I get an error:
MyProgram.java:1: error: package org does not exist
I've been following the instructions listed here:
https://www3.ntu.edu.sg/home/ehchua/programming/java/J9c_PackageClasspath.html
and I don't appear to be deviating from the instructions - yet I'm unable to locate an explanation on Stackoverflow or anywhere else as to a possible reason for this compile failure. If anyone has an idea, your help would be very much appreciated.
Thanks,
Your mistake is here
import org.somepackage; <--
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
you forgot to import class actually, you need to write this name
import org.somepackage.Human; import all package content import org.somepackage.*; or write full qualified name of class in your code
org.somepackage.Human myHuman = new org.somepackage.Human();
myHuman.scream();
correct mistake:
import org.somepackage.Human;
public class MyProgram {
public static void main(String arguments[]) {
System.out.println("Programme up and running...");
Human myHuman = new Human();
myHuman.scream();
}
after that compile your Human.java by this command:
javac -d classes Human.java
and MyProgram.java
javac -d classes -cp "classes" MyProgram.java
and run MyProgram by
java -cp "classes" MyProgram
Relevant Links:
Java: Passing combination of named and unnamed parameters to executable Jar/Main Method
Passing arguments to JAR which is required by Java Interpreter
I understand how to pass strings from the command line to execute my main method:
java -jar myApp.jar "argument1"
My question is: is it possible to set up my main method in a way that would accept:
java -jar myApp.jar -parameter1 "argument1"
Here is my simple main method for context if you need it
public class myApp {
public static void main (String[] args){
System.out.println("Argument1: "+args[0]);
}
}
Thing is: whatever you pass on the command line goes into that args array. To be precise:
java xxx -jar JAR yyy
xxx: would be arguments to the JVM itself, like -Dprop:value for properties
yyy: are passed as arguments to your main method
So, when you pass "-parameter 'argument1'" then ... that is what you will see inside main!
In other words: the idea that some command line strings are "arguments"; and other are "-switches", or "--flags", or "-h" shortcuts ... you simply have to write the code to do all of that.
Luckily, there are plenty of libraries out there that help with that; see enter link description here
my first java program is
import java.io.*;
class pgm10a
{
public static void main(String args[])
{
pgm10b b=new pgm10b();
b.display();
}
void display()
{
System.out.println("A class");
}
}
it is saved in C:\NNK\pack1
the second program is
import java.io.*;
class pgm10b
{
void pgm10b()
{
pgm10a a=new pgm10a();
a.display();
}
void display()
{
System.out.println("Class B");
}
}
it is in C:\NNK\pack2
I want to run pgm10a but it keeps showing pgm10b not found exception. i have set the class path and compiled for both and both are compiled successfully. but when i try to run them it shows pgm10b not found.
Have a look at the syntax for the java command:
java [options] classname [args]
Anything after the class name is not an option to the java command—it is simply passed as is, in a String array, to the program’s main method.
You can solve your problem by changing your final command from this:
java pgm10a -cp C:\NNK\pack2
to this:
java -cp .;C:\NNK\pack2 pgm10a
The classpath is a sequence of directories, separated by ; when running in Windows (: on other operating systems), which tell the java command where to find compiled classes. If you only specify C:\NNK\pack2, Java will only be able to see classes in that directory. The period (.) refers to the current directory, so the above classpath is pointing to both the current directory (which contains pgm10a) and the pack2 directory (which contains pgm10b).
I have two Java classes "giveMyOb" and "dataConn" declared in the same directory. Both are public classes. "giveMyOb" has a static method "getMine()". Inside dataConn, I called the static method as
giveMyOb.getMine();
When I try to compile dataConn.java, the following error is returned.
"Cannot find symbol
symbol: variable giveMyOb
location : class dataConn
giveMyOb.getMine(); "
It used to work earlier. But is not working now. Why is that?
Additional Information: JDK 1.6. Windows 7. 64 bit.
Update(30 days after the question): When compiled from Eclipse, the classes are referenced and it works. But the same won't work when compiling from command line. I was unable to figure out the reason and nothing logical comes to my mind!
javac -classpath . *.java
ought to create both .class files at the same time. It's more complicated by packages. I'm assuming you have none.
Learn the Sun Java coding conventions. You aren't following them with those class names. They should start with a capital letter.
Try this:
giveMyOb.java
public class giveMyOb {
public static String getMine() {
return "Yay, it works!";
}
}
dataConn.java
public class dataConn {
public static void main(String[] args) {
System.out.println(giveMyOb.getMine());
}
}
Then compile it all:
javac *.java
and run the main class:
java -cp . dataConn
// output: Yay, it works!
Note that Java's coding conventions recommend class names start with a capital.
If "it" still doesn't work, try removing the .class files manually then recompile again.