title: Keycloak Provider not found
body: <p>i got a Keycloak 4.2.1 Server and im trying to implement a custom "LoginFormsProvider" for it. My goal is to extend to the login page (freemarker) with an additional component, in my case a simple information box. The content of that box i would like to set in the Provider class.</p>
  
  <p>I already have implement two other custom provider and they works fine (UserStorageProvider and EventListenerProvider). So my .jar file is found by the server.</p>
  
  <p>But i have problems with the "LoginFormsProvider". The Server does not find the provider. See the stacktrace below...</p>
  
  <p>I added a file "org.keycloak.login.LoginFormsProviderFactory" in the "META-INF/services" path
  with the package and class name, "de.test.login.TestLoginFactory" (without quotes).</p>
  
  <p>Which leads to the Factory Class of my Provider.
  Like i did it for the other providers.</p>
  
  <p>My FactoryClass looks like this:</p>
  
  <pre><code>package de.test.login;
  
  import java.util.LinkedHashMap;
  import java.util.Map;
  
  import org.jboss.logging.Logger;
  import org.keycloak.Config.Scope;
  import org.keycloak.freemarker.FreeMarkerUtil;
  import org.keycloak.login.LoginFormsProvider;
  import org.keycloak.login.LoginFormsProviderFactory;
  import org.keycloak.models.KeycloakSession;
  import org.keycloak.models.KeycloakSessionFactory;
  import org.keycloak.provider.ServerInfoAwareProviderFactory;
  
  public class TestLoginFactory  implements  LoginFormsProviderFactory{
  
      private FreeMarkerUtil freeMarker;
      private final static String PROVIDER = "test-login-provider";
  
      @Override
      public LoginFormsProvider create(KeycloakSession session) {
          return new TestLoginProvider(session, freeMarker);
      }
  
      @Override
      public void init(Scope config) {        
          freeMarker = new FreeMarkerUtil();
      }
  
      @Override
      public void postInit(KeycloakSessionFactory factory) {
      }
  
      @Override
      public void close() {
          freeMarker = null;
      }
  
      @Override
      public String getId() {
          return PROVIDER;
      }
  
  }
  </code></pre>
  
  <p>Here the Provider class:</p>
  
  <pre><code>package de.test.login;
  
  import javax.ws.rs.core.Response;
  
  import org.jboss.logging.Logger;
  import org.keycloak.freemarker.FreeMarkerUtil;
  import org.keycloak.login.freemarker.FreeMarkerLoginFormsProvider;
  import org.keycloak.models.KeycloakSession;
  
  public class TestLoginProvider extends FreeMarkerLoginFormsProvider{
  
      final private Logger logger = Logger.getLogger(this.getClass());
  
      public TestLoginProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
          super(session, freeMarker);
      }
  
      @Override
      public Response createLogin(){
          logger.info("do crazy stuff");
          Response response = super.createLogin();
          return response;        
      }       
  }
  </code></pre>
  
  <p>In my standalone.xml i added a spi declaration near by the other spi declarations.</p>
  
  <pre><code>&lt;spi name="login"&gt;
      &lt;default-provider&gt;test-login-provider&lt;/default-provider&gt;
  &lt;/spi&gt;
  </code></pre>
  
  <p>Here the complete section of the standalone.xml:</p>
  
  <pre><code>...
      &lt;subsystem xmlns="urn:jboss:domain:keycloak-server:1.1"&gt;
          &lt;web-context&gt;auth&lt;/web-context&gt;
          &lt;providers&gt;
              &lt;provider&gt;
                  classpath:${jboss.home.dir}/providers/*                 
              &lt;/provider&gt;
          &lt;/providers&gt;
          &lt;master-realm-name&gt;master&lt;/master-realm-name&gt;
          &lt;scheduled-task-interval&gt;900&lt;/scheduled-task-interval&gt;
          &lt;theme&gt;
              &lt;staticMaxAge&gt;2592000&lt;/staticMaxAge&gt;
              &lt;cacheThemes&gt;true&lt;/cacheThemes&gt;
              &lt;cacheTemplates&gt;true&lt;/cacheTemplates&gt;
              &lt;dir&gt;${jboss.home.dir}/themes&lt;/dir&gt;
          &lt;/theme&gt;
          &lt;spi name="eventsStore"&gt;
              &lt;provider name="jpa" enabled="true"&gt;
                  &lt;properties&gt;
                      &lt;property name="exclude-events" value="[&amp;quot;REFRESH_TOKEN&amp;quot;]"/&gt;
                  &lt;/properties&gt;
              &lt;/provider&gt;
          &lt;/spi&gt;
          &lt;spi name="userCache"&gt;
              &lt;provider name="default" enabled="true"/&gt;
          &lt;/spi&gt;
          &lt;spi name="userSessionPersister"&gt;
              &lt;default-provider&gt;jpa&lt;/default-provider&gt;
          &lt;/spi&gt;
          &lt;spi name="timer"&gt;
              &lt;default-provider&gt;basic&lt;/default-provider&gt;
          &lt;/spi&gt;
          &lt;spi name="login"&gt;
              &lt;default-provider&gt;test-login-provider&lt;/default-provider&gt;
          &lt;/spi&gt;      
          &lt;spi name="connectionsHttpClient"&gt;
              &lt;provider name="default" enabled="true"/&gt;
          &lt;/spi&gt;
          &lt;spi name="connectionsJpa"&gt;
              &lt;provider name="default" enabled="true"&gt;
                  &lt;properties&gt;
                      &lt;property name="dataSource" value="java:jboss/datasources/KeycloakDS"/&gt;
                      &lt;property name="initializeEmpty" value="true"/&gt;
                      &lt;property name="migrationStrategy" value="update"/&gt;
                      &lt;property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/&gt;
                  &lt;/properties&gt;
              &lt;/provider&gt;
          &lt;/spi&gt;
          &lt;spi name="realmCache"&gt;
              &lt;provider name="default" enabled="true"/&gt;
          &lt;/spi&gt;
          &lt;spi name="connectionsInfinispan"&gt;
              &lt;default-provider&gt;default&lt;/default-provider&gt;
              &lt;provider name="default" enabled="true"&gt;
                  &lt;properties&gt;
                      &lt;property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/&gt;
                  &lt;/properties&gt;
              &lt;/provider&gt;
          &lt;/spi&gt;
          &lt;spi name="jta-lookup"&gt;
              &lt;default-provider&gt;${keycloak.jta.lookup.provider:jboss}&lt;/default-provider&gt;
              &lt;provider name="jboss" enabled="true"/&gt;
          &lt;/spi&gt;
          &lt;spi name="publicKeyStorage"&gt;
              &lt;provider name="infinispan" enabled="true"&gt;
                  &lt;properties&gt;
                      &lt;property name="minTimeBetweenRequests" value="10"/&gt;
                  &lt;/properties&gt;
              &lt;/provider&gt;
          &lt;/spi&gt;
          &lt;spi name="x509cert-lookup"&gt;
              &lt;default-provider&gt;${keycloak.x509cert.lookup.provider:default}&lt;/default-provider&gt;
              &lt;provider name="default" enabled="true"/&gt;
          &lt;/spi&gt;
      &lt;/subsystem&gt;
  ...
  </code></pre>
  
  <p>Now when i start the server i got the stacktrace below. I dont know why he cannot  find the Factory class?</p>
  
  <p>I checked the .jar file and there are not missing any files. </p>
  
  <p>Stacktrace:
  <pre><code> 
  08:54:32,971 INFO  [org.jboss.as.server] (Thread-2) WFLYSRV0220: Server shutdown has been requested via an OS signal
  08:54:32,973 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 49) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./auth: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./auth: java.lang.RuntimeException: RESTEASY003325: Failed to construct public org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:84)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at java.lang.Thread.run(Thread.java:745)
      at org.jboss.threads.JBossThread.run(JBossThread.java:320)
  Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to construct public org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
      at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:162)
      at org.jboss.resteasy.spi.ResteasyProviderFactory.createProviderInstance(ResteasyProviderFactory.java:2298)
      at org.jboss.resteasy.spi.ResteasyDeployment.createApplication(ResteasyDeployment.java:340)
      at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:253)
      at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:120)
      at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
      at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
      at org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
      at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
      at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:250)
      at io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:133)
      at io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:565)
      at io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:536)
      at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
      at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
      at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
      at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction$$Lambda$847/1223919585.call(Unknown Source)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction$$Lambda$848/1436296213.call(Unknown Source)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction$$Lambda$848/1436296213.call(Unknown Source)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction$$Lambda$848/1436296213.call(Unknown Source)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction$$Lambda$848/1436296213.call(Unknown Source)
      at io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:578)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
      at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:81)
      ... 6 more
  Caused by: java.lang.RuntimeException: Failed to find provider test-login-provider for login
      at org.keycloak.services.DefaultKeycloakSessionFactory.checkProvider(DefaultKeycloakSessionFactory.java:171)
      at org.keycloak.services.DefaultKeycloakSessionFactory.init(DefaultKeycloakSessionFactory.java:90)
      at org.keycloak.services.resources.KeycloakApplication.createSessionFactory(KeycloakApplication.java:326)
      at org.keycloak.services.resources.KeycloakApplication.(KeycloakApplication.java:117)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
      at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:150)
      ... 33 more
  </pre></code> </p>
  
  <p>If you guys need some more information let me know.</p>
  
  <p>Did i forgot something or is there a mistake?</p>
  
  <p>I would be very thankful for your help.</p>
  
  <p>kind regards </p>