1

I am writing an extension for a library which consists of several Maven modules. I need to add some functionality on top of one module but do not want to add unnecessary dependencies in case somebody wants to use this module without my extension (typical use case).

One solution that I can think of is to create another module with my extension and try to call methods from its classes using reflection. There would be some kind of check like this:

try { Class.forName("my.package.Foo", false, getClass().getClassLoader()); // extension will be enabled and some method will be called using reflection } catch(ClassNotFoundException e) { // extension will be disabled } 

And methods on that class will only be called if it is on classpath. The extension can then be activated if you add Maven dependency on its module (in addition to the dependency on the module it extends).

But this does not sound like the best approach. Are there any more elegant solutions to this problem?

3 Answers 3

1

The one way is to use built-in Service provider interface (SPI).

The basic idea is to make your optional libraries to provide an implementations of some interface (a "services") which may be easily found by your main application. Take a look at this example

// scan classpath for all registered // implementations of Module interface ServiceLoader<Module> loader = ServiceLoader.load(Module.class); for (Module module : loader) { module.doSomething(); } 

Once your optional dependency is in classpath service loader will find it.

You can find a lot of examples in "Creating Extensible Applications" tutorial from Oracle on how to make it.

The other way is to use dependency injection frameworks such as spring or google guice. These frameworks are also providing a classpath scanning mechanisms for automatic component discovery. This solution is a way more flexible but heavier than SPI.

Sign up to request clarification or add additional context in comments.

Comments

1

you can definite your dependency like this:

<dependency> <groupId>com.thoughtworks.paranamer</groupId> <artifactId>paranamer</artifactId> <version>2.6</version> <optional>true</optional> </dependency> 

checkout the detail from this link

Comments

0

Simplest would be to create a new Module as you mentioned. And in this new Project A you have a dependency to this existing Module that you are talking about Project B. So now any body who wants to use without your extension would use Project B. And anyone who would need your extension would use Project A. Just make sure to add the Maven dependencies in the build Path to avoid ClassNotFound conflicts.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.