当前位置: 首页 > news >正文

java生产环境增量部署_老旧Java Web应用实现增量自动化部署的一个方案

如果你也有一个老旧的Java Web应用,因为各种原因,代码库中的代码是不完整的,所以每次上线只能增量部署,或者研发规范里就要求增量部署,在这种情况下如何实现自动化的编译和部署呢?下面给出一个可行的方案:

1、部署前,将需要部署的代码合并到deliver分支

2、比较deliver分支和master分支的差异,得到差异列表之后,用于后续的编译

3、编译差异文件时,需要将应用所依赖的jar,已经部署的class文件等加入到CLASSPATH

4、如果各测试环境也使用这一套自动部署的方案,可能还需要考虑剥离环境相关的配置到配置文件中,并根据环境分目录存放,具体可以参考maven的profile机制

核心代码(代码结构请自行优化 :D):

1、比较两个分支的差异(忽略whitespace带来的差异):

try (Git git = Git.open(gitRepoFile);

ByteArrayOutputStream out = new ByteArrayOutputStream();

DiffFormatter df = new DiffFormatter(out);) {

Repository repository = git.getRepository();

ObjectReader reader = repository.newObjectReader();

String branchName = repository.getBranch();

ObjectId masterId = repository.resolve("remotes/origin/master^{tree}");

ObjectId branchId = repository.resolve(branchName + "^{tree}");

CanonicalTreeParser masterTreeParser = new CanonicalTreeParser();

masterTreeParser.reset(reader, masterId);

CanonicalTreeParser branchTreeParser = new CanonicalTreeParser();

branchTreeParser.reset(reader, branchId);

List diffs = git.diff()

.setNewTree(branchTreeParser)

.setOldTree(masterTreeParser)

.call();

Map> diffFileMap = new HashMap<>();

List changeFileList = new ArrayList<>();

List deleteFileList = new ArrayList<>();

df.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);

df.setRepository(git.getRepository());

for (DiffEntry diffEntry : diffs) {

df.format(diffEntry);

FileHeader fileHeader = df.toFileHeader(diffEntry);

@SuppressWarnings("unchecked")

List hunks = (List) fileHeader.getHunks();

int changedSize = 0;

for (HunkHeader hunkHeader : hunks) {

EditList editList = hunkHeader.toEditList();

for (Edit edit : editList) {

changedSize += edit.getLengthA() + edit.getLengthB();

}

}

if (changedSize > 0) {

ChangeType changeType = diffEntry.getChangeType();

if (ChangeType.DELETE.equals(changeType)) {

String oldFilePath = diffEntry.getOldPath();

log.info("{}|{}", changeType.name(), oldFilePath);

deleteFileList.add(oldFilePath);

} else {

String newFilePath = diffEntry.getNewPath();

log.info("{}|{}", changeType.name(), newFilePath);

changeFileList.add(newFilePath);

}

}

}

diffFileMap.put("change", changeFileList);

diffFileMap.put("delete", deleteFileList);

return diffFileMap;

}

2、编译:

Iterable options = Arrays.asList(

"-classpath", classpath,

"-encoding", encoding,

"-source", jdkVersion,

"-target", jdkVersion,

"-d", targetPath);

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

log.info("classpath:{}", classpath);

log.info("targetPath:{}", targetPath);

try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);) {

Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(fileList);

DiagnosticCollector diagnostics = new DiagnosticCollector<>();

CompilationTask compilationTask = compiler

.getTask(null, fileManager, diagnostics, options, null, compilationUnits);

if (!compilationTask.call()) {

log.error("JavaCompiler Build failed:");

for (Diagnostic> diagnostic : diagnostics.getDiagnostics()) {

long line = diagnostic.getLineNumber();

String source = diagnostic.getSource() != null ? diagnostic.getSource().toString() : "";

String kind = diagnostic.getKind().name();

String message = diagnostic.getMessage(null);

log.info("{} on line:{} in {}.", kind, line, source);

log.info("message:{}", message);

}

return false;

}

}

要实现完整的功能,还需要根据应用的具体情况完善,比如:从运行环境同步删除代码库中删除的文件;从代码库拉取文件时,用fetch,reset的方式;还可以借助Marathon、Mesos、Docker运行应用等。

相关文章:

  • java中list去除成员_Java中List集合去除重复数据的六种方法
  • form-data php,php HTTP请求类(支持GET,POST,Multipart/form-data)
  • php页眉,如何在php中创建Word文档页眉/页脚
  • 程序员角度的锁--乐观锁、悲观锁
  • msf生成php,MSF-Shellcode生成和使用
  • 如何在首次启动 Linux 虚拟机时对其进行自定义
  • php 比nodejs 容易学,粗大事了:花两天时间学习了 Go 语言,发现比 Node.js 高不知多少去了...
  • php获取cname解析结果,如何检测来自CNAME子域的传入请求(使用PHP脚本)?
  • Ubuntu16.04系统中Nmon的安装
  • CentOS 7 网络磁盘挂载到本地 并测试传输速度
  • 数字图像处理灰度变换java,数字图像处理:图像的灰度变换(Matlab实现)
  • java math 最大,在Java.lang包的Math类中,求最大值的方法为(选一项)
  • 递推算法
  • java方法传递对象,java面向对象-3-方法参数传递
  • iOS 对UIAlertController内的输入框进行输入监听,实时改变确定、取消按钮颜色
  • [译]前端离线指南(上)
  • 【前端学习】-粗谈选择器
  • avalon2.2的VM生成过程
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • ComponentOne 2017 V2版本正式发布
  • EOS是什么
  • Java 网络编程(2):UDP 的使用
  • java2019面试题北京
  • PV统计优化设计
  • Sublime Text 2/3 绑定Eclipse快捷键
  • VuePress 静态网站生成
  • vue数据传递--我有特殊的实现技巧
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 回顾 Swift 多平台移植进度 #2
  • 聚类分析——Kmeans
  • 手写一个CommonJS打包工具(一)
  • 学习笔记:对象,原型和继承(1)
  •  一套莫尔斯电报听写、翻译系统
  • 以太坊客户端Geth命令参数详解
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 透过事物看本质的能力怎么培养?
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (39)STM32——FLASH闪存
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (六)激光线扫描-三维重建
  • (强烈推荐)移动端音视频从零到上手(下)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)linux下的时间函数使用
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .net(C#)中String.Format如何使用
  • .net解析传过来的xml_DOM4J解析XML文件
  • .NET命名规范和开发约定
  • .NET项目中存在多个web.config文件时的加载顺序
  • .sh 的运行
  • 。Net下Windows服务程序开发疑惑
  • //解决validator验证插件多个name相同只验证第一的问题
  • ??eclipse的安装配置问题!??