/*
 * Licensed under MIT (https://github.com/ligoj/ligoj/blob/master/LICENSE)
 */
package org.ligoj.bootstrap.resource.system.plugin;

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;

import lombok.extern.slf4j.Slf4j;

/**
 * Application listener able to alter the class loader to the plugin class-loader.
 */
@Slf4j
public class PluginApplicationRunListener implements SpringApplicationRunListener, Ordered {

	/**
	 * Required Spring-Boot constructor to be compliant to {@link SpringApplicationRunListener}
	 * 
	 * @param application
	 *            The current application.
	 * @param args
	 *            The application arguments.
	 * @throws IOException
	 *             When reading plug-ins directory
	 */
	public PluginApplicationRunListener(final SpringApplication application, final String... args) throws IOException {
		if (PluginsClassLoader.getInstance() == null) {
			// Replace the main class loader
			log.info("Install the plugin classloader for application {}({})", application, args);
			Thread.currentThread().setContextClassLoader(new PluginsClassLoader());
		}
	}

	@Override
	public void starting() {
		// Nothing to do
	}

	@Override
	public int getOrder() {
		// Be sure to be executed before EventPublishingRunListener
		return -10;
	}

	@Override
	public void environmentPrepared(final ConfigurableEnvironment environment) {
		// Nothing to do
	}

	@Override
	public void contextPrepared(final ConfigurableApplicationContext context) {
		// Nothing to do
	}

	@Override
	public void contextLoaded(final ConfigurableApplicationContext context) {
		// Nothing to do
	}

	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		// Nothing to do
		log.error("Context failed to start", exception);
	}

	@Override
	public void running(ConfigurableApplicationContext context) {
		// Nothing to do
	}

	@Override
	public void started(ConfigurableApplicationContext context) {
		// Nothing to do
	}

}

@@ -537,32 +537,33 @@
 ader to the plug
+-
 in class-loader.
@@ -563,16 +563,16 @@
 loader.%0A
-
  */%0A@Slf
@@ -769,17 +769,16 @@
 ner%7D%0A%09 *
- 
 %0A%09 * @pa
@@ -1261,16 +1261,260 @@
 args);%0A%09
+%09%09replaceClassLoader();%0A%09%09%7D%0A%09%7D%0A%0A%09/**%0A%09 * Replace the current classloader by a %7B@link PluginsClassLoader%7D instance.%0A%09 *%0A%09 * @throws IOException%0A%09 *             When the stup failed.%0A%09 */%0A%09protected void replaceClassLoader() throws IOException %7B%0A
 %09%09Thread
@@ -1579,20 +1579,16 @@
 der());%0A
-%09%09%7D%0A
 %09%7D%0A%0A%09@Ov

Support custom classloader with spring-boot