<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    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 class="moz-signature"><br>
      Mit freundlichen Grüßen,<br>
      <hr>
      <b>Christian Beikov</b><br>
    </div>
    <div class="moz-cite-prefix">Am 12.11.2015 um 17:14 schrieb Erik
      Mulder:<br>
    </div>
    <blockquote
cite="mid:9A5619B792BBA041AE094585791BB71C0137B668B07A@DDPEX01.DDP.dcloud.local"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div class="moz-cite-prefix"><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 <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
cite="mid:CAJgngAedJ80KUqg3qh5grWBw1MLANwy52ctXmfM0N2-5HO5tnA@mail.gmail.com"
        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">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"><span class="">
                    <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> </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 class=""><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 class=""> <br>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <div>* JpaEntityProvider should have a single
                          method "Class&lt;?&gt; getEntities"</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> </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 class=""><br>
                    <br>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <div>* Implement <span>org.hibernate.boot.registry.classloading.spi.</span>ClassLoaderService


                          - looks like this can just return null for
                          everything except 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 ProviderLoader(Factory) is that a Hibernate
                thing?</div>
              <div> </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> </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 class="h5"><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"
                                    class="moz-txt-link-abbreviated"
                                    href="mailto:erik.mulder@docdatapayments.com"><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
                                      "deployment.keycloak-server.war:main"
                                      from Service Module Loader<br>
                                      2. ModuleClassLoader for Module
                                      "org.hibernate:main" 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("org.keycloak.models.jpa.entities.UserMerchantEntity",</tt><tt>
"org.keycloak.models.jpa.entities.MerchantEntity");</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"
                                              class="moz-txt-link-abbreviated"
href="mailto:erik.mulder@docdatapayments.com"><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> </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" class="moz-txt-link-abbreviated"
                                                          href="mailto:erik.mulder@docdatapayments.com"><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"
class="moz-txt-link-freetext"
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>)
                                                          and examples
                                                          for other
                                                          provider (<a
                                                          moz-do-not-send="true"
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"><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> </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> </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. 
                                                          I didn't
                                                          document it as
                                                          I wasn't<br>
                                                          &gt; sure if
                                                          we wanted to
                                                          make the SPI
                                                          public. 
                                                          Custom mappers
                                                          should just<br>
                                                          &gt; follow
                                                          the Provider
                                                          SPI and they
                                                          will be picked
                                                          up.  If you
                                                          see the<br>
                                                          &gt;
                                                          META-INF/services/...
                                                          file in the
                                                          resources
                                                          directory of
                                                          the "services"<br>
                                                          &gt; or
                                                          "broker"
                                                          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. 
                                                          See
                                                          connections/jpa. 
                                                          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"
class="moz-txt-link-freetext"
                                                          href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html"><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"
class="moz-txt-link-freetext"
                                                          href="http://maven.apache.org/plugins/maven-shade-plugin/"><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"
class="moz-txt-link-abbreviated"
                                                          href="mailto:keycloak-dev@lists.jboss.org"><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"
class="moz-txt-link-freetext"
                                                          href="https://lists.jboss.org/mailman/listinfo/keycloak-dev"><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"
class="moz-txt-link-abbreviated"
                                                          href="mailto:keycloak-dev@lists.jboss.org"><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"
class="moz-txt-link-freetext"
                                                          href="https://lists.jboss.org/mailman/listinfo/keycloak-dev"><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>
                                    <blockquote type="cite"> </blockquote>
                                    <br>
                                  </div>
                                </blockquote>
                              </div>
                              <br>
                            </div>
                          </div>
                        </div>
                      </blockquote>
                      <br>
                    </div>
                  </div>
                </div>
              </blockquote>
            </div>
            <br>
          </div>
        </div>
      </blockquote>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
keycloak-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
    </blockquote>
    <br>
  </body>
</html>