我需要向keycloak (基于WildFly的发行版)添加一个WildFly客户端。
我通过扩展org.keycloak.broker.provider.AbstractIdentityProviderMapper
中定义以下代码创建了一个新的类
Client client = ClientBuilder.newBuilder().build();
ClientWebTarget target = (ClientWebTarget) client.target(UriBuilder.fromPath(URL_PATH));
CustomFetcher fetcher = target.proxy(CustomFetcher.class);我将类添加到src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper中
当我将jar复制到keycloak的standalone/deployments目录时,我得到
20:55:01,522 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.deployment.unit."keycloak-user-mapper-0.0.1-SNAPSHOT.jar".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.unit."keycloak-user-mapper-0.0.1-SNAPSHOT.jar".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "keycloak-user-mapper-0.0.1-SNAPSHOT.jar"
at org.jboss.as.server@18.0.4.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:189)
at org.jboss.msc@1.4.13.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1739)
at org.jboss.msc@1.4.13.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1701)
at org.jboss.msc@1.4.13.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1559)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.util.ServiceConfigurationError: org.keycloak.broker.provider.IdentityProviderMapper: Provider org.myorg.UserAttributeMapper could not be instantiated
at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:582)
at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:804)
at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:722)
at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1395)
at org.keycloak.keycloak-services@17.0.0//org.keycloak.provider.DefaultProviderLoader.load(DefaultProviderLoader.java:60)
at org.keycloak.keycloak-services@17.0.0//org.keycloak.provider.ProviderManager.load(ProviderManager.java:94)
at org.keycloak.keycloak-services@17.0.0//org.keycloak.services.DefaultKeycloakSessionFactory.loadFactories(DefaultKeycloakSessionFactory.java:294)
at org.keycloak.keycloak-services@17.0.0//org.keycloak.services.DefaultKeycloakSessionFactory.deploy(DefaultKeycloakSessionFactory.java:154)
at org.keycloak.keycloak-services@17.0.0//org.keycloak.provider.ProviderManagerRegistry.deploy(ProviderManagerRegistry.java:42)
at org.keycloak.keycloak-wildfly-server-subsystem@17.0.0//org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor.deploy(KeycloakProviderDeploymentProcessor.java:58)
at org.jboss.as.server@18.0.4.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:182)
... 8 more
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl from [Module "org.jboss.as.server" version 18.0.4.Final from local module loader @66c92293 (finder: local module finder @332796d3 (roots: /opt/jboss/keycloak/modules,/opt/jboss/keycloak/modules/system/layers/keycloak,/opt/jboss/keycloak/modules/system/layers/base))]
at org.jboss.resteasy.resteasy-client-api@4.7.4.Final//org.jboss.resteasy.client.jaxrs.ProxyBuilder.builder(ProxyBuilder.java:41)
at org.jboss.resteasy.resteasy-client@4.7.4.Final//org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.createProxyBuilder(ClientWebTarget.java:107)
at org.jboss.resteasy.resteasy-client@4.7.4.Final//org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.proxy(ClientWebTarget.java:94)
at deployment.keycloak-user-mapper-0.0.1-SNAPSHOT.jar//org.myorg.UserAttributeMapper.<init>(UserAttributeMapper.java:55)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:780)
... 17 more
Caused by: java.lang.ClassNotFoundException: org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl from [Module "org.jboss.as.server" version 18.0.4.Final from local module loader @66c92293 (finder: local module finder @332796d3 (roots: /opt/jboss/keycloak/modules,/opt/jboss/keycloak/modules/system/layers/keycloak,/opt/jboss/keycloak/modules/system/layers/base))]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:200)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
at org.jboss.resteasy.resteasy-client-api@4.7.4.Final//org.jboss.resteasy.client.jaxrs.ProxyBuilder.builder(ProxyBuilder.java:35)
... 25 more显然,Wildfly自己的org.jboss.as.server模块没有正确配置,因此它的CLASSPATH上没有org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl,但是它存在于my的CLASSPATH上,因为我可以成功地执行
Class.forName("org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl")在我的类构造函数中。
解决方案----我在modules/system/layers/base/org/jboss/as/server/main/module.xml中添加了<module name="org.jboss.resteasy.resteasy-client"/>,它现在工作了,但是它似乎不是一个好的解决方案,我如何处理这个配置?
UPDATE我怀疑问题可能是热重新部署的问题,如果我首先将jar复制到keycloak,然后启动keycloak,则CLASSPATH不存在任何问题。但是,如果在运行jar时将keycloak复制到standalone/deployments中,则会抛出ClassNotFoundException。我试过keycloak-17.0.0.zip,keycloak-17.0.1.zip,keycloak-18.0.0.zip (基于WildFly)
这是一个复制问题的脚本。引用它时:
bash script.sh [17.0.0 | 17.0.1 | 18.0.0]要将jar部署到本地keycloak (如果以前没有下载,脚本将自动下载keycloak的zip存档)。
(*)方括号中的参数是可选的,默认版本是18.0.0
#! /bin/bash
set -x
mkdir -p so72280865 && cd so72280865 || {
echo "Unable to create a working directory"
exit 1
}
cat <<EOF > pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.myorg</groupId>
<artifactId>keycloak-so-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>17.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
EOF
mkdir -p src/main/java/org/myorg/
cat <<EOF > src/main/java/org/myorg/App.java
package org.myorg;
import org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget;
import org.keycloak.broker.provider.AbstractIdentityProviderMapper;
import org.keycloak.provider.ProviderConfigProperty;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.UriBuilder;
import java.util.Collections;
import java.util.List;
public class App extends AbstractIdentityProviderMapper {
private static final String URL_PATH = "https://api.myip.com";
private final CustomFetcher fetcher;
public static final String[] COMPATIBLE_PROVIDERS = {ANY_PROVIDER};
protected static final List<ProviderConfigProperty> configProperties = Collections.emptyList();
public App() {
final Client client = ClientBuilder.newBuilder()
.register(new org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider())
.build();
ClientWebTarget target = (ClientWebTarget) client.target(UriBuilder.fromPath(URL_PATH));
fetcher = target.proxy(CustomFetcher.class);
System.out.println(fetcher.get().toString());
}
@Path("/")
public interface CustomFetcher {
@GET String get();
}
@Override
public String[] getCompatibleProviders() {
return COMPATIBLE_PROVIDERS;
}
@Override
public String getDisplayCategory() {
return "Attribute Importer";
}
@Override
public String getDisplayType() {
return "Custom Fetcher";
}
@Override
public String getHelpText() {
return "Custom Fetcher";
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
return "custom-fetcher-idp-mapper";
}
}
EOF
mkdir -p src/main/resources/META-INF/services
cat <<EOF > src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
org.myorg.App
EOF
mvn package
if [ "$?" -ne "0" ] ; then
exit 1
fi
KEYCLOAK_VERSION=${1:-18.0.0}
[ -f "keycloak-legacy-${KEYCLOAK_VERSION}.zip" ] || {
curl -LO "https://github.com/keycloak/keycloak/releases/download/${KEYCLOAK_VERSION}/keycloak-legacy-${KEYCLOAK_VERSION}.zip"
}
[ -d "keycloak-${KEYCLOAK_VERSION}" ] || {
unzip "keycloak-legacy-${KEYCLOAK_VERSION}.zip"
} && cp target/keycloak-so-demo-0.0.1-SNAPSHOT.jar "keycloak-${KEYCLOAK_VERSION}"/standalone/deployments &&
./"keycloak-${KEYCLOAK_VERSION}"/bin/standalone.sh &
trap "./keycloak-${KEYCLOAK_VERSION}/bin/jboss-cli.sh --connect --command=:shutdown" EXIT
TIMEOUT=180
while true ; do
started=$(ss -lt | grep 9990 | wc -l)
[ "$started" -eq "1" ] && break
[ "$TIMEOUT" -le "0" ] && {
echo "Timeout reached starting keycloak"
exit 1
}
TIMEOUT=$((TIMEOUT - 10))
sleep 10
done
cp target/keycloak-so-demo-0.0.1-SNAPSHOT.jar "keycloak-${KEYCLOAK_VERSION}"/standalone/deployments
sleep 10发布于 2022-05-18 20:41:41
org.jboss.as.server不应该依赖于RESTEasy模块。您需要部署才能依赖它。如果定义了jaxrs子系统,默认情况下应该会发生这种情况。
如果jaxrs子系统不存在,则可以使用jboss-deployment-structure.xml或清单条目将依赖项添加到部署中。对于清单条目,只需将Dependencies: org.jboss.resteasy.resteasy-client services添加到JAR中的META-INF/MANIFEST.MF中即可。注意,这些是逗号分隔的条目,因此,如果需要类似于JSON提供程序的内容,则需要如下所示:
Dependencies: org.jboss.resteasy.resteasy-client services, org.jboss.resteasy.resteasy-json-p-provider services“服务”部分只是导入服务。在某些情况下可能不需要这样做。
https://stackoverflow.com/questions/72280865
复制相似问题