Compilando uma classe a partir de um button

4 respostas
I

Eaw pessoal,queria saber, como compilar uma classe a partir de um button em um Jframe ??

4 Respostas

rodriguesabner

Você quer chamar uma tela clicando no JButton?

staroski

Dê uma lida na documentação da interface JavaCompiler.

I

Compilar uma classe ao clickar em um botão, que está em um diretorio que eu definir!

staroski

Para isso existe a interface JavaCompiler, no entanto seu uso não é trivial então vou postar um exemplo.

Suponha que você queira compilar o seguinte código fonte e em seguida criar um objeto da MinhaClasse e invocar o método meuMetodo():

public class MinhaClasse {

    public String meuMetodo() {
        return "Funcionou!";
    }
}

Para abstrair a utilização da interface JavaCompiler vamos criar uma classe Compiler com um método sobrecarregado compile:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class Compiler {

    private static final URLClassLoader CLASS_LOADER;
    static {
        try {
            File currentDir = new File(System.getProperty("user.dir"));
            URL[] urls = new URL[] { currentDir.toURI().toURL() };
            CLASS_LOADER = URLClassLoader.newInstance(urls);
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public Class<?> compile(File arquivo) {
        try {
            String name = arquivo.getName();
            int index = name.lastIndexOf('.');
            if (index != -1) {
                name = name.substring(0, index);
            }
            return compile(name, new FileInputStream(arquivo));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public Class<?> compile(String arquivo) {
        return compile(new File(arquivo));
    }

    public Class<?> compile(String nome, InputStream arquivo) {
        try {
            JavaFileObject fonte = getJavaFileObject(nome, arquivo);
            return compile(nome, fonte);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public Class<?> compile(String nome, JavaFileObject fonte) {
        try {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            Writer out = null;
            JavaFileManager fileManager = null;
            DiagnosticCollector<JavaFileObject> diagnosticListener = new DiagnosticCollector<JavaFileObject>();
            Iterable<String> options = null;
            Iterable<String> classes = null;
            Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(fonte);
            CompilationTask task = compiler.getTask(out, fileManager, diagnosticListener, options, classes, compilationUnits);
            boolean success = task.call();
            if (!success) {
                StringBuilder message = new StringBuilder();
                for (Diagnostic<? extends JavaFileObject> diagnostic : diagnosticListener.getDiagnostics()) {
                    message.append(diagnostic.getMessage(null)).append("\n");
                }
                throw new IllegalArgumentException(message.toString().trim());
            }
            return Class.forName(nome, true, CLASS_LOADER);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private JavaFileObject getJavaFileObject(String nome, InputStream fonte) throws IOException {
        StringBuilder conteudo = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(fonte));
        String linha = null;
        while ((linha = reader.readLine()) != null) {
            conteudo.append(linha).append("\n");
        }
        class InMemoryJavaSource extends SimpleJavaFileObject {
            final String code;

            InMemoryJavaSource(String code) {
                super(URI.create("string:///" + nome.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
                this.code = code;
            }

            @Override
            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
                return code;
            }
        }
        return new InMemoryJavaSource(conteudo.toString());
    }
}

Agora um exemplo de utilização da classe Compiler que criamos:

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Exemplo {

    public static void main(String[] args) {
        try {
            Exemplo programa = new Exemplo();
            programa.executar();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public void executar() throws Exception {
        // compilar fonte
        String arquivo = <caminho onde se encontra o arquivo MinhaClasse.java>;
        Compiler compilador = new Compiler();
        Class<?> classe = compilador.compile(arquivo);
        
        // Executar metodo
        Constructor<?> construtor = classe.getConstructor();
        Method metodo = classe.getMethod("meuMetodo");
        Object objeto = construtor.newInstance();
        Object resultado = metodo.invoke(objeto);
        System.out.println(resultado);
    }
}
Criado 17 de outubro de 2018
Ultima resposta 18 de out. de 2018
Respostas 4
Participantes 3