【Java】使用javaassist修改jar包

简介: 由于工作需要,可能会涉及到一些需要对第三方的一些jar包与源码进行修改的情况,这个时候javaassist就可以派上用场。 javaassist是一个开源的编辑、修改、创建字节码的类库,它在JBoos项目的AOP框架中发挥了很大的作用。不过我们这次仅仅使用它的修改class的功能。 1 准备工具 1.1 需要用到的工具 1.javaassist.jar 修改class字节码,修改类

由于工作需要,可能会涉及到一些需要对第三方的一些jar包与源码进行修改的情况,这个时候javaassist就可以派上用场。

javaassist是一个开源的编辑、修改、创建字节码的类库,它在JBoos项目的AOP框架中发挥了很大的作用。不过我们这次仅仅使用它的修改class的功能。

1 准备工具

1.1 需要用到的工具

1.javaassist.jar 修改class字节码,修改类的结构,也可以将修改结果导出新的class文件,使用的时候需要作为lib导入到工程中  下载地址:javaassist

2.jd-gui 查看class和jar文件里的java代码  windows版下载  mac版下载  jd-gui下载官网


1.2 测试用的jar包

TestJar.jar

内部结构:


1.3 环境

jdk1.6 1.7 1.8 均可

任何编辑器均可,本人使用的是IntelliJ

1.4 工程源码

为了方便使用,首先给出当前工程的源码: TestJavaAssist

2 修改源码

2.1 使用JavaAssist

javaassist的使用需要先将javaassist.jar导入到工程中,之后就可以直接在工程里使用里面的方法了。下面给出用javaassist修改外部jar包中TestJar类的方法,并用反射测试了一下输出结果,最后将修改好的类输出到外部文件夹


// 修改方法
    public static void changeMethode() {
        try {
            ///////////////////////////////////
            //  使用javaassist修改 class/jar 代码
            ///////////////////////////////////
            //  设置jar包路径
            ClassPool.getDefault().insertClassPath("../JarDemo/out/production/JarDemo/TestJar.jar");

            // 获取需要修改的类
            CtClass testJarClass = ClassPool.getDefault().getCtClass("TestJar");
            // 获取类中的printTest方法
            CtMethod printTestMethod = testJarClass.getDeclaredMethod("printTest");
            // 修改该方法的内容
            printTestMethod.setBody("System.out.println(\"hello obo\");");




            ///////////////////////////////////
            //  使用反射测试输出,查看修改结果
            ///////////////////////////////////
            Class newTestJarClass = testJarClass.toClass();
            // 使用修改过的类创建对象
            Object newTestJar = newTestJarClass.newInstance();
            Method newPrintTestMethod = newTestJarClass.getDeclaredMethod("printTest");
            newPrintTestMethod.invoke(newTestJar);

            // 解除代码锁定,恢复可编辑状态
            testJarClass.defrost();
            // 写出到外存中
            testJarClass.writeFile();
            // testJarClass.writeFile(other path);

        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (CannotCompileException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
如果没有问题的话,将会在外部文件生成一个新的TestJar.class 文件,用jd-gui 查看该class可以看到里面的printTest方法已经被修改了


2.2 重新打包

使用jdk自带的打包工具jar可以将class文件重新打包成jar文件

其给出了一些使用例子如下:

示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中: 

       jar cvf classes.jar Foo.class Bar.class 

示例 2: 使用现有的清单文件 'mymanifest' 并

           将 foo/ 目录中的所有文件归档到 'classes.jar' 中: 

       jar cvfm classes.jar mymanifest -C foo/ .


所以,我们在使用的时候需要使用terminal进入到class所在到文件目录,使用命令:

jar cvf NewTestJar.jar TestJar.class
在当前目录下打包生成NewTestJar.jar文件。

该文件就是修改后的jar包,使用jd-gui打开查看可以看到源码已经被修改。




林深
+关注
目录
打赏
0
0
0
0
6
分享
相关文章
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
78 17
Java打包jar运行时分离lib和jar
在`pom.xml`的`build`节点中,设置`packaging`为`jar`,并配置插件分离依赖库到`lib`目录和资源文件到`resources`目录。这样可以在运行时通过`-Dloader.path=lib,resources`加载外部依赖和资源文件,便于独立升级依赖库和修改资源文件,而无需重新打包程序。具体插件包括`maven-dependency-plugin`、`maven-resources-plugin`和`spring-boot-maven-plugin`等。
100 1
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
4月前
|
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
在Java项目中,启动jar包时遇到“no main manifest attribute”错误,且打包大小明显偏小。常见原因包括:1) Maven配置中跳过主程序打包;2) 缺少Manifest文件或Main-Class属性。解决方案如下:
1269 8
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
|
5月前
|
Eclipse 创建 Java 包
Eclipse 创建 Java 包
74 1
Kettle的Java开发环境需要什么jar包?
【10月更文挑战第24天】Kettle的Java开发环境需要什么jar包?
240 2
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
368 0
Java/Spring项目的包开头为什么是com?
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
619 4
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
378 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等