package com.sun.tools.javac.v8; import com.sun.tools.javac.v8.JavaCompiler; import com.sun.tools.javac.v8.util.List; import com.sun.tools.javac.v8.util.Context; import com.sun.tools.javac.v8.comp.Gen; import com.sun.tools.javac.v8.comp.Env; import com.sun.tools.javac.v8.tree.Tree; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Hashtable; import java.util.ArrayList; import java.util.Iterator; public class Derik1 { static class Compiler { private ByteArrayOutputStream os; public byte[] compile(String name, final String source) throws Throwable { os= new ByteArrayOutputStream(1024); final Context context= new Context(); JavaCompiler compiler= new JavaCompiler(context) { public InputStream openSource(String filename) { return new ByteArrayInputStream(source.getBytes()); } void genCode(Env env, Tree.ClassDef classdef) throws IOException { Gen.instance(context).genClass(env, classdef); writer.writeClassFile(os, classdef.sym); } }; List list= new List(); list= list.append(name +".java"); compiler.compile(list); byte[] bytes= os.toByteArray(); os.close(); return bytes; } } static class Loader extends ClassLoader { private Hashtable mClasses= new Hashtable(); public void add(String name, byte[] bytes) { mClasses.put(name, bytes); } public Class findClass(String name) throws ClassNotFoundException { byte[] bytes= (byte[]) mClasses.get(name); if (bytes == null) return super.findClass(name); return defineClass(name, bytes, 0, bytes.length); } } static class Attribute { public String name; public String type; public Attribute(String name, String type) { this.name= name.substring(0,1).toUpperCase() + name.substring(1).toLowerCase(); this.type= type; } public String declaration() { return "private " +type +" m" +name +";"; } public String getter() { return "public " +type +" get" +name +"() { return m" +name +"; }"; } public String setter() { return "public void set" +name + "(" +type +" " +name.toLowerCase() +") { m" + name +"= " +name.toLowerCase() +"; }"; } } public static void main(String[] argv) throws Throwable { BufferedReader reader= new BufferedReader( new InputStreamReader(System.in)); System.out.print("Class: "); String cname= reader.readLine(); ArrayList attributes= new ArrayList(); while (true) { System.out.print("Attribute (return to finish): "); String name= reader.readLine(); if (name.length() < 1) break; System.out.print("Type for " +name +": "); String type= reader.readLine(); attributes.add(new Attribute(name, type)); } String src= "public class " +cname +" {"; Iterator iter= attributes.iterator(); while (iter.hasNext()) src += "\n\t" + ((Attribute) iter.next()).declaration(); iter= attributes.iterator(); while (iter.hasNext()) { Attribute a= (Attribute) iter.next(); src += "\n\t" + a.setter(); src += "\n\t" + a.getter(); } src += "\n\tpublic String toString() {"; src += "\n\t\treturn \""; iter= attributes.iterator(); boolean first= true; while (iter.hasNext()) { Attribute a= (Attribute) iter.next(); if (!first) src += "+\",\" +\n\t\t\t\""; src += a.name +"=\" +get" +a.name +"()"; first= false; } src += ";\n\t}\n}"; System.err.println("##### Source Code"); System.err.println(src); System.err.println("##### Compiling..."); byte[] bytes= new Compiler().compile(cname, src); System.err.println("##### Class Loading..."); Loader loader= new Loader(); loader.add(cname, bytes); Class clazz= loader.findClass(cname); System.err.println("##### Class: " +clazz.getName()); Object instance= clazz.newInstance(); System.err.println("##### Instance: " +instance); } }
quarta-feira, dezembro 15, 2004
Carregamento dinâmico de classes em Java
Tá aqui um truque java que vale a pena.
Basicamente, tenho o source code vindo do limbo e quero criar uma classe "on the fly". A dureza é que o java não é nada amistoso pra fazer isso, mas dá pra fazer. ;)
Peguei do seguinte fórum
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário