Could URLClassLoader be approperiate for SPI?

2019-09-10 07:21发布

问题:

I'm trying to load a jar at runtime by URLClassLoader through Service Provider API. However, it turns out a failure.

Following are what I've done:

  1. Create a module named shadow-plugin-api, which contains interface com.github.soiff.shadow.api.Plugin to be implemented by plugin;
  2. Create a implementation of shadow-plugin-api named shadow-plugin and packaged as shadow-plugin-0.0.1-SNAPSHOT.jar, the implementation class is com.github.soiff.shadow.plugin.SpringPlugin;
  3. Create spring boot application named shadow-core and include shadow-plugin-api;
  4. Load shadow-plugin-0.0.1-SNAPSHOT.jar by URLClassLoader dynamically and try to load my com.github.soiff.shadow.plugin.SpringPlugin through ServiceLoader but it gets nothing.

My git repository is : https://github.com/soiff/soiff-shadow.

I've tried following solution, but still could not make it work. Please give me some advice, thanks in advance!

  1. I've tried abstract class instead of interface of my SPI interface and change it back to interface when I could not achieve my goal;
  2. I've tried PathMatchingResourcePatternResolver to get resource and pass my URLClassLoader as the input parameter but it did not work;
  3. I've tried ResourceFinder implemented by Apache and it could not find proper resource neither;

My question is how could I load resources from an external jar by URLClassLoader? Could SPI be a possible solution?

回答1:

To put it simple, the answer is yes.

And you may curious about what was going wrong, good question, the answer is URLClassLoader. But how? URLClassLoader is good enough to handle this with each items you've put it. In other words, there could be as many items as you've put into your URLClassLoader by parameter urls. So, if you want to make it work, you need to uncompress your external jar to a specified directory and add all items extracted to your URLClassLoader by input parameter urls as:

loader = new URLClassLoader(list.toArray(new URL[0]));

Where list contains all items.

Maybe there is other good solution, but this is just working for me. It's appreciate that if any guy could post another better solution for this. Thanks in advance!

By the way, this solution is based on Hadoop project. Thanks for the excellent project of Apache Hadoop Work Team.



标签: java spi