JAVA 可执行文件格式

JAVA 可执行文件格式

springboot 程序使用 Maven PLugin插件编译时,可以生成可执行的 jar 和 war 程序。其核心原理是 spring-boot-loader 模块,详细原理如下

1 嵌套 JARS

java 本身不支持任何标准的加载嵌套 jar 的方式,要解决该问题,很多人使用 sharded jars 方式去打包程序,将所有 jar 包从新打包为一个独立的 “union-all.jar” 。但是 shared jars 方法使得很难判断应用程序中代码的归属、同时可能存在部分文件名冲突问题。

springboot 使用一种不同的方式实现嵌套 jar。

1.1 可执行 Jar 文件结构

springboot 加载 jar 文件结构如下:

pmsuite-web-5.4.1-SNAPSHOT.jar|+-META-INF|  +-MANIFEST.MF+-org|  +-springframework|     +-boot|        +-loader|           +-<spring boot loader classes> # springboot 提供加载机制实现+-BOOT-INF+-classes|  +-cn|     +-pinming|        +-suite|            +-SuiteApplication.class|            +- ...|  +-static|  +-templates|  +-application.yml|  +-spring-config.xml|  +-....+-lib+-druid-1.1.23.jar+-dubbo-2.7.15.jar+-...

MANIFEST.MF 文件内容

Manifest-Version: 1.0
Implementation-Title: pmsuite-web
Implementation-Version: 5.4.1-SNAPSHOT
Built-By: Administrator
Specification-Title: pmsuite-web
Implementation-Vendor-Id: cn.pinming
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: cn.pinming.pmsuite.SuiteApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_131
Specification-Version: 5.4
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-boot-starter-parent/pmsuite-boot-project/pmsuite/pmsuite-basic-parent/pmsuite-web

按文件结构约定依赖jar包必须放在 WEB-INF/lib 下,任何运行时必须但部署到传统web容器时不必须的依赖放到 WEB-INF/lib-provided 目录下,而应用程序的 classes 必须放在 BOOT-INF/classes 目录下。

1.2 索引文件

Spring Boot Loader-compatible jar and war 文件可以 在 BOOT-INF/ 目录下存放扩展的索引文件。 一个 classpath.idx 文件可以为 jar 和 war 文件提供扩展 jars 依赖,而 layers.idx 仅仅为 jar 可执行文件服务。

索引文件使用 YAML 兼容语法。索引文件案例:

example.jar|+-META-INF|  +-...+-BOOT-INF+-classes|  +...+-lib+-dependency1.jar+-dependency2.jar

索引文件如下:

- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"

2. Spring Boot 加载 jar file 机制

springboot 加载 嵌套jars 核心入口 org.springframework.boot.loader.jar.JarFile 。该程序从一个标准 jar 文件 或 嵌套子 jar 文件中加载数据。

3. 执行jar

springboot 使用 org.springframework.boot.loader.Launcher 作为 java 程序加载主程序。该程序是一个 springboot 启动程序。

该启动程序包括三个子加载程序 JarLauncher, WarLauncher, and PropertiesLauncher。

4 PropertiesLauncher

PropertiesLauncher 加载一些扩展特性(比如系统配置、环境变量、mainfest 入口、或加载配置)。详细配置清单如下:

键值用途
loader.path使用逗号分割classpath,如 ${home}/app/lib。 类似 javac命令行的 -classpath 参数
loader.homeloader.path 或 loader.propertis 中如果使用相对目录时的跟目录。
loader.args程序启动参数,多个参数使用空格分割
loader.main程序启动的 main-class,如 SuiteApplication.class
loader.config.nameloader配置名称
loader.config.locationloader配置路径,默认 classpath:loader.propertis
loader.system判断配置是否加载到系统配置中,默认 false
  • PropertiesLauncher工作规则:

loader.properties: 先从loader.home,如果找不到查询classpath跟目录,最后查询 classpath:/BOOT-INF/classes。 使用最先找到的配置。
loader.home:只有在loader.config.location为配置时,才会从该目录加载扩展配置(覆盖默认配置)。
loader.path:可以包含目录(包含 jar 或 zip文件)、JAR归档文件路径(内容包括诸如:dependencies.jar!/lib)、正则表达式。
loader.path:默认值为 BOOT-INF/lib (表示从嵌套 jar归档文件中加载),该情况下不需要加载额外配置信息。
配置信息搜索顺序:environment variables, system properties, loader.properties, the exploded archive manifest, and the archive manifest.

