在 docker 容器中启动项目时找不到 io.jsonwebtoken.impl.DefaultJwtBuilder

Can't find io.jsonwebtoken.impl.DefaultJwtBuilder when starting project in a docker container

当使用 mvn quarkus:dev 在本地启动我的 Quarkus 项目时,我在执行使用 JJWT 的函数时没有出现错误。 但是,当我将我的项目导出到 docker 容器时,它给我一个错误,指出它找不到 DefaultJwtBuilder。

当 docker 启动我的项目时,我首先执行

./mvnw package -Pnative -Dquarkus.native.container-build=true

the Quarkus docs 所述,用于在没有 GraalVM 的情况下创建 Linux 可执行文件。

其次是

docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .

使用 Docker 桌面启动项目时出现错误。

我的 pom.xml 中的依赖项如下。

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-api</artifactId>
  <version>0.11.2</version>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-impl</artifactId>
  <version>0.11.2</version>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-jackson</artifactId>
  <version>0.11.2</version>
  <scope>runtime</scope>
</dependency>

详细错误信息为

io.jsonwebtoken.lang.UnknownClassException: Unable to load class named [io.jsonwebtoken.impl.DefaultJwtBuilder] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found. Have you remembered to include the jjwt-impl.jar in your runtime classpath?

at io.jsonwebtoken.lang.Classes.forName(Classes.java:92)
at io.jsonwebtoken.lang.Classes.newInstance(Classes.java:136)
at io.jsonwebtoken.Jwts.builder(Jwts.java:141)
at org.roguedevelopment.logic.JWT.GenerateJWT(JWT.java:21)
at org.roguedevelopment.logic.JWT_ClientProxy.GenerateJWT(JWT_ClientProxy.zig:224)
at org.roguedevelopment.logic.AuthHandler.LoginUser(AuthHandler.java:62)
at org.roguedevelopment.logic.AuthHandler_ClientProxy.LoginUser(AuthHandler_ClientProxy.zig:164)
at org.roguedevelopment.controllers.AuthController.login(AuthController.java:72)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:643)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:507)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget(ResourceMethodInvoker.java:457)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:459)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:419)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:393)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke(SynchronousDispatcher.java:261)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess[=13=](SynchronousDispatcher.java:161)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:131)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access[=13=]0(VertxRequestHandler.java:37)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.run(VertxRequestHandler.java:94)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at java.lang.Thread.run(Thread.java:834)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:192)

我用来构建 docker 图像的 docker 文件是

## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/centos-quarkus-maven:20.2.0-java11 AS build
COPY pom.xml /usr/src/app/
RUN mvn -f /usr/src/app/pom.xml -B de.qaware.maven:go-offline-maven-plugin:1.2.5:resolve-dependencies
COPY src /usr/src/app/src
USER root
RUN chown -R quarkus /usr/src/app
USER quarkus
RUN mvn -f /usr/src/app/pom.xml -Pnative clean package

## Stage 2 : create the docker final image
FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY --from=build /usr/src/app/target/*-runner /work/application

# set up permissions for user `1001`
RUN chmod 775 /work /work/application \
  && chown -R 1001 /work \
  && chmod -R "g+rwX" /work \
  && chown -R 1001:root /work

EXPOSE 8000
USER 1001

CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

如有任何帮助,我们将不胜感激。

它不起作用,因为您使用的是本机模式并且 io.jsonwebtoken 库似乎不支持它。

Quarkus 尽最大努力集成库并通过添加原生模式所需的部分使它们在原生模式下工作。对于本机模式限制,请检查此 link:https://www.graalvm.org/reference-manual/native-image/Limitations/.

请检查适用于本机模式的 Quarkus JWT 支持:https://quarkus.io/guides/security-jwt

如果您真的想继续使用 io.jsonwebtoken,您可能需要为本机图像构建提供额外的元数据:https://quarkus.io/guides/writing-native-applications-tips