<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Ok, all clear! Thanks for the
      discussion/information so far.<br>
      We'll implement this feature in one of our coming sprints. We aim
      to be finished in time for 1.8.<br>
      <br>
      <br>
      On 16/11/15 13:41, Stian Thorgersen wrote:<br>
    </div>
    <blockquote cite="mid:CAJgngAeMJtR2Q&#43;EjXiJWbHbRJWMg9XN8STyhXz8gL_UVX2X-Fg@mail.gmail.com" type="cite">
      <div dir="ltr"><br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On 16 November 2015 at 13:26, Erik
            Mulder <span dir="ltr">&lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF">
                <div><i>@Christian:</i> Actually in Hibernate 5 the
                  Integrator does not offer the add entity feature
                  anymore. It seems this 'feature' was actually an
                  unintended side effect of the Integrator in Hibernate
                  4 (<a moz-do-not-send="true" href="http://stackoverflow.com/questions/32918808/how-to-use-integrator-service-in-hibernate-5-for-adding-annotated-classes" target="_blank">http://stackoverflow.com/questions/32918808/how-to-use-integrator-service-in-hibernate-5-for-adding-annotated-classes</a>
                  - <i>&quot;but the docs clearly point towards that not
                    being intentional as this should be done at the time
                    of initialization&quot;</i>). This complies with my
                  finding that adding the entity classes at this 'late'
                  stage skips some validation. So I guess I'll 'revert'
                  my solution to the one I found previously, which adds
                  the entity classes to the JPA persistence unit
                  configuration. I'll investigate if that is Hibernate 4
                  and 5 compatible.<br>
                  <br>
                  <i>@Stian: </i>It seems like almost all questions
                  have been answered and we can start to build the
                  feature and contribute it to KeyCloak. Maybe you can
                  provide some extra information / requirements /
                  guidelines to us. (we did read the 'Hacking on
                  Keycloak' page)<br>
                  - Is there a KeyCloak checkstyle configuration?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>No, we have not introduced one yet. However, we'd like
              code to follow code style from WildFly. You can get IDE
              configuration from here <a moz-do-not-send="true" href="https://github.com/wildfly/wildfly-core/tree/master/ide-configs">https://github.com/wildfly/wildfly-core/tree/master/ide-configs</a></div>
            <div>&nbsp;</div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF">
                <div> - Do we have to create one entry in the KeyCloak
                  JIRA for this or several under one epic?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>One is sufficient</div>
            <div>&nbsp;</div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF">
                <div> - Is there some peer review process? How does it
                  work?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Step one is to send an email to Keycloak Dev mailing
              list about what you are doing. This is obviously already
              done.</div>
            <div><br>
            </div>
            <div>Second stage is when you've prepared a PR one of the
              core developers will review it before merging.</div>
            <div><br>
            </div>
            <div>&nbsp;</div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF">
                <div> - What are the requirements for the documentation?</div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>No hard requirements, but in general for a new feature
              to be added it needs to be mentioned on the documentation.
              For this particular feature I think adding a section to&nbsp;<a moz-do-not-send="true" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html"><a class="moz-txt-link-freetext" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html">http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html</a></a>
              would be good.</div>
            <div>&nbsp;</div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF">
                <div>
                  <div>
                    <div class="h5"><br>
                      <br>
                      <br>
                      <br>
                      On 12/11/15 17:20, Christian Beikov wrote:<br>
                    </div>
                  </div>
                </div>
                <div>
                  <div class="h5">
                    <blockquote type="cite"> You need different code for
                      Hibernate 4 and 5 because the integrator
                      interfaces are not compatible.<br>
                      The integrator is a service that is loaded through
                      a java.util.ServiceLoader so I am not sure why you
                      would need the property.<br>
                      <div><br>
                        Mit freundlichen Grüßen,<br>
                        <hr> <b>Christian Beikov</b><br>
                      </div>
                      <div>Am 12.11.2015 um 17:14 schrieb Erik Mulder:<br>
                      </div>
                      <blockquote type="cite">
                        <div><i>@Christian Beikov</i>: Thanks for the
                          hint on integrators!<br>
                          <br>
                          I was afraid I could not use integrators when
                          working with the JPA 'route', but I found a
                          way. There is a property <tt>EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER
                          </tt>that you can use to supply custom
                          integrators. This even works with the original
                          'pure' JPA call: <tt>Persistence.createEntityManagerFactory</tt>.
                          In the integrator you can add annotated
                          classes to the Hibernate Configuration. So the
                          solution is still Hibernate only of course.<br>
                          <br>
                          The only downside is that there is less
                          validation on the supplied classes, they are
                          just added to the config directly. For
                          instance I tested with adding Object.class as
                          annotated class. This doesn't raise an
                          exception and seems to be silently ignored by
                          Hibernate. Not sure if it might result in
                          problems during runtime though. Either way,
                          normally this should be fine and with a little
                          extra documentation on how these extra classes
                          are handled I think using an integrator is the
                          least intrusive thus best way to go. Agreed?<br>
                          <br>
                          Ok, List as collection type is fine too,
                          indeed easier to use. Conceptually I like Set,
                          because List seems to imply there is some kind
                          of ordering involved which in this case there
                          isn't. But that's just a minor matter of
                          taste.<br>
                          <br>
                          By exotic&nbsp;<tt>ProviderLoader(Factory)</tt> I
                          meant the <tt>org.keycloak.provider.ProviderLoader(Factory)</tt>
                          that you can use to load <tt>Provider(Factory)</tt>'s
                          from other locations than a file system based
                          classpath. If that were to be a 'read once'
                          kindof location (like some stream) there could
                          be a problem. But with the integrator solution
                          that shouldn't matter anymore, since it's just
                          the Class object that we need.<br>
                          <br>
                          As for Hibernate 4/5, I'll try to make a
                          solution that works for both Hibernate 4 and 5
                          in the same way. If that's not possible, I
                          guess we could have separate code paths for 4
                          and 5, depending on the runtime version. I
                          hope there is an easy way of figuring this
                          out, maybe some static Hibernate class holding
                          a version or so. A quick Google returns some
                          useful results, so I'm sure we'll get that
                          sorted if needed.<br>
                          <br>
                          End of the month is probably too soon indeed,
                          so let's aim for 1.8. Should I (or someone
                          else) create one (or several) JIRA tickets for
                          this?<br>
                          <br>
                          <br>
                          On 12/11/15 14:32, Stian Thorgersen wrote:<br>
                        </div>
                        <blockquote type="cite">
                          <div dir="ltr"><br>
                            <div class="gmail_extra"><br>
                              <div class="gmail_quote">On 12 November
                                2015 at 13:58, Erik Mulder <span dir="ltr"> &lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>&gt;</span>
                                wrote:<br>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                  <div text="#000000" bgcolor="#FFFFFF"><span>
                                      <div>On 11/11/15 13:54, Stian
                                        Thorgersen wrote:<br>
                                      </div>
                                      <blockquote type="cite">
                                        <div dir="ltr">Would you be
                                          interested in contributing
                                          this feature? ATM we don't
                                          have anyone available that
                                          could work on it. A
                                          contribution would also need
                                          to include functional tests
                                          and documentation.</div>
                                      </blockquote>
                                      <br>
                                    </span>Yes, I'd like to contribute
                                    this feature. I'm not sure about the
                                    timeline though. I hope to be able
                                    to do it as part of our current
                                    project, but I might have to use my
                                    spare time as well. Is there some
                                    kind of deadline to be included in a
                                    certain release version?</div>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>We do a release every ~6 weeks.
                                  It's already a bit late for 1.7 (it's
                                  due end of the month) so would have to
                                  aim for 1.8 in either case (early
                                  January).</div>
                                <div>&nbsp;</div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                  <div text="#000000" bgcolor="#FFFFFF"><span><br>
                                      <br>
                                      <blockquote type="cite">
                                        <div dir="ltr">
                                          <div>If so I'm happy with
                                            going down the route of
                                            using the Hibernate specific
                                            classes. The remaining issue
                                            is figuring out how to deal
                                            with classloading.</div>
                                          <div><br>
                                          </div>
                                          <div>Looks like the following
                                            should work:</div>
                                          <div><br>
                                          </div>
                                          <div>* Add JpaEntitySPI,
                                            JpaEntityProviderFactory and
                                            JpaEntityProvider</div>
                                        </div>
                                      </blockquote>
                                      <br>
                                    </span>I've done this and it works
                                    fine, successfully providing the
                                    extra classes to the <tt>EntityManagerFactory</tt>
                                    build process in <tt>DefaultJpaConnectionProviderFactory</tt>.
                                    <br>
                                    <span><br>
                                      <blockquote type="cite">
                                        <div dir="ltr">
                                          <div>*&nbsp;JpaEntityProvider
                                            should have a single method
                                            &quot;Class&lt;?&gt; getEntities&quot;</div>
                                        </div>
                                      </blockquote>
                                      <br>
                                    </span>Yes, only we need some kind
                                    of collection type, so you can
                                    provide multiple entity classes per
                                    provider. I guess you were intending
                                    this, considering the plural name
                                    'getEntities'. I suggest either <tt>Collection&lt;Class&lt;?&gt;&gt;</tt>
                                    or <tt>Set&lt;Class&lt;?&gt;&gt;</tt>
                                    depending on what is most consistent
                                    with the rest of the system. Do you
                                    have a preference?</div>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>Yup - List would be fine, that's
                                  what we tend to use as it's nicer to
                                  use than collection or set.</div>
                                <div>&nbsp;</div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                  <div text="#000000" bgcolor="#FFFFFF"><span><br>
                                      <br>
                                      <blockquote type="cite">
                                        <div dir="ltr">
                                          <div>* Implement&nbsp;<span>org.hibernate.boot.registry.classloading.spi.</span>ClassLoaderService

                                            - looks like this can just
                                            return null for everything
                                            except&nbsp;classForName where it
                                            would return the classes
                                            returned by the
                                            JpaEntityProvider
                                            implementations</div>
                                        </div>
                                      </blockquote>
                                      <br>
                                    </span>I see no way to interfere in
                                    the creation of the <tt>ClassLoaderService</tt>.
                                    The official way is using the <tt>BootstrapServiceRegistryBuilder</tt>,
                                    but with the JPA / <tt>EntityManagerFactoryBuilderImpl</tt>
                                    route this happens 'out of reach'. I
                                    did find another way that works just
                                    as well: you can provide a 'custom'
                                    classloader to the <tt>Bootstrap.getEntityManagerFactoryBuilder</tt>.
                                    We can define a classloader that
                                    will return the extra
                                    JpaEntityProvider classes if
                                    requested. Only tricky part here is
                                    that Hibernate not only calls <tt>loadClass</tt>
                                    on a classloader, but before that
                                    also <tt>getResource</tt> to get a
                                    <tt>URL</tt> with an <tt>InputStream</tt>
                                    to the class bytes. It uses that to
                                    scan for annotations with Jandex. I
                                    fixed this by forwarding that
                                    request to the <tt>ClassLoader</tt>
                                    of the <tt>JpaEntityProvider</tt>
                                    provided class (through <tt>
                                      Class.getClassLoader()</tt>). This
                                    works fine and shouldn't be problem
                                    for any drop in jars. I can imagine
                                    though that if you use some exotic <tt>ProviderLoader(Factory)</tt>,
                                    you might somehow get in trouble if
                                    the class byte[] is not available
                                    anymore after class loading. But
                                    this is a problem with the way
                                    Hibernate works, not with the way we
                                    extend Hibernate in this case. So I
                                    think it's fine to have a warning
                                    about this in the documentation,
                                    since it will probably never be a
                                    real problem. If you consider this
                                    as a no-go, please let me know.<br>
                                  </div>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>Sounds OK, but not sure what you
                                  mean about
                                  exotic&nbsp;ProviderLoader(Factory) is that
                                  a Hibernate thing?</div>
                                <div>&nbsp;</div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                  <div text="#000000" bgcolor="#FFFFFF"><br>
                                    <br>
                                    Last question I have considers the
                                    Hibernate version of KeyCloak.
                                    Currently it's 4.3.10, are there any
                                    plans to upgrade to 5? The code
                                    related to classloading etc is
                                    refactored considerably in Hibernate
                                    5. So it would be a shame to fully
                                    get it working for 4.3.10, only to
                                    have to upgrade soon after that. I
                                    didn't look into the details of
                                    Hibernate 5 and I think the solution
                                    we came up with should remain more
                                    or less intact, but you never know,
                                    so that's why I ask.</div>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>We are soon moving to WildFly 10
                                  which includes Hibernate 5, but we
                                  still need to support EAP 6.4 which
                                  includes Hibernate 4. At some point
                                  next year we will drop support for EAP
                                  6.4 and move on to EAP 7.</div>
                                <div><br>
                                </div>
                                <div>We either have to support both
                                  Hibernate 4 and 5 for a while, or we
                                  make it use the old approach on
                                  Hibernate 4 (so now custom entity
                                  class support on EAP 6.4) and the new
                                  approach on Hibernate 5. That would
                                  probably require some magic reflection
                                  code though.</div>
                                <div>&nbsp;</div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                  <div text="#000000" bgcolor="#FFFFFF">
                                    <div>
                                      <div><br>
                                        <br>
                                        <br>
                                        <blockquote type="cite">
                                          <div dir="ltr">
                                            <div>
                                              <div class="gmail_extra">
                                                <div class="gmail_quote">On
                                                  7 November 2015 at
                                                  23:39, Erik Mulder <span dir="ltr"> &lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>&gt;</span>
                                                  wrote:<br>
                                                  <blockquote class="gmail_quote" style="margin:0px
                                                    0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                    <div bgcolor="#FFFFFF" text="#000000">
                                                      <div dir="ltr"><i>On
                                                          06/11/15
                                                          14:46, Stian
                                                          Thorgersen
                                                          wrote:</i><i><br>
                                                        </i><i>&gt; We
                                                          could use
                                                          Hibernate
                                                          directly to
                                                          boostrap as
                                                          long as it can
                                                          return an
                                                          EntityManager.
                                                          Do you know if
                                                          that's
                                                          possible?</i><i><br>
                                                        </i><br>
                                                        I was a little
                                                        quick to state
                                                        that with
                                                        Hibernate you
                                                        can add extra
                                                        entity class
                                                        names besides
                                                        the one in
                                                        persistence.xml,
                                                        since I spotted
                                                        a few answers on
                                                        StackOverflow
                                                        that said it
                                                        could be done.
                                                        But they resolve
                                                        around classpath
                                                        scanning or
                                                        using a Spring
                                                        managed
                                                        Hibernate. Then
                                                        I thought: 'if
                                                        Spring can do
                                                        it, I can do it
                                                        too' so I
                                                        investigated the
                                                        Hibernate source
                                                        code 'behind'<tt>
                                                          Persistence.createEntityManagerFactory(unitName,

                                                          properties)</tt>.
                                                        After some
                                                        digging it turns
                                                        out it's pretty
                                                        simple to get
                                                        extra class
                                                        names in the
                                                        configuration.
                                                        See code sample
                                                        below.<br>
                                                        <br>
                                                        The only problem
                                                        is that
                                                        Hibernate will
                                                        only find
                                                        classes that are
                                                        part of the
                                                        'main' KeyCloak
                                                        application,
                                                        because of the
                                                        way the Wildfly
                                                        module system
                                                        and ClassLoader
                                                        strategy work.
                                                        The debugger
                                                        showed me
                                                        Hibernate has
                                                        these 3 class
                                                        loaders
                                                        available to
                                                        look for
                                                        classes:<br>
                                                        1.
                                                        ModuleClassLoader
                                                        for Module
                                                        &quot;deployment.keycloak-server.war:main&quot;
                                                        from Service
                                                        Module Loader<br>
                                                        2.
                                                        ModuleClassLoader
                                                        for Module
                                                        &quot;org.hibernate:main&quot;
                                                        from local
                                                        module loader<br>
                                                        3.
                                                        sun.misc.Launcher$AppClassLoader<br>
                                                        <br>
                                                        Number 1 has all
                                                        other KeyCloak
                                                        modules in it,
                                                        so the entity
                                                        classes from
                                                        model-jpa will
                                                        be found, but
                                                        the
                                                        wildfly-extensions
                                                        module is
                                                        missing, so
                                                        entities in
                                                        classes in a jar
                                                        in the providers
                                                        folder cannot be
                                                        found. Now you
                                                        guys obviously
                                                        know a lot more
                                                        about these
                                                        internals, but
                                                        as currently
                                                        configured, it
                                                        seems to me
                                                        there is no way
                                                        to let Hibernate
                                                        'see' these
                                                        extra classes,
                                                        since only the
                                                        KeyCloak
                                                        services module
                                                        has a dependency
                                                        on
                                                        wildfly-extensions.<br>
                                                        <br>
                                                        So I think it
                                                        boils down to
                                                        these decisions:<br>
                                                        A. Do you accept
                                                        a non-pure-JPA
                                                        way of building
                                                        the
                                                        EntityManagerFactory
                                                        that has some
                                                        ties to the
                                                        Hibernate
                                                        internals?<br>
                                                        B. If A is no,
                                                        than we're done.
                                                        If yes, then you
                                                        must find some
                                                        way to get the
                                                        extra configured
                                                        classes 'into'
                                                        Hibernate. You
                                                        could get the
                                                        wildfly-extensions
                                                        module into
                                                        scope of the
                                                        Hibernate
                                                        classloading.
                                                        There are
                                                        serveral ways to
                                                        configure
                                                        Hibernate
                                                        classloading or
                                                        you could flip
                                                        some switches /
                                                        dependencies in
                                                        the module
                                                        configuration.
                                                        Another
                                                        alternative is
                                                        to create a
                                                        separate
                                                        'dropfolder'
                                                        besides themes
                                                        and providers
                                                        for JPA
                                                        extensions, like
                                                        'models' or so
                                                        and have that
                                                        one be on the
                                                        Hibernate
                                                        classpath. But I
                                                        don't know the
                                                        exact design
                                                        principles
                                                        behind KeyCloak
                                                        or the Wildfly
                                                        module system.
                                                        So maybe you
                                                        have a better
                                                        solution or
                                                        maybe you
                                                        conclude that
                                                        this is 'not
                                                        done' in terms
                                                        of the
                                                        architecture.<br>
                                                        <br>
                                                        Either way, I'd
                                                        really
                                                        appreciate some
                                                        feedback on this
                                                        and some
                                                        thoughts on
                                                        whether this
                                                        could be a
                                                        possible
                                                        addition to
                                                        KeyCloak in your
                                                        eyes.<br>
                                                        <br>
                                                        Thanks, Erik<br>
                                                        <br>
                                                        <br>
                                                        Current JPA way.
                                                        No way to
                                                        'interfere':<br>
                                                        <tt>emf =
                                                          Persistence.createEntityManagerFactory(unitName,
                                                          properties);</tt><tt><br>
                                                        </tt><br>
                                                        Alternative
                                                        Hibernate only
                                                        way with adding
                                                        extra entity
                                                        class names:<br>
                                                        <tt>// Let
                                                          Hibernate find
                                                          and parse all
                                                          'persistence.xml'

                                                          files found on
                                                          the classpath.<br>
                                                          List&lt;ParsedPersistenceXmlDescriptor&gt;

                                                          persistenceUnits
                                                          =
                                                          PersistenceXmlParser.locatePersistenceUnits(properties);</tt><tt><br>
                                                        </tt><tt>//
                                                          Assume there
                                                          is only one
                                                          persistence
                                                          unit found and
                                                          that is the
                                                          one we need.
                                                          This can be
                                                          made more
                                                          robust by
                                                          checking on
                                                          the
                                                          persistence
                                                          unit name.<br>
                                                          ParsedPersistenceXmlDescriptor

                                                          persistenceUnitDescriptor
                                                          =
                                                          persistenceUnits.get(0);</tt><tt><br>
                                                        </tt><tt>// Add
                                                          extra class
                                                          names. These
                                                          could come
                                                          from a 'JPA
                                                          class name
                                                          provider' SPI
                                                          or something
                                                          alike.<br>
