网站首页 > java教程 正文
大纲
- 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;
}
项目问题每天不重样,遇到问题解决问题, 调整升级方式为后续代码重构做铺垫
猜你喜欢
- 2025-06-19 草率了,又一个Maven打包的问题(maven shade打包)
- 2025-06-19 SpringBoot 项目打包命令 详细配置说明
- 2025-06-19 jenkins本地安装打包以及远程打包
- 2025-06-19 程序员你的maven多模块项目如何对外输出为一个构件?
- 2025-06-19 Java语言的智能名片系统源码,二次开发流程
- 2025-06-19 基于 mybatis generator生成 Mybatis文件图形化工具
- 2025-06-19 Android apk 打包流程(androidkiller打包apk)
- 2025-06-19 最全!最强大!Maven知识大全(maven详细教程)
- 2025-06-19 SpringBoot打包部署成Windows服务
- 2025-06-19 大数据Hadoop之——Kafka Streams原理介绍与简单应用示例
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)