`
gaoyuntao2005
  • 浏览: 312370 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

---JarCleaner工具

阅读更多

java的jar是一个很不错的技术。可是现在开源的发展,使得一个项目中会用到很多很多的jar文件(我们的一个项目中,刚开始lib目录下有超过100兆的jar文件),一直怀疑有些文件是用不到的,但是又不太确定哪些是有用的,哪些是没用的。

想了想,决定还是做个小工具,一劳永逸地解决这个问题吧。

此小工具能完成如下功能:

1、将原来lib路径的所有jar备份到lib\bak目录下;

2、删除不用的jar

那怎么判断哪些是没用的呢?

这里用到了java -verbose:class,这个命令会将所有加载class的过程打印出来,如果是jar中的class, 还会指明是从哪个jar中加载的。

因此,通过在tomcat或者其他应用服务器的启动脚本中,添加-verbose:class,然后运行,即可获得加载信息。将其复制到一个log文件中,作为参数传递给JarCleaner即可。

  1.  
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.FileReader;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.util.HashSet;
  11. import java.util.Set;
  12. /**
  13.  * 
  14.  * JarCleaner is an utility class to remove all un-referenced jar under the webapp\lib path.<br/>
  15.  * Before run this class, you need have two informations prepared. <br/>
  16.  * 1. The webapp lib path, such as: c:\tomcat\webapps\demo\WEB-INF\lib <br/>
  17.  * 2. The log file, which is generated by console, when adding "-verbose:class" argument <br/>
  18.  * in the end of the java command which is used to start the server. 
  19.  * 
  20.  * 
  21.  * @author Leo Liu
  22.  * <a href="http://www.smilingleo.cn">Homepage</a>
  23.  *
  24.  */
  25. public class JarCleaner {
  26.     
  27.     public Set<String> getNecessaryJarSet(String appLibPath , String logFile){
  28.         
  29.         String pattern = "\\[Loaded.*[\\/].*\\.jar\\]";     
  30.         Set<String> jarSet = new HashSet<String>();
  31.         
  32.         BufferedReader br = null;
  33.         try {
  34.             br = new BufferedReader(new FileReader(new File(logFile)));
  35.         } catch (FileNotFoundException ee) {
  36.             System.out.println("Can't find the log file." + ee.getMessage());
  37.         }
  38.         
  39.         String aLine = "";
  40.  
  41.         while(true){
  42.             
  43.             try {
  44.                 aLine = br.readLine();
  45.             } catch (IOException e) {
  46.                 System.out.println("End of log file.");
  47.             }
  48.             
  49.             if (aLine == nullbreak;
  50.             
  51.             if (aLine.matches(pattern)){
  52.                 String[] strs = aLine.split("from");
  53.                 if (strs.length <= 0continue;
  54.                 String jarName = strs[strs.length - 1].trim();
  55.                 if (jarName.startsWith("file")){
  56.                     jarName = jarName.substring(6);
  57.                 }
  58.                 jarName = jarName.substring(0, jarName.length() - 1);
  59.                 if (jarName.indexOf("/") > 0){                  
  60.                     jarName = jarName.replaceAll("[/]""\\\\");
  61.                 }
  62.                 // Only filter the jars in the web app path.
  63.                 if (jarName.startsWith(appLibPath)){                    
  64.                     if (!jarSet.contains(jarName))
  65.                         jarSet.add(jarName);                
  66.                 }
  67.             }
  68.         }
  69.         return jarSet;
  70.     }
  71.  
  72.     public Set<String> backupOriginalJars(String appLibPath){
  73.         File libPath = new File(appLibPath);
  74.         File[] jars = libPath.listFiles();
  75.         Set<String> jarSet = new HashSet<String>();
  76.  
  77.         File bakPath = new File(appLibPath + "\\bak");
  78.         if (!bakPath.exists())
  79.             bakPath.mkdir();
  80.         
  81.         for (File jar : jars){
  82.             String jarName = jar.getAbsolutePath();
  83.             jarName.replaceAll("[/]""\\\\");
  84.             jarSet.add(jarName);
  85.             // Backup the file to bak path
  86.             File newJar = new File(appLibPath + "\\bak\\" + jar.getName());
  87.             copyFile(newJar, jar);
  88.         }
  89.         
  90.         return jarSet;
  91.     }
  92.     
  93.     public void cleanJars(Set<String> allJars, Set<String> jarSet){
  94.         allJars.removeAll(jarSet);
  95.         
  96.         for (String jarName : allJars){
  97.             File oldJar = new File(jarName);
  98.             oldJar.delete();
  99.         }
  100.         
  101.     }
  102.     
  103.     private void copyFile(File targetFile, File file) {
  104.         if (targetFile.exists()) {
  105.             System.out.println("File:" + targetFile.getAbsolutePath()
  106.                     + " already existed, skip that file!");
  107.             return;
  108.         } else {
  109.             createFile(targetFile, true);
  110.         }
  111.         System.out.println("copied " + file.getAbsolutePath() + " to "
  112.                 + targetFile.getAbsolutePath());
  113.         try {
  114.             InputStream is = new FileInputStream(file);
  115.             FileOutputStream fos = new FileOutputStream(targetFile);
  116.             byte[] buffer = new byte[1024];
  117.             while (is.read(buffer) != -1) {
  118.                 fos.write(buffer);
  119.             }
  120.             is.close();
  121.             fos.close();
  122.         } catch (FileNotFoundException e) {
  123.             e.printStackTrace();
  124.         } catch (IOException e) {
  125.             e.printStackTrace();
  126.         }
  127.     }
  128.  
  129.     private void createFile(File file, boolean isFile) {
  130.         if (!file.exists()) {
  131.             if (!file.getParentFile().exists()) {
  132.                 createFile(file.getParentFile(), false);
  133.             } else {
  134.                 if (isFile) {
  135.                     try {
  136.                         file.createNewFile();
  137.                     } catch (IOException e) {
  138.                         e.printStackTrace();
  139.                     }
  140.                 } else {
  141.                     file.mkdir();
  142.                 }
  143.             }
  144.         }
  145.     }
  146.     
  147.     
  148.     /**
  149.      * @param args
  150.      */
  151.     public static void main(String[] args) throws Exception{
  152.         if (args.length != 2){
  153.             System.out.println("Usage : java JarCleaner <webapp lib path> <class verbose log file>\n" +
  154.                     "This command will backup all jar files in your specified webapp lib path,\n" +
  155.                     "and remain the necessary jars only.\n" + 
  156.                     "  <webapp lib path>    : the full path of your web application located.\n" +
  157.                     "  <class verbose file> : the full path of your log file. \n" +
  158.                     "                         use:java -verbose:class to get the log content.\n\n" + 
  159.                     "Note: You must shut down the server before run this command.");
  160.             System.exit(-1);
  161.         }
  162.         String appLibPath = args[0].trim();
  163.         String logFile = args[1].trim();
  164.         
  165.         JarCleaner cleaner = new JarCleaner();
  166.         // Get the referenced jars.
  167.         Set<String> jarSet = cleaner.getNecessaryJarSet(appLibPath, logFile);
  168.         
  169.         // Get all jars in web app lib path.
  170.         Set<String> allJars = cleaner.backupOriginalJars(appLibPath);
  171.         
  172.         // Remove all non-referenced jar files.
  173.         cleaner.cleanJars(allJars, jarSet);
  174.     }
  175.  
  176. }
  177.  
分享到:
评论

相关推荐

    YOLO算法-城市电杆数据集-496张图像带标签-电杆.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    (177406840)JAVA图书管理系统毕业设计(源代码+论文).rar

    JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代码+论文) JAVA图书管理系统毕业设计(源代

    (35734838)信号与系统实验一实验报告

    内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    YOLO算法-椅子检测故障数据集-300张图像带标签.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    基于小程序的新冠抗原自测平台小程序源代码(java+小程序+mysql+LW).zip

    系统可以提供信息显示和相应服务,其管理新冠抗原自测平台小程序信息,查看新冠抗原自测平台小程序信息,管理新冠抗原自测平台小程序。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7 小程序开发工具:hbuildx/微信开发者工具

    YOLO算法-俯视视角草原绵羊检测数据集-4133张图像带标签-羊.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    (171674830)PYQT5+openCV项目实战:微循环仪图片、视频记录和人工对比软件源码

    内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    新建 文本文档.docx

    新建 文本文档.docx

    hw06.zip

    hw06

    3. Kafka入门-安装与基本命令

    3. Kafka入门-安装与基本命令

    燃气管道施工资质和特种设备安装改造维修委托函.docx

    燃气管道施工资质和特种设备安装改造维修委托函.docx

    The state of AI 2024.pdf

    AI大模型研究相关报告

    lab02.zip

    lab02

    Unity视频插件AVPro的Win端2.2.3

    仅供学习使用,其他用途请购买正版资源AVPro Video Core Windows Edition 2.2.3 亲测可用的视频播放插件,能丝滑播放透明视频等.

    建设工程消防验收现场指导意见表.docx

    建设工程消防验收现场指导意见表.docx

    MVIMG_20241222_194113.jpg

    MVIMG_20241222_194113.jpg

    五相电机双闭环矢量控制模型-采用邻近四矢量SVPWM-MATLAB-Simulink仿真模型包括: (1)原理说明文档(重要):包括扇区判断、矢量作用时间计算、矢量作用顺序及切时间计算、PWM波的生成

    五相电机双闭环矢量控制模型_采用邻近四矢量SVPWM_MATLAB_Simulink仿真模型包括: (1)原理说明文档(重要):包括扇区判断、矢量作用时间计算、矢量作用顺序及切时间计算、PWM波的生成; (2)输出部分仿真波形及仿真说明文档; (3)完整版仿真模型:包括邻近四矢量SVPWM模型和完整双闭环矢量控制Simulink模型; 资料介绍过程十分详细,零基础手把手教学,资料已经写的很清楚

    YOLO算法-锡罐-牙罐-盖子打开数据集-179张图像带标签-锡罐-牙罐-盖子打开.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    java毕设项目之ssm基于JSP的乡镇自来水收费系统+jsp(完整前后端+说明文档+mysql+lw).zip

    项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7

Global site tag (gtag.js) - Google Analytics