I created a custom SBT Plugin for PMD (a sourcecode analysis tool) as there is no existing plugin available.
I based it on the SBT-RSS Plugin by Will Sargent.
I put the source on github:
https://github.com/domdorn/sbt-pmd
Right now, I have one problem, and I think it might be a bug in sbt or the way sbt uses classloaders:
PMD uses
java.util.ServiceLoader to load its Plugins. It does this in two places.
One is
net.sourceforge.pmd.lang.LanguageRegistryand one is
net.sourceforge.pmd.cpd.LanguageFactoryThe code looks more or less like how you would expect it:
public final class LanguageRegistry {
private static LanguageRegistry instance = new LanguageRegistry();
private Map<String, Language> languages = new HashMap();
private LanguageRegistry() {
ServiceLoader languageLoader = ServiceLoader.load(Language.class);
Iterator i$ = languageLoader.iterator();
while(i$.hasNext()) {
Language language = (Language)i$.next();
this.languages.put(language.getName(), language);
}
}
In my plugin, I've added the dependencies to PMD-Core, PMD-Java, PMD-Scala as libraryDependencies in build.sbt (is this the error?)
I can use/instantiate the above mentioned classes, in particular JavaLanguage/JavaLanguageModule in the plugin itself.
However, when the plugin calls into PMD, which itself then uses the ServiceLoader to look for the Services (JavaLanguage) nothing is
found.
So either it does not see these classes in the classloader at runtime or somehow the META-INF/services/... stuff disappeared.. ?
Is there a special thing needed so that the dependencies of the plugin are available during the plugins runtime?
Or is something broken in regard to classloaders?
You can test/reproduce this by checking out the project and change to the sbt-pmd-tester, then do a
sbt pmd
Thanks for your help.
Dominik