delrocco
delrocco

Reputation: 495

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.

Upvotes: 1

Views: 384

Answers (3)

Edwin Buck
Edwin Buck

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:

  1. Locates all the relevant classes.
  2. Runs javap on the class.
  3. 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.

Upvotes: 1

Stephen C
Stephen C

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

josh.trow
josh.trow

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

Related Questions