Это 4-й день моего участия в Gengwen Challenge, смотрите подробности мероприятия:Обновить вызов
Общая документация:Каталог статей
Github : github.com/black-ant
Каждый раз, когда я пытаюсь идти чисто техническим путем, почему никто не любит????
Введение
В этой статье разбирается пакет JAR, в чем заключаются его особенности.
1.1 Краткое описание JAR
JAR-файлэтоZip-формат файла, используемый для объединения многих файлов в один файл JAR, по сути, представляет собой zip-файл, который содержит необязательный каталог META-INF.
JAR-командаэто универсальный инструмент для архивирования и сжатия, основанный на форматах сжатия ZIP и ZLIB. Первоначально команда jar использовалась для упаковки апплетов Java (не поддерживается с JDK 11) или приложений;Однако, начиная с JDK 9, пользователи могут создавать модульные банки с помощью команды jar.
2. Структура пакета
Если вы хотите запустить проект на Java, обычно есть два способа: war и jar.В прошлом наиболее распространенным способом было развертывание проекта с помощью пакета war.
структура пакета
.
|-- BOOT-INF
| |-- classes
| | `-- com
| | `-- gang
| | `-- study
| | `-- maven
| | |-- BootdependencyApplication.class
| | `-- service
| | `-- AopAdvice.class
| `-- lib
| |-- 省略 JAR
|-- META-INF
| |-- MANIFEST.MF
| `-- maven
| `-- com.gang.study.maven.bootdependency
| `-- com-gang-study-maven-bootdependency
| |-- pom.properties
| `-- pom.xml
`-- org
`-- springframework
`-- boot
`-- loader
|-- 省略 class
Давайте посмотрим на роль каждого каталога в обычной структуре пакета.
// каталог META-INF Используется для хранения данных конфигурации пакетов и расширений, включая безопасность, управление версиями, расширения, приложения конфигурации, загрузчики классов и службы, файлы/каталоги в каталоге META-INF распознаются и интерпретируются платформой java2.
- MANIFEST.MF: файл манифеста, используемый для определения данных, связанных с расширением и пакетом.
- INDEX.LIST : Этот файл, созданный командой «-i», содержит информацию о расположении пакетов, определенных в приложении или расширении. Он является частью реализации JarIndex и используется загрузчиками классов для ускорения процесса загрузки классов.
- x.SF : файл подписи для файла JAR. 'x' представляет базовое имя файла.
- x.DSA : файл блока подписи, связанный с файлами подписи с тем же базовым именем файла. В этом файле хранится цифровая подпись соответствующего файла подписи.
- maven: сообщения конфигурации для maven
Каталог BOOT-INF подробно описан ниже.
Приложение 1: файл MANIFEST.MF
// 规范的版本
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
// 多重发布 : 存在多个 JDK 版本
Multi-Release: true
//创建清单文件的用户的名称
Built-By: 10169
// SpringBoot 启动类
Start-Class: com.gang.study.maven.BootdependencyApplication
// SpringBoot 类路径
Spring-Boot-Classes: BOOT-INF/classes/
// Spring-Boot lib 文件路径
Spring-Boot-Lib: BOOT-INF/lib/
// Spring Boot 版本
Spring-Boot-Version: 2.2.6.RELEASE
// 创建清单文件的工具版本和供应商
Created-By: Apache Maven 3.6.1
// 此自定义头给出创建清单文件的用户的名称
Build-Jdk: 1.8.0_152
// Main 方法入口 , 这里更像一个加载器
Main-Class: org.springframework.boot.loader.JarLauncher
// 到库或资源的相对路径的空格分隔列表
Class-Path: core.jar lib/ properties/
//---------------- 其他的属性
Name: 包名
Implementation-Build-Date: 实施的构建日期
Implementation-Title: 执行的标题
Implementation-Vendor: 实施的供应商
Implementation-Version: 实施版本
Specification-Title: 规范的标题
Specification-Vendor: 规范的供应商
Specification-Version: 规格版本
Sealed: 那么包的所有类是否都来自同一个 JAR
// 一 : 格式
MANIFEST.MF 是一个标准的 key:value ( headers:attributes)
key1: value1
Key2: value2
// 有效的标题必须在冒号和值之间有空格。另一个重要的地方是在文件的末尾必须有一个新的行 (这个地方坑了很久 , 怎么都导不进去 , 需要换行才对) , 否则最后一行会被忽略
Приложение II: Подпись пакета
Платформа JavaTM позволяет вам ставить цифровую подпись на файлы JAR,При подписании JAR-файла также можно поставить отметку времени подписи., отметка времени может использоваться для проверки сертификата, используемого для подписи файла JAR.Действителен ли он на момент подписания.
Для этого вы также можете настроить элементы управления политикой безопасности, вы можете настроить политики для предоставления привилегий безопасности аплетам и приложениям,Например, вы можете предоставить аплету разрешение на выполнение операций, которые обычно запрещены, например чтение и запись локальных файлов или запуск локальных исполняемых программ.
Подпись в основном состоит из 4 элементов:закрытый ключ, открытый ключ и сертификат, значение дайджеста
Как использовать подпись:Платформа Java реализует подпись и проверку с использованием специальных номеров, называемых открытыми и закрытыми ключами.
руководство :Подписывающая подписывает JAR-файл с помощью закрытого ключа, а открытый ключ приложения помещается в JAR-файл вместе с сертификатом, чтобы любой, кто хочет проверить подпись, мог его использовать.
Суммарное значение:Дайджест-значение представляет собой хэшированное или закодированное представление содержимого файла, как и при его подписании. Сводка файла изменяется тогда и только тогда, когда изменяется сам файл.
Сертификат:Использование только открытых и закрытых ключей недостаточно для фактической проверки подписи, некоторый способ подтвердить, что открытый ключ действительно принадлежит подписавшему, от которого он, как утверждается, принадлежит, использует концепцию сертификата (добавляя дополнительный элемент, который является подписывающей стороной). сертификат, включенный в подписанный файл JAR)
// 当一个 JAR 文件被签名时,一个签名文件被自动生成并放置在 JAR 文件的 META-INF 目录中
// 这个目录包含了归档文件的清单 , 签名文件的文件名是.SF 扩展
Signature-Version: 1.0
SHA1-Digest-Manifest: h1yS+K9T7DyHtZrtI+LxvgqaMYM=
Created-By: 1.7.0_06 (Oracle Corporation)
Name: test/classes/ClassOne.class
SHA1-Digest: fcav7ShIG6i86xPepmitOVo4vWY=
Name: test/classes/ClassTwo.class
SHA1-Digest: xrQem9snnPhLySDiZyclMlsFdtM=
Name: test/images/ImageOne.gif
SHA1-Digest: kdHbE7kL9ZHLgK7akHttYV4XIa0=
Name: test/images/ImageTwo.gif
SHA1-Digest: mF0D5zpk68R4oaxEqoS9Q7nhm60=
3. Общие операции
3.1 Получите путь к классам в пакете jar
// JAR 命令获取
打印出 jar 中所有的class名 : jar tf com-gang-bootdependency-1.0-SNAPSHOT.jar
打印所有的 class : jar tf com-gang-bootdependency-1.0-SNAPSHOT.jar | grep '\.class$'
// Java 代码获取
public static Set<String> getClassNamesFromJarFile(File givenFile) throws IOException {
Set<String> classNames = new HashSet<>();
try (JarFile jarFile = new JarFile(givenFile)) {
Enumeration<JarEntry> e = jarFile.entries();
while (e.hasMoreElements()) {
JarEntry jarEntry = e.nextElement();
if (jarEntry.getName().endsWith(".class")) {
String className = jarEntry.getName()
.replace("/", ".")
.replace(".class", "");
classNames.add(className);
}
}
return classNames;
}
}
// 运行时动态获取
public static Set<Class> getClassesFromJarFile(File jarFile) throws IOException, ClassNotFoundException {
Set<String> classNames = getClassNamesFromJarFile(jarFile);
Set<Class> classes = new HashSet<>(classNames.size());
try (URLClassLoader cl = URLClassLoader.newInstance(
new URL[] { new URL("jar:file:" + jarFile + "!/") })) {
for (String name : classNames) {
Class clazz = cl.loadClass(name); // Load the class by its name
classes.add(clazz);
}
}
return classes;
}
3.2 Несколько способов создания древовидной структуры
Если вы хотите напечатать древовидную структуру, есть несколько способов:
// 方式一 : tree 命令可以用于 Windows 生成目录数 (PS : 应该是系统本身就有该命令)
打印到当前文件 : tree /f >tree.txt
// 方式二 : tree for windows (PS : 这个和上面不是一个东西)
1. 下载 tree for windows 文件 : http://gnuwin32.sourceforge.net/packages/tree.htm (选择 Binaries.zip)
2. 解压获取 tree.exe , 放在 git 项目中 : Git\usr\bin (注意 , 外层的 bin , 需要到 usr 目录下)
3. 项目路径下反键 - git base here (即 git 控制台)
4. 运行 tree 命令
-A 使用ASNI绘图字符显示树状图而非以ASCII字符组合。
-C 在文件和目录清单加上色彩,便于区分各种类型。
-d 显示目录名称而非内容。
-D 列出文件或目录的更改时间。
-f 在每个文件或目录之前,显示完整的相对路径名称。
-F 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上"*","/","=","@","|“号。
-g 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
-i 不以阶梯状列出文件或目录名称。
-I 不显示符合范本样式的文件或目录名称。
-l 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。
-n 不在文件和目录清单加上色彩。
-N 直接列出文件和目录名称,包括控制字符。
-p 列出权限标示。
-P 只显示符合范本样式的文件或目录名称。
-q 用”?"号取代控制字符,列出文件和目录名称。
-s 列出文件或目录大小。
-t 用文件和目录的更改时间排序。
-u 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
-x 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。
$ tree
.
|-- classes
| `-- com
| `-- gang
| `-- study
// 方式三 : 在线 tree 转换
http://dir.yardtea.cc/
// 方式四 : 使用软件显示如上图所示的数结构
下载软件 DirPrintOK
3.3 Метод декомпиляции JAR
// 方案一 : 工具查看
1. ZIP 解压后 , 直接通过 Java Decompiler 查看
?- 该方案对于部分 class 有局限性 , 看出来的如下所示 : // INTERNAL ERROR //
2. JD Project : 最常用的最好的 java 脱机反编译器之一
3. Cavaj Java Decompiler
4. DJ Java Decompiler
5. JBVD
6. androidchef
7. Procyon
8. CFR Decompiler
9. FernFlower
10. Krakatau
11. Luyten
// 编译器大同小异 , 无非就是转码 , 以上任意一种都可以试着用一下 , 一般我自己使用 JD-GUI / Jar Explorer
https://java-decompiler.github.io/
// 方案二 : 命令行反编译
java -jar JDCommandLine.jar ${TARGET_JAR_NAME}.jar ./classes
3.4 Как предотвратить проблемы с декомпиляцией
Байт-код Java сохраняет информацию о типах полей, возвращаемых значениях метода и параметрах.Но он не содержит информации о типе для локальных переменных..
Информация о типах в файлах классов Java делает байт-кодЗадача декомпиляции проще, чем декомпиляция машинного кода.
Следовательно, декомпиляция байт-кода Java требует анализа большинства типов локальных переменных, инструкций плоского стека и структурированных циклов и условий.
Вариант 1. Используйте YGuard для запутывания файлов классов (аналогично ProGuard и т. д.)
Может преобразовывать скомпилированный код в код, который трудно понять людям, помогая сократить время запуска приложения..
Самое главное, что это программа с полностью открытым исходным кодом.Метод обфускации YGuard:
- Удалите файлы классов из обратного проектирования, заменив имена пакетов, классов, методов и полей невыразимыми символами.
- Механизм минимизации анализирует байт-код всех входных файлов Jar, чтобы определить, какие объекты кода недоступны из заданного набора точек входа кода. Затем yGuard удалит эти устаревшие фрагменты кода (либо целые классы, либо отдельные методы и поля).
То, что YGuard запутывает, является файлом класса, YGuard — это бесплатный обфускатор и сжатие байт-кода Java с открытым исходным кодом, посредством запутывания, ссылочный адрес:
@ GitHub.com/Work is/YG UA…
@ GitHub.com/Work is/YG UA…
<dependency>
<groupId>com.yworks</groupId>
<artifactId>yguard</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
<!-- 配置规则详见官方文档 -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<id>obfuscate</id>
<configuration>
<tasks>
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<taskdef name="yguard" classname="com.yworks.yguard.YGuardTask" />
<yguard>
<!-- see the yGuard task documentation for information about the <yguard> element-->
</yguard>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
Вариант 2. Если вы хотите скрыть строку, вы можете зашифровать атрибут
Решение 3: Многие декомпиляторы не адаптированы к новым функциям и некоторым инструментам, например: lambdas
Вариант 4. Настройте ClassLoader для выделенной расшифровки
Вариант 5. Используйте Protector4j для шифрования файлов JAR, преобразования файлов JAR в закрытый формат JARX, защиты файлов классов и структуры приложения.
@ protector4j.com/
(PS: лично не пользовался, не оцениваю, и JarProtector похож, но Protector4j относительно новый)
3.5 JAR-файлы Maven для упаковки
<!-- Maven pom.xml 文件构建 jar-->
<modelVersion>4.0.0</modelVersion>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- Plugin Java-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
com.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Plugin Spring -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
com.baeldung.executable.ExecutableMavenJar
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<!-- 通常也可以直接使用 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
3.6 Упаковка файлов в JAR
Вы можете использовать команду jar -u для обновления файлов в банке, которая часто используется для настройки системы и других операций.Обычный формат выглядит следующим образом:
jar uf JarExample.jar com/baeldung/jar/JarExample.class
// 案例 : 需要替换 parent.jar 内部的 child-1.3.4.jar 依赖
// Step 1 : 准备好相关的路径 (例如需要放在该路径下 , 先在外部创建一个相同的路径)
构建目录 : \new_version\BOOT-INF\classes\bundles
// Step 2 : 将 bundles jar 移动到 该路径
// Step 3 : 执行命令执行
jar -uvf0 parent.jar BOOT-INF/classes/bundles/child-1.3.4.jar
4. Прочие операции
4.1 Создание файла JAR вручную
В этом случае я попытаюсь вручную скомпилировать .java и упаковать его в файл jar и выполнить
// Step 1 : 准备一个 .java 方法
public class DefaultMain {
public static void main(String[] args){
System.out.println("Test Default Main Success!");
}
}
// Step 2 : 打包为 .class 文件 (运行后生成一个 DefaultMain.class)
javac -d . DefaultMain.java
// Step 3 : (此处可以省略 , 参考后文设置清单文件)
// Step 4 : 打包到 JAR 文件中 (运行后生成一个 example.jar)
jar cfe example.jar com/gang/DefaultMain com/gang/DefaultMain.class
// Step 5 : 执行 jar
java -jar example.jar
// 附录 : JAR 包结构
.
|-- META-INF
| `-- MANIFEST.MF
|-- com
| `-- gang
| `-- DefaultMain.class
`-- tree.txt
3 directories, 3 files
4.2 Maven добавляет файл MANIFEST.MF
Этот способ заключается в редактировании файла MANIFEST.MF через Maven.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<packageName>com.baeldung.java</packageName>
</manifest>
<manifestEntries>
<Created-By>baeldung</Created-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
4.3 JAR добавить файл MANIFEST.MF
Вручную добавьте MANIFEST.MF с помощью команды JAR, наиболее важной из которых является:Завершите файл манифеста новой строкой, иначе он по умолчанию игнорируется.
// Step 1 : 准备一个任意的文本文件 , 添加属性(记得回车)
Built-By: gang
// Step 2 : 使用命令打包
jar cvfm example.jar manifest.txt com/gang/DefaultMain.class
../test>jar cvfm example.jar manifest.txt com/gang/DefaultMain.class
已添加清单
正在添加: com/gang/DefaultMain.class(输入 = 442) (输出 = 299)(压缩了 32%)
// 解压后最终结果 :
Manifest-Version: 1.0
Built-By: gang
Created-By: 1.8.0_152 (Oracle Corporation)
4.4 Определение нескольких версий JDK в JAR
Если ожидается, что пакет JAR будет работать в нескольких версиях JDK, его можно построить следующим образом:
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── gang
│ │ │ └── test
│ │ │ ├── DefaultVersion.java
│ │ │ └── App.java
│ │ └── java9
│ │ └── com
│ │ └── gang
│ │ └── test
│ │ └── DefaultVersion.java
<!-- Step 1 : 通过 Maven 构建 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile-java-8</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</execution>
<execution>
<id>compile-java-9</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
</compileSourceRoots>
<!-- > 3.7.1 时替换下句 : <multiReleaseOutput>true</multiReleaseOutput> -->
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/9</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- Step 2 : MANIFEST 文件中将 Multi-Release 条目设置为 true -->
<!--使用这种配置,Java 运行时将在 JAR 文件的 META-INF/versions 文件夹中查找特定于版本的类; 否则,只使用基类-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
</plugin>
4.5 Упаковка в банки с жиром
Что такое Толстый джат?
Fat jar — это тоже jar, с отличием от обычного jar: он содержит классы из всех библиотек, от которых зависит ваш проект, и, конечно же, классы текущего проекта.
В качестве примера возьмем метод упаковки Spring: Spring упаковывает код приложения в BOOT-INF.classes и упаковывает пакет зависимостей в каталог BOOT-INF.lib.Spring это должен быть Fat JAR «Скопируйте jar зависимостей в основной jar, а затем используйте специальный загрузчик классов для загрузки
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>source-release-assembly</id>
<phase>none</phase>
</execution>
<execution>
<id>source-release-assembly-no-eclipse-libs</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
<descriptors>
<descriptor>src/assemble/${sourceReleaseAssemblyDescriptor}.xml</descriptor>
</descriptors>
<tarLongFileMode>gnu</tarLongFileMode>
</configuration>
</execution>
</executions>
</plugin>
<properties>
<start-class>org.baeldung.boot.Application</start-class>
</properties>
5. Команды JAR и общие операции
5.1 Шаблон команды JAR
jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...
Где {ctxu} — подкоманда команды jar, каждая команда jar может содержать только один из ctxu, они представляют
-c :Создайте новый пакет файлов JAR
-t :Список содержимого пакета файла JAR
-x :Раскрывает указанные файлы или все файлы пакета JAR.
-u :Обновите существующий пакет JAR (добавьте файлы в пакет JAR)
[vfm0M] :Параметры могут быть необязательными или нет, они являются параметрами параметров команды jar.
-v :Создание подробного отчета и печать на стандартный вывод
-f :Укажите имя JAR-файла, обычно этот параметр обязателен
-m :Укажите файл манифеста МАНИФЕСТА для включения
-0 :Только сохранять, а не сжимать, результирующий пакет файлов JAR будет больше, чем пакет без этого параметра, но быстрее
-M :Не создавать файл МАНИФЕСТА всех элементов, этот параметр игнорирует параметр -m
[jar-файл]:То есть пакет файла JAR, который необходимо сгенерировать, просмотреть, обновить или распаковать, что является вспомогательным параметром параметра -f.
[файл манифеста]:то есть файл манифеста MANIFEST, который является вспомогательным параметром параметра -m
[-C каталог]:Указывает операцию перехода в указанный каталог для выполнения команды jar. Это эквивалентно использованию команды cd для перехода в каталог, а затем выполнению команды jar без параметра -C.Его можно использовать только при создании и обновлении файловых пакетов JAR.
имя файла ... :Указывает список файлов/каталогов, которые должны быть добавлены в пакет файлов JAR. Если каталог указан, то команда jar автоматически поместит все файлы и подкаталоги в каталоге в пакет при упаковке.
5.2 Общие команды JAR
@ jar-The Java Archive Tool (oracle.com)
Один: команда JAR для установки основного класса Class
jar cfe example.jar com.gang.DefaultMain com/gang/*.class
// 生成的 MANIFEST 文件
Manifest-Version: 1.0
Created-By: 1.8.0_152 (Oracle Corporation)
Main-Class: com.gang.DefaultMain
Два: запустить банку
java -jar test.jar
Три: управление содержимым jar
// 提取 JAR 内容
jar xf jar-file [archived-file(s)]
// 查看 JAR 内容
jar tf jar-file
// 更新 JAR 内容
jar uf jar-file input-file(s)
Четыре : Управление списком
// 命令行修改清单文件
jar cfm jar-file manifest-addition input-file(s)
// 设置默认入口
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
// 添加 class
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
Другие поиски
// 指定主类 :
> java -cp JarExample.jar com.baeldung.jar.JarExample
> java -cp JarExample.jar com/baeldung/jar/JarExample
// 列出 Jar 的内容 :
> jar tf JarExample.jar
// 查看清单文件
> unzip -p JarExample.jar META-INF/MANIFEST.MF
6. Другое
6.1 Различия между WAR и JAR
JAR-пакет
Проще говоря, архив JAR или Java представляет собой формат файла пакета, файл JAR имеет расширение .Jar и может содержать файлы библиотеки, ресурсов и метаданных, фактически это сжатый файл, который содержит сжатую версию файла .class. а также Ресурсы для скомпилированных библиотек и приложений Java
ВОЕННЫЙ пакет
ВОЙНААрхив веб-приложения или ресурс веб-приложенияАббревиатура от , эти архивы имеют.WarРасширение для упаковки веб-приложений, которое можно развернуть в любом контейнере Servlet/JSP.
// WAR 包格式
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
jsp/
helloWorld.jsp
classes/
static/
templates/
application.properties
lib/
// *.jar files as libs
6.2 Использование API-интерфейса java.util.jar
Официальная документация по API
6.3 Сравнение с BOOT-INF
Я видел ранее, что есть еще и BOOT-INF, для чего эта папка?
Особенности структуры BOOT-INF:
- Форма загрузки приложения Spring Boot Папка BOOT-INF
- Классы приложений должны быть помещены во вложенный каталог BOOT-INF/classes.
- Зависимости должны быть размещены во вложенной директории BOOT-INF/lib
Проблемы, решаемые BOOT-INF:
Java не предоставляет какого-либо стандартного способа загрузки вложенных файлов jar (т. е. загрузки файлов jar, которые сами содержатся внутри jar). Проблема возникает, когда нужно распространить самодостаточное приложение, которое можно запустить из командной строки без распаковки.
PS: На самом деле это FAT JAR, упомянутый выше
С этой целью Spring использует следующую структуру каталогов, помещая классы приложений во вложенный каталог BOOT-INF/classes.
example.jar
|
+-META-INF
| +-MANIFEST.MF
+-org
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-BOOT-INF
+-classes
| +-mycompany
| +-project
| +-YourClasses.class
+-lib
+-dependency1.jar
+-dependency2.jar
// SpringBoot 对于 War 包的目录格式 (依赖项应该放在嵌套的 WEB-INF/lib 目录中) :
example.war
|
+-META-INF
| +-MANIFEST.MF
+-org
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-WEB-INF
+-classes
| +-com
| +-mycompany
| +-project
| +-YourClasses.class
+-lib
| +-dependency1.jar
| +-dependency2.jar
+-lib-provided
+-servlet-api.jar
+-dependency3.jar
Индекс BOOT-INF
Как упоминалось ранее, BOOT-INF предназначен для агрегирования пакетов и приложений и имеет различные индексные файлы:
- Индекс пути к классам (classpath.idx): обеспечивает порядок, в котором банки добавляются в путь к классам.
- Указатель слоя (layers.idx): содержит список слоев и частей, которые должны быть включены в JAR.
// classpath.idx
- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"
// layers.idx
- "dependencies":
- "BOOT-INF/lib/dependency1.jar"
- "BOOT-INF/lib/dependency2.jar"
- "application":
- "BOOT-INF/classes/"
- "META-INF/"
Загрузка BOOT-INF
BOOT-INF загружается на основе org.springframework.boot.loader.jar , этот класс позволяет загружать содержимое jar из стандартных файлов jar или вложенных данных sub-jar.
При первой загрузке расположение каждого JarEntry сопоставляется с физическим смещением файла внешнего jar-файла.
myapp.jar
+-------------------+-------------------------+
| /BOOT-INF/classes | /BOOT-INF/lib/mylib.jar |
|+-----------------+||+-----------+----------+|
|| A.class ||| B.class | C.class ||
|+-----------------+||+-----------+----------+|
+-------------------+-------------------------+
^ ^ ^
0063 3452 3980
// 可以看到 :
1. 在 myapp.jar 的位置0063的/BOOT-INF/classes 中找到 A.class
2. 在 myapp.jar 中位于3452的位置找到来自嵌套 jar 的 B.class
3. C.class 位于3980的位置
С этой информацией,Затем мы можем загрузить определенные вложенные записи, выполнив поиск соответствующей части внешней банки., это основной способ, с помощью которого BOOT-INF разрешает внешние
В то же время Spring предоставляет несколько ресурсов начальной загрузки:
- Springframework.boot.loader.Launcher
- Этот класс представляет собой специальный класс начальной загрузки, используемый в качестве основной точки входа для исполняемого файла jar. Это фактический основной класс в файле jar, который устанавливает соответствующий URLClassLoader и, наконец, вызывает метод main().
- JarLauncher: дополнительный лаунчер, находится в BOOT-INF/lib/
- WarLauncher : дополнительный лаунчер, находится в WEB-INF/lib/ и WEB-INF/lib-proved/
- PropertiesLauncher : вспомогательный лаунчер, по умолчанию ищет BOOT-INF/lib/ в архивах приложений (позволяет добавлять дополнительные пути)
// 配置方式 :
Main-Class: org.springframework.boot.loader.WarLauncher
Start-Class: com.mycompany.project.MyApplication
Суммировать
Резюме писать не умею, изначально это был сводной документ, так что резюмировать нечего..
Я просто хочу пожаловаться, я все время шел по техническому пути, но я глубоко чувствую, что длинные технические документы имеют очень маленькую аудиторию.Хотя сам документ написан для себя, никто его реально не видит и не влияет на менталитет.Я когда-то сомневался, было ли это резюме нехорошим, и я не пойму его, когда буду использовать его для обзора в будущем~~
Ссылаться на
Официальная справочная документация
Другие справочные документы
- Уууууу.Поставь арлингтон-терьера.com/jar-file-a…
- Woohoo. Возьмите арлингтонского терьера.com/java-view-just…
- Woohoo. Возьмите арлингтонского терьера.com/java-view-just…
- WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
- Ву-Ву. Поместите Arlington Terrier.com/executable-…
- Уууу.Поставь арлингтонского терьера.com/deployable-…
- ууууууу.поставь арлингтон терьер.com/java-jar-disgusting…
- Woohoo. Принесите Arlington Terrier.com/java-create…
- Ууууу.Поставь арлингтонского терьера.com/java-jar-wow…
- Ууууу.Поставь арлингтонского терьера.com/java-jar-horse…
- Ууууу.Поставь арлингтонского терьера.com/maven-multi…