O Java e uma plataforma que se multiplicou exponencialmente, uma de sua grande vantagem e o fato de que voce consegue com o mesmo codigo executar em diferentes plataformas, com isso se pode programar para servidor, dispositivos embarcados, desktop, etc. com a mesma linguagem. Alem disso a JVM possui suporte para diversas linguagens, das quais possuem, diversas caracteristicas e recursos interessantes. Um mito que existe e que o Java nao compila em tempo de execucao, o que faz muitas pessoas utilizem uma linguagem dinamica, apenas por esse objetivo, mas sera que isso e verdade?Possuir uma linguagem dinamica e muito interessante para alguns projetos especificos, por exemplo, quando se faz um projeto que realiza calculo tributario, como essa formula mudam muito ao ano e variam de municipio para municipio, nesse caso e melhor que o codigo fonte esteja em um banco de dados, por exemplo, para quando for necessario modificar o calculo nao seja necessario compilar todo o codigo fonte e fazer o deploy, correndo o risco do sistema ficar fora do ar mesmo que por alguns instantes. Sim e possivel em Java compilar codigos dinamicamente. Na verdade isso e muito comum do que imaginamos! Por exemplo, o Hibernate para gerenciar das entidades, para facilitar ainda o seu uso a partir da versao 1.6 com a JSR 199 foi criada um API com essa finalidade.Para demonstrar essa funcionalidade sera usado a solucao para o problema acima, fazer com que haja troca de formula, para facilitar a demonstracao e focar na solucao serao as 4 operacoes basicas, sendo que esse codigo fonte estara no banco de dados, no caso sera simulado com arquivos dentro de um txt. Como nao podemos referenciar uma classe nao compilada, criaremos uma interface Operacao, ela sera implementada por nossas classes que estarao em nosso banco de dados.public interface Calculo { Double calcular(Number valorA, Number valorB); } Interface na qual sera utilizada como referencias as classes compiladas dinamicamente.Explicando o processo de compilacao passo a passo: A classe JavaCompiler, que tem a responsabilidade de fazer a compilacao do codigo-fonte. A chamada ToolProvider.getSystemJavaCompiler() retorna este objeto. Se um compilador Java nao estiver disponivel, o retorno sera null. Ele conta com o metodo getTask(), que retorna um objeto CompilationTask. De posse desse objeto, a chamada call() efetua a compilacao do codigo e retorna um booleano indicando se ela foi feita com sucesso (true) ou se houve falha (false).public class JavaDinamicoCompilador { private JavaCompiler compiler; private JavaDinamicoManager javaDinamicoManager; private JavaDinamicoClassLoader classLoader; private DiagnosticCollector diagnostics; public JavaDinamicoCompilador() throws JavaDinamicoException { compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { throw new JavaDinamicoException("Compilador nao encontrado"); } classLoader = new JavaDinamicoClassLoader(getClass().getClassLoader()); diagnostics = new DiagnosticCollector(); StandardJavaFileManager standardFileManager = compiler .getStandardFileManager(diagnostics, null, null); javaDinamicoManager = new JavaDinamicoManager(standardFileManager, classLoader); } @SuppressWarnings("unchecked") public synchronized Class compile(String packageName, String className, String javaSource) throws JavaDinamicoException { try { String qualifiedClassName = JavaDinamicoUtils.INSTANCE.getQualifiedClassName( packageName, className); JavaDinamicoBean sourceObj = new JavaDinamicoBean(className, javaSource); JavaDinamicoBean compiledObj = new JavaDinamicoBean(qualifiedClassName); javaDinamicoManager.setSources(sourceObj, compiledObj); CompilationTask task = compiler.getTask(null, javaDinamicoManager, diagnostics, null, null, Arrays.asList(sourceObj)); boolean result = task.call(); if (!result) { throw new JavaDinamicoException("A compilacao falhou", diagnostics); } Class newClass =