动态编译 - Dynamically Compile and Load External Java Classes

news2024/11/18 23:24:05

文章目录

  • 概述
  • Code

概述

动态编译和加载外部Java类的核心流程可以概括为以下几个步骤:

  1. 读取源代码: 首先,需要获取到外部的Java源代码。这通常是通过读取文件、网络资源或者数据库中的源代码字符串来实现的。
  2. 编译源代码: 接下来,需要使用Java编译器来编译这些源代码。这可以通过调用javac命令行工具或者使用Java API中的编译器API(如javax.tools.JavaCompiler)来实现。
  3. 生成字节码: 编译过程会生成字节码文件(.class文件)。这些字节码文件包含了编译后的Java类的信息。
  4. 加载字节码: 最后,需要将这些字节码文件加载到Java虚拟机(JVM)中。这可以通过创建一个ClassLoader子类并重写其loadClass方法来实现。在这个方法中,你可以从文件系统、网络或其他来源读取字节码,并使用defineClass方法将其定义为一个Class对象。
  5. 创建实例和调用方法: 一旦类被加载,就可以使用newInstance方法来创建类的实例,并调用其方法。

Code

在这里插入图片描述

package com.artisan.jsr269;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class DynamicCompiler {

    public static void main(String[] args) throws Exception {

        //创建源文件
        String currentDir = System.getProperty("user.dir") + "/boot-beanUtils" ;

        // 定义一个简单的Java类,包含一个方法,该方法打印出“Hello Artisan”
        String src = "package com.artisan.jsr269 ;"
                + "public class ArtisanComplier {"
                + "    public void methodA() {"
                + "    System.out.println(\"Hello Artisan\");"
                + "}}";

        // 源文件路径和名称
        String filename = currentDir + "/src/main/java/com/artisan/jsr269/ArtisanComplier.java";
        File file = new File(filename);

        // 确保源文件所在的目录存在
        File fileParent = file.getParentFile();

        if (!fileParent.exists()) {
            fileParent.mkdir();
        }

        // 确保源文件存在
        if (!file.exists()) {
            file.createNewFile();
        }

        // 将源代码写入文件
        FileWriter fw = new FileWriter(file);
        fw.write(src);
        fw.flush();
        fw.close();

        // 使用JavaCompiler 编译java文件

        // 获取系统Java编译器
        JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
        // 获取标准文件管理器
        StandardJavaFileManager fileManager = jc.getStandardFileManager(null, null, null);
        // 获取要编译的文件对象
        Iterable fileObjects = fileManager.getJavaFileObjects(filename);
        // 创建编译任务
        JavaCompiler.CompilationTask cTask   = jc.getTask(null, fileManager, null, null, null, fileObjects);
        // 执行编译任务
        cTask.call();
        // 关闭文件管理器
        fileManager.close();

        // 使用URLClassLoader加载class到内存
        URL[] urls = new URL[]{new URL("file:/" + currentDir + "/src/main/java/com/artisan/jsr269/ArtisanComplier.java")};
        URLClassLoader cLoader = new URLClassLoader(urls);
        // 加载类
        Class c = cLoader.loadClass("com.artisan.jsr269.ArtisanComplier");
        // 关闭类加载器
        cLoader.close();
		
		// TODO 在这之前要确保编译任务完成,否则这里通过反射实例化会报错

        // 利用class创建实例,反射执行方法
        Object obj = c.newInstance();
        // 获取类中的方法
        Method method = c.getMethod("methodA");
        // 执行方法
        method.invoke(obj);
    }
}

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1362898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle VM VirtualBox xx needs the Micrsoft Visual C++ 2019错误

错误展示 解决方法 重修安装 Visual C 文件 1、前往官网 C 中 Windows 编程概述 | Microsoft Learn 2、找到对应的包 左边导航栏依次选择: 部署本机桌面应用程序-----重新分发Visual C 文件-----最新受支持的Visual C可再发型程序包下载 根据自己电脑系统进行选…

数据结构:树详解

创建二叉树 给出了完整的先序遍历序列,子树为空用’#’表示,所以这样我们在通过先序遍历序列创建二叉树时我们直到先序遍历序列是先进行根结点,然后左子树最后右子树的顺序进行遍历的,所以对于完整的先序遍历序列我们可以直到先序…

