Is it possible to compile a .java file in a c++ program (assuming the .java file is given to me)? If so, how?
3 Answers
Assuming you mean to include and run compiled java classes in your C++ program:
You could use the JNI, which is mostly used to solve the reversed problem (running native code from Java).
Have a look at http://java.sun.com/docs/books/jni/html/invoke.html detailing how to create a JNI environment and how to invoke a method in your Java code.
3 Comments
It is possible to compile a Java module using C++. In UNIX / Linux, you can have C++ use the fork() / exec() C functions to launch the javac compiler within a separate process. In Windows, you can use the CREATEPROCESS facilities.
Other techniques include launching a shell which then calls javac. This is used at times when you don't want to do more work to integrate input and output with the "launching" program.
You can also leverage the existing JNI (Java Native Interface) to start a JVM in your C / C++ process. Under such a solution, you could then use the new Java 1.6 facilities to grab the tool chain compiler. Once you have the compiler, you can invoke it via JNI calls to compile your source code.
The javac program is open source. Under the right conditions (if you are developing something that is GPL compatible) you can integrate the HotSpot code directly within your program.
Finally, if you are only compiling a small subset of Java, you can also write your own compiler. JVM bytecode is quite easy to understand, and the class file format is publicly accessible.
Comments
You can do this by embedding a JVM within your application and writing a little bit of (untested) JNI to get and call a method on the JavaCompiler:
jclass provider = env->FindClass("javax/tools/ToolProvider");
jmethodID providermid = env->GetStaticMethodID(provider, "getSystemJavaCompiler", "()Ljavax/tools/JavaCompiler");
jobject compiler = env->CallStaticVoidMethod(provider, providermid);
jclass cls = env->GetObjectClass(compiler);
jmethodID compilermid = env->GetMethodID(cls, "run", "(Ljava/io/InputStream;Ljava/io/OutputStream;Ljava/io/OutputStream;[Ljava/lang/String;)I");
jstring filename = env->NewStringUTF(env, "my_file.java");
env->CallIntMethod(compiler, compilermid, NULL, NULL, NULL, filename);
The compiler was looked up from ToolProvider.
So basically the earlier C++ code is a direct translation of:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null, "my_file.java");
into C++ via JNI.
2 Comments
JavaCompiler?JavaCompiler in any include file that I'm aware of. The example shows how using #include <jni.h> you can write the Java code shown in C++. The first bit is C++ which does the exact same thing as the Java, but from a C++ (or C) interface.
javacas a separate process. If you were really into self-abuse you could perhaps use JNI to execute javac from C++, but that would be graduate-level stuff.system("javac filename.java");