persistenceUnitDescriptor.addClasses(&quot;org.keycloak.models.jpa.entities.UserMerchantEntity&quot;,</tt><tt>
&quot;org.keycloak.models.jpa.entities.MerchantEntity&quot;);</tt><tt><br>
                                                        </tt><tt>// Let
                                                          Hibernate
                                                          create an
                                                          EntityManagerFactory
                                                          out of the
                                                          (enriched)
                                                          persistence
                                                          unit
                                                          configuration.<br>
                                                          emf =
                                                          Bootstrap.getEntityManagerFactoryBuilder(persistenceUnitDescriptor,
properties).build();</tt><tt><br>
                                                        </tt><br>
                                                        <br>
                                                        <br>
                                                        <div class="gmail_extra"><br>
                                                          <div class="gmail_quote">On
                                                          6 November
                                                          2015 at 14:29,
                                                          Erik Mulder <span dir="ltr">
                                                          &lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>&gt;</span>
                                                          wrote:<br>
                                                          <blockquote class="gmail_quote" style="margin:0px
                                                          0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <div text="#000000" bgcolor="#FFFFFF">
                                                          <div>
                                                          <div>Thanks
                                                          for pointing
                                                          me explicitly
                                                          to the SPI
                                                          documentation.
                                                          Of course that
                                                          is exactly
                                                          what I was
                                                          looking for in
                                                          my original
                                                          question. I
                                                          don't know how
                                                          I overlooked
                                                          this earlier!
                                                          Probably I was
                                                          not picking it
                                                          up, because of
                                                          almost a
                                                          decade of
                                                          developing on
                                                          Spring
                                                          projects,
                                                          where this
                                                          type of thing
                                                          works
                                                          differently.
                                                          :-)<br>
                                                          <br>
                                                          I tried a
                                                          quick test
                                                          with a jar
                                                          with one extra
                                                          ProtocolMapper
                                                          configured,
                                                          put it in the
                                                          providers
                                                          folder and it
                                                          worked like a
                                                          charm!<br>
                                                          <br>
                                                          As for the
                                                          JPA: We'll
                                                          probably go
                                                          with your
                                                          suggestion of
                                                          the separate
                                                          EntityManagerFactory.
                                                          Indeed there
                                                          seems to be no
                                                          way to
                                                          'programmatically
                                                          extend' the
                                                          list of entity
                                                          classes in JPA
                                                          besides
                                                          editing or
                                                          overwriting
                                                          the
                                                          persistence.xml.
                                                          As you
                                                          probably know
                                                          it can be done
                                                          in Hibernate,
                                                          but I guess
                                                          KeyCloak wants
                                                          to stick to a
                                                          generic JPA
                                                          solution. That
                                                          said, we might
                                                          consider the
                                                          Hibernate
                                                          specific
                                                          solution for
                                                          our case,
                                                          since being
                                                          able to switch
                                                          the JPA
                                                          provider is
                                                          not a
                                                          requirement
                                                          for us. And
                                                          keeping the
                                                          same
                                                          connection/transaction
                                                          is a lot
                                                          easier in
                                                          reasoning and
                                                          debugging.</div>
                                                          </div>
                                                          </div>
                                                          </blockquote>
                                                          <div><br>
                                                          </div>
                                                          <div>We could
                                                          use Hibernate
                                                          directly to
                                                          boostrap as
                                                          long as it can
                                                          return an
                                                          EntityManager.
                                                          Do you know if
                                                          that's
                                                          possible?</div>
                                                          <div>&nbsp;</div>
                                                          <blockquote class="gmail_quote" style="margin:0px
                                                          0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <div text="#000000" bgcolor="#FFFFFF">
                                                          <div>
                                                          <div>
                                                          <div>
                                                          <div><br>
                                                          <br>
                                                          <br>
                                                          On 05/11/15
                                                          10:52, Stian
                                                          Thorgersen
                                                          wrote:<br>
                                                          </div>
                                                          </div>
                                                          </div>
                                                          </div>
                                                          <div>
                                                          <div>
                                                          <blockquote type="cite">
                                                          <div dir="ltr">
                                                          <div class="gmail_extra">The

                                                          way to extend
                                                          Keycloak is by
                                                          implementing
                                                          your own
                                                          custom
                                                          providers of
                                                          the many SPIs
                                                          we provide.
                                                          Some SPIs are
                                                          more stable
                                                          (so marked as
                                                          public) and
                                                          others are not
                                                          (so marked as
                                                          private). If
                                                          there are
                                                          things that
                                                          you want to
                                                          customize that
                                                          can't be done
                                                          with an
                                                          existing SPI
                                                          then let us
                                                          know and we
                                                          may consider
                                                          adding
                                                          additional
                                                          SPIs.</div>
                                                          <div class="gmail_extra"><br>
                                                          <div class="gmail_quote">On

                                                          4 November
                                                          2015 at 17:16,
                                                          Erik Mulder <span dir="ltr">
                                                          &lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>&gt;</span>
                                                          wrote:<br>
                                                          <blockquote class="gmail_quote" style="margin:0px
                                                          0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          Thanks for
                                                          your response!<br>
                                                          <br>
                                                          Indeed we
                                                          already did a
                                                          proof of
                                                          concept where
                                                          we added a
                                                          custom mapper<br>
                                                          the way you
                                                          described
                                                          (didn't know
                                                          it was
                                                          'protected'
                                                          territory :).
                                                          The<br>
                                                          question is:
                                                          do we have to
                                                          override the
                                                          file<br>
                                                          'org.keycloak.protocol.ProtocolMapper'

                                                          for this and
                                                          add the new
                                                          mapper<br>
                                                          in the
                                                          original
                                                          project or is
                                                          there another
                                                          way where we
                                                          don't need to<br>
                                                          touch the
                                                          original
                                                          sources and
                                                          keep all our
                                                          changes in a
                                                          separate<br>
                                                          project? And
                                                          how can we do
                                                          it such that
                                                          it stays easy
                                                          to upgrade to<br>
                                                          newer KeyCloak
                                                          releases?<br>
                                                          </blockquote>
                                                          <div><br>
                                                          </div>
                                                          <div>Each jar
                                                          has it's own
                                                          org.keycloak.protocol.ProtocolMapper.
                                                          Take a look at
                                                          the docs (<a moz-do-not-send="true" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html" target="_blank"><a class="moz-txt-link-freetext" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html">http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html</a></a>)
                                                          and examples
                                                          for other
                                                          provider (<a moz-do-not-send="true" href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory" target="_blank"><a class="moz-txt-link-freetext" href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory">https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory</a></a>)</div>
                                                          <div>&nbsp;</div>
                                                          <blockquote class="gmail_quote" style="margin:0px
                                                          0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <br>
                                                          As for JPA: it
                                                          would be
                                                          easier to
                                                          integrate with
                                                          the existing
                                                          JPA<br>
                                                          project. Again
                                                          we are
                                                          wondering
                                                          whether to
                                                          start
                                                          modifying
                                                          original<br>
                                                          sources (like
                                                          persistence.xml)

                                                          or try to
                                                          'externalize'
                                                          our changes<br>
                                                          somehow and
                                                          integrate them
                                                          using existing
                                                          'hooks' in the
                                                          system or
                                                          maybe<br>
                                                          merge projects
                                                          during build.<br>
                                                          <br>
                                                          Maybe there is
                                                          no good answer
                                                          to this and
                                                          we'll always
                                                          be having some<br>
                                                          manual merge
                                                          pains when
                                                          upgrading to
                                                          new KeyCloak
                                                          versions. We
                                                          just<br>
                                                          wanted to
                                                          check if there
                                                          are preferred
                                                          ways to add
                                                          functionality
                                                          with<br>
                                                          the least
                                                          amount of
                                                          impact on the
                                                          original
                                                          sources.<br>
                                                          </blockquote>
                                                          <div><br>
                                                          </div>
                                                          <div>I
                                                          initially
                                                          wanted the
                                                          ability to add
                                                          custom
                                                          entities to
                                                          the
                                                          JpaConnectProvider,
                                                          but couldn't
                                                          find a way to
                                                          define
                                                          entities
                                                          programatically
                                                          with JPA. To
                                                          add your own
                                                          persistence.xml
                                                          you would have
                                                          to define your
                                                          own
                                                          implementation
                                                          of
                                                          JpaConnectionProvider
                                                          and change
                                                          what is loaded
                                                          by default
                                                          (connectionsJpa/provider
                                                          attribute in
                                                          keycloak-server.json).</div>
                                                          <div><br>
                                                          </div>
                                                          <div>Alternative,

                                                          which is
                                                          cleaner, but
                                                          you end up
                                                          with separate
                                                          connection/transaction,

                                                          is to create
                                                          your own
                                                          EntityManagerFactory.
                                                          If it's only
                                                          used by one
                                                          provider (for
                                                          example a
                                                          custom
                                                          UserFederationProvider)
                                                          there's no
                                                          need to add a
                                                          connect
                                                          provider
                                                          (that's just a
                                                          way to share
                                                          one
                                                          EntityManagerFactory
                                                          between
                                                          multiple
                                                          providers) and
                                                          you can just
                                                          create it in
                                                          the
                                                          MyUserFederationProviderFactory.</div>
                                                          <div>&nbsp;</div>
                                                          <blockquote class="gmail_quote" style="margin:0px
                                                          0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <div>
                                                          <div><br>
                                                          <br>
                                                          On 04/11/15
                                                          15:30, Bill
                                                          Burke wrote:<br>
                                                          &gt; Custom
                                                          mappers should
                                                          be possible.&nbsp;
                                                          I didn't
                                                          document it as
                                                          I wasn't<br>
                                                          &gt; sure if
                                                          we wanted to
                                                          make the SPI
                                                          public.&nbsp;
                                                          Custom mappers
                                                          should just<br>
                                                          &gt; follow
                                                          the Provider
                                                          SPI and they
                                                          will be picked
                                                          up.&nbsp; If you
                                                          see the<br>
                                                          &gt;
                                                          META-INF/services/...
                                                          file in the
                                                          resources
                                                          directory of
                                                          the &quot;services&quot;<br>
                                                          &gt; or
                                                          &quot;broker&quot;
                                                          modules you'll
                                                          see how to set
                                                          this up.<br>
                                                          &gt;<br>
                                                          &gt; As for
                                                          extending the
                                                          JPA datamodel,
                                                          what you could
                                                          do is write a
                                                          new JPA<br>
                                                          &gt;
                                                          Connections
                                                          Provider and
                                                          plug that in.&nbsp;
                                                          See
                                                          connections/jpa.&nbsp;
                                                          I'm not<br>
                                                          &gt; sure how
                                                          you would
                                                          handle the
                                                          liquibase db
                                                          migration.<br>
                                                          &gt;<br>
                                                          &gt; On
                                                          11/4/2015 6:03
                                                          AM, Erik
                                                          Mulder wrote:<br>
                                                          &gt;&gt; Hi
                                                          everybody,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Quick
                                                          intro: I’m
                                                          part of a
                                                          development
                                                          team in The
                                                          Netherlands
                                                          that is<br>
                                                          &gt;&gt;
                                                          building a
                                                          company-wide
                                                          SSO solution.
                                                          We’ve chosen
                                                          KeyCloak to
                                                          realize<br>
                                                          &gt;&gt; this
                                                          and will use
                                                          OpenID Connect
                                                          to secure our
                                                          REST services.
                                                          It’s a<br>
                                                          &gt;&gt; great
                                                          product and
                                                          seems to be
                                                          the only one
                                                          having both
                                                          support for
                                                          all<br>
                                                          &gt;&gt; kinds
                                                          of security
                                                          standards and
                                                          a model and
                                                          GUI for users
                                                          and roles.<br>
                                                          &gt;&gt;
                                                          Thanks for
                                                          creating it! J<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; (if
                                                          this should be
                                                          asked instead
                                                          on the users
                                                          mailing list,
                                                          please<br>
                                                          &gt;&gt;
                                                          correct me and
                                                          I’ll post it
                                                          there)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; So
                                                          far, so good,
                                                          but we have
                                                          some extra
                                                          requirements
                                                          that do not
                                                          fit<br>
                                                          &gt;&gt; into
                                                          the base
                                                          KeyCloak data
                                                          model. See
                                                          below for
                                                          details if
                                                          you’re<br>
                                                          &gt;&gt;
                                                          interested. My
                                                          question is:
                                                          what is the
                                                          preferred way
                                                          / best
                                                          practice to<br>
                                                          &gt;&gt;
                                                          extend the
                                                          functionality
                                                          of KeyCloak
                                                          while keeping
                                                          the impact on
                                                          the<br>
                                                          &gt;&gt;
                                                          original
                                                          sources to a
                                                          minimum? Of
                                                          course we
                                                          could just
                                                          fork the most<br>
                                                          &gt;&gt;
                                                          recent version
                                                          and start
                                                          hacking away,
                                                          but we’d like
                                                          to be able to<br>
                                                          &gt;&gt;
                                                          upgrade to
                                                          newer versions
                                                          of KeyCloak
                                                          without too
                                                          much hassle.<br>
                                                          &gt;&gt;
                                                          Possibilities
                                                          that we’ve
                                                          come up with
                                                          so far:<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          1.Create
                                                          completely
                                                          separate
                                                          modules that
                                                          will extend
                                                          the
                                                          functionality<br>
                                                          &gt;&gt; the
                                                          way we need.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          2.Fork on
                                                          Github, apply
                                                          custom
                                                          changes, and
                                                          try to merge
                                                          in updates
                                                          from<br>
                                                          &gt;&gt; the
                                                          master /
                                                          release
                                                          branches /
                                                          tags<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          3.Apply custom
                                                          changes on
                                                          KeyCloak
                                                          artifacts
                                                          using a Maven
                                                          plugin, such<br>
                                                          &gt;&gt; as
                                                          Truezip<br>
                                                          &gt;&gt; (<a moz-do-not-send="true" href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html" target="_blank"><a class="moz-txt-link-freetext" href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html">http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html</a></a>)
                                                          -<br>
                                                          &gt;&gt;
                                                          manipulate zip
                                                          files by
                                                          adding/removing/replacing
                                                          or Shade<br>
                                                          &gt;&gt; (<a moz-do-not-send="true" href="http://maven.apache.org/plugins/maven-shade-plugin/" target="_blank"><a class="moz-txt-link-freetext" href="http://maven.apache.org/plugins/maven-shade-plugin/">http://maven.apache.org/plugins/maven-shade-plugin/</a></a>)
                                                          - combine
                                                          multiple<br>
                                                          &gt;&gt; jars
                                                          to 1
                                                          'uber-jar'
                                                          containing the
                                                          contents of
                                                          both and when<br>
                                                          &gt;&gt;
                                                          overlapping
                                                          decide on
                                                          conflicts
                                                          through
                                                          configuration.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Of
                                                          course number
                                                          1 is
                                                          preferred, but
                                                          I do not see
                                                          how to add
                                                          custom<br>
                                                          &gt;&gt;
                                                          mappers or JPA
                                                          entities
                                                          without making
                                                          changes in the
                                                          original
                                                          module<br>
                                                          &gt;&gt;
                                                          files. The
                                                          other options
                                                          seem like
                                                          valid
                                                          alternatives,
                                                          but maybe
                                                          there<br>
                                                          &gt;&gt; is
                                                          better /
                                                          standard way
                                                          to do this. So
                                                          any help /
                                                          insight /
                                                          shared<br>
                                                          &gt;&gt;
                                                          experience on
                                                          this is much
                                                          appreciated,
                                                          thanks!<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Kind
                                                          regards,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Erik
                                                          Mulder<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Senior
                                                          Software
                                                          Engineer<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Docdata
                                                          Payments – NL<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; P.S.
                                                          Details on why
                                                          we want to
                                                          extend the
                                                          KeyCloak data
                                                          model: (any<br>
                                                          &gt;&gt;
                                                          feedback on
                                                          the contents
                                                          of this P.S.
                                                          is also
                                                          welcome!)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Our
                                                          clients are
                                                          merchants that
                                                          have several
                                                          webshops. We
                                                          manage their<br>
                                                          &gt;&gt;
                                                          online
                                                          payments
                                                          (shopping cart
                                                          checkout). We
                                                          want to be
                                                          able to let a<br>
                                                          &gt;&gt;
                                                          merchant
                                                          manage their
                                                          own users and
                                                          let a user
                                                          have different
                                                          roles for<br>
                                                          &gt;&gt;
                                                          different
                                                          webshops
                                                          within the
                                                          same merchant.
                                                          The overall
                                                          possible roles<br>
                                                          &gt;&gt; are
                                                          fixed though,
                                                          no specific
                                                          roles per
                                                          merchant. We
                                                          could create a<br>
                                                          &gt;&gt;
                                                          separate realm
                                                          for every
                                                          merchant, but
                                                          then we need
                                                          to duplicate
                                                          all<br>
                                                          &gt;&gt; roles
                                                          every time.
                                                          Furthermore,
                                                          in KeyCloak
                                                          there is no
                                                          concept of a
                                                          role<br>
                                                          &gt;&gt;
                                                          within a
                                                          certain
                                                          context. This
                                                          is very
                                                          understandable,
                                                          since every<br>
                                                          &gt;&gt;
                                                          situation has
                                                          it’s own
                                                          requirements.
                                                          We did a proof
                                                          of concept by
                                                          adding<br>
                                                          &gt;&gt;
                                                          tables and
                                                          entities for
                                                          Merchant,
                                                          UserMerchant,
                                                          UserMerchantRole

                                                          etc.<br>
                                                          &gt;&gt; and
                                                          adding a
                                                          custom mapper
                                                          that can put
                                                          this
                                                          information on
                                                          the Access<br>
                                                          &gt;&gt;
                                                          token. Worked
                                                          like a charm!
                                                          But it does
                                                          need some
                                                          changes in the<br>
                                                          &gt;&gt;
                                                          KeyCloak
                                                          modules and
                                                          sources to
                                                          work, hence
                                                          the question
                                                          above.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          _______________________________________________<br>
                                                          &gt;&gt;
                                                          keycloak-dev
                                                          mailing list<br>
                                                          &gt;&gt; <a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"> </a><a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a></a><br>
                                                          &gt;&gt; <a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">
                                                          </a><a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank"><a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></a><br>
                                                          &gt;&gt;<br>
                                                          <br>
                                                          <br>
_______________________________________________<br>
                                                          keycloak-dev
                                                          mailing list<br>
                                                          <a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a></a><br>
                                                          <a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank"><a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></a><br>
                                                          </div>
                                                          </div>
                                                          </blockquote>
                                                          </div>
                                                          <br>
                                                          </div>
                                                          </div>
                                                          </blockquote>
                                                          <br>
                                                          </div>
                                                          </div>
                                                          </div>
                                                          </blockquote>
                                                          </div>
                                                          <br>
                                                        </div>
                                                      </div>
                                                      <br>
                                                    </div>
                                                  </blockquote>
                                                </div>
                                                <br>
                                              </div>
                                            </div>
                                          </div>
                                        </blockquote>
                                        <br>
                                      </div>
                                    </div>
                                  </div>
                                </blockquote>
                              </div>
                              <br>
                            </div>
                          </div>
                        </blockquote>
                        <br>
                        <br>
                        <fieldset></fieldset>
                        <br>
                        <pre>_______________________________________________
keycloak-dev mailing list
<a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>
<a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
                      </blockquote>
                      <br>
                    </blockquote>
                    <br>
                  </div>
                </div>
              </div>
              <br>
              _______________________________________________<br>
              keycloak-dev mailing list<br>
              <a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
              <a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>