0

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.

omni
  • 4,104
  • 8
  • 48
  • 67
  • Would you consider using java decompiler to see how the ServiceLoader is used in the 3rd party library? And just guessing, could it be that it uses the wrong classloader? Do you have multiple external.lib.path.TheConreteClass or TheFactoryInterface in classpath? – Zoran Regvart Nov 12 '14 at 13:10
  • decompiler would be like the last thing ever I'd try if nothing else works. Yes, I'm almost sure it's using the wrong classloader but I dunno how to fix it since the external lib dosn't provide a way to provide a different classloader to the method that is using the serviceLoader. No, there are not multiple paths to the conrete in the classpath - checked that already. – omni Nov 12 '14 at 15:22
  • There you go, use the decompiler ;) – Zoran Regvart Nov 12 '14 at 21:31

1 Answers1

0

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.

omni
  • 4,104
  • 8
  • 48
  • 67