maven项目打包全面解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: maven项目打包全面解析

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

1 前言

由于要对敏感数据加密,之前做了一个加密工具 要整个平台使用,所以将加密代码项目打成了jar包。很简单,但是也遇到了一些问题,下面分享将项目打包及打包中遇到的问题和经验

2 实现

1) 项目打包

idea项目打包很简单,只需要执行 mvn clean mvn install就可以了,也可以手动执行

image.png

执行后查看下打包后文件

image.png

打包成功!

2)项目依赖问题

打包成功只是开始,其实jar包还要注意一些问题,因为jar包是要被很多项目所引入的,jar包项目中本身也会引入一些依赖,如果不注意,就会导致项目中依赖混乱,最后很可能到只依赖冲突,在实际的开发中,大部分开发都会遇到依赖冲突的情况,而且比较难定位,这个和maven的依赖管理息息相关,所以在我们打jar包时就要考虑到,一定要做好maven依赖的管理。

<dependencies>
  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

我的项目很简单,只引入了slf4j-api,而我对他的作用于描述是provided,provided的作用是,当其他项目引入我的jar包时,slf4j-api不会传递给其他项目,因为他是私有的,这样就是防止了依赖的乱用。

但是思考了一下,这里是存在问题的,provided之所以不会传递给其他引入jar包的项目是因为打包时没有将他修饰的依赖打包进去,这样一定要要求,引入这个依赖的项目本身就有这个provided修饰的依赖,比如servlet api,因为tomcat本身有这个提供这个依赖,所以可以声明为provided。

provided属于maven修饰作用域中的其中一个,我们看看maven作用域的介绍

compile (编译范围)
compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。

provided (已提供范围)
provided 依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译
classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。

runtime (运行时范围)
runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。

test (测试范围)
test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。

system (系统范围)
system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用赖)。

回到我的打包jar项目,最终我进行的依赖时

<dependencies>
  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
  </dependency>
</dependencies>

这样可能会造成依赖传递,不过maven提供了另外一种方式,防止依赖的滥用

        <groupId>groupId</groupId> 
        <artifactId>artifactId</artifactId> 
        <version>version</version>
        <exclusions> 
            <exclusion> 
                <groupId>*</groupId> 
                <artifactId>*</artifactId> 
            </exclusion>
        </exclusions> 
    </dependency>

这种形式就可以排除掉所引用依赖中所引用的其他依赖,也就防止了依赖冲突发生的可能性,对于我这次的依赖而言,是一个日志依赖,比较简单,所以没有使用这种形式,但是对于一些较多依赖的项目,使用这种形式我认为还是不错的

3) 配置文件读取问题

功能需要首先读取配置文件,使用静态代码块赋值静态属性,在本地测试的时候读取文件是没有问题的,将项目打包成jar包后,却发现可以读取到配置文件,但是配置文件里面却读取不到内容

