Why did Spring Boot 1.4 change its jar layout to find application classes in BOOT-INF?

(This is primarily a matter of history. Pivotal recommended that all forum discussions be held on StackOverflow, so I ask it here.)

What are the reasons the Spring boot project was used to justify porting application classes and dependencies from the top level of the jar executable format to BOOT-INF/ ?

Just trying to guess, it seems that this makes it easy to retrieve only the classes and banks associated with the application from the fat jar with the simple command java -xf the-jar.jar BOOT-INF/classes . It was? Was there another reason?

+6
source share
1 answer

TL DR

Classes of packaging applications in the jar root directory required Spring bootloader to use the unconventional delegation model, and also caused problems with Java agents.

Detailed explanation

When the jar file starts with java -jar , all classes in the root jar are in the class path of the system class loader. In the Spring Boot fat jar, this includes startup classes that are responsible for creating a class loader that can load application classes and their dependencies that are nested inside the fat jar.

In Spring Boot 1.3 and earlier, application classes are packaged at the root of the fat file. This means that they are in the path of the system class loader class. With a standard model with a parent first delegation, this would mean that application classes would be loaded by the system class loader, not Spring by the boot class loader. This is problematic because it is only a Spring bootloader class loader that can load classes from dependencies that are nested inside a fat jar. As a result, the application cannot load classes of any of its dependencies.

Spring Boot 1.3 overcame this problem using the unconventional delegation model for its class loader. He created a new class loader using URLs from the system class loader, but did not use the system class loader as a parent - instead, the system class parent loader was used. This meant that the Spring Boot class loader would be used to load application classes in the root jar and application dependency classes in nested banks.

This approach had some disadvantages. First, it made the Spring Boot class bootloader quite complex. Second, he violated a number of assumptions that Java agents make about how their classes will load. We worked on several of them, but it became clear that we are fighting a lost battle.

Spring Boot 1.4 shuffles the jar to place application classes in BOOT-INF/classes (it also moves nested jars to BOOT-INF/lib , but this does not affect the perspective of loading the class). Moving application classes to BOOT-INF/classes means that they are no longer in the class path of the system class loader. This means that the Spring Boot class loader can be configured to load classes from BOOT-INF/classes and from jars to BOOT-INF/lib and use the system class loader as a parent. Java agents can be packaged in the root jar, from where they will be loaded by the system class loader, as usual.

For further reading, you may be interested in the message of the command in which the change was made , and other problems with which it refers.

+10
source

Source: https://habr.com/ru/post/1011784/


All Articles