Download and replace the Java 9 ServiceLoader runtime module

I just read about modular system Java 9 and I would like to ask about ServiceLoader . Is there a way to add a service implementation when the application is already running? How about removing some service implementation?

Use case: I will have some kind of application that calculates something. The calculation algorithm will be defined in some service (Java module 9). Are there any steps to replace this algorithm without stopping the application? When I will replace the banks, is it just that the calculation will fail and I will need to catch the error and restart when the module is loaded?

Is there any other project that can support this use case?

+5
source share
1 answer

Suppose BankController is your service. If you want to load its implementation dynamically from a dynamic path, create a new module layer and load the implementation.

 private final BankController loadController(final BankConfig config) { System.out.println("Loading bank with config : " + JSON.toJson(config)); try { //Curent ModuleLayer is usually boot layer. but it can be different if you are using multiple layers ModuleLayer currentModuleLayer = this.getClass().getModule().getLayer(); //ModuleLayer.boot(); final Set<Path> modulePathSet = Set.of(new File("path of implementation").toPath()); //ModuleFinder to find modules final ModuleFinder moduleFinder = ModuleFinder.of(modulePathSet.toArray(new Path[0])); //I really dont know why does it requires empty finder. final ModuleFinder emptyFinder = ModuleFinder.of(new Path[0]); //ModuleNames to be loaded final Set<String> moduleNames = moduleFinder.findAll().stream().map(moduleRef -> moduleRef.descriptor().name()).collect(Collectors.toSet()); // Unless you want to use URLClassloader for tomcat like situation, use Current Class Loader final ClassLoader loader = this.getClass().getClassLoader(); //Derive new configuration from current module layer configuration final Configuration configuration = currentModuleLayer.configuration().resolveAndBind(moduleFinder, emptyFinder, moduleNames); //New Module layer derived from current modulee layer final ModuleLayer moduleLayer = currentModuleLayer.defineModulesWithOneLoader(configuration, loader); //create new instance of Implementation, in this case org.util.npci.coreconnect.CoreController implements org.util.npci.api.BankController final BankController bankController = ServiceLoader.load(moduleLayer, BankController.class); return bankController; } catch (Exception e) {BootLogger.info(e);} return null; } 
0
source

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


All Articles