This is the fourth day of my participation in the More text Challenge. For details, see more text Challenge

General documentation: Article directory Github: github.com/black-ant

Every article is as far as possible pure technical route, why no one point like?????

A. The preface

This article looks at a JAR package. What are the main points involved

1.1 the JAR is briefly

A JAR file is a Zip-based file format used to aggregate many files into one. A JAR file is essentially a Zip file that contains an optional meta-INF directory.

The JAR command is a universal archive and compression tool based on the ZIP and ZLIB compression formats. Originally, the JAR command was used to package Java applets (not supported since JDK 11) or applications; However, starting with JDK 9, users can create modular Jars using the JAR command

2. Package structure

In Java, there are usually two ways to run a project: WAR and JAR. In the past, the most common way to deploy a project is through the WAR package.


Package structure action

. |-- BOOT-INF | |-- classes | | `-- com | | `-- gang | | `-- study | | `-- maven | | |-- BootdependencyApplication. Class | | ` - service | | ` -- AopAdvice. Class | ` - lib | | - omitted JAR | - meta-inf | | - MANIFEST.MF | `-- maven | `-- com.gang.study.maven.bootdependency | `-- com-gang-study-maven-bootdependency | |-- Pom. The properties | ` -- pom. XML ` - org ` - springframework ` - boot ` - loader | - omittedclass

Copy the code

Take a look at the role of each directory in a normal package structure

// The meta-INF directory is used to store package and extension configuration data, including security, version-control, extensions, configuration applications, classloaders, and services. The files/directories in the Meta-INF directory are identified and interpreted by the JavA2 platform

  • Manifest.mf: the MANIFEST file used to define the extension and package-related data
  • Index. LIST: Generated by the “-i” command, this file contains the location information of packages defined in the application or extension. It is part of the JarIndex implementation and is used by class loaders to speed up their class loading process
  • X. sf: signature file of the JAR file, where ‘x’ represents the basic file name
  • X.dsa: indicates the signature block file associated with the signature file with the same base file name. This file stores the digital signature of the corresponding signature file
  • Maven: Configuration message for Maven

The boot-INF directory is described later

Appendix I: the manifest.mf file

// The version of the specification
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
// Multiple releases: there are multiple JDK versions
Multi-Release: true
// The name of the user who created the manifest file
Built-By: 10169
// SpringBoot boot class
Start-Class: com.gang.study.maven.BootdependencyApplication
// SpringBoot classpath
Spring-Boot-Classes: BOOT-INF/classes/
// Spring-boot lib file path
Spring-Boot-Lib: BOOT-INF/lib/
// Spring Boot version
Spring-Boot-Version: 2.26..RELEASE
// Create the version and vendor of the tool for the manifest file
Created-By: Apache Maven 3.61.
// This custom header gives the name of the user who created the manifest file
Build-Jdk: 1.8. 0 _152
// Main method entry, which is more like a loader
Main-Class: org.springframework.boot.loader.JarLauncher
// A space-separated list of relative paths to a library or resource
Class-Path: core.jar lib/ properties/
    
    
//---------------- Other attributesName: package Name; implementation-build-date: Implementation Build Date; implementation-title: Implementation Title; implementation-vendor: Specification-Title Specification-Vendor Specification-Version Specification-Version Specification-Version Specification-Version Specification version Sealed: So do all the classes of the package come from the same JAR// 1: formatManifest.mf is a standard key:value (headers:attributes) KEY1: value1 Key2: value2// A valid header must have space between the colon and the value. Another important point is that there must be a new line at the end of the file, otherwise the last line will be ignored

   

Copy the code

Appendix II: Package signature

The JavaTM platform allows you to digitally sign JAR files, and when you sign a JAR file, you also have the option of timestamp the signature, which can be used to verify that the certificate used to sign the JAR file is valid at the time of signing.

To do this, you can also configure security policy control, which can be configured to grant security privileges to the applet and the application. For example, you can grant the applet permission to perform operations that are normally forbidden, such as reading and writing local files or running local executables

A signature consists of four elements: the private key, the public key and certificate, and the digest value

How signatures are used: The Java platform implements signing and verification by using special numbers called public and private keys

Usage process: The signer signs the JAR file with the private key, and the applied public key is placed in the JAR file with the certificate so that anyone who wants to verify the signature can use it

Summary value: The summary value is the hashed or encoded representation of the contents of the file, the same as the signature. A file summary changes only if and when the file itself changes.

Certificate: Using the public and private keys alone is not enough to really verify the signature, you need some way to verify that the public key is actually from the signer it claims to be from, which uses the concept of a certificate (by adding an additional element that is the certificate that the signer includes in the signed JAR file)


// When a JAR file is signed, a signature file is automatically generated and placed in the META-INF directory of the JAR file
// This directory contains the list of archive files. SF, extension

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=


Copy the code

3. Common operations

3.1 Obtaining the classpath in the JAR Package

// Obtain the value by using the JAR commandPrint out everything in the JARclassName:jar tf com-gang-bootdependency- 1.0 -SNAPSHOT.jarPrint allclass : jar tf com-gang-bootdependency- 1.0 -SNAPSHOT.jar | grep '\.class$' / /JavaThe code forpublic 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); }}returnclassNames; }}// Dynamic fetch at runtime
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 nameclasses.add(clazz); }}return classes;
}
    
Copy the code

3.2 Methods for generating a tree Structure

There are several ways to print the tree structure:


// The tree command can be used to generate the number of directories (PS: should be the system itself has this command).Print to the current file: tree /f >tree.txt// Tree for Windows (PS: this is not the same thing as the above)
1.Download the treeforWindows files: HTTP:/ / gnuwin32.sourceforge.net/packages/tree.htm (choose Binaries.zip)
2.Unzip tree.exe and put it in git project: git \usr\bin3.Antibonding - in the project pathgit base here (Git console)4. Run the tree -a command to display the tree using ASNI drawing characters instead of ASCII character combinations. -c Adds colors to the lists of files and directories to distinguish different types. -d Displays the directory name instead of the contents. -d Lists when files or directories have been changed. -f Displays the complete relative path name before each file or directory. -f add "*","/"," to the file, directory, Socket, symbolic connection, and pipe name respectively.=","@","| "number. -g Lists the group name of a file or directory. If there is no group name, the group ID is displayed. -i does not list file or directory names in ladder form. -i does not display the file or directory names that match the template style. -l Lists the original directory to which the link points if the directory is a symbolic link. -n Does not add colors to file and directory listings. -n Lists the file and directory names, including control characters. -p Lists permission identifiers. -p displays only file or directory names that match the template style. - q "?"Replaces the control character to list file and directory names. -s Lists the size of a file or directory. -t Sorts files and directories by change time. -u Lists the owner name of a file or directory. If there is no corresponding name, the user ID is displayed. -x limits the scope to the current file system. If some subdirectories of the specified directory are stored on another file system, the subdirectories are excluded from the search scope. $tree. | -- -- classes | ` - com | ` - gang | ` - study / / third way: / / http://dir.yardtea.cc/ online tree translation four: Use software to display the number structure as shown above to download software DirPrintOKCopy the code

