[keycloak-dev] creating JPA user storage provider difficult
Bill Burke
bburke at redhat.com
Thu Aug 4 09:10:24 EDT 2016
On 8/4/16 4:00 AM, Marek Posolda wrote:
> On 04/08/16 01:48, Bill Burke wrote:
>> I wrote an JPA example for the new User Storage Provider SPI [1]. It
>> was very difficult to figure out how to wire in JPA. I'm going to take
>> a guess that very very few users have actually tried to implement a
>> JPA-based User Federation Provider. They would have run into a ton of
>> hurdles.
>>
>> * Putting just a jar within the "providers/" directory is unusable. JPA
>> classes and other dependencies will not be visible.
>>
>> * So, you have to craft a *CORRECT* module.xml file and know exactly
>> which dependencies to bring in. [2]
>>
>> * javax.persistence.Persistence.createEntityManagerFactory() did not
>> work, so I had to call Hibernate APIs directly. Not only that, but
>> non-simple Hibernate APIs. [3]
>>
>> * When configuring JPA I also had to know what classloader to use so
>> that persistence.xml was visible.
> In some recent release, we added JpaEntityProvider SPI. This allows to
> register your own JPA entities with Keycloak own EntityManager . So in
> your provider, you don't need to care about the complex stuff like
> proprietary Hibernate API, classloader or transaction enlisting.
>
The JpaEntityProvider SPI extends the keycloak persistence unit. Not
very useful if you are integrating some other external RDBMs.
> We have a docs [1] and example for that [2]
>
> [1]
> https://keycloak.gitbooks.io/server-developer-guide/content/v/2.1/topics/extensions.html
> [2]
> https://github.com/patriot1burke/keycloak/tree/master/examples/providers/domain-extension
>
>
> That's much easier, isn't it? Just not sure if it helps with EJB...
Easier if you don't need any other dependency defined. What if they
want to JAX-RS client and a specific provider from Resteasy? As I
mentioned in a previous point, its just not as simple as including the
modules. Persistence.createEMF() doesn't work as the classloaders all
seem confused.
>> * Had to use JpaKeycloakTransaction to enlist EntityManager with
>> keycloak transactions. This means using EJBs is out of the question.
>>
>> This is unacceptable. Keycloak is supposed to be simple and this is
>> extremely difficult. When Keycloak was an exploded WAR you could use
>> every Java EE component type as you could just plop your extensions
>> within META-INF/lib. Classloading was simple as it was all the same
>> classloader.
>>
>> Going forward we need to write an actual deployer for Keycloak
>> extensions that allow you to define Keycloak providers within EE jars,
>> ears, etc. Writing an extension to Keycloak should be as easy as
>> writing a Java EE application. Extension developers should be able to
>> leverage the entire JBoss/Wildfly platform. Minimally, we also need to
>> begin and commit/rollback a UserTransaction within a Keycloak request
>> flow so that transaction EE and Spring component layers can function.
> +1 for deployer. Maybe we can try to prototype an example, which uses
> stuff like EJB and then see what exactly we need to add?
>
> For UserTransaction, we can maybe have the KeycloakTransaction
> implementation, which will delegate to UserTransaction? Then people
> can optionally enlist it in their provider if they need it :
>
> session.getTransactionManager().enlistAfterCompletion(new
> UserTransactionWrapper());
>
> Then Keycloak will automatically take care of commit/rollback this
> transaction at end of request.
Why wouldn't they just use UserTransaction?
Bill
More information about the keycloak-dev
mailing list