Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package nl.timdebrouwer.dynamiccompileandload;
- import java.io.File;
- import java.io.IOException;
- import java.net.URI;
- import java.util.Arrays;
- 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 Compiler {
- final Logger logger = Logger.getLogger(Compiler.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 static void doCompilation (SimpleJavaFileObject fileObject){
- /*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();
- if(compiler==null){
- System.out.println("Compiler is dood");
- return;
- }
- /**
- * 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, null, 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"} ;
- String[] compileOptions = new String[]{"-d", "compiled"} ;
- File folder = new File(compileOptions[1]);
- if(!folder.exists()){
- try{
- folder.mkdirs();
- }catch(Exception e){
- }
- }
- 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 Compiler ().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;
- }
- }
- ===== END CLASS COMPILER =====
- package nl.timdebrouwer.dynamiccompileandload;
- import java.io.File;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.net.URI;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Scanner;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import javax.tools.SimpleJavaFileObject;
- @SuppressWarnings("unused")
- public class DynamicCompileAndLoad{
- private File classFolder;
- private List<ClassFile> classFiles;
- public URLClassLoader loader;
- public static void main(String args[]){
- DynamicCompileAndLoad loader = new DynamicCompileAndLoad();
- }
- public DynamicCompileAndLoad(){
- File inputFolder = new File("scripts");
- List<File> javaFiles = getFiles(inputFolder);
- classFiles = new ArrayList<ClassFile>();
- classFolder = new File("compiled");
- if(!inputFolder.exists()){
- inputFolder.mkdir();
- }
- if(!classFolder.exists()){
- classFolder.mkdir();
- }
- try{
- loader = new URLClassLoader(new URL[]{classFolder.toURI().toURL()},DynamicCompileAndLoad.class.getClassLoader());
- deleteFiles(classFolder);
- }catch(Exception e){
- e.printStackTrace();
- }
- if(!classFolder.exists()){
- classFolder.mkdir();
- }
- for(File file:javaFiles){
- try{
- Scanner scanner = new Scanner(file);
- String code = "";
- String pack = null;
- String name = stripName(file.getAbsolutePath());
- while(scanner.hasNext()){
- String line = scanner.nextLine();
- code = code+"\n"+line;
- if(line.startsWith("package")){
- pack = line.split(" ")[1];
- pack = pack.substring(0, pack.length()-1);
- //System.out.println("Package: " + pack);
- }
- }
- scanner.close();
- List<String> methods = getMethods(code);
- List<String> imports = getImports(code);
- ClassFile f = new ClassFile();
- f.source = code;
- //System.out.println(pack + " "+name);
- f.name = name;
- f.pack = pack;
- f.imports = imports;
- f.methods = methods;
- classFiles.add(f);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- System.out.println("First compilation");
- for(ClassFile file:classFiles){
- compileFirst(file);
- }
- System.out.println("");
- System.out.println("");
- System.out.println("Second compilation");
- for(ClassFile file:classFiles){
- compileSecond(file);
- }
- System.out.println("");
- System.out.println("");
- System.out.println("Last compilation");
- for(ClassFile file:classFiles){
- compileThird(file);
- }
- System.out.println("");
- System.out.println("");
- System.out.println("");
- System.out.println("Done compiling");
- System.out.println("");
- System.out.println("");
- try{
- Class<?> clazz = Class.forName("nl.timdebrouwer.helloworld.EmptyClass");
- }catch(Exception e){
- e.printStackTrace();
- }
- for(ClassFile file:classFiles){
- System.out.println(file.clazz.getName());
- }
- }
- private void compileThird(ClassFile file) {
- try{
- Field uriField;
- Class<?> c;
- c = SimpleJavaFileObject.class;
- uriField = c.getDeclaredField("uri");
- uriField.setAccessible(true);
- String pack = file.pack;
- String name = file.name;
- String code = file.source;
- DynamicJavaSourceCodeObject ob = new DynamicJavaSourceCodeObject(pack,code);
- URI oldURI = ob.toUri();
- //System.out.println(oldURI.toString());
- //URI newURI = new URI(oldURI.toString().replaceAll(name.toLowerCase(), name));
- String first = oldURI.toString().split(name.toLowerCase())[0].replaceAll(".java", "") + "/" + name+".java";
- //System.out.println("First: "+first);
- //URI newURI = new URI(oldURI.toString());
- URI newURI = new URI(first);
- //System.out.println(newURI.toString());
- uriField.set(ob, newURI);
- Compiler.doCompilation(ob);
- //System.out.println(pack+"."+name);
- Class<?> clazz = loader.loadClass(pack+"."+name);
- Object instance = clazz.newInstance();
- file.clazz = clazz;
- //loader.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- private void compileSecond(ClassFile file) {
- try{
- Field uriField;
- Class<?> c;
- c = SimpleJavaFileObject.class;
- uriField = c.getDeclaredField("uri");
- uriField.setAccessible(true);
- String pack = file.pack;
- String name = file.name;
- String code = "package "+pack+";\n";
- for(String impor:file.imports){
- code = code + impor+"\n";
- }
- code = code+"public class "+name+"{";
- for(String method:file.methods){
- code = code + method+"\n";
- }
- code = code + "}";
- DynamicJavaSourceCodeObject ob = new DynamicJavaSourceCodeObject(pack,code);
- URI oldURI = ob.toUri();
- //System.out.println(oldURI.toString());
- //URI newURI = new URI(oldURI.toString().replaceAll(name.toLowerCase(), name));
- String first = oldURI.toString().split(name.toLowerCase())[0].replaceAll(".java", "") + "/" + name+".java";
- //System.out.println("First: "+first);
- //URI newURI = new URI(oldURI.toString());
- URI newURI = new URI(first);
- //System.out.println(newURI.toString());
- uriField.set(ob, newURI);
- Compiler.doCompilation(ob);
- //System.out.println(pack+"."+name);
- //URLClassLoader loader = new URLClassLoader(new URL[]{classFolder.toURI().toURL()},DynamicCompileAndLoad.class.getClassLoader());
- Class<?> clazz = loader.loadClass(pack+"."+name);
- file.clazz = clazz;
- //loader.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- private void compileFirst(ClassFile file) {
- try{
- Field uriField;
- Class<?> c;
- c = SimpleJavaFileObject.class;
- uriField = c.getDeclaredField("uri");
- uriField.setAccessible(true);
- String pack = file.pack;
- String name = file.name;
- String code = "package "+pack+"; public class "+name+"{}";
- //System.out.println(pack);
- DynamicJavaSourceCodeObject ob = new DynamicJavaSourceCodeObject(pack,code);
- URI oldURI = ob.toUri();
- //System.out.println(oldURI.toString());
- //URI newURI = new URI(oldURI.toString().replaceAll(name.toLowerCase(), name));
- String first = oldURI.toString().split(name.toLowerCase())[0].replaceAll(".java", "") + "/" + name+".java";
- //System.out.println("First: "+first);
- //URI newURI = new URI(oldURI.toString());
- URI newURI = new URI(first);
- //System.out.println(newURI.toString());
- uriField.set(ob, newURI);
- Compiler.doCompilation(ob);
- //System.out.println(pack+"."+name);
- //URLClassLoader loader = new URLClassLoader(new URL[]{classFolder.toURI().toURL()},DynamicCompileAndLoad.class.getClassLoader());
- Class<?> clazz = loader.loadClass(pack+"."+name);
- file.clazz = clazz;
- //loader.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- private String stripName(String input) {
- String[] parts = input.split(Pattern.quote(File.separator));
- String name = parts[parts.length-1].split(Pattern.quote("."))[0];
- return name;
- }
- private List<File> getFiles(File inputFolder) {
- List<File> fileList = new ArrayList<File>();
- for(File file:inputFolder.listFiles()){
- if(file.isDirectory()){
- fileList.addAll(getFiles(file));
- continue;
- }
- if(file.getAbsolutePath().toLowerCase().endsWith(".java")){
- fileList.add(file.getAbsoluteFile());
- }
- }
- return fileList;
- }
- private void deleteFiles(File inputFolder) {
- for(File file:inputFolder.listFiles()){
- if(file.isDirectory()){
- deleteFiles(file);
- }else{
- file.delete();
- }
- }
- }
- private static List<String> getMethods(String source){
- List<String> functions = new ArrayList<String>();
- //Pattern pattern = Pattern.compile("^\\s*(public|private|protected|static|abstract)*");
- Pattern pattern = Pattern.compile("((public|private|protected|static|abstract)\\s)+(\\S+\\s*){2}[(](\\S+\\s\\S+)*[)]");
- Matcher match = pattern.matcher(source);
- while(match.find()){
- String reg = match.group();
- if(!reg.isEmpty()){
- //System.out.println("Method found: '"+reg+"'");
- String returns = "void";
- Pattern returnPattern = Pattern.compile("((public|private|protected|static|abstract)\\s)+(\\S+\\s*){1}");
- Matcher returnMatch = returnPattern.matcher(reg);
- returnMatch.find();
- returns = returnMatch.group();
- returnPattern = Pattern.compile("((public|private|protected|static|abstract)\\s)+");
- returnMatch = returnPattern.matcher(returns);
- returnMatch.find();
- String returnsStrip = returnMatch.group();
- returns = returns.split(returnsStrip)[1];
- //System.out.println("Returns "+returns);
- if(returns.equalsIgnoreCase("void ")){
- //System.out.println("Something returns void");
- functions.add(reg+"{}");
- continue;
- }
- if(returns.equalsIgnoreCase("boolean ")){
- //System.out.println("Something returns boolean");
- functions.add(reg+"{return false;}");
- continue;
- }
- if(returns.equalsIgnoreCase("int ") || returns.equalsIgnoreCase("double ") || returns.equalsIgnoreCase("float ")){
- //System.out.println("Something returns void");
- functions.add(reg+"{return 0;}");
- continue;
- }
- functions.add(reg+"{return null;}");
- continue;
- }
- }
- return functions;
- }
- private static List<String> getImports(String source){
- List<String> functions = new ArrayList<String>();
- //Pattern pattern = Pattern.compile("^\\s*(public|private|protected|static|abstract)*");
- Pattern pattern = Pattern.compile("(import\\s){1}(\\S)+;");
- Matcher match = pattern.matcher(source);
- while(match.find()){
- String reg = match.group();
- if(!reg.isEmpty()){
- reg = reg.split(" ")[1];
- //System.out.println("Import found: '"+reg+"'");
- functions.add("import "+reg);
- }
- }
- return functions;
- }
- private static Field getField(Class<?> clazz, String fieldName)throws NoSuchFieldException {
- try {
- Field f = clazz.getDeclaredField(fieldName);
- //System.out.println(clazz.getName());
- return f;
- } catch (NoSuchFieldException e) {
- Class<?> superClass = clazz.getSuperclass();
- if (superClass == null) {
- throw e;
- } else {
- return getField(superClass, fieldName);
- }
- }
- }
- }
- ===== END MAIN CLASS =====
- package nl.timdebrouwer.dynamiccompileandload;
- import java.net.URI;
- import java.util.List;
- public class ClassFile {
- public String name;
- public URI path;
- public String pack;
- public String source;
- public List<String> imports;
- public List<String> methods;
- public Class<?> clazz;
- }
- ===== END STORAGE CLASS
Advertisement
Add Comment
Please, Sign In to add comment