You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraalVM原生镜像部署Spring Boot应用时出现依赖注入异常

Spring Boot原生镜像部署K8S无法注册Eureka问题

我用Spring 3.1.2开发了一个简单的REST应用,打包成JAR部署到K8S集群时能正常注册到Eureka服务器并运行。但用mvn clean -Pnative native:compile编译成GraalVM原生镜像后部署,日志出现如下错误:

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.2)

2023-10-09T22:33:25.141-05:00  INFO 30700 --- [           main] c.e.creditscore.CreditscoreApplication   : Starting AOT-processed CreditscoreApplication using Java 17.0.8 with PID 30700 (/Users/atael/Documents/GitHub/microservices-datadriven/cloudbank-v2/spring-apps-spring3/creditscore/target/creditscore started by atael in /Users/atael/Documents/GitHub/microservices-datadriven/cloudbank-v2/spring-apps-spring3/creditscore/target)
2023-10-09T22:33:25.142-05:00  INFO 30700 --- [           main] c.e.creditscore.CreditscoreApplication   : No active profile set, falling back to 1 default profile: "default"
2023-10-09T22:33:25.144-05:00  INFO 30700 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=368d3e47-1089-3f9a-85bc-0c3f5dcda5ab
2023-10-09T22:33:25.162-05:00  INFO 30700 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-10-09T22:33:25.163-05:00  INFO 30700 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-10-09T22:33:25.163-05:00  INFO 30700 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.11]
2023-10-09T22:33:25.170-05:00  INFO 30700 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-10-09T22:33:25.170-05:00  INFO 30700 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 28 ms
2023-10-09T22:33:25.195-05:00  WARN 30700 --- [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthContributorRegistry': Unsatisfied dependency expressed through method 'healthContributorRegistry' parameter 2: Error creating bean with name 'discoveryCompositeHealthContributor': Unsatisfied dependency expressed through method 'discoveryCompositeHealthContributor' parameter 0: Error creating bean with name 'eurekaHealthIndicator': Unsatisfied dependency expressed through method 'eurekaHealthIndicator' parameter 0: No qualifying bean of type 'com.netflix.discovery.EurekaClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

pom.xml相关配置

<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
</plugin>

使用的Java版本

java version "17.0.8" 2023-07-18 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 17.0.8+9.1 (build 17.0.8+9-LTS-jvmci-23.0-b14)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 17.0.8+9.1 (build 17.0.8+9-LTS-jvmci-23.0-b14, mixed mode, sharing)

应用代码

启动类

package com.example.creditscore;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class CreditscoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(CreditscoreApplication.class, args);
    }

}

控制器

package com.example.creditscore.controller;

import org.springframework.web.bind.annotation.*;

import lombok.extern.slf4j.Slf4j;

import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/v1")
@Slf4j
public class CreditScoreController {

    @GetMapping("/creditscore")
    public Map<String, String> getCreditScore() {
        log.info("CREDITSCORE: getCreditScore");
        int max = 900;
        int min = 500;
        SecureRandom secureRandom = new SecureRandom();
        HashMap<String, String> map = new HashMap<>();
        map.put("Credit Score", String.valueOf(secureRandom.nextInt(max - min) + min));
        map.put("Date", String.valueOf(java.time.LocalDate.now()));
        return map;
    }
}

application.yaml配置

spring:
  application:
    name: creditscore
  zipkin:
    base-url: ${zipkin.base-url}

eureka:
  instance:
    hostname: ${spring.application.name}
    preferIpAddress: true
  client:
    service-url:
      defaultZone: ${eureka.service-url}
    fetch-registry: true
    register-with-eureka: true
    enabled: true

management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    tags:
      application: ${spring.application.name}

K8S Deployment描述信息

Name:                   creditscore
Namespace:              nativetest
CreationTimestamp:      Mon, 09 Oct 2023 15:53:20 -0500
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=creditscore
Replicas:               1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=creditscore
           version=0.0.1
  Containers:
   creditscore:
    Image:      <notforpublic>
    Port:       8080/TCP
    Host Port:  0/TCP
    Environment:
      app.container.port:                     8080
      spring.profiles.active:                 default
      spring.config.label:                    0.0.1
      eureka.instance.preferIpAddress:        true
      eureka.instance.hostname:               creditscore.nativetest
      MP_LRA_COORDINATOR_URL:                 http://otmm-tcs.otmm.svc.cluster.local:9000/api/v1/lra-coordinator
      MP_LRA_PARTICIPANT_URL:                 http://creditscore.nativetest.svc.cluster.local:8080
      eureka.client.register-with-eureka:     true
      eureka.client.fetch-registry:           true
      eureka.client.service-url.defaultZone:  http://eureka.eureka:8761/eureka
      zipkin.base-url:                        http://jaegertracing-collector.observability:9411
      otel.exporter.otlp.endpoint:            http://open-telemetry-opentelemetry-collector.open-telemetry:4317
      hystrix.metrics.enabled:                true
    Mounts:                                   <none>
  Volumes:                                    <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      False   MinimumReplicasUnavailable
OldReplicaSets:  <none>
NewReplicaSet:   creditscore-5774cb4757 (1/1 replicas created)
Events:          <none>

请问我哪里操作出错了?


解决方法

问题核心是GraalVM原生镜像的AOT处理未正确生成Eureka客户端相关Bean,导致Spring上下文无法找到com.netflix.discovery.EurekaClient类型实例。可按以下步骤修复:

  1. 补充Spring Cloud Native依赖
    确保pom.xml中加入适配原生镜像的Spring Cloud组件依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-native-core</artifactId>
</dependency>
  1. 完善原生镜像编译插件配置
    增强native-maven-plugin的配置,确保Spring Boot AOT处理被正确触发:
<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
    <extensions>true</extensions>
    <executions>
        <execution>
            <id>build-native</id>
            <goals>
                <goal>compile-no-fork</goal>
            </goals>
            <phase>package</phase>
        </execution>
    </executions>
</plugin>
  1. 手动指定AOT注册类(可选)
    如果自动处理仍有遗漏,可在启动类添加@NativeHint指定需要预注册的Eureka相关类:
@EnableDiscoveryClient
@SpringBootApplication
@NativeHint(types = {com.netflix.discovery.EurekaClient.class, org.springframework.cloud.client.discovery.DiscoveryClient.class})
public class CreditscoreApplication {
    public static void main(String[] args) {
        SpringApplication.run(CreditscoreApplication.class, args);
    }
}
  1. 验证版本兼容性
    确保使用的Spring Cloud版本(2022.0.x系列)与Spring Boot 3.1.x完全匹配,避免版本冲突导致的原生镜像适配问题。

内容的提问来源于stack exchange,提问作者Tallen67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 04:17:33