We want to make a plugin-type main program based on spring. The main program can load other Spring jars and non-spring jars as a plugin. Each plugin is based on IPlugin, And the plugin's 'IPlugin' class same as the main program's 'IPlugin' class. We make the non-spring plugin work by 'URLClassLoader', But the way not for the spring plugin. In the 'TestPlugin' project, the implementation named of 'PluginTest' and execute 'SpringApplication.run(PluginTest.class, args);' in function 'init(String[])'. 'ClassNotFoundException' occurred for load class 'PluginTest'.

     String pluginClassName =  "com.example.demo.PluginTest";
    c = newClassLoader.loadClass(pluginClassName);

So, We replace the pom 'plugins' section like following:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <finalName>${project.artifactId}-${project.version}</finalName>
        <appendAssemblyId>false</appendAssemblyId>
        <attach>false</attach>
        <archive>
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

But, We got another error 'Caused by: java.lang.NoClassDefFoundError: com/zaxxer/hikari/HikariConfig' (JDBC used in test project). I don't know how to properly load other spring jars at run time.

Whole codes of plugin loader:

@Component
public class Initializer implements ApplicationRunner
{
    @Override
    public void run(ApplicationArguments args)
    {
        String jarPath = "e:/tmp/demo-0.0.1-SNAPSHOT.jar";
        File file = new File(jarPath);
        IPlugin p;

        try
        {

            ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
            URLClassLoader newClassLoader = new URLClassLoader(new URL[]{file.toURI().toURL()}, oldClassLoader);
            Thread.currentThread().setContextClassLoader(newClassLoader);

            String pluginClassName =  "com.example.demo.PluginTest";
            Class<?> c = newClassLoader.loadClass(pluginClassName);
            Object pluginTest = c.newInstance();
            p = (IPlugin)pluginTest;
            p.init(new String[]{
                    "--spring.config.location=e:/tmp/application.properties"
            });
        }
        catch (Exception e)
        {
            System.out.println(e);
            e.printStackTrace();
        }
    }
}

Comment From: snicoll

Unfortunately, there's nothing Spring Boot specific in your question and we prefer to use this tracker for bug and enhancement reports.