案例

使用 loader.path 方式启动 springboot程序

  • Maven plugin 配置

       <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><layout>ZIP</layout><includes><include><groupId>non-exists</groupId><artifactId>non-exists</artifactId></include></includes></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><!--拷贝依赖到jar外面的lib目录--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><!--指定的依赖路径--><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin>
    1. 配置 layout 修改为 ZIP,使得启动的时候能够设别 loader.path属性
    2. 配置 include 为 non-exists,lib包 只包含 non-exists 包,而non-exists不存在,使用不打包lib依赖,这样就能保障所有依赖统一走 loader.path
    3. 使用 maven-dependency-plugin 独立打包依赖
  • 生成目录结构如下:

      +-target|  +- pm-bigdata-web.jar|  +- lib\|     +- ...
  • 启动脚本

      java -jar -Dloader.path=lib -Dspring.config.location=./config/application.yml pm-bigdata-web.jar

java 外部lib

java -jar -Djava.ext.dirs=./libs

如果在libs内 ,命令-Djava.ext.dirs=参数为./ ,如果生成jar与libs同级那么改为./libs 意思就是告诉jar 我的依赖jar包相对于我要执行的jar包的位置在哪里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探秘高级代理技术:SK5代理在网络安全中的应用

在当今数字化时代&#xff0c;网络安全和隐私保护日益受到重视。作为网络工程师和网络文章主编&#xff0c;我将为您介绍一种强大而高级的代理技术——SK5代理&#xff0c;并探讨其在网络安全、爬虫以及HTTP通信中的重要应用。 1. SK5代理简介 SK5代理是一种基于SOCKS5协议的…

学SQL JOINS看这一篇文章就够了

目录 下面以实例进行分析 内连接 inner join 或者join&#xff08;等同于inner join&#xff09; 外连接 left join 或者left outer join(等同于left join) [ left join 或者left outer join(等同于left join) ] [ where B.column is null ] right join 或者right outer…

Docker Registry本地镜像仓库部署并实现远程连接拉取镜像

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

Centos系列:shell编程综合练习(个人学习记录)

shell编程综合练习&#xff08;个人学习记录&#xff09; shell编程until 循环跳出循环1. break命令2. continue 命令 Shell函数特殊变量输入输出重定向输出重定向输入重定向重定向 Shell实战监控centos7运行状态/proc/stat文件编写脚本free命令监控系统内存 shell编程 until …

ubuntu几个版本开启或关闭图形界面小结

在下面几个系统做过验证&#xff1a; ubuntu-16.04.7-desktop-amd64&#xff08;内核版本&#xff1a;Linux 4.15.0-112&#xff09; ubuntu-18.04.6-desktop-amd64&#xff08;内核版本&#xff1a;Linux 5.4.0-150&#xff09; ubuntu-20.04.6-desktop-amd64&#xff08;内…

h5网站开发-微信浏览器无法自动播放视频的解决方式?

一、需求&#xff1a; 使用h5开发的网站&#xff0c;首页的banner是一个video视频&#xff0c;在PC端上和手机浏览器上都能正常播放&#xff0c;但是在手机微信浏览器里面视频是无法自动播放的。 二、实现效果&#xff1a; 1.微信浏览器的效果&#xff1a; 2.正常效果&…

如何实现高效代码审查,赋能大规模开发

对于许多企业来说&#xff0c;代码审查都是开发过程中不可缺少的一环。软件开发人员通常会对代码审查感到又爱又恨。一般来说&#xff0c;实施代码审查的企业普遍认为通过及早发现问题和低效率&#xff0c;在长远来看可节省时间。 阅读本篇文章&#xff0c;您将了解到什么是代…

JS浮点数精度问题及解决方案

前端面试大全JS浮点数精度问题及解决方案 &#x1f31f;经典真题 &#x1f31f;浮点数精度常见问题 &#x1f31f;为什么会有这样的问题 &#x1f31f;真题解答 &#x1f31f;总结 &#x1f31f;经典真题 为什么 console.log(0.20.10.3) 得到的值为 false &#x1f31f;…

vs-code之vue3插件

1.Vue 3 Support - All In One Vue3 代码片段突出显示了 Visual Studio Code 的格式化程序生成器 生成vue3对应的的代码 如ref等&#xff0c; 2.Volar 相信使用 VSCode 开发 Vue2 的同学一定对 Vetur 插件不会陌生&#xff0c;作为 Vue2 配套的 VSCode 插件&#xff0c;它的主…