指定日期D的年份和月份返回日期D所在的月份:(1)第一天是星期几?(2)该月共有多少天?calendar.monthrange(year,month)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定日期D的年份和月份 返回日期D所在的月份: (1)第一天是星期几? (2)该月共有多少天? calendar.monthrange(…

CMU15-445-Spring-2023-Project #1 - 前置知识(lec01-06)

Lecture #01_ Relational Model & Relational Algebra Databases 数据库是相互关联的数据的有组织集合,对现实世界的某些方面进行建模。区别于DBMS(MySQL、Oracle)。 Flat File Strawman 数据库以CSV文件的形式存储,并由D…

梦想家内容管理系统(Dreamer CMS)跨站请求伪造漏洞

梦想家内容管理系统(Dreamer CMS)跨站请求伪造漏洞 目标:GitHub - iteachyou-wjn/dreamer_cms: Dreamer CMS 梦想家内容发布系统采用流行的SpringBoot搭建,支持静态化、标签化建站。不需要专业的后台开发技能,会HTML就能建站&…

真核微生物基因组质量评估工具EukCC的安装和详细使用方法

介绍: GitHub - EBI-Metagenomics/EukCC: Tool to estimate genome quality of microbial eukaryotes 安装: docker: docker pull microbiomeinformatics/eukcc 推荐conda 环境: conda install -c conda-forge -c bioconda …

Jenkins修改全局maven配置后不生效解决办法、以及任务读取不同的settings.xml文件配置

一、修改Global Tool Configuration的maven配置不生效 说明:搭建好jenkins后,修改了全局的settings.xml,导致读取settings一直是之前配置的。 解决办法一 Jenkins在创建工作任务时,会读取当前配置文件内容,固定在这…

Spring+Vue实战项目环境准备跑通程序

SpringVue 源项目 后端: 首先在GitHub上克隆项目到本地(zip包下载/sourcetree拉取/gitbash克隆)。 https://github.com/songboriceman/doubao_community_backend 然后下载Lombok安装到你的IDE(eclipse)。 https://p…

【uniapp】APP打包上架应用商-注意事项

初雪云-uniapp启动图自定义生成(支持一键生成storyboard) 一、修改App端上传图片/视频 uni.uploadFile let thatthis; uni.chooseImage({count: 1,sourceType: [camera,album],sizeType: [compressed, original],success: rey > {uni.showLoading({ t…

VS code的使用介绍

VS code的使用介绍 简介下载和安装常用的插件使用教程快捷键 集成Git未找到 Git。请安装 Git,或在 "git.path" 设置中配置。操作步骤打开文件夹初始化仓库文件版本控制状态提交文件到git打开git操作栏位 好用的插件ChineseDraw.io Integration实体关系 Gi…

案例099:基于微信小程序的外卖小程序的研究与开发

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

leetcode 每日一题 2023年12月30日 一周中的第几天

题目 给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。 输入为三个整数:day、month 和 year,分别表示日、月、年。 您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", &qu…

数字图像处理 Harris 角点和边缘检测器

一、简述 Harris角点和边缘检测器是一项古老的技术,说它古老是因为该技术从1988年被发明。下面是论文地址,技术出现的时间虽然很久,但是并不代表没有用处了,很多神经网络无法发挥作用的场景下,类似的技术还是会大行其道。 https://web.stanford.edu/class/cs231m/referen…

通过聚道云软件连接器实现钉钉与自研主数据系统的完美融合

客户介绍 某知名高校,拥有数千名教职工,日常管理涉及大量的人员异动信息。该高校设有多个学院和研究所,涵盖了工、理、管、文等多个学科领域。该高校是一所充满活力和潜力的学府,致力于为学生提供优质的教育资源和多元化的学习环…

大型语言模型的幻觉问题

1.什么是大模型幻觉? 在语言模型的背景下,幻觉指的是一本正经的胡说八道:看似流畅自然的表述,实则不符合事实或者是错误的。 幻觉现象的存在严重影响LLM应用的可靠性,本文将探讨大型语言模型(LLMs)的幻觉问题&#x…

[嵌入式C][入门篇] 快速掌握基础2 (数据类型、常量、变量)

开发环境: 网页版:跳转本地开发(Vscode):跳转 文章目录 一、基本变量大小和范围(1)在8位/32位单⽚机中:测试代码结果:64位机器结果:32位机器(单片机)无对齐限…

Web爬虫中CAPTCHA挑战的解决方法

CAPTCHA是网站用来区分人类用户和自动机器人的一种安全措施。它包括向用户提出一些挑战,如扭曲的文本、图像或拼图,用户必须解决以证明其真实性。然而,在Web爬取过程中,遇到验证码可能会带来相当大的挑战。本文将探讨在Web爬虫过程…

使用 C# Winfrom编写倒计时功能

在日常生活中,我们经常需要倒计时来提醒自己重要的时间节点,比如倒计时到达一个特定的日期和时间。介绍一个使用 C# 编写的倒计时应用程序的实现。 步骤一:应用程序的功能 它具有以下几个主要特点: 用户输入目标日期和时间&…

Wrk压测发送Post请求的正确姿势

一、Wrk简介 wrk 是一个能够在单个多核 CPU 上产生显著负载的现代 HTTP 基准测试工具。它采用了多线程设计,并使用了像 epoll 和 kqueue 这样的可扩展事件通知机制。此外,用户可以指定 LuaJIT 脚本来完成 HTTP 请求生成、响应处理和自定义报告等功能。 …

个人笔记:分布式大数据技术原理(二)构建在 Hadoop 框架之上的 Hive 与 Impala

有了 MapReduce,Tez 和 Spark 之后,程序员发现,MapReduce 的程序写起来真麻烦。他们希望简化这个过程。这就好比你有了汇编语言,虽然你几乎什么都能干了,但是你还是觉得繁琐。你希望有个更高层更抽象的语言层来描述算法…