static {
    AESConfig.readConfigFile();
}
public static void readConfigFile() {
    ResourceBundle resourceBundle = ResourceBundle.getBundle(AES_UTILS);
    key = resourceBundle.getString(DST_AES_KEY);

经过排查发现是因为打包之后,代码读取的配置文件读取成了同名的引入改jar包项目的配置文件,导致读取不到配置,存在一个规则,项目会有限读取项目本身的资源文件再读取jar中的配置文件

查看了一下读取配置文件的源码,ClassLoader中的getResource方法,类似于loadClass进行双亲委派,也是先找父类加载器,只不过这个算资源文件加载器吧,双亲委派防止子类覆盖父类,这个对资源的加载处理估计也是处理覆盖问题

public URL getResource(String name) {
    URL url;
    if (parent != null) {
        url = parent.getResource(name);
    } else {
        url = getBootstrapResource(name);
    }
    if (url == null) {
        url = findResource(name);
    }
    return url;
}

设定maven项目版本号,打包项目发布到远程场库,这样一个jar包项目就完成了。

image.png

3 结语

有时候很简单的东西里面也蕴含了很多的小问题,而这些小技术都是非常基础的技术能力,比如maven的作用域,maven的依赖管理,这些都是非常微小的且在我们日常开发中经常能过看到的,资源文件的读取也是很简单的,但是是如何读的却是很复杂的,关注每一个微小的技术,也是一个不小的进步吧

相关文章
|
5天前
|
Java Maven
2022最新版超详细的Maven下载配置教程、IDEA中集成maven(包含图解过程)、以及导入项目时jar包下载不成功的问题解决
这篇文章是一份关于Maven的安装和配置指南,包括下载、环境变量设置、配置文件修改、IDEA集成Maven以及解决jar包下载问题的方法。
2022最新版超详细的Maven下载配置教程、IDEA中集成maven(包含图解过程)、以及导入项目时jar包下载不成功的问题解决
|
4天前
|
人工智能 PyTorch 算法框架/工具
Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程
【8月更文挑战第6天】Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程
Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【热门开源项目】阿里开源巨擘:Qwen-2 72B深度解析与推荐
在人工智能的浪潮中,开源模型如同璀璨的星辰,指引着开发者们探索未知的领域。而今天,我们将聚焦在阿里云推出的开源模型Qwen-2 72B上,从其项目介绍、技术特点、代码解析等多个角度,深入解析并推荐这一卓越的开源项目。
14 1
|
4天前
|
Java 应用服务中间件 Maven
Mac使用Idea配置传统SSM项目(非maven项目)
Mac使用Idea配置传统SSM项目(非maven项目)
13 1
|
4天前
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
14 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
4天前
|
Java Maven
成功解决IDEA中建立新项目Maven会默认选择配置(图解详细说明)
这篇文章提供了在IntelliJ IDEA中设置新项目的Maven配置的详细步骤,包括如何通过菜单路径进入设置,选择Maven配置,以及展示设置后的效果,还提供了Maven的安装教程和解决导入项目时jar包下载问题的方案。
成功解决IDEA中建立新项目Maven会默认选择配置(图解详细说明)
|
4天前
|
SQL 前端开发 Java
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
这篇文章介绍了如何在IntelliJ IDEA中使用Maven将Spring Boot项目打包成可运行的jar包,并提供了运行jar包的方法。同时,还讨论了如何解决jar包冲突问题,并提供了在IDEA中同时启动Vue前端项目和Spring Boot后端项目的步骤。
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
|
9天前
|
Java Apache Maven
Maven 项目文档
本章介绍如何创建Maven项目文档。例如,在C:/MVN下创建名为`consumerBanking`的项目,可通过命令`mvn archetype:generate`快速搭建。之后需在`pom.xml`中添加或更新插件配置,如`maven-site-plugin`版本至3.3,以避免运行`mvn site`时遇到类未找到错误。这确保文档能成功生成。
|
9天前
|
XML Java Maven
"Maven项目模块化大揭秘!掌握Model间最佳继承设计,让你的代码优雅如诗,项目维护不再愁!"
【8月更文挑战第11天】Maven是Java项目中常用的构建工具,其模块化特性对大型项目的管理至关重要。本文介绍Maven中的继承与聚合机制,指导如何通过继承消除重复配置,以及如何通过聚合统一构建多个模块。遵循单一职责原则,文章建议按功能划分模块,并提供了父POM与子POM的配置示例。此外,还讨论了适度模块化、依赖管理的原则,帮助提升项目的可维护性和扩展性。
22 4
|
7天前
|
Java Apache Maven
Maven 项目文档
本章介绍如何创建Maven项目文档。以在C:/MVN下建立的`consumerBanking`项目为例,利用`mvn archetype:generate`命令快速搭建Java项目骨架。为避免运行`mvn site`时出现`NoClassDefFoundError`错误,需在`pom.xml`中升级`maven-site-plugin`至3.3版本,并加入`maven-project-info-reports-plugin`插件以完善站点文档生成配置。

推荐镜像

更多