it took some time, but I now I figured out what made Keycloak not load the SPI.
When an SPI is created, a new provider factory interface (that extends Keycloak ProviderFactory class) needs to be created as well. This interface should be returned by the getProviderFactoryClass method. A file for this interface implementation need to be present in the META-INF/services.
I was skipping this step, and instead creating a provider factory class that directly implements the ProviderFactory. This causes Keycloak not to load the SPI, because Keycloak does not load an SPI when it does not find a ProviderFactory implementation that can be loaded using the java ServiceLoader, in other words it should be present in META-INF/services.
Example:
public class DemoSPI implements Spi {
public boolean isInternal() {
return false;
}
public String getName() {
return "demoSPI";
}
public Class<? extends Provider> getProviderClass() {
return DemoProvider.class;
}
public Class<? extends ProviderFactory> getProviderFactoryClass() {
return DemoProviderFactory.class;
}
}
public interface DemoProviderFactory extends ProviderFactory<DemoProvider> {
}
public interface DemoProvider extends Provider {
void sayHi();
}
implementations:
public class SayHiProvider implements DemoProvider {
public void close() {
}
@Override
public void sayHi() {
System.out.println("Hi there void provider!");
}
}
public class SayHiProviderFactory implements DemoProviderFactory {
public DemoProvider create(KeycloakSession session) {
return new SayHiProvider();
}
public void init(Config.Scope config) {
System.out.println(" init");
}
public void postInit(KeycloakSessionFactory factory) {
}
public void close() {
}
public String getId() {
return "say-hi-provider";
}
}
Now under META-INF services, there should be two files that contains the implementations