一,先到自己打包好的jar包目录下执行命令行:java -jar -verbose:class>getClass.txt snake.jar
二,分析getClass.txt文件内容
三,执行代码如下代码
四,得到结果
五,看到我们已经成功复制了,现在进行打包,执行命令:jar -cvf rt.jar -C rt/ .
打包好以后,把jdk中的rt,jar和charsets.jar换成我们自己弄的这个就好,最后贴个代码吧!
JarFileDecompression.java
package cn.simple.jre;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JarFileDecompression {
/**
* 解压jar文件到指定目录
* @param jarFilePath jar文件的绝对路径,例如:D:/test/rt.jar
* @param decompressionJarPath 存放目录的绝对路径,例如:D:/myrt/
*/
public JarFileDecompression(String jarFilePath, String decompressionJarPath) {
JarFile jarFile=null;
File saveDir = new File(decompressionJarPath);
if(saveDir.isDirectory()) {
saveDir.mkdirs();
}
InputStream is = null;
FileOutputStream fos = null;
try {
jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> jarItems = jarFile.entries();
while(jarItems.hasMoreElements()) {
JarEntry jarItem = jarItems.nextElement();
// 判断是否是文件夹
if(!jarItem.isDirectory()) {
int index = jarItem.getName().lastIndexOf("/");
String dir ="";
if(index > 0) {
dir = jarItem.getName().substring(0, index);
}
new File(decompressionJarPath+dir).mkdirs();
File newFile = new File(decompressionJarPath+jarItem.getName());
if(!newFile.exists()) {
newFile.createNewFile();
}
is = jarFile.getInputStream(jarItem);
fos = new FileOutputStream(newFile);
byte[] b = new byte[1];
int len;
while((len=is.read(b)) != -1) {
fos.write(b, 0, len);
}
}
System.out.println("解压文件:"+jarItem.getName()+" 完成!");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != fos) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != jarFile) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
GetNeedFile.java
package cn.simple.jre;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GetNeedFile {
/**
* 得到所需class文件
* @param filterClassPath filterClass.txt文件的绝对路径,例如:D:/test/filterClass.txt
* @param decompressionJarPath jar文件解压的绝对路径,例如:D:/myjar/
* @param copyedFileDir 复制文件存放的绝对路径,例:D:/myrt/
*/
public GetNeedFile(String filterClassPath,String decompressionJarPath
, String copyedFileDir) {
FileInputStream fis=null;
BufferedReader br=null;
try {
fis = new FileInputStream(filterClassPath);
br = new BufferedReader(new InputStreamReader(fis));
String textLine;
String dirName ="";
List<String> allText = new ArrayList<String>();
while((textLine=br.readLine()) != null) {
allText.add(textLine);
}
Iterator<String> getJar = allText.iterator();
// 先将需要的jar文件解压
while(getJar.hasNext()) {
textLine = getJar.next();
if(textLine.endsWith(".jar")) {
int lastindex=textLine.lastIndexOf(".");
int firstindex=textLine.lastIndexOf("\\");
// 获取jar包名,如rt.jar的rt/
dirName = textLine.substring(firstindex, lastindex)+"/";
// 解压jar文件
new JarFileDecompression(textLine,decompressionJarPath+dirName);
System.out.println(dirName+"解压完成!");
}
}
// 再将需要的class文件复制
Iterator<String> getClass = allText.iterator();
while(getClass.hasNext()) {
textLine = getClass.next();
if(textLine.endsWith(".class")) {
new CopyFile(decompressionJarPath+textLine
, copyedFileDir+textLine);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FilterFile.java
package cn.simple.jre;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
public class FilterFile {
/**
* getClass.txt文件过滤器,将需要的所有文件全路径写到filterClass.txt文件中
* 将getClass.txt文件中的内容进行解析,获取其相关类的绝对路径
*
* @param filterFilePath getClass.txt文件的绝对路径,例如:C:/dir/getClass.txt
* @param findSavePath filterClass.txt存放路径,例如:C:/sava/
* @param yourPackagePath 自己包名的前缀,例如我的:cn/snake/
* 当然,也可以只写cn因为jdk中没有cn开头的包,这里只是为了区分自己的包和jdk中的包
*/
public FilterFile(String filterFilePath, String findSavePath, String yourPackagePath) {
// 读取progress.txt内容的流
FileInputStream fis = null;
BufferedReader br = null;
// 写入finaPath.txt内容的流
try {
fis = new FileInputStream(filterFilePath);
br = new BufferedReader(new InputStreamReader(fis));
String lineText;
while ((lineText = br.readLine()) != null) {
// 去除开头的"["和尾部的"]"字符
lineText = lineText.substring(1, lineText.length() - 1);
// 第一个空格
int index_first = lineText.indexOf(' ');
// 判断开头内容是什么
if (lineText.startsWith("Opened")) {
// 获取分开以后的绝对路径
String jarPath = lineText.substring(index_first + 1, lineText.length());
// 创建文件
if (!(new File(findSavePath).exists())) {
new File(findSavePath).mkdirs();
}
File saveFile = new File(findSavePath + "filterClass.txt");
if (!saveFile.exists()) {
saveFile.createNewFile();
}
writeText(saveFile, jarPath);
} else if (lineText.startsWith("Loaded")) {
// 获取第一个空格以后的内容
String packageAllText = lineText.substring(index_first + 1, lineText.length());
// 如果不是以.jar结尾的,那不是我们寻找的包
if (packageAllText.endsWith(".jar")) {
// 获取其属于哪个jar文件
int start = packageAllText.lastIndexOf("\\");
int end = packageAllText.lastIndexOf(".");
String rootDir = packageAllText.substring(start + 1, end) + "/";
// 获取第二个空格
int index_second = packageAllText.indexOf(' ');
// 获取包名
String packageText = rootDir + packageAllText.substring(0, index_second);
// 将包名转换成路径名
String packageFilePath = packageText.replace('.', '/') + ".class";
// 排除自己的jar包
if (!(packageFilePath.startsWith(yourPackagePath))) {
// 创建保存路径
if (!(new File(findSavePath).exists())) {
new File(findSavePath).mkdirs();
}
// 创建文件
File saveFile = new File(findSavePath + "filterClass.txt");
if (!saveFile.exists()) {
saveFile.createNewFile();
}
// 写内容
writeText(saveFile, packageFilePath);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 将得到的packagePath写入文件
*
* @param saveFile findPath.txt文件
* @param packageFilePath 要增加的内容
*/
private void writeText(File saveFile, String packageFilePath) {
FileOutputStream fos = null;
BufferedWriter bw = null;
FileInputStream fis = null;
BufferedReader br = null;
try {
fis = new FileInputStream(saveFile);
br = new BufferedReader(new InputStreamReader(fis));
// 装原来文件内容的容器
List<String> oldText = new ArrayList<String>();
// 读取内容不包括换行符
String text;
while ((text = br.readLine()) != null) {
oldText.add(text);
}
br.close();
fis.close();
fos = new FileOutputStream(saveFile);
bw = new BufferedWriter(new OutputStreamWriter(fos));
if (oldText.isEmpty()) {
bw.write(packageFilePath + "\n");
} else {
for (int i = 0; i < oldText.size(); i++) {
bw.write(oldText.get(i) + "\n");
}
bw.write(packageFilePath + "\n");
}
System.out.println("完成文件:" + packageFilePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != bw) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
CopyFile
package cn.simple.jre;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
/**
* 复制文件
* @param uncopyFile 要复制的文件绝对路径,例如:C:/test/t.txt
* @param copyedFilePath 复制文件存放的绝对路径,例如:C:/ss/fds.txt
*/
public CopyFile(String uncopyFile,String copyedFilePath) {
File copyFile = new File(copyedFilePath);
FileInputStream inFile =null;
FileOutputStream outFile =null;
try {
int index = copyedFilePath.lastIndexOf("/");
if(index > 0) {
String dirPath = copyedFilePath.substring(0, index);
if(!(new File(dirPath).isDirectory())){
new File(dirPath).mkdirs();
if(!copyFile.exists()) {
copyFile.createNewFile();
}
}
inFile = new FileInputStream(uncopyFile);
outFile = new FileOutputStream(copyFile);
byte[] b=new byte[1];
int len;
while((len=inFile.read(b)) != -1){
outFile.write(b,0,len);
}
System.out.println("复制文件:"+copyedFilePath+" 成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
if(null != outFile) {
try {
outFile.flush();
outFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != inFile) {
try {
inFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
start.java
package cn.simple.jre;
public class start {
public static void main(String[] args) {
// 先过滤掉getClass.txt文件,得到所有需要的filterClass.txt
new FilterFile("D://MyTest/getClass.txt", "D://MyTest/", "cn/snake/");
// 再获取
new GetNeedFile("D://MyTest/filterClass.txt"
, "D://MyTest/DecomJarFile/", "D://MyTest/NeedAllFile/");
}
}