3.3 JAR decompile method

// Solution 1: Tool view

1.ZIP decompressed, directly through Java Decompiler view? - The scheme for partsclassThe limitations are as follows: //INTERNAL ERROR/ / 2.JD Project: The most commonly used bestjavaOne of offline decompilers 3.Cavaj Java Decompiler 
4. DJ Java Decompiler
5. JBVD 
6. androidchef 
7. Procyon 
8. CFR Decompiler
9. FernFlower
10. Krakatau
11. Luyten// The compiler is the same, but only transcoding, I can try to use any of the above, I usually use myselfJD-GUI / Jar Explorer
https: / /java-decompiler.github.io// / Solution 2: decompile command linejava -jar JDCommandLine.jar ${TARGET_JAR_NAME}.jar ./classes
Copy the code

3.4 How can I Prevent Decompilation

Java bytecode retains type information about fields, method return values, and parameters, but it does not contain type information about local variables.

The type information in Java class files makes the bytecode decompilation task much easier than machine code decompilation.

Therefore, decompilating Java bytecode requires analyzing most local variable types, flat stack instructions, and structured loops and conditions.

Option 1: Obfuscate class files with YGuard (similar to ProGuard, etc.)

It can transform compiled code into code that is difficult for humans to understand, while helping to reduce application startup time.

