接
谁动了他的jar包(一)
http://ilab.iteye.com/blog/984823
谁动了他的jar包(二)
http://ilab.iteye.com/blog/1002629
一的方法侵入性较强,可维护性较差.
二的方法逻辑分工明确,维护性较好,使用起来简单.但无法适用所有的修改情况;
对于不同情况的类,要进行不同的反射改造,和继承.
特别的,对于,final标识的属性或者类来说,二的方法,就无能为力了.
有没有两全其美的方法呢,既可以做到无侵入,易维护,并且可以适用于所有不同的情况,达到完美的替换,以达到修改jar包的目的呢;
可以试试,用jvmti~.
先简单介绍下
http://download.oracle.com/javase/1.5.0/docs/guide/jvmti/
偷个懒,直接翻译了
jvm 工具接口(jvmti) 是一种新的本地编程工具接口.
通过它,你可以对虚拟机中的程序进行监控,也能够控制其执行;
jvmti 支持了所有的需要访问虚拟机状态的工具,
包括,但不仅限于: 分析,调试(debug),监控,线程分析,覆盖分析工具;
jvmti 用来替代 jvmpi及jvmdi(原来的分析调试工具);
"控制其执行",是否包括,改变某些类的执行方式呢.答案是肯定的,我们现在仍然用上面的例子,
来演示下如何用jvmti的技术,来达到我们的目的;
新建类Transformer,实现 java.lang.instrument.ClassFileTransformer
public class Transformer implements ClassFileTransformer {
public static Properties transferClass = new Properties();
static {
transferClass.put("Feature", "Feature.class");
}
// 获取我们指定的想要的类的原代码,这里的代码很偷懒...具体怎么获取可以根据场景而定
public static byte[] getBytesFromFile(String target) {
try {
System.out.println("start replacing");
InputStream is = new FileInputStream(new File("D:/" + target));
// bytes空间大于目标类即可,这里只做简单演示;完整的处理,可能需要做循环读取数据到bytes;
byte[] bytes = new byte[1024 * 1024];
int length = is.read(bytes);
byte[] rs = new byte[length];
System.arraycopy(bytes, 0, rs, 0, length);
is.close();
return rs;
} catch (Exception e) {
System.out.println("error occurs in _ClassTransformer!" + e.getClass().getName());
e.printStackTrace();
return null;
}
}
public byte[] transform(ClassLoader l, String className, Class<?> c, ProtectionDomain pd, byte[] b)
throws IllegalClassFormatException {
String temp = transferClass.getProperty(className);
if (temp != null && temp.length() > 0) {
System.out.println("stealing : " + className);
return Transformer.getBytesFromFile(temp);
}
return null;
}
}
以及类Premain
public class Premain {
public static void premain(String agentArgs, Instrumentation inst) throws ClassNotFoundException,
UnmodifiableClassException {
inst.addTransformer(new Transformer());
}
}
打成jar包premain.jar,修改\META-INF\MANIFEST.MF
为
Manifest-Version: 1.0
Class-Path: .
Premain-Class: Premain
这样,我们就简单完成了一个类代理的小工具;
该工具的作用是,监控jvm所有加载的类,当该类是在transferClass中配置有存在时,从D盘读取.class文件进行替换;
我们来试下功能:)
修改Feature
public class Feature {
private String content;
public Feature(){
this.content = "hello kitty";
}
public void show() {
System.out.println(this.content);
}
}
将.class文件放在D:盘根目录 ,将premain.jar包也放在根目录
此时再将Feature改回来
public class Feature {
private String content;
public void show() {
System.out.println(this.content);
}
}
执行
public class Test {
public static void main(String[] args) throws Exception {
Function function = new Function();
function.show();
}
}
输出, 为 null
嗯是的,因为没加参数
设置runConfigration VMargument 为
-javaagent:D:/premain.jar
然后,再跑下?
输出,
stealing : Feature
start replacing
hello kitty
分享到:
相关推荐
动态加载jar包是一种在程序运行时按需引入外部库或者组件的技术,这使得应用程序更加灵活,可以适应不同的环境和需求。这种技术广泛应用于插件系统、框架开发以及服务升级等场景,因为它允许程序在不重启的情况下...
在Java编程语言中,动态加载jar包是一种常见的需求,它允许程序在运行时根据需要加载新的功能或更新现有的模块,增强了软件的灵活性和可扩展性。动态加载jar包技术主要涉及Java的反射机制、类加载器和插件系统。下面...
asm动态代理jar包,是java开发的好的工具类
在IT行业中,jar包是Java应用程序的标准打包格式,它包含了类文件、资源文件以及元数据。当多个jar包包含相同类名时,可能会引发版本冲突问题。为了应对这种问题,"jar包修改神器"应运而生。这个压缩包文件提供了...
Java开发者经常使用jar包来整合第三方库,因为它们包含了运行特定功能所需的全部代码和资源。这些jar包可能包括了数据库连接池、网络通信模块、加密算法、日志系统、JSON解析库等众多功能。巴巴运动的jar包很可能也...
在Java编程环境中,动态加载jar包是一项重要的技术,它允许我们无需重启服务器就能引入新的功能或更新已有的类。这在大型系统维护和迭代中尤为关键,因为它提高了系统的灵活性和可扩展性。以下是对"动态加载jar包的...
jar动态加载测试包,for Android开发系列之动态添加dex。
"动态树jar包"主要指的是Struts2-jquery-tree-plugin,这是一个专门用于在Struts2应用中创建和管理动态树形视图的插件。它允许用户以交互式的方式展示层次结构的数据,如目录结构、组织架构等,极大地提高了用户体验...
以下将详细阐述这三个框架及其基本的jar包需求。 1. **Struts2框架**: Struts2是基于MVC设计模式的Web应用框架,它极大地简化了Java Web应用程序的开发。其核心组件包括Action、Result和Interceptor。基本的jar包...
在Java编程中,动态加载JAR或ZIP包是一项重要的技术,它允许程序在运行时根据需求加载外部库,而不是在编译时静态地链接。这种技术对于实现插件化、模块化系统,或者处理频繁更新的组件非常有用。下面将详细讲解如何...
这个压缩包包含了POI项目中所有必要的jar包,总计十二个,确保了对Office文档全面的支持。这些jar包通常在开发需要读写Excel、Word或PowerPoint的Java应用时非常有用。 1. **Apache POI核心库**:`poi-ooxml-...
要使用Spring的AOP功能,我们需要引入特定的库,这正是标题中提到的"Spring使用AOP的三个jar包"。 首先,我们来看`aspectjrt.jar`。这个库是AspectJ运行时环境的一部分,包含了运行时织入(runtime weaving)所需的...
`taglibs-jar包`是一个包含了一系列预定义的JSP标签的库,这些标签可以简化网页的编写,提高代码的可读性和可维护性。在本篇文章中,我们将深入探讨`taglibs`及其在Java Web开发中的应用。 首先,我们需要理解什么...
可以使用Java内置的`JarFile`类来实现这一功能,也可以借助第三方工具,例如`jdgui_0.3.6`,它是一个可视化的反编译工具,能够帮助开发者查看`jar`包内的类文件源代码。 3. **加载**:在Java程序中,`ClassLoader`...
"S2SH需要的所有jar包"这个压缩包文件包含了这三个框架以及Java Web开发所需的其他相关库。下面将详细阐述SSH框架的主要组件及其相关的jar包,以及它们在开发中的作用。 1. Struts2:Struts2是一个基于MVC(Model-...
Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class文件,动态实现spring bean 的动态加载,并通过UrlClassLoader完成jar和class文件的加载。可以实现jar的热替换。spring的bean动态加载则需要对...
【标题】"Ireport的JAR包"是一个包含多个组件的集合,主要用于报表设计和开发。IReport是一款基于Java的开源报表工具,它允许开发者通过直观的用户界面创建复杂的SQL查询,设计美观的报表,并将其集成到Java应用程序...
在Java服务器页面(JSP)开发中,jar包扮演着至关重要的角色,它们是Java类库的集合,封装了大量的功能,使得开发者能够便捷地利用已有的功能模块进行开发,节省时间和资源。本合集主要针对JSP动态网站开发,同时也...
在使用Struts2进行开发之前,我们需要先将Struts2的jar包引入到项目中,这样才能利用其提供的API和服务。 Struts2的核心jar包通常包括以下几个部分: 1. **struts2-core.jar**:这是Struts2的核心库,包含了框架的...