----- Original Message -----
From: "Marko Strukelj" <mstrukel(a)redhat.com>
To: "keycloak dev" <keycloak-dev(a)lists.jboss.org>
Sent: Thursday, 21 May, 2015 10:56:40 PM
Subject: [keycloak-dev] User apps and HttpClient
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.
HttpClientBuilder is an internal helper class and shouldn't be used directly by
applications. We just need to rewrite the examples to not use it and Bob's your uncle
the problem is no longer ;)
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?
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev