如何根据版本过滤掉 Java 方法?
How can I filter out Java methods according to version?
我需要生成三个不同版本的jar 库。 类 的某些方法标有注释,这些注释指定了添加它们时的版本。例如:
public class A {
@SinceVersion(2)
public int getTotal() {
// do something...
}
@SinceVersion(5)
public int getMax() {
// do something...
}
@SinceVersion(4)
public int getAverage() {
// do something...
}
}
然后:
当我生成my-library-2.jar
时,应该只包含getTotal()
。
当我生成my-library-4.jar
时,应该只包含getTotal()
和getAverage()
。
当我生成 my-library-5.jar
时,应该包括所有三种方法。
这是一个简化的例子。真正的问题跨越 300 类、10 个版本,每个版本有 6 个子版本。
为什么不使用源代码管理(git 等)来管理您的版本?当您使用 v2.0 标记发布时,到那时为止的代码将只有 getTotal()。然后 v4.0 来了一个 long,到那个点的代码会有 getTotal() 和 getAverage() 等等。
每个版本都可以独立管理和构建,并为该特定版本生成特定的 jar 文件。
然后您的客户端将包括它需要的任何版本的 jar。
您可能想研究实现注释处理器。
注释处理器 运行 在编译期间用于创建 and/or 操作代码,我用它们来创建样板代码,以及手动维护起来很乏味的代码,但是结构清晰。
我想 post 我找到的解决方案以防对其他人有帮助。
经过一周的研究,我终于找到了Apache Commons BCEL。该库允许您检查和修改 JVM 中加载的 class;修改后,它可以作为 .class 文件写入文件系统。
像这样的一段代码会生成一个新的 class 文件 没有 一些方法:
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.AnnotationEntry;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
JavaClass clazz = Repository.lookupClass("test.House");
ClassGen cg = new ClassGen(clazz);
Method m = findMethod(clazz, "close");
AnnotationEntry ae = m.getAnnotationEntries(); // process annotations here...
cg.removeMethod(m); // remove the method you want to remove
JavaClass modifiedClazz = cg.getJavaClass();
modifiedClazz.dump("./gen/test/House.class"); // save to a new file
通过遍历 classes 的整棵树(或子包树),可以找到所有受影响的 classes,处理它们的方法,如果注释值符合某些条件则删除它们.
我需要生成三个不同版本的jar 库。 类 的某些方法标有注释,这些注释指定了添加它们时的版本。例如:
public class A {
@SinceVersion(2)
public int getTotal() {
// do something...
}
@SinceVersion(5)
public int getMax() {
// do something...
}
@SinceVersion(4)
public int getAverage() {
// do something...
}
}
然后:
当我生成
my-library-2.jar
时,应该只包含getTotal()
。当我生成
my-library-4.jar
时,应该只包含getTotal()
和getAverage()
。当我生成
my-library-5.jar
时,应该包括所有三种方法。
这是一个简化的例子。真正的问题跨越 300 类、10 个版本,每个版本有 6 个子版本。
为什么不使用源代码管理(git 等)来管理您的版本?当您使用 v2.0 标记发布时,到那时为止的代码将只有 getTotal()。然后 v4.0 来了一个 long,到那个点的代码会有 getTotal() 和 getAverage() 等等。
每个版本都可以独立管理和构建,并为该特定版本生成特定的 jar 文件。
然后您的客户端将包括它需要的任何版本的 jar。
您可能想研究实现注释处理器。
注释处理器 运行 在编译期间用于创建 and/or 操作代码,我用它们来创建样板代码,以及手动维护起来很乏味的代码,但是结构清晰。
我想 post 我找到的解决方案以防对其他人有帮助。
经过一周的研究,我终于找到了Apache Commons BCEL。该库允许您检查和修改 JVM 中加载的 class;修改后,它可以作为 .class 文件写入文件系统。
像这样的一段代码会生成一个新的 class 文件 没有 一些方法:
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.AnnotationEntry;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
JavaClass clazz = Repository.lookupClass("test.House");
ClassGen cg = new ClassGen(clazz);
Method m = findMethod(clazz, "close");
AnnotationEntry ae = m.getAnnotationEntries(); // process annotations here...
cg.removeMethod(m); // remove the method you want to remove
JavaClass modifiedClazz = cg.getJavaClass();
modifiedClazz.dump("./gen/test/House.class"); // save to a new file
通过遍历 classes 的整棵树(或子包树),可以找到所有受影响的 classes,处理它们的方法,如果注释值符合某些条件则删除它们.