Most importantly, it’s a completely open source program. How to confuse YGuard:

  • Remove class files from reverse engineering by replacing package, class, method, and field names with unexpressible characters
  • The shrink engine analyzes the bytecode of all input Jar files to determine which code entities cannot be reached from a given set of code entry points. YGuard then removes these outdated code snippets (entire classes or individual methods and fields).

YGuard is a free open source Java bytecode obfuscator and Shrinker that obfuscates and obfuscates bytecode.

@ github.com/yWorks/yGua… @ github.com/yWorks/yGua…

<dependency>
	<groupId>com.yworks</groupId>
	<artifactId>yguard</artifactId>
	<version>3.0. 0</version> <scope>compile</scope> </dependency> <! <artifactId> <version> <version> <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 documentationfor information about the <yguard> element-->
                    </yguard>
                </tasks>
            </configuration>
		</execution>
	</executions>
</plugin>


    

Copy the code

Option 2: If you want to hide a string, consider encrypting the property

Scenario 3: Many decompilers do not adapt to new features and some tool frameworks, such as lambdas

Solution 4: Customize a ClassLoader for specialized decryption

Solution 5: Use Protector4J to encrypt jar files, convert jar files to private JARX format, and protect class files and application structure

Protector4j.com/ (PS: personal use, no evaluation, similar to JarProtector, but protector4j is newer)

3.5 Maven package jars

<! Build jar with Maven pom.xml file -->
<modelVersion>4.0.0</modelVersion>
<version>0.1.0 from - the 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>
    
<! -- Can also be used directly -->
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
    
Copy the code

3.6 Package files into jars

You can use the jar -u command to update files in the JAR. This command is usually used for system customization. The common format is as follows:



jar uf JarExample.jar com/baeldung/jar/JarExample.class
    
    
// Example: need to replace child-1.3.4.jar dependency inside parent-.jar

// Step 1: Prepare the related path (for example, if you want to place it under the path, create a similar path externally)Build directory: \new_version\ boot-INF \classes\bundles// Step 2: Move the bundles jar to this path
    
// Step 3: Run the command
jar -uvf0 parent.jar BOOT-INF/classes/bundles/child-1.34..jar


Copy the code

4. Other operations

4.1 Manually Creating a JAR file

In this case, I’ll just compile.java and package it into a JAR file and execute it

// Step 1: Prepare a.java method
public class DefaultMain {
    public static void main(String[] args){
        System.out.println("Test Default Main Success!"); }}// Step 2: Package it as a.class file (run it to generate a defaultMain.class)
javac -d . DefaultMain.java
    
    
// Step 3:
    
// Step 4: Package it into a JAR file (run it to generate an example.jar)
jar cfe example.jar com/gang/DefaultMain com/gang/DefaultMain.class
    
// Step 5: Execute jar
java -jar example.jar    
    
    
// Appendix: JAR package structure
.
|-- META-INF
|   `-- MANIFEST.MF
|-- com
|   `-- gang
|       `-- DefaultMain.class
`-- tree.txt

3 directories, 3 files

    
Copy the code

4.2 Maven added manifest.mf file

This is done by editing the manifest.mf file with 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>
Copy the code

4.3 JAR Add the manifest.mf file

Add manifest.mf manually with the JAR command. The most important thing is to end the MANIFEST file with a newline, otherwise it will be ignored by default

// Step 1: Prepare an arbitrary text file and add properties.
Built-By: gang

// Step 2: Package with a commandjar cvfm example.jar manifest.txt com/gang/DefaultMain.class .. / test > jar CVFM example. The jar manifest. TXT com/gang/DefaultMain. The class has been added listing are added: com/gang/DefaultMain. Class (= input442Output =299) (compressed32%)
    
// Unzip the final result:
Manifest-Version: 1.0
Built-By: gang
Created-By: 1.8. 0 _152 (Oracle Corporation)    

Copy the code

4.4 Define multiple JDK versions in JAR

