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?
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.
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.
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.
Yes, Ofcourse! you can do this.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With