For now let's just make sure examples don't use HttpClientBuilder. That should be
relatively quick to fix and solves you're problem. We can worry about the rest later
when we start defining public/private stuff.
----- Original Message -----
From: "Marko Strukelj" <mstrukel(a)redhat.com>
To: "Stan Silvert" <ssilvert(a)redhat.com>
Cc: keycloak-dev(a)lists.jboss.org
Sent: Friday, 22 May, 2015 9:50:27 AM
Subject: Re: [keycloak-dev] User apps and HttpClient
I like Stian's solution much better ... it's much simpler :)
@Stian: Is there some docs where I can get a better understanding of what's
an API that is exposed to client, and what is implementation details never
to be used by client apps ...
Ideally that would be easy to establish based on package names - e.g.
anything not in org.keycloak.something.impl might be an API, or nothing but
what's in org.keycloak.something.api might be an API ...
Or maybe we have one single module that's client API?
On 5/21/2015 4:56 PM, Marko Strukelj wrote:
We package examples with jboss-deployment-structure.xml that looks like this:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.apache.httpcomponents"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
If we drop a .war containing this into Wildfly 9 (distribution/server-dist -
ATM distribution/demo-dist, and distribution/adapters/wildfly-adapter-zip
look buggy as they still use slot=4.3), things are fine.
However, if we dropped this into Wildfly 8 with keycloak adapter modules
using org.apache.httpcomponents slot=4.3, we get a java.lang.LinkageError as
soon as some Keycloak logic is triggered by user app.
The question: how come jboss modules isolation doesn’t kick in and allow
keycloak adapter modules to use slot=4.3 while at the same time user app
(our examples) uses slot=main?
The answer is that org.keycloak.adapters.HttpClientBuilder which seems to be
our helper class for org.apache.httpcomponents inevitably leaks the version
of HttpClient its module refers to - can’t be any other way (unless we
change the code to use client app’s classloader - opening a can of worms).
Any user app using HttpClientBuilder.build() method receives an instance of
HttpClient loaded through org.keycloak.keycloak-adapter-core module, and
transitively through org.apache.httpcomponents referred to therein.
Any attempt of an application (.war) to package its own httpcomponents jars,
or to refer to a different jboss module than the exact one referred to by
org.keycloak.keycloak-adapter-core will result in ‘catastrophic failure’.
Example:
HttpClient client = new
HttpClientBuilder().disableTrustManager().build();
HttpClient on the left is loaded by app’s classloader. The one returned by
build() on the right is loaded by org.keycloak.keycloak-adapter-core
module’s version of httpcomponents. If it’s not the same classloader (jboss
module) on both sides loading HttpClient you get a LinkageError.
In light of this I wonder if it wasn’t the best solution to reexport
org.apache.httpcomponents to .wars by default, thereby removing the
necessity to package jboss-deployment-structure.xml at all, and ensuring
that user application always uses the proper module.
Currently jboss-deployment-structure.xml is required for wildfly / as7, and
is a nuisance, especially as it has to be different (refer to slot=4.3) for
Wildfly 8.
If using HttpClientBuilder is supposed to be completely optional, we could
maybe add configuration to keycloak subsystem to control exposing it to all
or specific secure deployments.
We could simply add another common attribute that can be used in <realm> and
<secure-deployment>. We could expose it by default and have something like:
<expose-httpcomponents>false</expose-httpcomponents>
to inhibit exposing it if a situation calls for it.
WDYT?
What do I think? I think that classloading questions always make my head
hurt!
The best solution would be to find a way to detect the problem and fix it at
deploy time. Using a DependencyProcessor, it should be possible to detect
that the deployment contains the same module from two different slots. Then
pick the best slot and spit out a warning message that you are removing the
undesirable module.
It should be possible, but I don't know if it actually IS possible. A version
mismatch between modules is like a cancer. I think you should speak to an
oncologist or David Lloyd. Since Red Hat doesn't employ any oncologists, go
with David. :-)
_______________________________________________
keycloak-dev mailing list keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev