How to make Java serviceLoader of a external library work

1.8k views Asked by At

I'm working on a plugin for a 3rd party software that is quite undocumented. For the plugin I'm using a external lib (.jar) managed by maven and is later on executed on a tomcat server. Everything was working great till I updated to the latest release of the library, which now is using java.util.serviceLoader in order to load a concrete implementation of a interface. When build, my project has this package structure on a tomcat server:

mypluginPackage.jar
|
---META-INF
---lib
   |
   --- theExternalLibUsingServiceLoader.jar
      |
      ---META-INF
         |
         ---services
            |
            --- full.path.to.TheFactoryInterface
      ---external.lib.path
         |
         --- TheFactoryInterface.class
         --- TheConreteClass.class
   --- mypluginCore.jar
      |
      ---META-INF
      --- my.plugin.path
         |
         --- MyClassUsingTheExternalLib.class

As you can see, the external library has the correct services entry which is necessary for the serviceLoader to find the concrete of a interface within META-INF. The content of the full.path.to.TheFactoryInterface file is full.path.to.TheConcreteClass, which seems legit.

My plugin (package as well as the core) however do not have any of those META-INF information.

What happens now is that every time my plugin is using a method that will trigger the serviceLoader of the external library, the serviceLoader is unable to find the concrete implementation.

What I already tried is adding the exact same services/full.path.to.TheFactoryInterface to all my META-INF directories, which is not working (I guess I would need to change the content of the full.path.to.TheFactoryInterface file but I'm not sure - because of the undocumented plugin structure for the 3rd party software - what the right (relative) path would look like).

Can anybody give me a shot what I'm doing wrong here and how to fix it so the concrete class is found by serviceLoader? What META-INF folder should the services folder with it's content be placed in and should I change the paths? Is that the error at all or am I missing something compleatly different?

I understand that this is a very special topic since the 3rd party software is unkown, but any information depending serviceLoader and it's behaviour when run across multiple jars with multiple META-INF folders and in different execution context / classpaths would be appreciated.

1

There are 1 answers

0
omni On BEST ANSWER

I was able to get it working by extending the external lib so I'm able to provide a custom ClassLoader. Turned out, the default ClassLoader was wrong.

Also I was able to get in touch with the 3rd party tool devs and get the information I needed - call it "social decompiling".

Everything working now.