Reputation: 495
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.
Upvotes: 1
Views: 384
Reputation: 70909
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:
javap
on the class.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.
Upvotes: 1
Reputation: 718758
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 ...)
Upvotes: 1
Reputation: 4901
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
Upvotes: 0