Spring Boot 3.0.2+GraalVM nativeCompile启动Bean创建异常求助
将Spring Boot版本升级至3.0.2后,常规方式运行应用一切正常,但使用GraalVM的nativeCompile生成可执行文件启动时出现异常,异常信息如下:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0: Error creating bean with name 'mvcHandlerMappingIntrospector': Error creating bean with name 'resourceHandlerMapping': Instantiation of supplied bean failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0: Error creating bean with name 'mvcHandlerMappingIntrospector': Error creating bean with name 'resourceHandlerMapping': Instantiation of supplied bean failed
已尝试使用@RegisterReflectionForBinding注解注册Bean,但异常依旧。
安全配置类
@Configuration @EnableMethodSecurity @EnableWebSecurity public class SecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .headers() .and() .authorizeHttpRequests() .anyRequest().authenticated() .and() .addFilterBefore(getAuthContext(), UsernamePasswordAuthenticationFilter.class); return httpSecurity.build(); } @Bean public AuthContextFilter1 getAuthContext() { return new AuthContextFilter1(); } }
AuthContextFilter1 过滤器类
@Slf4j public class AuthContextFilter1 extends GenericFilterBean { private static final String X_CLIENT_ID = "ID"; private static final String X_CLIENT_ROLES = "ROLE"; private static final String ROLE_PREFIX = "ROLE_"; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Collection<GrantedAuthority> authorities = new ArrayList<>(); HttpServletRequest httpServletRequest = (HttpServletRequest) request; String clientId = httpServletRequest.getHeader(X_CLIENT_ID); String roles = httpServletRequest.getHeader(X_CLIENT_ROLES); if (Objects.nonNull(clientId)) { try { if ((!StringUtils.isEmpty(roles))) { authorities = Arrays.stream(roles.split(",")) .map(role -> new SimpleGrantedAuthority(ROLE_PREFIX + role)) .collect(Collectors.toList()); } Authentication auth = new CustomAuthentication(clientId, authorities); SecurityContextHolder.getContext().setAuthentication(auth); } catch (Exception e) { log.error("Auth context initialization failed for clientId: {}, message: {}", clientId, e.getMessage()); } } chain.doFilter(request, response); } }
可行解决方向
补充Native模式反射配置
单独使用@RegisterReflectionForBinding可能遗漏了关键类,尝试扩展注解覆盖更多相关类:@RegisterReflectionForBinding({SimpleGrantedAuthority.class, CustomAuthentication.class, ResourceHandlerMapping.class})如果仍无效,通过代理模式自动收集反射配置:
java -agentlib:native-image-agent=config-output-dir=./src/main/resources/META-INF/native-image 你的主类全路径将生成的配置文件放到指定目录后,重新执行
nativeCompile。显式声明MvcHandlerMappingIntrospector Bean
避免Native模式下自动装配失败,手动注册该Bean:@Bean MvcHandlerMappingIntrospector mvcHandlerMappingIntrospector(ApplicationContext context) { return new MvcHandlerMappingIntrospector(context); }匹配GraalVM版本
Spring Boot 3.0.2要求搭配GraalVM 22.3+(对应JDK 17),确认本地GraalVM版本是否符合要求。
内容的提问来源于stack exchange,提问作者Farid Guluzade

