Compile a .java file without knowing the public class name

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

To provide an example use: I work with a sandbox and users are allowed to send me a string. I write this line to a .java file, which I compile, evaluate the resulting class, and respond to the result.

?????. Java

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

If I accidentally gave ?????.java name such as test.java and ran the javac test.java , then it failed

error: the HelloWorld class is public, must be declared in the HelloWorld.java file as follows:

HelloWorld.java

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

Is it possible? Should I give up Java compilation or is there an alternative solution?

+7
java
source share
6 answers

Well ... To evaluate custom code, you also need to know the class name using the main method.

I think the cheapest way is to get users to stick with some kind of code legend. ie "the package name must be foo.bar.baz, the name of the class is Qux, the main class is required." In this case, you can simply pass the error message from the compiler to the user as is and show the conditional agreement.

A slower way is to do some dirty tricks, for example, correctly process the resulting code with another class with a known name, mess with package names, and then try to make a reflexive call to the main class methods of the main , but in this case you will have problems with correct error reporting and it’s easy to do it wrong.

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

EDIT

You can also take the java-repl project. This may allow you to use script-like programs.

Hope this helps!

+1
source share

There is no easy way to compile a .java file if the base name of the source file does not match the class name in the source code. If you do not know what the file name should be, then your only option is to (partially) analyze the source code to find it.


But honestly, this is a problem that you should handle differently:

  • If you generated the source code yourself, you should know when this is the name of the class, and therefore you should be able to output the correct name for the ".java" file.

  • If you are compiling a file that has been "provided for you", you can (and IMO) insist that it be provided in the ".java" file with the appropriate file name. If the file name does not match the class name, this is an error ... and you do not know if the error is a file name or a class name!


Here is a thought experiment for you. Suppose someone provides you with source code files:

  • A.java ... contains class A
  • B.java ... also contains class A

What should you do? If you tried to figure out the β€œcorrect” file name from the class name in the file, you can skip that the user made a mistake in B.java and put the wrong class name in the source code!

In short, you have two pieces of conflicting information. Any of these may be wrong. If you allow one to automatically take precedence over the other, you skip errors.

+1
source share

In fact, you can compile a class if you do not declare it public.

example:

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

Save the file as .java and compile as such on cmd

 javac .java 

You can run later using the class name

 java Test 
0
source share

If I accidentally gave javas a name, such as test.java, and ran the javac test.java command, then it failed

error: the HelloWorld class is public, must be declared in the HelloWorld.java file

OK, so look at the error message! The compiler helps you tell you what the file name should look like. Do not drop this information. Parse the error message to find the correct file name, rename the file, and try again.

0
source share

I have a suggestion. When someone sends you the xxxx.jar file, you must save it somewhere so that you know the path to the folder. Then you can use the code below to get the name. After you get the name and path to the file, use java mapping technology to get methods and call methods.

 final static void showAllFiles(File dir) throws Exception { File[] fs = dir.listFiles(); for(int i=0; i<fs.length; i++) { // here you can get file name and path, then use reflection to get the instance and methods. } } 
0
source share

The name of the class to merge with the same name. In the "public class HelloWorld", "HelloWorld" is the name of the class. At the same time, this name is compiled.

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


That you can compile as such on cmd javac Hello.java .
Run java Hello


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

You can execute as such on cmd javac Hello2.java
Run java Hello2

-3
source share

All Articles