Not able to register a custom SPI

Hello,

I have a keycloak extension in which I am overriding a bunch of provider factories (e.g EmailSenderProviderFactory, EventListenerProviderFactory,…etc). To do so, I simply add my class name inside a file that bears the providers name under /META-INF/services. I deploy everything as an ear file inside the /deploy folder and everything works ok.

When I create a custom Spi with my own providers, it is not picked up by keycloak (or wildfly) and I always get null when trying to load my provider using session.getProvider(MyOwnProvider.class), knowing that I followed the steps in docs here https://www.keycloak.org/docs/latest/server_development/#implementing-an-spi

in short I created an SPI e.g MyOwnSPI, and added a file name org.keycloak.provider.Spi under META-INF/services in which I put my SPI qualified name (with packages). I also tried playing with the standalone.xml spi and providers sections, still getting null.

am I missing on some step ?

Thanks in advance.

1 Like

I will try to create a sample project later

Hi zak, I am also trying to do that and experiencing the same issue, have you been able to find what’s wrong?

Hi,

unfortunately, I could not find a solution. I just did without using a custom SPI. It would be great to have this working.

take a look at https://github.com/zonaut/keycloak-extensions and see if this helps in any way

Hi zonaut,

nice examples, but there is no example of implementing your own Spi. You are just extending existing providers, and this is working for everyone. Here is what I meant: https://www.keycloak.org/docs/latest/server_development/#_extensions_spi

To do that you need add a org.keycloak.provider.Spi under META-INF/services, and add your own implementation. In this way, you can create your custom providers (vs. overriding exisiting ones)

If you find any way, I am happy to try.

Did you take a look at the example in the keycloak repo -> https://github.com/keycloak/keycloak/tree/master/examples/providers/domain-extension

and this is not working. at least for me and @matbest1.

1 Like

I’m facing the same issue.

I was capable of tracing that getProvider methods call getProviderFactory which in turn does not find our implemented factories… The thing is that is only happening with deployed providers… the same code loaded as a module works just fine.

Do anyone know why this happen?

PS.: I’m using the deployment approach mainly because I can define templates and messages inside theme-resources directory, what I couldn’t with module method.

Hi

I had the same experience with Custom SPIs.
The Steps that ive taken:

  1. public class ExampleSpi implements Spi {


}

  1. public interface ExampleServiceProviderFactory extends ProviderFactory {

    }

  2. public class ExampleServiceProviderFactoryImpl implements ExampleServiceProviderFactory {

    }

  3. public interface ExampleService extends Provider {

    }

  4. public class ExampleServiceImpl implements ExampleService {

    }

  5. then under META-INF/services created the file org.keycloak.provider.Spi with the content com.xxx.xxx.xxx.xxx.ExampleSpi (xxx just denoting the full package path )

  6. then under META-INF/services created the file com.xxx.xxx.xxx.xxx.ExampleServiceProviderFactory with the content com.xxx.xxx.xxx.xxx.ExampleServiceProviderFactoryImpl

And Keycloak never picks up my provider factory.
But if i use RealmResourceProviderFactory and RealmResourceProvider, it works just fine. providerfactory and provider seems to be internal interfaces.

or?

Servet

Hi @servetzeybek,

as @mths0x5f mentionned, only the module method works. If you really need to use a deployment (in case you have a custom theme), then you can have two jars. One with your custom SPI interfaces and definitions which can be deployed as a Wildfly module. And the other one with your implementations and your custom themes which you can simply drop in standalone/deployment. This latter would need to depend on the module, so you will need to add a dependency on your module in the jboss-deployment-structure file.

Hope this helps.

yes, thanks it helped

1 Like

I was trying this approach before, and the custom spi is registered fine on keycloak, but when trying to implement on external apps/jars i only get ClassNotFoundException, event adding the module as dependency in the jboss-deployment-structure.xml.

I then tried to include the dependency on my ear as well, and I get a “not subtype” error when the spi is being created.

I gave up thinking it wont work, did get it working?

It is very unfortunate that the Spi provider is not supported in the server deployment mode. Are there any plans for it to be supported?

1 Like

Maybe worth mentionning this in the keycloak-dev group in Google groups.

You want to look into jboss-deployment-structure.xml
This is a file very similar to module.xml and it is packaged inside the jar one meta-inf.
So it describes inside-out the modules dependencies and the deployment works fine.

I needed this to leverage the standard docker container. I was able to mount the file from outside the docker container and if it’s being replaced it will be uninstalled and installed including details on the log.

I do have the jboss-deployment-structure.xml and it solved issues such as having all the jpa stuff and hibernate in place in order for custom entities and db migrations to work, but is there a specific dependency to add in there for a custom SPI to be recognized?

Yes I think so.
Here’s my example:

Hm, obviously xml is filtered out.

Use module name="org.keycloak.keycloak-server-spi-private”

hello,I have this same problem,custom spi,provider,providerFactory not register into keycloak.
do you reslove?

We are in process of upgrading the Keycloak from 3.4.0 to 15.0.2
After upgrading the Keycloak the server is not registering the AccessTokenIntrospectProviderFactory however it is loading the other factory classes like AutoLinkIdpLoginAuthenticatorFactory, RealmResourceProviderFactory etc…

All these files were added under META-INF.services