When you want a JAR package to run across multiple versions of the JDK, you can build it as follows:

├ ─ ─ pom. XML ├ ─ ─ the SRC │ ├ ─ ─ the main │ │ ├ ─ ─ Java │ │ │ └ ─ ─ com │ │ │ └ ─ ─ gang │ │ │ └ ─ ─ the test │ │ │ ├ ─ ─ DefaultVersion. Java │ │ │ └ ─ ─ App. Java │ │ └ ─ ─ java9 │ │ └ ─ ─ com │ │ └ ─ ─ gang │ │ └ ─ ─ the test │ │ └ ─ ─ DefaultVersion. Java<! Build with 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>
    				   <! <multiReleaseOutput>true</multiReleaseOutput> -->
                        <outputDirectory>${project.build.outputDirectory}/META-INF/versions/9</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
    
<! -- Step 2: Set the multi-release entry in the MANIFEST to true -->
<! With this configuration, the Java runtime will look for version-specific classes in the Meta-INF/Versions folder of the JAR file; Otherwise, use only the base class -->

<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>
    
    
    
Copy the code

4.5 Fat JAR packaging

What is a Fat JAT?

A Fat JAR is also a JAR, and differs from a regular JAR in that it contains classes from all the libraries that your project depends on, as well as the classes of your current project.

Take Spring’s packaging as an example: Spring packages the application code to boot-INF. classes, and packages the dependencies to the boot-inf. lib directory Spring. It is then loaded using a special class loader

 

    

    
<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>
Copy the code

5. JAR commands and common operations

5.1 JAR command template

Jar {ctxu}[vfm0M] [manifest- file] [-c directory] file name...

{ctxu} is a subcommand of the JAR command. Each JAR command can contain only one ctXU

-t: lists the contents of the JAR package. -x: expands the specified or all JAR files in the JAR package. -u: updates the existing JAR package (adds files to the JAR package). -v: generates a detailed report and prints it to standard output. -f: specifies the name of the JAR file, which is usually required. -m: Specifies the MANIFEST file to include. -m: Does not generate an all-item MANIFEST file. This argument ignores the -m parameter [JAR – file] : The manifest file is an auxiliary parameter to the -f parameter. The manifest file is an auxiliary parameter to the -m parameter. [-c directory] indicates the operation of executing the JAR command in the specified directory. It is equivalent to running the CD command to the directory and then executing the JAR command without the -c argument. It is only available when creating and updating jar packages. The file name… : Specifies a list of files/directories to be added to the JAR package. If a directory is specified, all files and subdirectories in that directory are automatically packaged by the JAR command.

5.2 Common JAR commands

@ jar-The Java Archive Tool (oracle.com)

One: JAR command to set the Class main Class

