Skip to content

Destroy method not found in native image if concrete bean type is not exposed #29545

@joshlong

Description

@joshlong

I have a spring boot 3 snapshots app with nothing on the classpath save spring-boot-starter with spring boot 3 aot and graalvm apps.

if I use the code:

package shutdown.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

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

	@Bean
	Controller myController  (){
		return new ControllerManager();
	}
}

class ControllerManager implements Controller {

	@Override
	public void shutdown() {
		System.out.println("calling ControllerManager#shutdown" );
	}
}

interface Controller {

	void shutdown() ;
}

and then compile/run in a graalvm application, I get the following error:

022-11-21T17:56:24.631-08:00 INFO 66325 --- [ main] shutdown.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-21T17:56:24.633-08:00 WARN 66325 --- [ main] o.s.c.support.GenericApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myController': Invalid destruction signature
2022-11-21T17:56:24.633-08:00 ERROR 66325 --- [ main] o.s.boot.SpringApplication : Application run failed

If I return ControllerManager from the @Bean method, that works.

It's still pretty dissatisfying when I have a builder that returns Controller, and not the subclass, and I have no way of knowing what subclass it is. Plus, it works on the JVM with no issues even with just the interface.

I know there is a best practice that we should use direct subclasses in @Bean method return types, but this feels like a different kind of bug, especially since shutdown is visible on the interface and the subclass.

The other issue here is that it is not my intent that this shutdown be used to clean up the bean when the application context shuts down. That is, I don’t want this to be used as the spring bean destroyMethod; it’s just a method that happened to be on the class. So to get these inscrutable errors about Invalid destruction signature is weird.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)theme: aotAn issue related to Ahead-of-time processingtype: enhancementA general enhancement

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions