class 增量发包改造为 jar 包方式发布
wxin55 2025-05-11 19:03 2 浏览 0 评论
大纲
- class 增量发包介绍
- 项目目录结构介绍
- jar 包方式发布落地方案
class 增量发包介绍
当前项目的迭代修复都是通过 class 增量包来发版本的
将改动的代码 class 增量打包,如下图
class 发包方式优点
- class 增量发布,增量包体积较小
- 出现问题时,可以本地打log编译后,临时替换对应 class,便于调试
- 可以方便的看出本地迭代包文件变动情况 (用户不太关心)
但是也存在一些问题,开发人员维护困难,主要体现在以下几个点
- 每次编译后需要开发人员根据变动记录,手动收集本次迭代变动 class,容易出现错漏
- 本地打包后,一个 class可能会生成 n 个 class 文件 (FileToolsUI$1.class,FileToolsUI$2.class); ( 在 idea 中是看不出来的,必须在目录下才能看到) 导致增量包经常出问题...
- 经常要维护一个稳定版本的全量基线包
- 由于是 class 增量升级,误打包或重构删除的类,客户那边依旧会冗余,不利于重构; (而当前项目代码臃肿,项目亟需重构 很多java文件代码量的比较大 3k,5k,7k代码; )
于是大家商量一下想改变升级包提供方式,通过提供全量可 jar 包升级
项目目录结构介绍
项目工程结构如下
KingDomFileToolCombine
java 源代码
resources 资源目录1
source 资源目录 2
doc 文档
lib 外部依赖 jar 包存放目录
由于早期项目没有使用构建工具,当初导入项目也是花了些时间;
具体可以查看 idea 导入并配置非标准maven工程
jar 包方式发布落地方案
改造后要求满足以下需求
- 当前项目 jar包形式发布
- 外部依赖单独存放在 lib目录下 (减少升级包体积)
- 配置文件单独存放在jar包的同级目录的bin目录下 (方便用户调整配置)
使用 maven 打 jar'包方案实现步骤如下
- 添加 pom.xml 使用 maven 管理依赖
- 使用 maven <systemPath>管理本地 jar 包
- 选择maven构建插件,打 jar 包
- 刷新 maven 依赖; (最好是手动删除 project structure中的依赖,然后刷新maven)
- mvn clean package 打 jar 包
- cd 到目录下 java -jar xxx.jar 启动应用
pom,xml 配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.szkingdom.filetool</groupId>
<artifactId>KingDomFileToolCombine</artifactId>
<version>V3.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>7</maven.compiler.source>
<maven.compiler.target>7</maven.compiler.target>
<!-- Java版本 -->
<java.version>1.7</java.version>
<!-- 通过${hutool.version}来使用 -->
<spring.version>3.2.2.RELEASE</spring.version>
</properties>
<dependencies>
<!-- 使用 maven <systemPath>管理本地 jar 包
项目依赖的外部jar 是放在/lib目录下 (有的jar存在多版本)
- 1 <scope>system</scope>
- 2 <systemPath>${project.basedir}/lib/dom4j-1.6.1.jar</systemPath>
- 3 实在不知道 groupId 的用了自定义值替换; 比如local
- 4 在maven-dependency-plugin 打包到 lib 目录时,会改变jar名称为 (artifactId-version.jar)
- 5 配置完成后重新刷新 maven 依赖 (idea 中建议先手动移除
project structure>modules>dependencies 中的依赖,刷新后maven会自动配置)
-->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
<!--system,类似provided,需要显式提供依赖的jar以后,Maven就不会在Repository中查找它-->
<scope>system</scope>
<systemPath>${project.basedir}/lib/dom4j-1.6.1.jar</systemPath>
</dependency>
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<!--
在maven-dependency-plugin 打包到 lib 目录时,会改变 jar 名称为 (artifactId-version.jar; )
将原 jar包数字拆分到 <version>;可以实现重新打包后名称不变 如: bcprov-jdk15-133.jar
-->
<version>133</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/bcprov-jdk15-133.jar</systemPath>
</dependency>
<dependency>
<!--实在不知道 groupId 的用了自定义值替换; 比如local-->
<groupId>local</groupId>
<artifactId>chinapnr</artifactId>
<!--实在不知道 version 的用了自定义值替换; 比如localversion;
在maven-dependency-plugin 打包到 lib 目录时,
会改变 jar 名称为 (artifactId-version.jar;如: chinapnr-localversion.jar )
需要配合 maven-jar-plugin <Class-Path>标签一起使用,
配置的 class-path jar名称为 chinapnr-localversion.jar
-->
<version>localversion</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/chinapnr.jar</systemPath>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/spring-beans-3.2.2.RELEASE.jar</systemPath>
</dependency>
</dependencies>
<build>
<!--构建后 jar 文件名称-->
<finalName>kingDomFileToolCombine</finalName>
<!--java 源代码所在目录 默认 src/main/java-->
<sourceDirectory>java</sourceDirectory>
<!--配置文件所在目录 默认 src/main/resources-->
<scriptSourceDirectory>source</scriptSourceDirectory>
<!--<!–构建目录 默认target–>-->
<directory>bin</directory>
<!--编译后class存放目录 默认target/classes-->
<outputDirectory>bin</outputDirectory>
<!--资源文件夹,可配置多个-->
<resources>
<resource>
<directory>resources</directory>
</resource>
<resource>
<directory>source</directory>
</resource>
</resources>
<!--插件打包-->
<plugins>
<!--在打包阶段将依赖的jar包导出到lib目录下-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<outputDirectory>out/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<!-- 生成MANIFEST.MF的设置 -->
<manifest>
<useUniqueVersions>false</useUniqueVersions>
<!-- jar启动入口类 -->
<mainClass>com.szkingdom.FileTools.UI.FileToolsSurface</mainClass>
<!-- 为依赖包添加路径, 这些路径会写在MANIFEST文件的Class-Path下 -->
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<!--将依赖.jar 写进MANIFEST.MF文件中的Class-Path-->
<Class-Path>lib/bcprov-jdk15-133.jar lib/cipher-localversion.jar</Class-Path>
</manifestEntries>
</archive>
<!-- 指定打包后 jar包的位置,设置为根目录下 /out -->
<outputDirectory>out</outputDirectory>
<excludes>
<exclude>*.jar</exclude> <!--排除打包后的 jar文件本身-->
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
打包启动 jar 后报错记录解决
mvn clean package 打包 后 cd 到 jar 所在目录 java -jar 启动程序
#### Error assembling JAR: A zip file cannot include itself
- 装配JAR错误:zip文件不能包含自身
```asp
<excludes>
<exclude>*.jar</exclude> <!--排除打包后的 jar文件本身-->
</excludes>
```
#### java -jar 运行程序报错, java.lang.NoClassDefFoundError
- java.lang.NoClassDefFoundError 找不到外部依赖的 jar
- 解决:
- 1 打包时插件配置 <Class-Path>
- 2 需要将 lib 目录放到 jar同级别目录
#### java -jar 运行程序报错, java.lang.Error: Properties init: Could not determine current working directory.
- 原因: 找不到当前所在目录; 每次重新 mvn clear package 时 ,旧的命令行窗口所在目录已经被清除了
- 解决: 重新 cd 到 jar 目录 运行 java -jar
代码改造,之前读取 classpath 下的配置,改造为从 jar 包外文件中读取
//编写配置文件加载工具类
public class ConfigFileUtil {
/**
* 文件分割路径 ,mac windows 适配
*/
public final static String PATH_SPLIT = File.separator;
private static String CONFIG_FILE_PATH;
static {
//System.out.println(" 相对于当前用户目录的相对路径 user.dir :" + System.getProperty("user.dir"));
//获取当前 jar 包路径 .....jar
String jarFilePath = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
System.out.println(" jar文件所在路径为 :" + jarFilePath);
try {
jarFilePath=URLDecoder.decode(jarFilePath, "utf-8");// 转化为utf-8编码,支持中文
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
File file = new File(jarFilePath);
CONFIG_FILE_PATH = file.getParent();
System.out.println(" 配置文件所在路径为 :" + CONFIG_FILE_PATH);
}
public static String getFileAbsolutePath(String underBinPath) {
String filePath = "";
if (underBinPath.startsWith("bin")) {
filePath = FileUtil.CONFIG_FILE_PATH + FileUtil.PATH_SPLIT + underBinPath;
} else {
filePath = FileUtil.CONFIG_FILE_PATH + FileUtil.PATH_SPLIT + "bin" + FileUtil.PATH_SPLIT + underBinPath;
}
System.out.println(" 配置文件所在绝对路径为 :" + filePath);
return filePath;
}
/**
* @param underBinPath 存放在 /src/main/resources/bin 下的相对路径
* @return
*/
public static FileInputStream getConfigFileInputStream(String underBinPath) {
FileInputStream is = null;
try {
String fileAbsolutePath = getFileAbsolutePath(underBinPath);
is = new FileInputStream(fileAbsolutePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return is;
}
public static FileOutputStream getConfigFileOutPutStream(String underBinPath) {
FileOutputStream os = null;
try {
String fileAbsolutePath = getFileAbsolutePath(underBinPath);
os = new FileOutputStream(fileAbsolutePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return os;
}
项目问题每天不重样,遇到问题解决问题, 调整升级方式为后续代码重构做铺垫
相关推荐
- Java框架 —— Spring简介
-
简介一般来说,Spring指的是SpringFramework,它提供了很多功能,例如:控制反转(IOC)、依赖注入(DI)、切面编程(AOP)、事务管理(TX)主要jar包org.sprin...
- Monkey自动化测试
-
Monkey1.通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常;2.Monkey主要用于Android的压力...
- 十年之重修SpringBoot启动&自动装载&Bean加载过程
-
总结Springboot的自动装载,完全是依赖Bean的自动注册,其中默认的规则,是把需要自动装载的bean全名称编辑在spring.factories(2.7之后的版本,还支持.imports文件)...
- 一些可以显著提高大型 Java 项目启动速度的尝试
-
我们线上的业务jar包基本上普遍比较庞大,动不动一个jar包上百M,启动时间在分钟级,拖慢了我们在故障时快速扩容的响应。于是做了一些分析,看看Java程序启动慢到底慢在哪里,如何去优化,...
- class 增量发包改造为 jar 包方式发布
-
大纲class增量发包介绍项目目录结构介绍jar包方式发布落地方案class增量发包介绍当前项目的迭代修复都是通过class增量包来发版本的将改动的代码class增量打包,如下图cla...
- Flink架构及其工作原理(很详细)
-
原文链接:https://www.cnblogs.com/code2one/p/10123112.html关键词:Flink架构、面试杀手锏!更多大数据架构、实战经验,欢迎关注【大数据与机器学习】,...
- 大促系统优化之应用启动速度优化实践
-
作者:京东零售宋维飞一、前言本文记录了在大促前针对SpringBoot应用启动速度过慢而采取的优化方案,主要介绍了如何定位启动速度慢的阻塞点,以及如何解决这些问题。希望可以帮助大家了解如何定位该类问...
- Maven工程如何使用非Maven仓库jar包
-
使用Maven之前,一直都是自己手工在网上搜索需要的jar包,然后添加到工程中。以这样的方式开发,工作了好多年,曾经以为以后也会一直这样下去。直到碰上Maven,用了第一次,就抛弃老方法了。Maven...
- 【推荐】一款开源免费、功能强大的短链接生成平台
-
项目介绍reduce是一款开源免费、功能强大的短链接生成平台。部署在服务器,使用短域名解析即可提供服务。CoodyFramework首秀,自写IOC、MVC、ORM、TASK、JSON、DB连接池、...
- K8S官方java客户端之七:patch操作
-
欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;...
- Java 的业务逻辑验证框架 之-fluent-validator
-
开发人员在维护核心业务逻辑的同时,还需要为输入做严格的校验。当输入不合法时,能够给caller一个明确的反馈,最常见的反馈就是返回封装了result的对象或者抛出exception。一些常见...
- 互联网大厂后端必看!手把手教你替换 Spring Boot 中的日志框架
-
在互联网大厂的后端开发工作中,SpringBoot框架是搭建项目的“得力助手”,使用十分普遍。但不少开发者都遇到过这样的困扰:SpringBoot默认集成的Logback日志框架,在实际...
- 测试经理教你如何用monkey进行压力测试!
-
一、monkey是什么1、monkey程序由android系统自带,使用Java语言写成,在Android文件系统中的存放路径是:/system/framework/monkey.jar2、Mo...
- Java-Maven详解
-
一、什么是Maven?ApacheMaven是一个软件项目管理的综合工具。基于项目对象模型(POM)的概念,提供了帮助管理构建、文档、报告、依赖、发布等方法,Maven简化和标准化项目建设过程。处理...
- SpringBoot打包部署最佳实践
-
springboot介绍SpringBoot目前流行的javaweb应用开发框架,相比传统的spring开发,springboot极大简化了配置,并且遵守约定优于配置的原则即使0配置也能正常运...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)