Jar包class文件查增
针对已经打包好的jar,对里面的文件进行增删改查(现只修改class,其他文件同理)
准备一个要查看的Jar包,如“XXXX.jar”
一、查询
//原jar包地址
String jarPath = "XXXX.jar";
List<JarEntry> jarEntryList = JarTool.getJarEntryList(jarPath);
System.out.println("Jar包里的数据 : ");
//循环jarEntryList 获取
//获取方法
public static List<JarEntry> getJarEntryList(String jarPath) throws IOException {
File file = new File(jarPath);
JarFile jarFile = new JarFile(file);
//获取 entries 集合lists
List<JarEntry> lists = new LinkedList<>();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
lists.add(jarEntry);
}
// 将修改后的内容写入jar包中的指定文件
jarFile.close();
return lists;
}
二、新增
//原jar包地址
String jarPath = "XXXX.jar";
//原jar包数据
List<JarEntry> jarEntryList = JarTool.getJarEntryList(jarPath);
//新jar包地址
String jarNewPath =="test/XXXX.jar";
//获取新jar包的输出流
File file = new File(jarPath);
JarFile jarFile = new JarFile(file);
FileOutputStream fos = new FileOutputStream(jarNewPath, true);
JarOutputStream jos = new JarOutputStream(fos);
//准备新加入jar包的class文件
Map<String, byte[]> addClassMap = new HashMap<>();
通过javassist生成新的class文件
String classPath = "com.test.AddTest";
ClassPool pool = new ClassPool(true);
CtClass ctClass = pool.makeClass(classPath );
//省掉添加 属性 和 方法 的过程....
//把生成好的class放入addClassMap (注意: “.”变成“/”,再加上“.class”)
addClassMap .put(classPath .replaceAll("\\.", "/") + ".class", ctClass.toBytecode());
//输出生成新的jar包
JarTool.addNewClassToJar(jos, jarEntryList, jarFile, addClassMap );
jos.close();
fos.close();
//输出方法
public static void addNewClassToJar(JarOutputStream jos, List<JarEntry> lists, JarFile jarFile, Map<String, byte[]> newClass) {
try {
//先写原jar数据
for (JarEntry je : lists) {
//表示将该JarEntry写入jar文件中 也就是创建该文件夹和文件
jos.putNextEntry(new JarEntry(je));
jos.write(streamToByte(jarFile.getInputStream(je)));
}
//再写新添加的class数据
for (Map.Entry<String, byte[]> entry : newClass.entrySet()) {
jos.putNextEntry(new JarEntry(entry.getKey()));
jos.write(entry.getValue());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] streamToByte(InputStream inputStream) {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return outSteam.toByteArray();
}