Use lib to separate the packaging structure

The package structure is as follows

target lib bin config

The main package is in the target directory.

When we use a development tool such as IDEA, we scan the Classpath class loader when the AppClassLoader.

So when we rewrite the third party framework class (all the class names are exactly the same), in the CLASSPATH, according to the ClassLoader parent delegate model, it is possible to replace the concrete implementation of the third party framework, in the Java development tool IDEA, war package deployment is possible

However, when using the above packaging structure, we will separate the lib (i.e. the third party JAR), and use the SpringBoot Maven packaging plug-in to configure zip, we will use PropertiesLauncher, and use -dloader. path to point to /lib, When used arthas surveillance main bag class, as well as third-party jar package class, class loading is org. Springframework.. The boot loader. LaunchedURLClassLoader, however, The above mentioned overwriting of the third party JAR class was not as expected when using IDEA at development time and deploying the WAR package. The implementation of the class is still the implementation of the third party JAR, not mine.

Comment From: wilkinsona

Thanks for the report. Unfortunately, I don’t understand the problem that you have described. Could you please share a minimal example that reproduces it?

Comment From: nogggan

Because there is a problem with a class in the third party framework, I want to modify it in my project. The easiest way is to rewrite the same class in this project. In this way, when the AppClassLoader scans the classpath, it will load our rewritten class first, and will not load the implementation in the third party JAR.

However, in SpringBoot's packaging structure that separates the target jar from the lib, the LaunchedUrlClassLoader does not meet expectations.

In springboot engineering, for example, I think in the org. Springframework. Boot. Autoconfigure. AutoConfigurationImportSelector selectImports method to print the log.

The best way to do this is to rewrite this class for this project

`public class AutoConfigurationImportSelector implements DeferredImportSelector {

public AutoConfigurationImportSelector() {
}

public String[] selectImports(AnnotationMetadata annotationMetadata) {

    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
        //log print
        String[] importBeanNames = StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        log.info("importBeanNames:{}",importBeanNames);
        return importBeanNames;
    }
}`

This can be done in either a single JAR or a WAR package.

However, with Maven Assembly packaging, the executable JAR, configuration file and third-party lib are separated and only the executable JAR is updated with each deployment update. In this packaging mode, the executable JAR is loaded by the LaunchedUrlClassLoader class loader in Spring-Boot.

So I specified -dloader. path=/lib and told the LaunchedUrlClassLoader to load the third party JAR as well.

But, cannot achieve expected, because LaunchedUrlClassLoader class loader without prior to loading AutoConfigurationImportSelector class in the executable jar file.

Comment From: wilkinsona

PropertiesLauncher should add BOOT-INF/classes and BOOT-INF/lib/*.jar to the end of the classpath, after anything specified by loader.path:

https://github.com/spring-projects/spring-boot/blob/2f852fa25694e593693e6faa175cd31ae5e62c8a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java#L643-L657

If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

Comment From: nogggan

Indeed, the boot-info /classes directory in the executable JAR is a low priority, thank you