使用org.keycloak.authentication.authenticators.broker.util类时,提供程序jar包中出现NoClassDefFoundError错误

7

我正在为 Keycloak 编写一个认证提供程序,将其打包成一个 .jar 文件。 一旦它使用了来自 keycloak-services 的类,我就会收到一个 NoClassDefFoundError 错误。 当通过 "mvn wildfly:deploy" 部署提供程序时,我也会收到相同的错误。

我必须漏掉了些什么,但我很少写 Java 代码,现在一头雾水。

我在 pom.xml 中定义了依赖项,并尝试了 'provided' 和 'compile' 作为范围:

    <dependencies>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-core</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi-private</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>jboss-logging</artifactId>
            <scope>provided</scope>
            <version>3.1.4.GA</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-services</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
    </dependencies>

我一旦将以下代码添加到authenticate函数中,就会收到错误信息:
    AuthenticationSessionModel authSession = context.getAuthenticationSession();
    SerializedBrokeredIdentityContext serializedCtx =
        SerializedBrokeredIdentityContext.readFromAuthenticationSession(
            authSession, "BROKERED_CONTEXT");

我遇到的错误:

20:05:03,844 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-6) Uncaught server error: java.lang.NoClassDefFoundError: org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext

当你遇到NoClassDefFoundError时,意味着在编译时找到了该类,但在运行时该类不存在。这可能以多种方式发生。其中两种是:不同的代码版本,不同的源代码与执行类路径。 - ControlAltDel
我明白这一点,但我已经按照文档定义了提供程序,并且我对类路径没有任何控制(据我所知)。该类必须存在,因为它被内置提供程序使用。编译时和运行时的Keycloak版本相同,而且我认为Java版本也是相同的(如果不是这种情况,我的.jar文件会被加载吗?)。 - Christophe de Vienne
2个回答

26
因为Wildfly隔离了类加载器,所以我必须在META-INF/MANIFEST.MF文件中声明依赖关系。
为此,我将以下代码添加到我的pom.xml文件中:
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Dependencies>org.keycloak.keycloak-services</Dependencies>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>

我在keycloak用户列表中得到了解决方案:https://lists.jboss.org/pipermail/keycloak-user/2019-September/019108.html


2
谢谢,它为我节省了很多时间和精力。 - FaizanHussainRabbani
1
同时在使用maven-assembly-plugin的jar-with-dependencies时也适用: <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifestEntries> <Dependencies>org.keycloak.keycloak-services</Dependencies> </manifestEntries> </archive> </configuration> - nico
我在Quarkus分发版上遇到了类似的错误,并通过将缺失的jar文件添加到keycloak主目录下的“providers”文件夹中来解决了该问题。 - maxivis

2

如果要使用Gradle完成与@Christophe de Vienne相同的操作:

build.gradle

configurations {
    bundleLib
}

dependencies {
    //...
    compile "org.keycloak:keycloak-services:$keycloakVersion"
}

jar {
    from {
        configurations.bundleLib.collect { it.isDirectory() ? it : zipTree(it) }
    }
    manifest {
        attributes(
                'Dependencies'   : "org.keycloak.keycloak-services"
        )
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接