C++学习之路(十)C++ 用Qt5实现一个工具箱(增加一个时间戳转换功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《JSON数据格式化》功能&#xff0c;还是比较实用的。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 时间戳转换 」功能&#xff0c;而且实现点击按钮后文字进行变…

Unity中C#如何访问并修改Shader材质

文章目录 前言一、我们用点击按钮来改变Shader传入的颜色值1、在渲染GUI时&#xff0c;绘制一个按钮2、我们使用一个公共的成员变量存储需要进行修改的游戏对象3、最后给绘制的按钮点击增加逻辑即可 二、测试使用的代码1、Shader代码&#xff1a;2、C#脚本 前言 我们写好Shade…

电源自动测试系统| 电源模块温度循环怎么测试?

在一些应用领域&#xff0c;电源模块会在极端环境温度条件下工作。为了确保电源在高低温环境下可以正常运行&#xff0c;满足设备需求&#xff0c;需要对电源模块进行温度循环测试。 温度循环测试是指电源模块经过升温、保温、降温等多次循环试验来检测其在温度变化下的耐热性、…

关于自动化测试框架pytest的Fixture固件

什么是固件 Fixture 翻译成中文即是固件的意思。它其实就是一些函数&#xff0c;会在执行测试方法/测试函数之前&#xff08;或之后&#xff09;加载运行它们&#xff0c;常见的如接口用例在请求接口前数据库的初始连接&#xff0c;和请求之后关闭数据库的操作。 我们之前在A…

Hana Studio打开BW失败

Hana Studio打开BW失败 JCo initialization failed with java.lang.UnsatisfiedLinkError: D:\ycy\BW培训\HANA\configuration\org.eclipse.osgi\357\0.cp\lib\sapjco3.dll: Can’t find dependent libraries 这个提示应该是VC版本问题&#xff0c;按如下链接中的地址下载安装…

使用SD-WAN新方式,解锁分公司访问总部私有云

某企业是一家跨地区运营的大型企业&#xff0c;总部位于上海&#xff0c;拥有多个分公司遍布全国。其中北京分公司作为该企业在北方地区的重要分支机构&#xff0c;负责着该地区的市场开拓和业务发展。 为了实现分公司与总部之间的有效沟通和信息共享&#xff0c;北京分公司使用…

Linux快速配置拨号

在Linux上进行ADSL拨号配置&#xff0c;通常需要使用pppoeconf命令进行设置。pppoeconf是一个用于配置pppoe连接的工具&#xff0c;它可以帮助用户快速设置pppoe连接并生成配置文件。下面是一个详细的步骤指南&#xff0c;以帮助您在Linux上进行ADSL拨号配置。 步骤1&#xff…

ToDesk优惠码来了,需要的不容错过

最近发现Todesk也有活动了&#xff0c;很多小伙伴不知道&#xff0c;除了中秋国庆双节&#xff0c;ToDesk另有专享优惠码&#xff0c;输入优惠码最高立减25元&#xff0c;即使是活动日也能折上折&#xff0c;不影响此优惠码的折扣力度&#xff01; Todesk作为国内优良的远程控制…

Centos系列:Centos7下的DNS服务器部署(每一步图文结合超详细,适用于初学者)

Centos7下的DNS服务器部署&#xff08;每一步图文结合超详细&#xff0c;适用于初学者&#xff09; Centos7下的DNS服务器部署引言部署步骤实验环境DNS服务端&#xff1a;DNS客户端&#xff1a; 正向解析安装DNS&#xff08;DNS服务端&#xff0c;客户端都要操作&#xff09;修…

node.js学习笔记——内部模块、自定义模块的导入和使用方式

文章目录 前文提要内部模块fs模块导入方式fs.readFilefs.writeFile path模块导入方式__dirnamepath.join http模块导入方式创建服务器实例绑定request事件启动服务器 自定义模块和第三方模块导入方式模块作用域 共享方式 前文提要 本人仅做个人学习记录&#xff0c;如有错误&a…

gitlab-ci.yml 同步https 仓库地址

1. 先在要部署的机器上&#xff0c;执行如下命令, 输入一次密码后&#xff0c;保存该密码git config --global credential.helper store2. 然后执行 git pull 命令, 然后会提示输入密码, 输入密码即可.3. 编写 gitlab-ci.yml 文件stages:- deploy# 部署master服务 deployMaster…