Question

I have solution split into 2 projects:

  • The independent project contains interface ExampleInf and declares some services needed for the application. Those services are provided by the third party API (Hadoop client API). This project contains GUI components and other application logic but does not link third party libraries that provide services declared by ExampleInf. There is no class implementing ExampleInf in this project.
  • The dependent project that contains links to third party libraries. This project contains class ExampleImpl that encapsulates third party API and implements ExampleInf.

In the independent project there is class (let's call it class A) that consumes (uses) services declared by ExampleInf. Because the independent does not link the dependent project, in order to use ExampleInf it needs to load its implementation ExampleImpl dynamically in runtime. Also it needs to dynamically load all the third party libraries required by ExampleImpl.

Currently this is done by a bunch of constants (public static final String attributes) that contain paths to dependent project where dynamically loaded resources are located and a lot of messy ClassLoader code. I do not consider this to be a good solution. Is there any pattern, best practice or common way how this can be done? What would you recommend in your experience?

This pattern reminds me a bit of dependency injection in Java EE. At least I think it is good idea to externalize the locations of classes and libraries (.jar-s) that need to be loaded dynamically to XML and then load them all in cycle instead of calling ClassLoader.loadClass separately for each constant. Is there any nice clean way how to load XML in the same package and load classes and jars specified by that XML? Code example would be much appreciated.

Was it helpful?

Solution

You can use the ServiceLoader utility to do this (this is how many of the jdk services are loaded, e.g. xml libraries and modern jdbc driver libraries). If the dependent project is part of the classpath at startup, then you are good to go (assuming it is setup correctly). otherwise, you would need to load the dependent project in a nested classloader and pass that to the load(Class,ClassLoader) method (or set the classloader as the current context classloader before calling load(Class)).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top