简体   繁体   中英

Maven Dependency & Java Service Provider Interface

Quick Background:
I have set up a Java Service Provider Interface to allow users to create their own custom plugins. The interface they implement is in its own stand alone package so I can release a smaller package to them without other bulky code.

Once users create their JAR, they can dynamically load it into the application during runtime using some reflection hacks (that I found here on SO). These seem to work well, but as soon as I moved to another developers machine (and our Jenkins box) the dependencies start getting thrown off somehow.

The JAR for the interface is a dependency of both the main app, and the smaller user created plugins. When users upload the JAR, they have been using a JAR that contains that dependency which is helping ensure the interface is the same. This allows the Java SPI to pick it up and make it useable. I have started switching the user packages to use the dependency as <scope>provided</scope> in hopes this fixes org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.util.ServiceConfigurationError: com.company.interface.MyInterface: Provider com.usercode.ClassName not a subtype org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.util.ServiceConfigurationError: com.company.interface.MyInterface: Provider com.usercode.ClassName not a subtype .

When using provided scope I run into different errors of java.lang.NoClassDefFoundError: com/company/interface/MyInterface when trying to load in user jars.

Anyone know what I could do with this Interface JAR and Maven to make these play nice together?

If the plugins are using provided scope for this jar then you need to make sure that the main application that runs these plugins does actually provide that jar on the classpath that the plugins can access.

Also this error: java.lang.NoClassDefFoundError is not the root cause. You should find the first instance of that error in the application logs which should show the root cause of that error. If the class is missing off the classpath it will be java.lang.ClassNotFoundException .

When you run your app, you need to put the implementation jar in -Djava.ext.dirs =..., instead of -cp ....
The app won't work or even throw exception if the implementation jar wasn't configured correctly.

java -Djava.ext.dirs=../DictionaryServiceProvider/dist:../GeneralDictionary/dist -cp dist/DictionaryDemo.jar dictionary.DictionaryDemo

see spi tutorial

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM