Program:
package com.accordess.ca;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Logger;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
/**
* A test class to test dynamic compilation API.
*
*/
public class CompilerAPITest {
final Logger logger = Logger.getLogger(CompilerAPITest.class.getName()) ;
/**Java source code to be compiled dynamically*/
static String sourceCode = "package com.accordess.ca;" +
"class DynamicCompilationHelloWorld{" +
"public static void main (String args[]){" +
"System.out.println (\"Hello, dynamic compilation world!\");" +
"}" +
"}" ;
/**
* Does the required object initialization and compilation.
*/
public void doCompilation (){
/*Creating dynamic java source code file object*/
SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject ("com.accordess.ca.DynamicCompilationHelloWorld", sourceCode) ;
JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
/*Instantiating the java compiler*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
/**
* Retrieving the standard file manager from compiler object, which is used to provide
* basic building block for customizing how a compiler reads and writes to files.
*
* The same file manager can be reopened for another compiler task.
* Thus we reduce the overhead of scanning through file system and jar files each time
*/
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
/* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
/*Prepare any compilation options to be used during compilation*/
//In this example, we are asking the compiler to place the output files under bin folder.
String[] compileOptions = new String[]{"-d", "bin"} ;
Iterable<String> compilationOptionss = Arrays.asList(compileOptions);
/*Create a diagnostic controller, which holds the compilation problems*/
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
/*Create a compilation task from compiler by passing in the required input objects prepared above*/
CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, compilationOptionss, null, compilationUnits) ;
//Perform the compilation by calling the call method on compilerTask object.
boolean status = compilerTask.call();
if (!status){//If compilation error occurs
/*Iterate through each compilation problem and print it*/
for (Diagnostic diagnostic : diagnostics.getDiagnostics()){
System.out.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
}
}
try {
stdFileManager.close() ;//Close the file manager
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
new CompilerAPITest().doCompilation() ;
}
}
/**
* Creates a dynamic source code file object
*
* This is an example of how we can prepare a dynamic java source code for compilation.
* This class reads the java code from a string and prepares a JavaFileObject
*
*/
class DynamicJavaSourceCodeObject extends SimpleJavaFileObject{
private String qualifiedName ;
private String sourceCode ;
/**
* Converts the name to an URI, as that is the format expected by JavaFileObject
*
*
* @param fully qualified name given to the class file
* @param code the source code string
*/
protected DynamicJavaSourceCodeObject(String name, String code) {
super(URI.create("string:///" +name.replaceAll(".", "/") + Kind.SOURCE.extension), Kind.SOURCE);
this.qualifiedName = name ;
this.sourceCode = code ;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
throws IOException {
return sourceCode ;
}
public String getQualifiedName() {
return qualifiedName;
}
public void setQualifiedName(String qualifiedName) {
this.qualifiedName = qualifiedName;
}
public String getSourceCode() {
return sourceCode;
}
public void setSourceCode(String sourceCode) {
this.sourceCode = sourceCode;
}
}
Thanks to www.javaworld.com
package com.accordess.ca;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Logger;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
/**
* A test class to test dynamic compilation API.
*
*/
public class CompilerAPITest {
final Logger logger = Logger.getLogger(CompilerAPITest.class.getName()) ;
/**Java source code to be compiled dynamically*/
static String sourceCode = "package com.accordess.ca;" +
"class DynamicCompilationHelloWorld{" +
"public static void main (String args[]){" +
"System.out.println (\"Hello, dynamic compilation world!\");" +
"}" +
"}" ;
/**
* Does the required object initialization and compilation.
*/
public void doCompilation (){
/*Creating dynamic java source code file object*/
SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject ("com.accordess.ca.DynamicCompilationHelloWorld", sourceCode) ;
JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
/*Instantiating the java compiler*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
/**
* Retrieving the standard file manager from compiler object, which is used to provide
* basic building block for customizing how a compiler reads and writes to files.
*
* The same file manager can be reopened for another compiler task.
* Thus we reduce the overhead of scanning through file system and jar files each time
*/
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
/* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
/*Prepare any compilation options to be used during compilation*/
//In this example, we are asking the compiler to place the output files under bin folder.
String[] compileOptions = new String[]{"-d", "bin"} ;
Iterable<String> compilationOptionss = Arrays.asList(compileOptions);
/*Create a diagnostic controller, which holds the compilation problems*/
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
/*Create a compilation task from compiler by passing in the required input objects prepared above*/
CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, compilationOptionss, null, compilationUnits) ;
//Perform the compilation by calling the call method on compilerTask object.
boolean status = compilerTask.call();
if (!status){//If compilation error occurs
/*Iterate through each compilation problem and print it*/
for (Diagnostic diagnostic : diagnostics.getDiagnostics()){
System.out.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
}
}
try {
stdFileManager.close() ;//Close the file manager
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
new CompilerAPITest().doCompilation() ;
}
}
/**
* Creates a dynamic source code file object
*
* This is an example of how we can prepare a dynamic java source code for compilation.
* This class reads the java code from a string and prepares a JavaFileObject
*
*/
class DynamicJavaSourceCodeObject extends SimpleJavaFileObject{
private String qualifiedName ;
private String sourceCode ;
/**
* Converts the name to an URI, as that is the format expected by JavaFileObject
*
*
* @param fully qualified name given to the class file
* @param code the source code string
*/
protected DynamicJavaSourceCodeObject(String name, String code) {
super(URI.create("string:///" +name.replaceAll(".", "/") + Kind.SOURCE.extension), Kind.SOURCE);
this.qualifiedName = name ;
this.sourceCode = code ;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
throws IOException {
return sourceCode ;
}
public String getQualifiedName() {
return qualifiedName;
}
public void setQualifiedName(String qualifiedName) {
this.qualifiedName = qualifiedName;
}
public String getSourceCode() {
return sourceCode;
}
public void setSourceCode(String sourceCode) {
this.sourceCode = sourceCode;
}
}
Thanks to www.javaworld.com