java本地增量打包工具
在打增量包每次都需要将class文件、jsp文件等拷贝到增量包中比较麻烦。所以就写了一个增量打包工具。
工作原理:根据文件的最后修改时间来打增量。
1、查找Java类增量:根据eclipse工程下的.classpath文件中配置的javasrc目录,来查找修改的java文件,然后将其class文件拷贝到增量目录下。
2、查找jsp文件、配置文件,可以自定义配置。
下面为代码:
XmlReadUtil
package com.aspire.bdc.common.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
/**
* This class is used to parse an xml configuration file and return specified value.
*/
public final class XmlReadUtil {
private static final String KEY_CONNECTOR = ".";
private static final String DATA_FILE_NAME = System.getProperty("user.dir") + "/.classpath";
private static final Logger LOGGER = Logger.getLogger(XmlReadUtil.class);
private static XmlReadUtil instance;
private XMLConfiguration xmlConfig;
private XmlReadUtil() {
try {
xmlConfig = new XMLConfiguration(DATA_FILE_NAME);
} catch (ConfigurationException e) {
LOGGER.error(e);
throw new RuntimeException(e);
}
}
public static XmlReadUtil getInstance() {
if (instance == null) {
instance = new XmlReadUtil();
}
return instance;
}
@SuppressWarnings("rawtypes")
public List<String> getClasspathEntry() {
List lstSrc = xmlConfig.getList("classpathentry[@kind]");
List listPath = xmlConfig.getList("classpathentry[@path]");
List<String> listResult = new ArrayList<String>();
if (listPath != null && !listPath.isEmpty()) {
for (int i = 0; i < listPath.size(); i++) {
if (lstSrc.get(i).equals("src")) {
listResult.add(System.getProperty("user.dir") + File.separator + listPath.get(i));
}
}
}
return listResult;
}
}
IncremenPublish.java
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
/**
* 增量打包工具类
*
*
@author lipeng
*
@since 1.0
* @version 2014-8-19 lipeng
*/
public class IncremenPublish {
private static final Logger logger=Logger.getLogger(IncremenPublish.class);
private List<String> javaPath;
private Date lastDate;
private String classPath;
private String webPath;
private String configPath;
private String dbScriptPath;
private static final String tempFileDir = "D:\\patch";
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
/**
* 构造函数
*
* @param lastDate
* @param webDirName 存放web应用的目录名称,比如说webapps、webContent等
*/
public IncremenPublish(String hour, String webPath, String configPath, String dbScriptPath) {
this.javaPath = XmlReadUtil.getInstance().getClasspathEntry();
this.lastDate = parseDate(hour);
classPath = IncremenPublish.class.getClass().getResource("/").getPath();
classPath = classPath.substring(1, classPath.length() - 1);
if (StringUtils.isNotBlank(webPath)) {
this.webPath = webPath;
} else {
this.webPath = classPath.replace("WEB-INF/classes", "");
}
if (StringUtils.isNotBlank(configPath)) {
this.configPath = configPath;
} else {
this.configPath = System.getProperty("user.dir") + File.separator + "config";
}
if (StringUtils.isNotBlank(dbScriptPath)) {
this.dbScriptPath = dbScriptPath;
} else {
this.configPath = System.getProperty("user.dir") + File.separator + "db_script";
}
}
/**
* 获取增量文件
*
* @Date 2013-11-9
* @author lipeng
*/
public void getIncremenPublishClassFile() {
System.out.println("######################## patch start#####################");
try {
File tempFile = new File(tempFileDir);
FileUtils.deleteDirectory(tempFile);
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(tempFileDir);
if (!file.exists()) {
file.mkdirs();
}
// 获取class增量
System.out.println("**********start class increment**********");
for (String path : javaPath) {
moveIncremenFile(path, "classes", new String(path));
}
System.out.println("**********start jsp increment**********");
moveIncremenFile(webPath, null, webPath);
System.out.println("**********start config increment*********");
moveIncremenFile(configPath, null, configPath);
System.out.println("**********start jsp increment**********");
moveIncremenFile(dbScriptPath, null, dbScriptPath);
System.out.println("######################## patch end #####################");
}
/**
* 获取增量文件
*/
public boolean moveIncremenFile(String javaPath, String dirName, String srcPath) {
try {
File file = new File(javaPath);
if(!file.exists()) return false;
if (!file.isDirectory()&&!file.getAbsolutePath().contains("vssver2")) {
Date fileDate = new Date(file.lastModified());
if (fileDate.getTime() > lastDate.getTime()) {
copyFile(srcPath, file, dirName);
}
} else if (file.isDirectory() && !file.getAbsolutePath().contains("svn")
&& !file.getAbsolutePath().endsWith("WEB-INF")) {
String[] filelist = file.list();
for (int i = 0; i < filelist.length; i++) {
File readfile = new File(javaPath + File.separator + filelist[i]);
if (!readfile.isDirectory()&&!file.getAbsolutePath().contains("vssver2")) {
Date fileDate = new Date(readfile.lastModified());
if (fileDate.getTime() > lastDate.getTime()) {
copyFile(srcPath, readfile, dirName);
}
} else if (readfile.isDirectory()) {
moveIncremenFile(javaPath + File.separator + filelist[i], dirName, srcPath);
}
}
}
} catch (Exception e) {
System.out.println("获取增量文件 Exception:" + e.getMessage());
}
return true;
}
public static void main(String[] args) {
String hour = null;
String webpath = null;
String configPath = null;
String dbScriptPath = null;
if (args.length > 0) {
hour = args[0];
System.out.println("hout:" + hour + "小时");
}
if (args.length > 1) {
webpath = args[1];
System.out.println("webPath:" + webpath);
}
if (args.length > 2) {
configPath = args[2];
System.out.println("configPath:" + configPath);
}
if (args.length > 1) {
dbScriptPath = args[3];
System.out.println("dbScriptPath:" + dbScriptPath);
}
IncremenPublish publish = new IncremenPublish(hour, webpath, configPath, dbScriptPath);
publish.getIncremenPublishClassFile();
}
/**
* parseDate
*
* @Date 2013-11-12
* @author lipeng
* @param strDate
* @return
*/
public static Date parseDate(String hour) {
Date date = null;
if (StringUtils.isBlank(hour) || !hour.matches("[1-9]*")) {
try {
date = format.parse(format.format(new Date()));
} catch (Exception e) {
e.printStackTrace();
}
} else {
date = new Date(new Date().getTime() - 3600 * Integer.parseInt(hour));
}
return date;
}
/**
* 移动增量文件
*
* @Date 2013-11-12
* @author lipeng
* @param file
* @param dirName
*/
private void copyFile(String srcPath, File file, String dirName) {
if (dirName == null) {
copyJspFile(file);
} else {
copyClassFile(srcPath, file, dirName);
}
}
/**
* 迁移class文件
*
* @Date 2013-11-12
* @author lipeng
* @param file
* @param dirName
*/
private void copyClassFile(String srcPath, File file, String dirName) {
File tempJava = new File(srcPath);
String path1 = file.getPath().replace(tempJava.getAbsolutePath(), classPath).replace("java", "class");
File tempFile = new File(path1);
String path2 = path1.replace(classPath, tempFileDir + File.separator + dirName);
File tempFile1 = new File(path2);
tempFile1.getParentFile().mkdirs();
try {
FileUtils.copyFile(tempFile, tempFile1);
} catch (Exception e) {
System.out.println("拷贝class文件出错");
}
logger.info("path=" + path2);
System.out.println("path=" + path2);
}
/**
* 迁移jsp文件
*
* @Date 2013-11-12
* @author lipeng
* @param file
*/
private void copyJspFile(File file) {
String path = file.getPath().replace(System.getProperty("user.dir"), tempFileDir);
File tempFile = new File(path);
tempFile.getParentFile().mkdirs();
try {
FileUtils.copyFile(file, tempFile);
} catch (Exception e) {
System.out.println("拷贝jsp文件出错");
}
System.out.println("path=" + path);
}
}
ant脚本
<?xml version="1.0" encoding="UTF-8"?>
<project name="anttest" basedir="." default="run.test">
<!-- 定义一个属性 classes -->
<property name="classes" value="func_unit_web/uspc/WEB-INF/classes">
</property>
<property name="lib" value="func_unit_web/uspc/WEB-INF/lib">
</property>
<target name="init">
<path id="ant.run.lib.path">
<pathelement path="${classes}" />
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</path>
</target>
<target name="run.test" id="run">
<!--指明要调用的java类的名称 -->
<java classname="com.aspire.bdc.common.utils.IncremenPublish" fork="true" failonerror="true">
<!--指明要调用的java类的class路径 -->
<classpath refid="ant.run.lib.path"></classpath>
<!--时间间隔,如果是3小时,则扫描时只扫描3小时内修改的文件,不配置则扫描当天修改的文件 -->
<arg value="" />
<!--webpath -->
<arg value=""/>
<!--configpath -->
<arg value=""/>
<!--dbscriptpath -->
<arg value=""/>
</java>
</target>
</project>
java本地增量打包工具的更多相关文章
- java的jar打包工具的使用
java的jar打包工具的使用 java的jar是一个打包工具,用于将我们编译后的class文件打包起来,这里面主要是举一个例子用来说明这个工具的使用. 在C盘下的temp文件夹下面: ...
- iOS 本地自动打包工具
1.为什么要自动打包工具? 每修改一个问题,测试都让你打包一个上传fir , 你要clean -> 编译打包 -> 上传fir -> 通知测试.而且打包速度好慢,太浪费时间了.如果有 ...
- 增量打包DOC版
压缩zip的命令有的系统没有的自己去下载一个,否则关闭压缩zip的命令. 有需要的自行更改,这是满足我需求的. 执行 publish.bat 即可,当然需要将文件清单写好放在 resources.tx ...
- Java 14 令人期待的 5 大新特性,打包工具终于要来了
随着新的 Java 发布生命周期的到来,新版本预计将于 2020 年 3 月发布,本文将对其中的 5 个主要特性作些概述. Java 13刚刚发布给开发人员使用不久,最新版本的JDK于2019年9月发 ...
- Java&Android反编工具打包
Java&Android反编工具: 1.Eclipse反编插件:安装到Eclipse后,可以简要的查看jar包中的*.class; 2.DoAPK:反编*.apk为smali和一些资源文件,可 ...
- Android自动打包工具aapt详解
概念 在Android.mk中有LOCAL_AAPT_FLAGS配置项,在gradle中也有aaptOptions,那么aapt到底是干什么的呢? aapt即Android Asset Packagi ...
- 产品打包工具的制作,ant,编译源码,打jar包,打tag,打war包,备份release版本等
1. 在进行打包工具的制作前,需要准备的软件有: svnant-1.3.1 作用是让ant和svn相关联 apache-ant-1.9.7 需要设置ant_home,path,我的配置是: ANT_ ...
- 一个灵活的AssetBundle打包工具
尼尔:机械纪元 上周介绍了Unity项目中的资源配置,今天和大家分享一个AssetBundle打包工具.相信从事Unity开发或多或少都了解过AssetBundle,但简单的接口以及众多的细碎问题 ...
- atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结
atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结 1. 为什么虚拟机语言容易被反编译 1 2. 源码泄露的问题问题 1 3. Excelsior JET 1 4. gcj.的流 ...
- Java并发包同步工具之Exchanger
前言 承接上文Java并发包同步工具之Phaser,讲述了同步工具Phaser之后,搬家博客到博客园了,接着未完成的Java并发包源码探索,接下来是Java并发包提供的最后一个同步工具Exchange ...
随机推荐
- 记录用C#写折半查找算法实现
折半查找算法 前言 最近要考试了,重新回顾一下之前学的算法,今天是折半查找,它的平均比较次数是Log2 n 思想 给定一个有序数组A[0..n-1],和查找值K,返回K在A中的下标. 折半查找需要指定 ...
- Java高效率查询Mysql节点树数据
示例 目前有一个功能:任务计划管理,必然存在多级子任务的父子级关系,每个任务还会存在其它数据的关联表. mysql无法一次性递归查出想要的数据结构,想必很多人都会是通过根目录递归查询数据库的方式查出树 ...
- Spring(XML方式)简单入门
环境准备 maven jdk Spring Eclipse 项目创建 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0 ...
- redis基本数据结构-字符串
reids字符串数据结构相关命令 序号 命令 命令实例 意义 1 set key value set bar 1 设置key为bar的值为"1" 2 incr k ...
- 扬州万方:基于申威平台的 Curve 块存储在高性能和超融合场景下的实践
背景 扬州万方科技股份有限公司主要从事通信.计算机和服务器.智能车辆.基础软件等产品的科研生产,是国家高新技术企业.专精特新小巨人企业.国家火炬计划承担单位. 业务介绍 申威处理器是在国家" ...
- oeasy 教您玩转linux 010304 图形界面 xfce
我们来回顾一下 上一部分我们都讲了什么? 讲了文件管理器和命令行终端互相交互 用命令nautilus在文件管理器打开某路径 这次我们来看看 图形用户界面(GUI)的情况 图形界面和发行版的关系 一个发 ...
- 用ssh同时push 项目到github和gitee的方法
分别为两个网站声称pubkey cd ./ssh ssh-keygen -t rsa -C "oeasy@oeasy.org" -f "github_id_rsa&q ...
- Linux 文本文件编辑相关命令简介【Linux 常用命令系列二】
〇.前言 本文介绍了如何通过 vim 命令,对文本文件进行打开.编辑.保存等相关操作,并通过简单的示例演示了常用用法. 一.关于文本文件的操作 1.1 打开,查看(cat).编辑(vim) 打开文本文 ...
- 服务端渲染中的数据获取:结合 useRequestHeaders 与 useFetch
title: 服务端渲染中的数据获取:结合 useRequestHeaders 与 useFetch date: 2024/7/24 updated: 2024/7/24 author: cmdrag ...
- 逆向动态加载Dex(内存加载class)
逆向一个app, 其核心算法是通过反射调用的, 反编译软件中无法找到该类, 并且也无法hook. Java.perform(function(){ Java.enumerateClassLoaders ...