按源包

时间:2016-07-13 21:43:41

标签: java spring maven bytecode java-bytecode-asm

我有一个包含5个类的jar文件。我只想改变那门课程中的一个逻辑。

BaseClass是我需要解决的问题。请检查以下基础结构。 我只需删除一行并在changeMe方法中添加3行。

班级结构

package com.temp;

public class BaseClass{
    public interface IClassA{ String sayRaw(String raw); }
    private BaseClass(){}
    protected static class ClassToFix extends ClassParent {
         @Override public void changeMe ()  {
                ........
         }
    }
}


//---------Source from jar file--------------
package com.temp;

public class ClassA implements IClassA{
    public static final BaseClass.IClassA ABC = ....;
    String sayRaw(String raw){
    } 

}

我尝试了什么

  1. 该类没有公共构造函数,因此扩展了类选项。
  2. 我尝试了来自bytebuddy的方法拦截器,发生了同样的问题。
  3. 最后我尝试了javaassist。它也不起作用,因为它没有在jar文件中更新方法定义。
  4. 我在src目录中创建了相同的包并复制了类定义并添加了我的修复。此修复程序适用于动态Web项目,但不适用于Maven Java项目。它表示链接错误

      

    ClassA是BaseClass的接口(IClassA)的实现   是经过修改的来源。

         

    java.lang.LinkageError:加载器约束违规:解析时   字段“ABC”类加载器(实例)   组织/ springframework的的/ boot / devtools /重启/类加载器/ RestartClassLoader)   引用类,com / temp / ClassA和类加载器   (字段的sun / misc / Launcher $ AppClassLoader的实例)   已解析的类型,com / temp / BaseClass $ IClassA,具有不同的类   该类型的对象

    建议我是否有其他方法可以解决此问题。

2 个答案:

答案 0 :(得分:0)

您无法在运行时创建在编译时不允许创建的类。 JVM在加载之前验证任何类,并且将禁止您尝试的内容。

使用Byte Buddy或Javassist,您可以定义一个可以在启动时添加的所谓Java代理。这样做,您可以在首次加载时重新定义ClassToFix

Byte Buddy包含AgentBuilder抽象,这使得这很容易实现。你可以找到tutorials on how to implement an agent online。 Javassist不提供定义Java代理的机制,但它允许您在创建自己的ClassFileTransformer时重新定义类。

答案 1 :(得分:0)

你试过方面吗? Aspect为任何非final类的对象创建代理(但我不确定它是否适用于私有构造函数)并允许您拦截任何方法的请求。所以你可以编写自定义逻辑。