0

I have a maven application and I like to use the ServiceLoader mechanism to load plugins.

Currently I achieve this by adding the dependency to the pom, so that the dependency jar is in the classpath and the ServiceLoader can pick it up.

But how can this be achieved without declaring the dependency in the pom ?

I don't like to change the pom with every plugin that shall be used.

How can I do this - or must the plugin jar always be in the pom ?

Emerson Cod
  • 1,990
  • 3
  • 21
  • 39
  • How are you running your application? – Thorn G May 23 '16 at 20:30
  • Currently I use `GrizzlyHttpServerFactory.createHttpServer` to create a server. Its `ResourceConfig` shall load the plugins via the `ServiceLoader`. I guess when its more stable the idea is to use tomcat or similar. – Emerson Cod May 23 '16 at 20:33
  • So are you building a JAR? If so, how are you running it? You can always manually download these plugins and add them to the classpath yourself when running your app - but there is no way for Maven to read your mind and know you want them present without declaring them in your POM. – Thorn G May 23 '16 at 20:53
  • yes - for now I'm building a jar. I know that maven cannot read my mind, therefore I asked. I simply forgot the URLClassloader though and could work this out with it (see my answer). thanks for the help ! – Emerson Cod May 23 '16 at 22:08

1 Answers1

0

I was blind...

I simply can use the URLClassloader to load all plugin jars from a folder of my application.

public class IntegrationServiceLoader {
    public static <T> ServiceLoader<T> loadIntegrations(Path path, Class<T> clazz) {
        List<URL> fileNames = new ArrayList<>();
        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path)) {
            for (Path each : directoryStream) {
                fileNames.add(each.toUri().toURL());
            }
        } catch (IOException ex) {
        }
        URL[] array = fileNames.stream().toArray(size -> new URL[size]);
        ClassLoader cl = new URLClassLoader(array, IntegrationServiceLoader.class.getClassLoader());
        return ServiceLoader.load(clazz, cl);
    }
}

This is valid and works for the setup now.

punkeel
  • 869
  • 8
  • 12
Emerson Cod
  • 1,990
  • 3
  • 21
  • 39