在 wildfly jar (keycloak SPI) 中包含第三方库
Include third party library in wildfly jar (keycloak SPI)
我正在使用服务提供者接口为 keycloak 创建插件(提供者)。我已经能够建立一对。现在我需要添加 smallrye-graphql-client 库来查询 graphql 服务器。但是,当我部署插件时,在class路径中找不到该库。
问题
- 是否仍然可以创建包含依赖库的 jar?
- 如果 1 不可能,可以用 war 来完成吗?
- 如何将库添加到 class 路径。最好将它们与插件一起添加,而不是静态地添加到 Wildfly。我正在使用 gradle。下面有更多详细信息。
背景信息
我成功地为它创建了 class 和集成测试。但是,当我将插件部署到 keycloak 时,出现以下错误:
16:38:38,127 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-1)
Uncaught server error: java.util.ServiceConfigurationError: no
io.smallrye.graphql.client.typesafe.api.GraphQlClientBuilder in classpath
我已将 gradle 配置为包括导致问题的依赖项,并将其添加到 class 路径。我怀疑我应该在 jboss-deployment-structure.xml 中添加一个条目,但我不知道应该在那里写什么。
gradle配置
plugins {
id 'war'
id 'java-library'
id 'maven-publish'
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
configurations {
dependenciesToInclude
}
dependencies {
dependenciesToInclude "io.smallrye:smallrye-graphql-client:1.0.20"
providedCompile group: 'javax.enterprise', name: 'cdi-api', version: '2.0'
providedCompile "org.keycloak:keycloak-server-spi:${keycloakVersion}"
providedCompile "org.keycloak:keycloak-server-spi-private:${keycloakVersion}"
providedCompile("org.keycloak:keycloak-services:${keycloakVersion}") {
exclude group: 'org.slf4j', module: 'slf4j-api'
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
providedCompile group: 'org.keycloak', name: 'keycloak-model-api', version: '1.8.1.Final'
providedCompile "org.jboss.resteasy:resteasy-jaxrs"
providedCompile group: 'org.eclipse.microprofile.graphql', name: 'microprofile-graphql-api', version: '1.0.3'
compile group: 'org.apache.geronimo.config', name: 'geronimo-config-impl', version: '1.2.2'
configurations.compile.extendsFrom(configurations.dependenciesToInclude)
}
jar {
manifest {
attributes(
"Class-Path": configurations.dependenciesToInclude.collect { it.getName() }.join(' '))
}
from {
configurations.dependenciesToInclude.collect { it.isDirectory() ? it : zipTree(it) }
}
}
❯ cat META-INF/MANIFEST.MF ─╯
Manifest-Version: 1.0
Class-Path: smallrye-graphql-client-1.0.20.jar geronimo-config-impl-1.2.
2.jar smallrye-graphql-client-api-1.0.20.jar microprofile-graphql-api-1
.0.3.jar microprofile-config-api-1.3.jar org.osgi.annotation.versioning
-1.0.0.jar
下面是 jboss-部署-structure.xml。在那里你可以看到我试图包含 graphql 库(注释掉)
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-services"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.apache.commons.codec"/>
<module name="org.apache.commons.lang"/>
<module name="org.jboss.logging"/>
<!-- <module name="io.smallrye.smallrye-graphql-client"/>-->
</dependencies>
</deployment>
</jboss-deployment-structure>
我正在使用 Keycloak 11.0.2 (WildFly Core 12.0.3.Final)
我不确定我是否正确理解了将库静态添加到 jboss 的部分。我会根据我对你的问题的理解来回答。
您的问题有多种解决方案。
Jboss 依赖关系
您应该首先了解 JBoss 如何解析它的 类 和依赖项。我会非常简单地解释。
JBoss 分为模块和部署。
模块放置在您 JBoss 的主文件夹中。模块是您在运行时不会更改的库。
每个模块都有一个名为 module.xml 的描述符文件,您可以在其中定义工件、依赖项和模块名称。
文件 module.xml 基本上类似于模块世界中的 jboss-deployment-structure.xml。
部署放置在部署文件夹中,可以在 JBoss 服务器为 运行 时重新部署。如果一个部署需要依赖另一个 module/deployment,它需要包含在给定部署的 jboss-deployment-structure 中。
Note that modules cannot be dependent on deployments but it works the other way around
您可以在 Internet 上找到更多信息,但这是您可以使用的基本信息。
解决方案 1 - JBoss 模块
如果你想获得对 JBoss 中模块的依赖,你需要在 module.xml 中找到它的名称并将其写入你的 jboss-deployment-structure.xml(假设您的库是一个部署)
因此,例如,如果您想要依赖 jackson-dataformat-cbor-2.10.5.jar 在 keycloak 模块路径中:
modules/system/layers/keycloak/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/main/jackson-dataformat-cbor-2.10.5.jar
在同一文件夹中有一个 module.xml,内容为:
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<module name="com.fasterxml.jackson.dataformat.jackson-dataformat-cbor" xmlns="urn:jboss:module:1.3">
<resources>
<resource-root path="jackson-dataformat-cbor-2.10.5.jar"/>
</resources>
<dependencies>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-databind"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
</dependencies>
</module>
这意味着您的模块名称是 com.fasterxml.jackson.dataformat.jackson-dataformat-cbor
,这就是您作为依赖项放入 jboss-deployment-structure.xml 中的内容。
你的情况
在您的情况下,您需要 smallrye-graphql-client
的依赖项,但 JBoss 模块中未包含该依赖项。这意味着您必须将其添加到那里。
通过在图层中创建文件夹来创建 JBoss 图层:
modules/system/layers/[name of your layer]
这样做之后,您还应该将图层包含在 modules/layers.conf
中。您可以通过在 keycloak 层之后写逗号来包含它,如下所示:
layers=keycloak,[your layer]
创建它之后,您可以将您的插件添加到您的图层中,例如:
modules/system/layers/[name of your layer]/org/my/plugins/main
文件夹内将是:
- 你的罐子
- module.xml(根据其他模块创建)
那么您要做的唯一一件事就是将此模块作为依赖项包含在您的 jboss-deployment-structure.xml 中。 (你总是包括模块的名称)
Note that you might have to add more libraries as dependencies to your modules. You can include all of it in the modules
如果您不喜欢手动创建这些东西,您可以创建 jboss-modules-builder,例如这个。它将使用 maven:
创建你的模块 xml
https://github.com/marcel-ouska/jboss-modules-builder
解决方案 2 - 肥胖 JAR/WAR
基本上,如果您想要一个简单的解决方案,您可以使用 maven/Gradle 插件直接将库添加到 JAR/WAR。
- 胖罐子 - http://tutorials.jenkov.com/maven/maven-build-fat-jar.html
- WAR - 您的依赖项会自动打包
我不建议使用 Fat JAR/WAR 解决方案,因为添加更多插件可能会迷失在依赖项中并出现错误,例如重复依赖项 类.
我正在使用服务提供者接口为 keycloak 创建插件(提供者)。我已经能够建立一对。现在我需要添加 smallrye-graphql-client 库来查询 graphql 服务器。但是,当我部署插件时,在class路径中找不到该库。
问题
- 是否仍然可以创建包含依赖库的 jar?
- 如果 1 不可能,可以用 war 来完成吗?
- 如何将库添加到 class 路径。最好将它们与插件一起添加,而不是静态地添加到 Wildfly。我正在使用 gradle。下面有更多详细信息。
背景信息
我成功地为它创建了 class 和集成测试。但是,当我将插件部署到 keycloak 时,出现以下错误:
16:38:38,127 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-1)
Uncaught server error: java.util.ServiceConfigurationError: no
io.smallrye.graphql.client.typesafe.api.GraphQlClientBuilder in classpath
我已将 gradle 配置为包括导致问题的依赖项,并将其添加到 class 路径。我怀疑我应该在 jboss-deployment-structure.xml 中添加一个条目,但我不知道应该在那里写什么。
gradle配置
plugins {
id 'war'
id 'java-library'
id 'maven-publish'
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
configurations {
dependenciesToInclude
}
dependencies {
dependenciesToInclude "io.smallrye:smallrye-graphql-client:1.0.20"
providedCompile group: 'javax.enterprise', name: 'cdi-api', version: '2.0'
providedCompile "org.keycloak:keycloak-server-spi:${keycloakVersion}"
providedCompile "org.keycloak:keycloak-server-spi-private:${keycloakVersion}"
providedCompile("org.keycloak:keycloak-services:${keycloakVersion}") {
exclude group: 'org.slf4j', module: 'slf4j-api'
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
providedCompile group: 'org.keycloak', name: 'keycloak-model-api', version: '1.8.1.Final'
providedCompile "org.jboss.resteasy:resteasy-jaxrs"
providedCompile group: 'org.eclipse.microprofile.graphql', name: 'microprofile-graphql-api', version: '1.0.3'
compile group: 'org.apache.geronimo.config', name: 'geronimo-config-impl', version: '1.2.2'
configurations.compile.extendsFrom(configurations.dependenciesToInclude)
}
jar {
manifest {
attributes(
"Class-Path": configurations.dependenciesToInclude.collect { it.getName() }.join(' '))
}
from {
configurations.dependenciesToInclude.collect { it.isDirectory() ? it : zipTree(it) }
}
}
❯ cat META-INF/MANIFEST.MF ─╯
Manifest-Version: 1.0
Class-Path: smallrye-graphql-client-1.0.20.jar geronimo-config-impl-1.2.
2.jar smallrye-graphql-client-api-1.0.20.jar microprofile-graphql-api-1
.0.3.jar microprofile-config-api-1.3.jar org.osgi.annotation.versioning
-1.0.0.jar
下面是 jboss-部署-structure.xml。在那里你可以看到我试图包含 graphql 库(注释掉)
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-services"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.apache.commons.codec"/>
<module name="org.apache.commons.lang"/>
<module name="org.jboss.logging"/>
<!-- <module name="io.smallrye.smallrye-graphql-client"/>-->
</dependencies>
</deployment>
</jboss-deployment-structure>
我正在使用 Keycloak 11.0.2 (WildFly Core 12.0.3.Final)
我不确定我是否正确理解了将库静态添加到 jboss 的部分。我会根据我对你的问题的理解来回答。 您的问题有多种解决方案。
Jboss 依赖关系
您应该首先了解 JBoss 如何解析它的 类 和依赖项。我会非常简单地解释。 JBoss 分为模块和部署。
模块放置在您 JBoss 的主文件夹中。模块是您在运行时不会更改的库。 每个模块都有一个名为 module.xml 的描述符文件,您可以在其中定义工件、依赖项和模块名称。 文件 module.xml 基本上类似于模块世界中的 jboss-deployment-structure.xml。
部署放置在部署文件夹中,可以在 JBoss 服务器为 运行 时重新部署。如果一个部署需要依赖另一个 module/deployment,它需要包含在给定部署的 jboss-deployment-structure 中。
Note that modules cannot be dependent on deployments but it works the other way around
您可以在 Internet 上找到更多信息,但这是您可以使用的基本信息。
解决方案 1 - JBoss 模块
如果你想获得对 JBoss 中模块的依赖,你需要在 module.xml 中找到它的名称并将其写入你的 jboss-deployment-structure.xml(假设您的库是一个部署)
因此,例如,如果您想要依赖 jackson-dataformat-cbor-2.10.5.jar 在 keycloak 模块路径中:
modules/system/layers/keycloak/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/main/jackson-dataformat-cbor-2.10.5.jar
在同一文件夹中有一个 module.xml,内容为:
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<module name="com.fasterxml.jackson.dataformat.jackson-dataformat-cbor" xmlns="urn:jboss:module:1.3">
<resources>
<resource-root path="jackson-dataformat-cbor-2.10.5.jar"/>
</resources>
<dependencies>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-databind"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
</dependencies>
</module>
这意味着您的模块名称是 com.fasterxml.jackson.dataformat.jackson-dataformat-cbor
,这就是您作为依赖项放入 jboss-deployment-structure.xml 中的内容。
你的情况
在您的情况下,您需要 smallrye-graphql-client
的依赖项,但 JBoss 模块中未包含该依赖项。这意味着您必须将其添加到那里。
通过在图层中创建文件夹来创建 JBoss 图层:
modules/system/layers/[name of your layer]
这样做之后,您还应该将图层包含在 modules/layers.conf
中。您可以通过在 keycloak 层之后写逗号来包含它,如下所示:
layers=keycloak,[your layer]
创建它之后,您可以将您的插件添加到您的图层中,例如:
modules/system/layers/[name of your layer]/org/my/plugins/main
文件夹内将是:
- 你的罐子
- module.xml(根据其他模块创建)
那么您要做的唯一一件事就是将此模块作为依赖项包含在您的 jboss-deployment-structure.xml 中。 (你总是包括模块的名称)
Note that you might have to add more libraries as dependencies to your modules. You can include all of it in the modules
如果您不喜欢手动创建这些东西,您可以创建 jboss-modules-builder,例如这个。它将使用 maven:
创建你的模块 xmlhttps://github.com/marcel-ouska/jboss-modules-builder
解决方案 2 - 肥胖 JAR/WAR
基本上,如果您想要一个简单的解决方案,您可以使用 maven/Gradle 插件直接将库添加到 JAR/WAR。
- 胖罐子 - http://tutorials.jenkov.com/maven/maven-build-fat-jar.html
- WAR - 您的依赖项会自动打包
我不建议使用 Fat JAR/WAR 解决方案,因为添加更多插件可能会迷失在依赖项中并出现错误,例如重复依赖项 类.