对于Java程序员来说,工作中经常会遇到这样一些问题,比如引用了些第三方提供的非开源jar包,这个时候我们需要用它,甚至需要改它的内容。怎么办?下面看看开发中会遇到哪些问题?
- 某个类的里面的字段默认值不符合需求要改掉.
- 某个方法里面有很多校验,想直接return ;绕过校验。
- 某个方法里面的计算方法太复杂,想用自己的计算方式。替换方法体。
- 首先声明一点,如果是收费的,切勿参加商业性质。
往往这个时候我们就会很棘手,因为确实不好操作,不好处理。现在我给大家介绍两种方式,解决一些比较常见且简单的问题。
1、反编译class文件,推荐Java Decompiler
这个工具几乎能正确的反编译出源代码。如果反编译出的源码,没有出现很明显的错误。或者说很难修改的错误时。通常这个时候我们直接修改该类已达到我们的需求就可以了,把修改后的class文件覆盖jar里的class文件,即可。
不过,有时候第三方提供的jar里面,某些类写的特别复杂,反编译后一堆错误,真的没法修改。这个时候可以试试第二种方法。
2、利用工具直接修改class字节码,推荐Javassist
先给大家介绍一下Javassist,Javassist是一个开源的分析、编辑和创建Java字节码的类库,它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。
关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
1、我们可以用Javassist实现什么。
- 添加修改父类
- 添加修改方法
- 添加修改字段
- 创建类
2、准备工作
2.1首先下载Javassist,jar文件
2.2获得ClassPool对象,他控制者class字节码的修改。
ClassPool pool = ClassPool.getDefault();
2.3.如果你准备修改的class文件在某个路径或者jar文件里或者网络的某个路径。需要设置路径
1
2
3
4
5
6
7
|
pool.insertClassPath( "E:\\test" );或者提供一个jar文件
pool.insertClassPath( "E:\\test.jar" );或者提供一个网络路径
ClassPath cp = new URLClassPath( "www.javassist.org" , 80 , "/java/" , "org.javassist." );
pool.insertClassPath(cp);或者直接提供 byte 字节码
byte [] b = a byte array;
String name = class name;
pool.insertClassPath( new ByteArrayClassPath(name, b));
|
2.4.下面我们就要处理class文件了,每个class文件对应一个CtClass对象,而CtClass是从对象ClassPool对象里得到。需要完整的包名+类名,不需要.class
1
|
CtClass cc = pool.get( "com.my.TestMain" );
|
2.5.完整代码
1
2
3
4
|
ClassPool pool = ClassPool.getDefault(); //pool.insertClassPath("E:\\test.jar");
pool.insertClassPath( "E:\\test" );
CtClass cc = pool.get( "com.my.TestMain" );
|
3、添加修改父类
3.1.添加接口
cc.setInterfaces(new CtClass[] { pool.get("com.my.TestMain2") });
3.2.添加抽象类
1
2
|
cc.setSuperclass(pool.get( "com.my.TestMain1" ));
cc.writeFile(); |
如果父类已经存在就用现在的类替换了。
4、添加修改方法
4.1.添加新的方法
1
2
3
4
|
CtClass cc = pool.get( "sample.TestMain" );
CtMethod cm = CtNewMethod.make( "public void toInt(int i){i++;}" , cc);
cc.addMethod(cm); cc.writeFile() |
4.2.修改方法
1
2
3
|
CtClass cc = pool.get( "sample.TestMain" );
CtMethod cm = cc.getDeclaredMethod( "toInt" , new CtClass[]{ CtClass.intType });
cc.writeFile(); |
getDeclaredMethod的第一个参数是方法名,第二个参数是方法的参数。
获得方法对象后,以下三种方法是最常用的。
- cm.setBody("");重新设置方法体
- cm.insertBefore("");在原来方法的最前面插入代码
- cm.insertAfter("");在原来方法的后面插入代码
4.3.删除方法
1
|
cc.removeMethod() |
5.添加修改字段
5.1.添加字段
1
2
3
4
5
|
//方式1 CtClass cc = pool.get( "sample.TestMain" );
CtField f = new CtField(CtClass.intType, "t1" , cc);
cc.addField(f, "2" ); // initial value is 0.
cc.writeFile(); |
//方式2
1
2
3
4
|
CtClass cc = pool.get( "sample.TestMain " );
CtField f = CtField.make( "public int z = 0;" , point);
cc.addField(f); cc.writeFile(); |
5.2.修改字段,方法里没有提供直接修改,我们需要删删除在修改
1
2
3
4
5
|
CtClass cc = pool.get( "sample.TestMain" );
CtField f = cc.getDeclaredField( "t" );
cc.removeField(f); cc.addField(CtField.make( "public int t=3;" , cc));
cc.writeFile(); |
6.创建新类
1
2
3
|
ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass( "Point" );
cc.writeFile(); |
7.Import
1
2
3
4
|
ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass( "sample.TestMain" );
pool.importPackage( "java.awt" );
cc.writeFile(); |
jar包在附件中
相关推荐
Java字节码编辑器是一种工具,它允许开发者直接编辑Java程序编译后的`.class`文件,而不是反编译后再重新编译。这种编辑器对于理解、调试和优化Java代码非常有用,尤其是对于那些无法访问源代码或者需要进行底层操作...
Java字节码反编译是Java开发者在进行代码分析、逆向工程或学习类库源码时常用的一种技术。它允许我们将已经编译过的.class文件转换回可读性更强的.java源代码文件,以便理解程序的运行逻辑。在这个过程中,我们通常...
在本篇讨论中,我们将专注于如何使用BCEL(Byte Code Engineering Library)这个工具来动态地设计和修改Java字节码。 BCEL是Apache软件基金会下的一个开源项目,它提供了一系列API,用于分析、创建和修改Java字节码...
**Recaf:现代Java字节码编辑器** 在Java开发领域,字节码编辑器是一种不可或缺的工具,...在实际使用中,配合其提供的文档和社区资源,开发者可以更深入地掌握Java字节码操作的技巧,提升开发效率和解决问题的能力。
综上所述,学习Java字节码不仅能够帮助我们理解JVM的工作机制,还能够提升我们的编程技巧和解决复杂问题的能力。在这个项目中,你将有机会亲手实践,从实践中深化对Java字节码的理解。通过分析和修改字节码,你将...
Java字节码技术是Java平台的核心组成部分,它与Java虚拟机(JVM)紧密相连,为各种编程语言在Java平台上提供了可移植性和高效执行的基础。本篇将详细讲解Java字节码的概念、用途以及JVM如何执行字节码。 首先,让...
CGlib库利用ASM库(一个底层的Java字节码操作和分析框架)来生成和修改字节码。通过这种方式,开发者可以在程序运行时动态地创建新的类或修改现有类的行为,而无需重新编译源代码。 **动态代理** CGlib常用于实现...
总的来说,Java字节码的深入研究能够使开发者具备更高级别的编程能力,能够解决复杂的技术难题,优化程序性能,并且更好地应对各种运行时问题。而通过阅读《通过Java字节码发现有趣的内幕之初始化篇(下)》这份资料...
**JByteMod-Beta:Java字节码编辑器** JByteMod-Beta是一款强大的Java字节码编辑器,专为开发者设计,旨在提供一个高效、...通过掌握这个工具,开发者能更深入地理解Java字节码,从而提升编程技能和解决问题的能力。
它们可以帮助开发者查看类文件的结构,理解字节码指令的含义,甚至修改字节码以实现调试、优化或逆向工程的目的。 5. **字节码优化**: 通过理解字节码,开发者可以进行针对性的优化,比如减少对象创建、优化循环...
Dalvik字节码是一种专门为Android设计的中间语言,它是基于Java字节码的,但进行了优化以适应移动设备的资源限制。每个Android应用都包含一个或多个.dex(Dalvik Executable)文件,这些文件包含了编译后的Dalvik...
基于Java字节码的方法可以提供一种有效的方式来解决这些问题。 1. **动态字节码注入**:在运行时修改字节码,可以实现对特定功能的快速测试。例如,通过AOP(面向切面编程)框架如AspectJ,可以在不改变原有代码的...
Java字节码灰盒动态漏洞检测是一种针对Java应用程序的安全测试技术,它结合了白盒测试和...通过深入理解Java字节码和Java Agent机制,开发人员和安全专家可以构建更强大的安全解决方案,及时发现并修复潜在的安全威胁。
总之,JByteMod是一款强大且易用的Java字节码编辑器,它集成了语法高亮和实时反编译等功能,为开发者提供了一个直观的平台来探索和修改Java字节码,从而提升开发和调试的效率。对于想要深入理解JVM工作原理或者进行...
Bytecoder 提供了一个详尽的Java字节码的富领域模型,允许开发者以一种高级且易于理解的方式创建和修改字节码。这种模型简化了字节码的操作,避免了直接与复杂的ASM库或JVMTI接口打交道,使得开发者可以更专注于...
`java修改class文件`这个主题涵盖了如何操作和理解Java字节码,以便对二进制类文件进行更改。在这个过程中,`jclasslib bytecode viewer`是一个非常重要的工具,它允许开发者可视化并分析Java字节码。 首先,我们要...
Java字节码工程工具包,通常被称为Javassist,是一个强大的开源项目,它为Java开发者提供了在运行时操作和分析类以及字节码的能力。这个工具包被广泛应用于动态代理、AOP(面向切面编程)、代码生成以及单元测试等...
与Java字节码不同,Dalvik字节码是专门为Android设计的,它在设备上被即时编译(JIT)或提前编译(AOT),如ART(Android RunTime)环境,以提高执行效率。 在Android系统中,修改运行时内存中的Dalvik字节码通常...