java动态加载

先贴个笔记,后续用得着再深究。

package test;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class SimpleRun {

    public static void showCompile() {
        // Prepare source somehow.
        String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\");} public void Hello(){System.out.println(\"fuck\");} }";
        // Save source in .java file.
        File root = new File("~/temp"); // On Windows running on C:\, this is
                                        // C:\java.
        File sourceFile = new File(root, "test/Test.java");
        sourceFile.getParentFile().mkdirs();
        try {
            Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
            // Compile source file.
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int success = compiler.run(null, null, null, sourceFile.getPath());
            if (success == 0) {
                // Load and instantiate compiled class.
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
                Class<?> cls;
                try {
                    // Should print "hello".
                    cls = Class.forName("test.Test", true, classLoader);
                    // Should print "world".
                    Object instance = cls.newInstance();
                    // Should print "[email protected]".
                    System.out.println(instance);
                    Method m = cls.getMethod("Hello", new Class<?>[] {});
                    System.out.println(m);
                    m.invoke(instance, new Object[]{});
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("compile failed");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static double calculate(String expr) {
        String className = "Calculator";
        String methodName = "calculate";
        String source = "package test;  public class " + className + " { public static double " + methodName + "() { return " + expr
                + "; } }";
        // set work directory
        File root = new File("~/temp");
        // set work package
        File sourceFile = new File(root, "test/Calculator.java");
        sourceFile.getParentFile().mkdirs();
        try {
            Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
            // Compile source file.
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int success = compiler.run(null, null, null, sourceFile.getPath());
            if (success == 0) {
                // Load and instantiate compiled class.
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
                Class<?> cls;
                try {
                    cls = Class.forName("test.Calculator", true, classLoader);
                    Object instance = cls.newInstance();
                    Method method = cls.getMethod(methodName, new Class<?>[] {});
                    Object value = method.invoke(instance, new Object[] {});
                    return (Double) value;
                } catch (ClassNotFoundException | IllegalAccessException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("compile failed");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0.0;
    }

    public static void main(String[] args) {
        SimpleRun.showCompile();
        if (args.length >= 1) {
            System.out.println(args[0] + "=" + SimpleRun.calculate(args[0]));
        }
    }
}

参考:

http://www.infoq.com/cn/articles/cf-java-byte-code

时间: 2024-08-12 15:52:13

java动态加载的相关文章

java动态加载指定的类或者jar包反射调用其方法

序言 有时候,项目中会用到java动态加载指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大降低,更加的模块化,代码利用率更高.模式中的代理模式就用到java的这一机制.下边就让我们通过代码来看看如何实现此功能. 代码详细 package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoad

避免缓存,Java动态加载配置文件

Java动态加载配置文件 关键:每次读取都要重新生成流 今天无意间在项目的代码中看到如下这样一段简单加载配置文件的代码: Properties prop = new Properties(); InputStream in = PropertiesTest.class.getClassLoader().getResourceAsStream("/config.properties"); prop.load(in); 其实代码本身是没有什么问题的 问题就是用这种方式来读取配置文件,会存在

java动态加载机制

假设有一个class,ClassLoader首先把它load到内存里的code segment(内存里存放代码段的),站在ClassLoader的角度,内存里的一个一个的class就是一个一个的对象,这个对象就是xx.class,实际就是Class类的对象.Load完class,找到main函数开始执行,然后会把很多其他的类Load进来,动态加载机制. 测试动态加载机制: 新建项目Reflection,new一个class,TestDynamicLoading: public class Tes

java动态加载jar包,并运行其中的类和方法

动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一:定义一个抽象类 AbstractAction (稍后换成接口的实例) [java] view plain copy package com.java.loader; public abstract class AbstractAction { public abstract String actio

java动态加载类和静态加载类笔记

JAVA中的静态加载类是编译时刻加载类  动态加载类指的是运行时刻加载类 二者有什么区别呢 举一个例子  现在我创建了一个类  实现的功能假设为通过传入的参数调用具体的类和方法 class office { public static void main(String args[]) { if("word".equals(args[0]) { word w=new word(); word.run(); } if("excel".equals(args[0]) {

Java动态加载类

详见:https://blog.csdn.net/zai_xia/article/details/80026325 扩展:java反射机制与动态加载类 https://www.cnblogs.com/wzk-0000/p/9322866.html 在讲解动态加载类之前呢,我们先弄清楚为什么要动态加载类,静态加载不行吗?我们可以看下面的实例: 我在文件夹里写了Office.java 类和 Word.java类,如下: Office.java class Office{ public static

Java动态加载属性文件.properties

问题: 当我们使用如下语句加载.properties时: ClassLoader classLoader = this.getClass().getClassLoader(); Properties prop = new Properties(); prop.load(classLoader.getResourceAsStream("/Application.properties")); 会发现修改了.properties后,即使重新执行,读入的仍为修改前的参数.此问题的原因在于Cla

27 Java动态加载第三方jar包中的类

我加载的方法是://参数fileName是jar包的路径,processorName 是业务类的包名+类名public static A load(String fileName, String processorName) {            String filePath = fileName;              A processor = null;  URL url;try {  url = new URL(filePath);} catch (MalformedURLEx

ECharts Java 动态加载数据

1.前台JSP页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd&quo