jar cfe example.jar com.gang.DefaultMain com/gang/*.class // MANIFEST file MANIFEST -Version: 1.0 Created-By: 1.8.0_152 (Oracle Corporation) main-class: com.gang.DefaultMainCopy the code

Two: Run the JAR

java -jar test.jar
Copy the code

Three: JAR content management

// Extract the JAR contents
jar xf jar-file [archived-file(s)]

// Check the contents of the JAR
jar tf jar-file

// Update the JAR contents
jar uf jar-file input-file(s)

Copy the code

Four: list management

// The command line modifies the manifest file
jar cfm jar-file manifest-addition input-file(s)

// Set the default entry
jar cfm MyJar.jar Manifest.txt MyPackage/*.class

// 添加 class
jar cfm MyJar.jar Manifest.txt MyPackage/*.class

Copy the code

Other retrieval

// Specify the main class:
> java -cp JarExample.jar com.baeldung.jar.JarExample
> java -cp JarExample.jar com/baeldung/jar/JarExample
    
// List the contents of the Jar:
> jar tf JarExample.jar
    
// Look at the manifest file
> unzip -p JarExample.jar META-INF/MANIFEST.MF    
    
Copy the code

6. Other

6.1 Differences between WAR and JAR

The JAR package

Simply put, a JAR or Java Archive is a package file format. A JAR file has a.jar extension and may contain library, resource, and metadata files. In fact, it is a compressed file that contains. Compressed versions of class files and compiled Java libraries and application resources

WAR file

WAR is short for Web Application Archive or Web Application Resource. These Archive files have the.war extension for packaging Web applications, These applications can be deployed on any Servlet/JSP container.

// WAR format
META-INF/
    MANIFEST.MF
WEB-INF/
    web.xml
    jsp/
        helloWorld.jsp
    classes/
        static/
        templates/
        application.properties
    lib/
        // *.jar files as libs

Copy the code

6.2 Java.util. jar API usage

Official API documentation

6.3 compared to BOOT – INF

Boot-inf, what’s the purpose of this folder?

Refer to the address

Features of the boot-INF structure:

  • The Spring Boot application loads the form boot-INF folder
  • Application classes should be in a nested boot-INF /classes directory
  • Dependencies should be in a nested boot-INF /lib directory

Boot-inf solves the following problem:

Java does not provide any standard way to load nested JAR files (that is, to load a JAR file that is itself contained within a JAR). The problem arises when you need to distribute a self-contained application that can be run from the command line without decompressing

PS : 其实这里就是前文说的 FAT JAR

To do this, Spring adopts the following directory structure, placing application classes in a nested boot-INF /classes directory

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 for the War package directory format (dependencies should be in a nested WEB-INF/lib directory) :
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


Copy the code

The BOOT – INF index

Boot-inf is all about aggregating packages and applications. It has multiple index files:

  • Classpath Index (classpath.idx) : Provides the order in which jars are added to the Classpath
  • Layer Index (layers.idx) : Provides a list of the sections that should be included in the Layer and 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/"


Copy the code

The BOOT – loaded INF

The BOOT – INF based on org. Springframework.. The BOOT loader. The jar to load, this class allows from the standard of sub jar jar files or nested data loading jar in the content

When first loaded, the location of each JarEntry is mapped to the physical file offset of the external JAR

myapp.jar +-------------------+-------------------------+ | /BOOT-INF/classes | /BOOT-INF/lib/mylib.jar | |+-----------------+||+-----------+----------+| || A.class ||| B.class | C.class || | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | | + -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- + | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + ^ ^ ^0063                 3452        3980
 
// You can see:
1.In the location of myApp.jar0063Find a.lass in/boot-INF /classes2.In myApp.jar3452To find the B.lass from the nested JAR3.Arthur c. lass, located in the3980The location of theCopy the code

Armed with this information, we can load specific nested entries by looking for the appropriate part of the external JAR, which is the main way boot-INF has dealt with externals since

Spring also provides multiple initiators to load resources:

  • Springframework.boot.loader.Launcher
    • This class is a special bootstrap class that serves as the main entry point for the executable JAR. This is the actual main-class in the JAR file that is used to set up the appropriate URLClassLoader and ultimately to call the Main () method
  • JarLauncher: child launcher. Find it in boot-INF /lib/
  • WarLauncher: child launcher, find it in web-INF /lib/ and web-INF /lib-proved/
  • PropertiesLauncher: Child launcher that looks for boot-INF /lib/ in the application archive by default (additional paths allowed)
// Configuration mode:
Main-Class: org.springframework.boot.loader.WarLauncher
Start-Class: com.mycompany.project.MyApplication

Copy the code

conclusion

Do not know how to write a summary, is a summary of the document, so there is no need to summarize..

I just want to make fun of it. I have been taking the technical route all the time, but I deeply feel that the technical documents of long length have little appeal. Although writing the document itself is still to serve themselves, but no one really affect the mentality, once doubted whether the summary is not good, later when they used to review will not understand ~~

reference

Official Reference Document

  • JAR File Specification (oracle.com)
  • The Java ™ Tutorials

Other Reference Documents

  • www.baeldung.com/jar-file-ge…
  • www.baeldung.com/java-view-j…
  • www.baeldung.com/java-view-j…
  • www.baeldung.com/install-loc…
  • www.baeldung.com/executable-…
  • www.baeldung.com/deployable-…
  • www.baeldung.com/java-jar-ex…
  • www.baeldung.com/java-create…
  • www.baeldung.com/java-jar-wa…
  • www.baeldung.com/java-jar-ma…
  • www.baeldung.com/maven-multi…