2

The situation is as follows: I'm using some libraries that use a specific class to load and access configuration parameters. The config loader class is implemented in one of the libraries. What I did is: to extend the config loader class so that it fits my requirements and is able to load different config sources:

public class BetterConfigLoader extends OldConfigLoader {
    ...
}

Now I want to make the existing libraries use my compatible BetterConfigLoader without applying changes to the libraries or without the need to recompile them. Is there a way of best practice to accomplish this?

MiH
  • 115
  • 2
  • 13

2 Answers2

1

This depends on how your libraries refer to the configuration class. Do they have a hardcoded new OldConfigLoader().configure()?

Or do they use some kind of SPI technique, e.g. checking for existence of a resource named META-INF/services/ConfigLoader, and only if not existing, falling back to the default configuration class?

Instead of checking such a resource, they could as well check a System Property. In these cases, you can set your special class by creating a matching SPI resource, or by setting the System Property.

In case of hardcoded reference, you are out of luck.

Florian Albrecht
  • 2,266
  • 1
  • 20
  • 25
  • @MiH do you have the invocation example from the libraries' code? Do they directly call the constructor, or do they use some static factory method? In the latter case, if you are able to change the `OldConfigLoader` code, you could make the static factory method return the `BetterConfigLoader`. – Florian Albrecht Jan 18 '17 at 09:52
  • They call the constructor. I actually didn't want to change OldConfigLoader's code because it is part of an existing library which should be interchangeable – MiH Jan 19 '17 at 09:18
0

Instead of extending OldConfigLoader you can replace it. Start with the source code of OldConfigLoader, change it to suit your needs and then make sure your version is higher in the classpath then the original. Make sure your implementation has the same classname and is in the same package as the original.

  • "make sure your version is higher" - what do you mean with this? The only way to "replace" this class is by putting the new version of the class **before** the previous version on the CLASSPATH (see http://stackoverflow.com/a/6935725/2235015). Depending on environment, this may not be possible for the OP at all, and still, it would be very bad practice. – Florian Albrecht Jan 18 '17 at 14:36
  • Ah, ok, understood - "higher in the classpath", so preceding. Still, very bad practice. – Florian Albrecht Jan 18 '17 at 14:41
  • What do you think of using a custom class loader to accomplish this? – MiH Jan 19 '17 at 09:22
  • Of course this method is a patch and should be avoided if possible. The maintenance cost is high - the solution is very likely to break with future versions of the patched library. Point is, it does work and actually is not uncommon. – Michiel Pelt Jan 19 '17 at 13:10