`
bewithme
  • 浏览: 422833 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

eclipse实现JavaWeb应用增量打包

阅读更多

       

        很多情况下,项目是不允许全量发布的,所以你得把有做修改的文件一个个挑出来,如果有成千上百的文件,你是不是要头大了? 以下方法应该可以让你得到解救!前提是你是用装有svn plugin的eclipse上做开发。

 

      第一步,用svn生成项目的补丁文件。

     

 

选中你需要增量升级的文件,点击完成。

 

       

   运行如下代码

 

package verysoft.freepath;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class FreePatchUtil {

	public static String patchFile="D:/patch.txt";//补丁文件,由eclipse svn plugin生成
	
	public static String projectPath="D:/workspace/FordClubJeeCms";//项目文件夹路径
	
	public static String webContent="WebContent";//web应用文件夹名
	
	public static String classPath="D:/workspace/FordClubJeeCms/build";//class存放路径
	
	public static String desPath="C:/Users/xuwen/Desktop/update_pkg";//补丁文件包存放路径
	
	public static String version="20140711";//补丁版本
	
	
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		copyFiles(getPatchFileList());
	}
	
	public static List<String> getPatchFileList() throws Exception{
		List<String> fileList=new ArrayList<String>();
		FileInputStream f = new FileInputStream(patchFile); 
		BufferedReader dr=new BufferedReader(new InputStreamReader(f,"utf-8"));
		String line;
		while((line=dr.readLine())!=null){ 
			if(line.indexOf("Index:")!=-1){
				line=line.replaceAll(" ","");
				line=line.substring(line.indexOf(":")+1,line.length());
				fileList.add(line);
			}
		} 
		return fileList;
	}
	
	public static void copyFiles(List<String> list){
		
		for(String fullFileName:list){
			if(fullFileName.indexOf("src/")!=-1){//对源文件目录下的文件处理
				String fileName=fullFileName.replace("src","");
				fullFileName=classPath+fileName;
				if(fileName.endsWith(".java")){
					fileName=fileName.replace(".java",".class");
					fullFileName=fullFileName.replace(".java",".class");
				}
				String tempDesPath=fileName.substring(0,fileName.lastIndexOf("/"));
				String desFilePathStr=desPath+"/"+version+"/WEB-INF/classes"+tempDesPath;
				String desFileNameStr=desPath+"/"+version+"/WEB-INF/classes"+fileName;
				File desFilePath=new File(desFilePathStr);
				if(!desFilePath.exists()){
					desFilePath.mkdirs();
				}
				copyFile(fullFileName, desFileNameStr);
				System.out.println(fullFileName+"复制完成");
			}else{//对普通目录的处理
				String desFileName=fullFileName.replaceAll(webContent,"");
				fullFileName=projectPath+"/"+fullFileName;//将要复制的文件全路径
				String fullDesFileNameStr=desPath+"/"+version+desFileName;
				String desFilePathStr=fullDesFileNameStr.substring(0,fullDesFileNameStr.lastIndexOf("/"));
				File desFilePath=new File(desFilePathStr);
				if(!desFilePath.exists()){
					desFilePath.mkdirs();
				}
				copyFile(fullFileName, fullDesFileNameStr);
				System.out.println(fullDesFileNameStr+"复制完成");
			}
			
		}
		
	}

	private static void copyFile(String sourceFileNameStr, String desFileNameStr) {
		File srcFile=new File(sourceFileNameStr);
		File desFile=new File(desFileNameStr);
		try {
			copyFile(srcFile, desFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

	
	
	public static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            // 新建文件输入流并对它进行缓冲
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));

            // 新建文件输出流并对它进行缓冲
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

            // 缓冲数组
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            // 刷新此缓冲的输出流
            outBuff.flush();
        } finally {
            // 关闭流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }
	
}

 

注意,以下部份请按照实际情况填写

 

	public static String patchFile="D:/patch.txt";//补丁文件,由eclipse svn plugin生成
	
	public static String projectPath="D:/workspace/FordClubJeeCms";
	
	public static String webContent="WebContent";//web应用文件夹名
	
	public static String classPath="D:/workspace/FordClubJeeCms/build";//class存放路径
	
	public static String desPath="C:/Users/xuwen/Desktop/update_pkg";//补丁文件包存放路径
	
	public static String version="20140711";//补丁版本

 

   好了,运行后得到结果

 

 

 如果有多个人都修改了代码,那么每个人在提交代码之前先按第一步生成补丁文件再提交。当所有人都提交代码后,在一台电脑上更新所有代码,再在这台电脑上用以上代码运行所有人生成的补丁文件即可。

 

有任何问题请联系qq 359709421

 

如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!
  • 大小: 170.5 KB
  • 大小: 149 KB
  • 大小: 76.3 KB
1
0
分享到:
评论
20 楼 xudada 2017-12-05  
楼主好,请问您是怎么实现增量编译的,
我看代码中58,59行直接替换后缀名,这是什么操作。
fileName=fileName.replace(".java",".class"); 
fullFileName=fullFileName.replace(".java",".class");
只改后缀名,这个。。。
19 楼 qitian422 2016-03-09  
这个好像没有考虑java编译内部类生成多个class文件的情况啊
18 楼 bewithme 2015-11-03  
maolincool99 写道
为什么有报错,找不到文件路径
ublic static String patchFile="D:/work/tips/patch.txt";//补丁文件,由eclipse svn plugin生成
   
    public static String projectPath="D:/work/Workspaces/cssdj_nszhdj";//项目文件夹路径
   
    public static String webContent="ROOT";//web应用文件夹名
   
    public static String classPath="D:/work/Workspaces/cssdj_nszhdj/WebRoot/WEB-INF/classes";//class存放路径
   
    public static String desPath="D:/work/tips/update_pkg";//补丁文件包存放路径
   
    public static String version="20150826";//补丁版本



是web应用文件夹名错误吗,我写的是tomcat里的web ContextRoot名啊,???????


不是tomcat ,是在项目中的web内容存放的文件夹啊,就是项目根目录
17 楼 maolincool99 2015-08-26  
为什么有报错,找不到文件路径
ublic static String patchFile="D:/work/tips/patch.txt";//补丁文件,由eclipse svn plugin生成
   
    public static String projectPath="D:/work/Workspaces/cssdj_nszhdj";//项目文件夹路径
   
    public static String webContent="ROOT";//web应用文件夹名
   
    public static String classPath="D:/work/Workspaces/cssdj_nszhdj/WebRoot/WEB-INF/classes";//class存放路径
   
    public static String desPath="D:/work/tips/update_pkg";//补丁文件包存放路径
   
    public static String version="20150826";//补丁版本



是web应用文件夹名错误吗,我写的是tomcat里的web ContextRoot名啊,???????
16 楼 sun_mingtao 2015-08-25  
可以考虑用updiff增量更新。
------------------------
updiff 是一个增量更新(升级)的工具,支持备份、更新、异常恢复功能。依据 Git 两个提交版本号提取差异文件进行更新操作。依赖maven、git并可以和jenkins无缝隙集成。http://git.oschina.net/soenter/updiff
15 楼 床上鬼见愁 2015-07-31  
非常感谢大神,这个技巧不仅能节省时间,而且还能避免由于繁琐的操作造成打包文件出错。再次感谢大神分享。
14 楼 bewithme 2015-03-11  
u013057721 写道
我有一个中文文件夹下面有一个jsp文件需要修改;但是生成补丁后,补丁文件里面出现乱码了;请问如何处理?

看看是不是本来就是乱码,这里只做了复制操作应该不会出现乱码
13 楼 u013057721 2015-03-07  
我有一个中文文件夹下面有一个jsp文件需要修改;但是生成补丁后,补丁文件里面出现乱码了;请问如何处理?
12 楼 bewithme 2014-07-17  
aaron198 写道
这个程序还是挺好用的

tks
11 楼 aaron198 2014-07-16  
这个程序还是挺好用的
10 楼 white_crucifix 2014-07-13  
bewithme 写道
white_crucifix 写道
楼主,我们这的老系统也都是增量更新,新系统特别是我们自己做的才会全量,毕竟自己清楚里面的内容。增量的做法也是比较常见和原始,把修改过的class文件和资源文件拷贝到服务器上,手动替换掉原先的。甚至还必要将原先的文件添加时间后缀保留在原处以防万一。当然拷贝的时候是基于目录结构的,这样覆盖的时候就能一定程度上简单一点。其实理论上存在从顶端覆盖就可以了,未被覆盖的文件不会被破坏。但真正操作的人没人敢这么做,虽是心理作用,但可以理解。

其实我有一种设想,当然并没有实践过。就是通过svn,维护线上系统的内容,注意不是java文件而是class文件,这样每次全量打包上去,通过svn diff就知道最终影响了哪些文件,同时作为老文件的备份也不用手动备份了,都受到svn的管理。


从理论上来讲你的想法是可行的,但实际上从安全角度来讲这样是不太合理的,如果你把一份包括了.svn文件的代码发上去,安全扫瞄会没办法通过的。


哦,还不是这个意思。比如本地打一个war包,里面是不含svn信息的。传到服务器后解压覆盖掉老版本的系统,这个叫全量更新。而由于服务器上系统的目录受svn管理,含有.svn信息,那么就能比较出你更新后到底变化了多少文件。
9 楼 edhn 2014-07-12  
SVN创建补丁,个人没用过,试验了一下是将未提交的文件和SVN最新文件做比对并生成报告。
系统发布补丁,都是要经过一段时间的修改吧,这期间每个参与开发者都要提交相当多次文件,要每次提交前都做创建补丁?
关于增量发布补丁,这个增量的概念也就是本次发布对比上次发布所增删改的文件内容吧,不用细化到每次svn提交,也就是最新全量发布包和已有发布包做对比即可。
我一般使用beyondcompare比对,文件不多就手动比对,文件多了也是可以自动化生成报告的,具体参照bc的帮助文档,还有脚本例子。
8 楼 bewithme 2014-07-12  
white_crucifix 写道
楼主,我们这的老系统也都是增量更新,新系统特别是我们自己做的才会全量,毕竟自己清楚里面的内容。增量的做法也是比较常见和原始,把修改过的class文件和资源文件拷贝到服务器上,手动替换掉原先的。甚至还必要将原先的文件添加时间后缀保留在原处以防万一。当然拷贝的时候是基于目录结构的,这样覆盖的时候就能一定程度上简单一点。其实理论上存在从顶端覆盖就可以了,未被覆盖的文件不会被破坏。但真正操作的人没人敢这么做,虽是心理作用,但可以理解。

其实我有一种设想,当然并没有实践过。就是通过svn,维护线上系统的内容,注意不是java文件而是class文件,这样每次全量打包上去,通过svn diff就知道最终影响了哪些文件,同时作为老文件的备份也不用手动备份了,都受到svn的管理。


从理论上来讲你的想法是可行的,但实际上从安全角度来讲这样是不太合理的,如果你把一份包括了.svn文件的代码发上去,安全扫瞄会没办法通过的。
7 楼 white_crucifix 2014-07-12  
楼主,我们这的老系统也都是增量更新,新系统特别是我们自己做的才会全量,毕竟自己清楚里面的内容。增量的做法也是比较常见和原始,把修改过的class文件和资源文件拷贝到服务器上,手动替换掉原先的。甚至还必要将原先的文件添加时间后缀保留在原处以防万一。当然拷贝的时候是基于目录结构的,这样覆盖的时候就能一定程度上简单一点。其实理论上存在从顶端覆盖就可以了,未被覆盖的文件不会被破坏。但真正操作的人没人敢这么做,虽是心理作用,但可以理解。

其实我有一种设想,当然并没有实践过。就是通过svn,维护线上系统的内容,注意不是java文件而是class文件,这样每次全量打包上去,通过svn diff就知道最终影响了哪些文件,同时作为老文件的备份也不用手动备份了,都受到svn的管理。
6 楼 white_crucifix 2014-07-12  
LinApex 写道
bewithme 写道
LinApex 写道
有这必要吗?


你没遇到过增量发布?还是你有比较好的办法?


第一种,全部打包,无论更改过什么东西,重新打一次包,缺点:体积较大

第二种,打补丁形式,核心是对比,对比上一次的文件有哪些进行了修改,然后对修改的文件进行打包,上传到服务器,打完手工



体积大永远不是全量打包时考虑的问题。上线系统不敢全量更新的原因是基于一个很丑陋的原因,就是怕有前人没将修改过的代码提交至svn而导致生产系统里那是唯一一份。。。。这是真事。
另外……楼主说的核心是对比完后将生产系统的对应文件自动化替换。这与怎么对比一点关系都没有吧。
5 楼 LinApex 2014-07-11  
bewithme 写道
LinApex 写道
bewithme 写道
LinApex 写道
有这必要吗?


你没遇到过增量发布?还是你有比较好的办法?


第一种,全部打包,无论更改过什么东西,重新打一次包,缺点:体积较大

第二种,打补丁形式,核心是对比,对比上一次的文件有哪些进行了修改,然后对修改的文件进行打包,上传到服务器,打完手工



很多生产环境是不允许全量升级的,所以你必须把全量包里的只对这次升级的文件取出来,而我这个方法就是实现这种自动取出升级文件。我不知道你的核心比对是用什么完成的。


看需求吧。全量升级,在本地测试环境过了之后,是可以上正式环境的。无非是改些配置文件。

如:classe 可以打一个包. 每次增量+1

对比很多种,常用的是文件大小,java 监控文件,svn检测等等等

4 楼 bewithme 2014-07-11  
LinApex 写道
bewithme 写道
LinApex 写道
有这必要吗?


你没遇到过增量发布?还是你有比较好的办法?


第一种,全部打包,无论更改过什么东西,重新打一次包,缺点:体积较大

第二种,打补丁形式,核心是对比,对比上一次的文件有哪些进行了修改,然后对修改的文件进行打包,上传到服务器,打完手工



很多生产环境是不允许全量升级的,所以你必须把全量包里的只对这次升级的文件取出来,而我这个方法就是实现这种自动取出升级文件。我不知道你的核心比对是用什么完成的。
3 楼 LinApex 2014-07-11  
bewithme 写道
LinApex 写道
有这必要吗?


你没遇到过增量发布?还是你有比较好的办法?


第一种,全部打包,无论更改过什么东西,重新打一次包,缺点:体积较大

第二种,打补丁形式,核心是对比,对比上一次的文件有哪些进行了修改,然后对修改的文件进行打包,上传到服务器,打完手工
2 楼 bewithme 2014-07-11  
LinApex 写道
有这必要吗?


你没遇到过增量发布?还是你有比较好的办法?
1 楼 LinApex 2014-07-11  
有这必要吗?

相关推荐

Global site tag (gtag.js) - Google Analytics