Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDE plugin support - information about beans #43208

Open
grisha9 opened this issue Nov 18, 2024 · 4 comments
Open

IDE plugin support - information about beans #43208

grisha9 opened this issue Nov 18, 2024 · 4 comments
Labels
for: team-meeting An issue we'd like to discuss as a team to make progress status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged

Comments

@grisha9
Copy link

grisha9 commented Nov 18, 2024

It would be nice to get all the information about beans (bean definition) in a native way, without starting the application and creating bean instances (start application may have many side effects: DB modification, execute post-construct logic and etc). This can be very useful for creating plugins for IDE independent of IDE implementation.
Maybe there is already something for this?

Maybe it is worth adding some task to Spring Boot Plugins (Maven/Gradle) that like the Maven task 'mvn dependency:tree' , would print out information about beans without starting the application? Then we could just run a build system plugin task, for example for Maven: "mvn org.springframework.boot:spring-boot-maven-plugin:3.2.0:print-bean-definition" , and output information about the beans in some format to the console or file.

I made some prototype - https://github.com/grisha9/spring-bean-printer
The module bean-printer contain logic to print all the bean definition information to the console after the phase "spring.context.beans.post-process". I have custom ApplicationStartup implementation that throw exception after it phase. And custom SpringApplicationRunListener that print all bean info from ConfigurableApplicationContext in failed method.
Also in this module I rewrote the method for launching the spring boot application as shown below. I pass SpringBootApplication class name as env parameter - "org.example.spring.appClassName" and I use my own implementation for ApplicationStartup and SpringApplicationRunListener. And packed it into a jar file - bean-printer.jar

public class BeanDefinitionPrinter {    
    public static void main(String[] args) throws ClassNotFoundException {    
        Class<?> applicationClass = Class.forName(System.getenv("org.example.spring.appClassName"));    
        SpringApplication springApplication = new SpringApplication(applicationClass);     
        springApplication.setApplicationStartup(new SampleApplicationStartup());    
        SpringApplicationHook applicationHook = application -> new SampleFailedSpringApplicationRunListener();    
        SpringApplication.withHook(applicationHook, () -> springApplication.run(args));    
    }
}

The module project-sample contains simple project for test usages. In this module I added spring-boot-maven-plugin this next configuration

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <environmentVariables>
            <org.example.spring.appClassName>org.springframework.sample.Application</org.example.spring.appClassName>
        </environmentVariables>
        <additionalClasspathElements>../bean-printer/target/bean-printer-3.0.0.jar</additionalClasspathElements>
        <mainClass>org.example.bean.printer.BeanDefinitionPrinter</mainClass>
    </configuration>
</plugin>

Configuration contains additional classpath element with bean-printer.jar and main class for run it - org.example.bean.printer.BeanDefinitionPrinter and env variable to real application class name.
As result it print bean definition information in console (mvn org.springframework.boot:spring-boot-maven-plugin:3.2.0:run):

BeanInfo{beanName='application', className='org.springframework.sample.Application', methodName='null', methodReturnTypeName='null', scope='singleton', primary=false}
BeanInfo{beanName='testComponentBean', className='org.springframework.sample.TestComponentBean', methodName='null', methodReturnTypeName='null', scope='singleton', primary=false}
BeanInfo{beanName='testConfig', className='org.springframework.sample.TestConfig', methodName='null', methodReturnTypeName='null', scope='singleton', primary=false}
BeanInfo{beanName='methodBean', className='org.springframework.sample.TestConfig', methodName='methodBean', methodReturnTypeName='org.springframework.sample.TestMethodBean', scope='singleton', primary=false}
...

Maybe it's worth creating a separate task for build systems for this?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 18, 2024
@wilkinsona
Copy link
Member

Thanks for the suggestion.

This can be very useful for creating plugins for IDE independent of IDE implementation

I'm not aware of a shared framework for building IDE plugins that allows a plugin implementation to be independent of the IDE implementation. Can you please expand on this?

Given that major IDEs such as IntelliJ IDEA already have support for introspecting an application's beans and Spring Boot already has the beans endpoint that makes this information available at runtime, my feeling is that what you're proposing is likely to occupy a niche for which there's not much demand. As such, I don't think it's something that we'd want to support in Spring Boot itself.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Nov 18, 2024
@grisha9
Copy link
Author

grisha9 commented Nov 18, 2024

Spring Boot already has the beans endpoint that makes this information available at runtime

Yes, but it requires running the application. But this is not always possible. I worked on large projects where there was no possibility to run the application locally and development was carried out through tests. (This often requires a local environment - DB and etc.)

For example IDEA has also problem with DI context recognized:
image
On this example IDEA successful recognize ConditionalBean, but it is not context and a warning about this should be shown. And the application does not starting.

Can you please expand on this?

If Spring Boot had a build tool plugin (Maven/Gradle) for getting information about beans (without run application) it would greatly simplify the creation of IDE plugins, namely support for DI. Such a build tool task is a platform-independent solution for get context beans and can be used to create a spring-boot support plugin for any IDE (IDEA or VS-CODE)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 18, 2024
@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label Nov 18, 2024
@ciscoo
Copy link

ciscoo commented Nov 18, 2024

Another case too is beans registered through ImportBeanDefinitionRegistrar. At least for our internal libaray, we define some configuration in application.yml which is then read in the ImportBeanDefinitionRegistrar to register additional beans.

IntelliJ IDEA currently shows a red squiggly because it can't locate a formal @Bean bean definition, even though the bean definitely exists. But I don't think this could be found out without actually running the app and inspecting the beans which I think is done today for AOT if I'm not mistaken.

@bclozel
Copy link
Member

bclozel commented Nov 21, 2024

I think that the premise here is flawed.
IDEs tend to implement such features by only looking at the source code. They don't compile nor run the application (not even partially), as suggested by the prototype or our existing AOT arrangement. This is a common design pattern to update hints live.

I agree with Andy, this seems like a rather niche feature for a market that doesn't really exist for now on our side. We're already in touch with IDE vendors and this never came up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: team-meeting An issue we'd like to discuss as a team to make progress status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

6 participants