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

文章目录

  • 概述
  • 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.hqwc.cn/news/327835.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html5实现好看的个人博客模板源码

文章目录 1.设计来源1.1 主界面1.2 认识我界面1.3 我的文章界面1.4 我的模板界面1.5 文章内容界面 2.结构和源码2.1 目录结构2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/135368653 html5实现好看…

物联网的感知层、网络层与应用层分享

物联网的概念在很早以前就已经被提出,20世纪末期在美国召开的移动计算和网络国际会议就已经提出了物联网(Internet of Things)这个概念。 最先提出这个概念的是MIT Auto-ID中心的Ashton教授,他在研究RFID技术时,便提出了结合物品编码、互联网…

【论文解读】基于神经辐射场NeRF的像素级交互式编辑(Seal-3D)

来源:投稿 作者:橡皮 编辑:学姐 论文链接:https://arxiv.org/pdf/2307.15131 项目主页:https://windingwind.github.io/seal-3d/ 摘要: 随着隐式神经表征或神经辐射场(NeRF)的普及…

针对人工智能的攻击并发布策略和建议

人工智能系统已经渗透到现代社会的各个领域。从自动驾驶到疾病诊断以及作为在线聊天机器人与客户互动。 为了学习如何执行这些任务,聊天机器人需要接受大量数据的训练。然而,主要问题之一是这些数据可能不可靠。攻击者有很多机会破坏它们。这都是在AI系…

docker、docker-compose 离线安装、shell脚本一键安装、卸载

注:二进制包,与脚本在同级目录 docker 离线安装: 包下载:https://download.docker.com/linux/static/stable/x86_64/ docker_install.sh: #!/bin/bash# 指定 Docker 版本和文件名 DOCKER_VERSION"24.0.7" D…

【影刀RPA_如何使用影刀的企业微信指令?】

思路:先用python代码过一遍,再将必要参数填到指令里面。 第一步: 1、在企业微信后台新建应用,设置消息接收地址(需要服务器的公网ip地址),进行签名验证。然后,从浏览器中查询ip地址…

C语言基础知识(5):TCP网络编程

TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此…

Redis 持久化——AOF

文章目录 为什么需要AOF?概念持久化查询和设置1. 查询AOF启动状态2. 开启AOF持久化2.1 命令行启动AOF2.2 配置文件启动 AOF 3. 触发持久化3.1 自动触发3.3 手动触发 4. AOF 文件重写4.1 什么是AOF重写?4.2 AOF 重写实现4.3 AOF 重写流程 5. 配置说明6. 数据恢复6.1…

【SpringCloud】之远程消费(进阶使用)

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《SpringCloud开发之远程消费》。🎯&a…

H266/VVC多样化视频编码工具概述

全景视频编码 全景视频: 具有360度全包围视角的球面视频。 全景视频编码: 包括H266在内的视频编码算法都是以平面视频为对象的,为了采用传统的视频编码编码算法,全景视频需要转换为平面视频,其中经纬图等角映射&#…

dubbo的基础知识

dubbo是什么 Dubbo是一个分布式服务框架,是一种高性能的远程通讯框架。它提供了基于Java的RPC(远程过程调用)通信机制,使得应用之间可以方便地进行远程调用,实现分布式服务的调用和管理。Dubbo提供了服务注册、发现、负…

【大数据进阶第三阶段之Hive学习笔记】Hive常用命令和属性配置

目录 1、Hive安装 2、HiveJDBC访问 2.1、启动hiveserver2服务 2.2、连接hiveserver2服务 2.3、注意 3、Hive常用交互命令 3.1、“-e”不进入hive的交互窗口执行sql语句 3.2、“-f”执行脚本中sql语句 4、Hive其他命令操作 4.1、退出hive窗口 4.2、在hive cli命令窗口…

基于OpenCV的透视变换

基础概念 透视变换(Perspective Transformation)是仿射变换的一种非线性扩展,是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。 原理:将二维的图片投影到一个三维视平面上,然后再转换到二维坐标下&#…

LeetCode 2807.在链表中插入最大公约数

【LetMeFly】2807.在链表中插入最大公约数 力扣题目链接:https://leetcode.cn/problems/insert-greatest-common-divisors-in-linked-list/ 给你一个链表的头 head ,每个结点包含一个整数值。 在相邻结点之间,请你插入一个新的结点&#x…

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

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

CSS3 边框border、outline、box-shadow

1 border 语法:border: width style color 2 outline 语法:outline: width style color 2.1 outline-offet MDN解释:用于设置outline与一个元素边缘或边框之间的间隙 即:设置outline相对border外边缘的偏移,可以为…

excel统计分析——两因素有重复方差分析

参考资料:生物统计学 无重复观测值的两因素方差分析只能研究两个因素的主效应,不能考察因素间的交互作用,只有在确定因素间不存在交互作用时才能进行无重复观测值的试验和分析。为了准确估计因素的主效应、交互作用和随机误差,每个…

DQL命令查询数据 (二)

本课目标 掌握 ORDER BY 子句 使用 LIMIT 子句实现分页查询 掌握MySQL的分组查询 掌握MySQL的子查询 SELECT 语法 ORDER BY 排序 ORDER BY 子句:按照一定顺序显示查询结果 排序可以是升序(ASC)或者是降序(DESC)&…

使用C#发送邮箱验证码

使用C#发送邮箱验证码 在很多应用程序中,我们需要使用邮箱来进行用户身份验证。其中一种常见的方式是通过发送验证码到用户的邮箱,然后要求用户输入该验证码进行验证。本文将介绍如何使用 C# 发送邮箱验证码。 声明 验证码登录没有用任何的工具&#…

【大数据】Zookeeper 数据写入与分布式锁

Zookeeper 数据写入与分布式锁 1.数据是怎么写入的2.基于 Zookeeper 实现分布式锁 1.数据是怎么写入的 无论是 Zookeeper 自带的客户端 zkCli.sh,还是使用 Python(或者其它语言)实现的客户端,本质上都是连接至集群,然…