Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile .java file without knowing public class name

Tags:

java

I'd like to know how to compile .java files without knowing the public class name.

To provide an example use case: I am operating a sandbox, and users are allowed to send me a string. I write that string to a .java file, which I compile, evaluate the resulting class and reply the output.

?????.java

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}

If I were to randomly assign ?????.java a name such as test.java and ran the command javac test.java then it would fail

error: class HelloWorld is public, should be declared in a file named HelloWorld.java like so:

HelloWorld.java

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}

Is this possible? Should I forego the ability to compile Java, or is there an alternative solution?

like image 645
Trevor Avatar asked Aug 20 '16 00:08

Trevor


People also ask

Can we run java program without public class?

Yes, we can execute a java program without a main method by using a static block. Static block in Java is a group of statements that gets executed only once when the class is loaded into the memory by Java ClassLoader, It is also known as a static initialization block.

Can I compile a java file with a different name than the class?

Yes,it is possible to compile a java source file with different file name but you need to make sure none of the classes defined inside are public... when you compile the source file the corresponding . class files for the classes inside the source file are created.

Does a java file have to have a public class?

Show activity on this post. Okay, so a java source file must have at least one public class and the file should be called "class-name.

Can you save a java file other than Java class name?

Yes, Ofcourse! you can do this.


1 Answers

Well... To be able to evaluate custom code you also have to know a class name with main method.

I think the cheapest way is to force users to stick to some sort of code convention i.e "package name should be foo.bar.baz, class name is Qux, main class is mandatory". In that case you can just pass through an error message from compiler to user as is and show a code convention.

Less quick way is to do some dirty tricks like wrapping received code properly with another class with known name, messing with package names and then try to make reflective call to inner classes main method, but in that case you'll have a problems with proper error reports and easy to do it wrong.

The proper and potentially long way is to take java source code parser (like this), build AST, find out top-level class, rename file according package/class name and execute javac (or even produce bytecode from AST).

EDIT

Also you can take a took at java-repl project. This can allow you to eval script-like programs.

Hope that helps!

like image 125
vsminkov Avatar answered Sep 21 '22 09:09

vsminkov