java11 allows the compilation and execution in a single line - java

in a file named filename.java
class filename{
public static void main(String[] a){
System.out.println("From filename main method");
}
}
public class ClassName{
public static void main(String[] a){
System.out.println("From First main method");
}
}
Observe below commands:
Command 1:
C:\javaDJ>java filename.java
From filename main method
Command 2:
C:\javaDJ>javac filename.java
filename.java:7: error: class ClassName is public, should be declared in a file named ClassName.java
public class ClassName{
^
1 error
Observation:
command 1 compiles (i assume internally ) and executes successfully.
command 2 throws compilation error.
Problem Statement :
How is java cmd able to compile the file called filename.java, when the file(filename.java) contains a public class (ClassName)which is not named 'filename.java' (the name of the file-name.) ?

To highlight a specific section from the JEP#Launch Single-File Source-Code Programs with regards to the behavior
In source-file mode, execution proceeds as follows:
The class to be executed is the first top-level class found in the
source file. It must contain a declaration of the standard public
static void main(String[]) method.

The feature which enabled you to execute Command 1 successfully was introduced in Java 11. The feature allows you to execute a Java source code file directly using the java interpreter. The source code is compiled in memory and then executed by the interpreter, without producing a .class file on disk. Check this for more information.
The error you got in Command 2 has been there since the beginning of Java.

Related

From shell, is there a Java tool to check which compiled .class file(s) have a main method?

I'm putting together some (Python) scripts to help me automate some of my grading of hundreds of simple student Java repos. Not all of them have the same directory structure or naming of files. I've traversed them all and compiled them and if I make assumptions I can run them and test them, etc. But I'd like to know if there's a way I could find the "main" .class that has the main() method in it, so that I don't have to make assumptions about their file naming (which wouldn't work all the time anyway).
I'm aware of reflection, so yes, I know I could write another simple helper Java program to assist me in identifying it myself. But I was wondering if anything already exists (java command line option, tool from the jdk, etc.) to test a .class file to see if it is has the main() method in it.
I was wondering if anything already exists (java command line option, tool from the JDK, etc.) to test a .class file to see if it is has the main() method in it.
There is no tool or option in Java SE that does that directly.
I know I could write another simple helper Java program to assist me ...
It would be simpler to write a shell script that iterates a file tree, finds .class files, calls javap on them, and greps for a method with the appropriate main method signature.
Or you could do something similar on the source code tree.
(In retrospect, you should have set the assignment requirements so that the students had to use a specified class and package name for the class containing their main method. But it is too late for that now ...)
In the C++ days, distributing the headers files to use a shared object file was a big deal. People would get one or the other without both, and there was always the chance you'd get mis-matched versions.
Java fixed that with javap which prints the methods (and other major interfaces) of a compiled .class file.
To test if a class file has a main, run
javap SomeFile.class
which will list all public interfaces. Within that list, see if it has the "main entry point"
public static void main(java.lang.String[])
Now to handle this in mass, simply create a Python script that:
Locates all the relevant classes.
Runs javap on the class.
Reads the output for a method that matches (at the beginning, as there can be a variable number of Exceptions at the end "public static void main(java.lang.String[])
And you'll find all entry points.
Keep in mind that sometimes a single library or JAR file has many entry points, some of which are not intended as the primary entry point.
Well simply calling java -cp . <file> will either completely blow out if the class doesn't have a main method or will run the relevant code. Now, if the code fails to run right and errors out you may see it as the same effect as not having a main method.
public class HasMain {
public static void main(String[] args) {
System.out.println("Hit main");
}
}
public class HasDoIt {
public static void doIt(String[] args) {
System.out.println("Hit doIt");
}
}
public class WillBlowUp {
public static void main(String[] args) {
System.out.println("Hit blowUp");
throw new IllegalStateException("oops");
}
}
Using PowerShell:
PS D:\Development\sandbox> javac HasMain.java
PS D:\Development\sandbox> javac HasDoIt.java
PS D:\Development\sandbox> javac WillBlowUp.java
PS D:\Development\sandbox> java -cp . HasMain
Hit main
PS D:\Development\sandbox> $?
True
PS D:\Development\sandbox> java -cp . HasDoIt
Error: Main method not found in class HasDoIt, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
PS D:\Development\sandbox> $?
False
PS D:\Development\sandbox> java -cp . WillBlowUp
Hit blowUp
Exception in thread "main" java.lang.IllegalStateException: oops
at WillBlowUp.main(WillBlowUp.java:4)
PS D:\Development\sandbox> $?
False
So simply checking return values could be a quick way to test if the class has what you want, albeit any exit(1) type return will throw a false-false

GCJ throws error: "Undefined reference to main" when compiling

I´d wanted to compile a simple Java "Hello World" program like it was repesented on the GeeksforGeeks Hello World Tutorial, by using gcj in Linux Ubuntu. This is the source code:
class HelloWorld
{
public static void main(String args[])
{
System.out.println("Hello, World");
}
}
But gcj threw two errors:
(.text+0x18): undefined reference to main
collect2: error: ld returned 1 exit status
Original output from the terminal:
gcj -o helloworld HelloWorld.java
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
I´d take attention on the requirement, that the .java file should be named after the class which holds main:
Important Points :
The name of the class defined by the program is HelloWorld, which is same as name of file(HelloWorld.java). This is not a coincidence. In Java, all codes must reside inside a class and there is at most one public class which contain main() method.
By convention, the name of the main class(class which contain main method) should match the name of the file that holds the program.
What am I doing wrong?
You are missing the --main= option, from the documentation, this option is used when linking to specify the name of the class whose main method should be invoked when the resulting executable is run.
gcj -o helloworld --main=HelloWorld HelloWorld.java

Trying to understand how to create a jar file that opens terminal and takes in a argument

I finished creating a program but I was told that my program
must be a Java application that takes as a command line argument the name of the file."
I understand I can use the jar command in terminal but I don't undestand how you open the terminal and take a file name as a argument. I was wondering if someone could explain what code is required to do this.
Thanks alot.
I tried creating a basic jar file in terminal with the line "jar cvf findOptimalTransport.jar ." but the jar file does not open, I think its because the current implementation takes the users input with a scannar in the code and prints via the terminal. However, this wont work because a terminal window is not opened with this command.
It doesn't have to be a jar file. Command line arguments can be entered from the command line, when you run your application.
Let me give you an example, about how this works. Let's say you have the below simple Java application:
public class MyApplication{
public static void main(String[] arguments){
System.out.println("Hello World!");
}
}
That public static void main() is a method; and more specifically the main method of your application which is what is executed when compiled and ran.
To compile and then run it, you type in the command line/terminal:
javac MyApplication.java //this will compile it
java MyApplication //this will run the main method of MyApplication
But what is that parameter in the main method? What is String[] arguments ?
When you run your program, whatever you type after the application name is an argument, of type String and it is stored in the String array String[] arguments (or most commonly String[] args).
What this means, is that, if you execute your application like this:
java MyApplication some_file.txt // Run application with one arg.
You can access that argument like so:
public class MyApplication{
public static void main(String[] arguments){
System.out.println("Hello World!");
System.out.println("You entered: " + arguments[0]);
}
}
Output:
Hello World!
You entered: some_file.txt
Note: To run a jar file, you need to navigate to the folder that the jar file is in and from the command line you can run it by typing:
java -jar <jarname>.jar

Unable to run java with command line arguments

I have been trying to run Java with command line arguments, but for some reason the class can not be found. I am very certain the directory is correct. Is there any way to fix this?
CLDemo.java file
public class Demo {
public static void main(String[] args) {
System.out.print("It works!!!");
}
}
You need to do cd out\production before java CLDemo.
The default compile output of IntelliJ IDEA is under out\production folder, and Java needs to run at the corresponding package (folder) of your compile output.

Different results when compiling with command prompt and BlueJ

I'm just starting Java ... again.
I just made a simple program
class first
{
public static void main()
{
System.out.println("Hello!");
}
}
This runs perfectly fine in BlueJ but it gives an error during run-time when running from command prompt.
This is the error
Exception in thread "main" java.lang.NoSuchMethodError: main
It's because I didn't give String args[] in the main parameter list
Till now, I used to give it subconsciously. I know that the string array contains all the parameter values when running but then why is it running in BlueJ?
(BlueJ is a student-friendly Java editor and compiler)
Your program is valid and will compile to the same thing whether you compile from BlueJ or from the command line.
However, blueJ will let you run any static method in a class (so you can test your functions) where as the command line java command will (only) look for a special main method to run. This main method tages a String array with all the command line parameters and your program should look like this even though you don't use these command line parameters:
class first
{
public static void main(String[] args)
{
System.out.println("Hello!");
}
}

Categories

Resources