Skip to content

Unnecessary parameter name introspection for constructor-arg resolution (leading to LocalVariableTableParameterNameDiscoverer warnings) #29612

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

Closed
leonchen83 opened this issue Nov 30, 2022 · 13 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@leonchen83
Copy link
Contributor

after upgrade to springframework 6.0.2. we got following warnings

22-11-30 17:39:11.513 WARN [main LocalVariableTableParameterNameDiscoverer.inspectClass:123]Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer
22-11-30 17:39:15.632 WARN [main LocalVariableTableParameterNameDiscoverer.inspectClass:123]Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer
22-11-30 17:39:19.351 WARN [main LocalVariableTableParameterNameDiscoverer.inspectClass:123]Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.eclipse.jetty.server.Server
22-11-30 17:39:19.394 WARN [main LocalVariableTableParameterNameDiscoverer.inspectClass:123]Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.eclipse.jetty.server.HttpConnectionFactory
22-11-30 17:39:19.409 WARN [main LocalVariableTableParameterNameDiscoverer.inspectClass:123]Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.eclipse.jetty.server.ServerConnector

all we source code already add compile args -parameters. I want to ask how to handle third party jar's compile args. and how to eliminate above warning

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 30, 2022
@sbrannen sbrannen added this to the Triage Queue milestone Nov 30, 2022
@jhoeller
Copy link
Contributor

jhoeller commented Dec 1, 2022

Why are those Jasypt/Jetty classes getting introspected in the first place? Do you have bean configuration that refers to their constructor parameter names or the like?

Generally speaking, Spring-driven parameter name introspection is only being triggered by actual demand at runtime. Some step has to trigger the introspection attempt through asking for a parameter name on a specific method/constructor. It would be very helpful to find out what it is in your scenario.

We intend to remove debug symbol introspection completely in 6.1, exclusively relying on -parameters. That's the main reason for that warn logging. Aside from missing -parameters, we also found quite a few places where parameter names were introspected but effectively not used - which is quite costly since we are unnecessarily parsing the class file for every affected class there. We'd like to identify and fix all such remaining cases.

@leonchen83
Copy link
Contributor Author

leonchen83 commented Dec 1, 2022

@jhoeller
I create a simple project to reproduce our scenario.

please refer to spring-test

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd">
    
    <!-- server -->
    <bean id="jetty.server" class="org.eclipse.jetty.server.Server">
        <property name="stopAtShutdown" value="true"/>
        <property name="dumpAfterStart" value="false"/>
        <property name="dumpBeforeStop" value="false"/>
        <property name="connectors" ref="jetty.connectors"/>
    </bean>
    
    <util:list id="jetty.connectors" list-class="java.util.ArrayList">
        <bean id="jetty.connector.server" class="org.eclipse.jetty.server.ServerConnector">
            <constructor-arg index="0" ref="jetty.server"/>
            <constructor-arg index="1" ref="jetty.connections"/>
            <property name="port" value = "8080"/>
            <property name="host" value = "127.0.0.1"/>
            <property name="idleTimeout" value = "30000"/>
        </bean>
    </util:list>
    
    <util:list id="jetty.connections" list-class="java.util.ArrayList">
        <bean id="jetty.connection.http" class="org.eclipse.jetty.server.HttpConnectionFactory">
            <constructor-arg>
                <bean class="org.eclipse.jetty.server.HttpConfiguration">
                    <property name="securePort" value="8442"/><property name="secureScheme" value="https"/>
                    <property name="headerCacheSize" value="512"/><property name="outputBufferSize" value="32768"/>
                    <property name="sendDateHeader" value="false"/><property name="sendServerVersion" value="false"/>
                    <property name="requestHeaderSize" value="8192"/><property name="responseHeaderSize" value="8192"/>
                </bean>
            </constructor-arg>
        </bean>
    </util:list>
</beans>

@jhoeller jhoeller added type: bug A general bug in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 1, 2022
@jhoeller jhoeller modified the milestones: Triage Queue, 6.0.3 Dec 1, 2022
@jhoeller
Copy link
Contributor

jhoeller commented Dec 1, 2022

It looks like the core bean factory is unnecessarily retrieving constructor parameter names during the constructor autowiring algorithm, despite no constructor argument names having been specified. That's a bug we're going to fix in 6.0.3.

Thanks for the configuration snippet! There is no need to change anything there as far as I can see. The warnings should disappear when running that same code on 6.0.3 then.

@jhoeller
Copy link
Contributor

jhoeller commented Dec 1, 2022

For the time being, you may simply disable the warn log category for org.springframework.core.LocalVariableTableParameterNameDiscoverer. There is unnecessary reading of class files in the meantime but otherwise no harm for your application.

@jhoeller jhoeller changed the title LocalVariableTableParameterNameDiscoverer warnings after upgrade springframework 6.0.2 Unnecessary parameter name introspection for constructor resolution (leading to LocalVariableTableParameterNameDiscoverer warnings after upgrade to 6.0.2) Dec 1, 2022
@jhoeller jhoeller changed the title Unnecessary parameter name introspection for constructor resolution (leading to LocalVariableTableParameterNameDiscoverer warnings after upgrade to 6.0.2) Unnecessary parameter name introspection for constructor-arg resolution (leading to LocalVariableTableParameterNameDiscoverer warnings) Dec 1, 2022
@ikannak
Copy link

ikannak commented Mar 8, 2023

I still have this issue in Spring Boot 3.0.4, which should be using Spring 6.0.6, on my Spring repositories, when starting Spring Boot in a Tomcat that's running in Eclipse. Editing the project settings to include "-parameters" as a cmpiler flag fixed it, but it's weird that it didn't default to the other discoverer. Or is this just to indicate that you should in fact be using that -parameters" flag?

@sbrannen
Copy link
Member

sbrannen commented Mar 8, 2023

Or is this just to indicate that you should in fact be using that -parameters" flag?

Yes, the warning is an indication that you should be compiling with -parameters.

@abuijze
Copy link

abuijze commented Mar 9, 2023

We have received a very similar bug report in Axon Framework. The issue still appears in Spring 6.0.5.

We've been able to trace the issue down to the following bean definition:

BeanDefinitionBuilder.genericBeanDefinition(SpringPrototypeAggregateFactory.class)
    // using static method to avoid ambiguous constructor resolution in Spring AOT
    .setFactoryMethod("withSubtypeSupport")
    .addConstructorArgValue(aggregateBeanName)
    .addConstructorArgValue(subTypes)
    .getBeanDefinition()

The slight difference with this issue is that the bean definition above uses a static factory method, rather than a constructor. However, there is no need to use parameter names for this definition (if I'm not mistaken), as the "addConstructorArgValue" methods use index-based parameter resolution.

I was in doubt of creating a separate issue for this, but I figured I'd double check here first.

@sdeleuze
Copy link
Contributor

@abuijze I don't think by itself BeanDefinitionBuilder uses LocalVariableTableParameterNameDiscoverer, could you please share the stacktrace that leads to the usage of LocalVariableTableParameterNameDiscoverer or share a minimal repro to allow me to let you know if a dedicated issue should be created?

@smcvb
Copy link

smcvb commented Mar 10, 2023

@sdeleuze I've validated the warning @abuijze shared in my personal sample project, which uses Axon Framework 4.7.1 (containing the code Allard refers to) and Spring Boot 3.0.3.
If you want to run it yourself, it's easiest to add the property axon.axonserver.enabled=false (or connect to an Axon Server instance).

For convenience, I've also drafted a stack trace through IntelliJ starting from the referred to warn message:

...
2023-03-10T13:05:47.056+01:00  INFO 33772 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 206 ms. Found 1 JPA repository interfaces.
Breakpoint reached
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass(LocalVariableTableParameterNameDiscoverer.java:123)
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer$$Lambda$593/0x0000000800ff3cc0.apply(Unknown Source:-1)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer.doGetParameterNames(LocalVariableTableParameterNameDiscoverer.java:96)
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:84)
	at org.springframework.core.PrioritizedParameterNameDiscoverer.getParameterNames(PrioritizedParameterNameDiscoverer.java:55)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:763)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:653)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getType(AbstractBeanFactory.java:692)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAnnotationOnBean(DefaultListableBeanFactory.java:732)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAnnotationOnBean(DefaultListableBeanFactory.java:723)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForAnnotation(DefaultListableBeanFactory.java:693)
	at org.axonframework.spring.config.SpringSagaLookup.postProcessBeanFactory(SpringSagaLookup.java:48)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:747)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565)
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:310)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293)
	at io.axoniq.demo.gamerental.GameRentalApplication.main(GameRentalApplication.java:10)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
2023-03-10T13:05:47.530+01:00  WARN 33772 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: org.axonframework.spring.eventsourcing.SpringPrototypeAggregateFactory
...

Let me know whether this suffices.

@sdeleuze
Copy link
Contributor

Thanks, I have created #30103 follow-up issue.

@vishalsingh2972
Copy link

vishalsingh2972 commented Apr 13, 2023

Getting similar warning after trying everything....any resolution?

Apr 14, 2023 1:09:54 AM org.springframework.core.LocalVariableTableParameterNameDiscoverer inspectClass WARNING: Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: demo.LoggingAspect

I am currently using Spring 6.0.7

@runeflobakk
Copy link
Contributor

runeflobakk commented May 10, 2023

Just to add some "report from the trenches" which may or not help @vishalsingh2972 and others:

In my case, I got three such warnings after upgrading to Spring 6 (not Spring Boot-application). Two of the warnings were for my own classes.

Warn about my own classes

The warnings were for real issues, and because I have multiple DataSource-beans in my context. The two classes I got a warning about were configuration classes with @Bean-annotated methods requiring a DataSource-parameter, but they were not qualified with e.g. a @Qualifier annotation. So the warning told me that for those two methods, the DataSource-bean is injected via the deprecated parameter name resolution. I added a @Qualifier("dataSource") to remove those two warnings. This is also how we inject that particular DataSource a few other places in the application (since we intentionally have two instances), but these two cases were left out, and the logged warnings told me about them.

If you get this warning on your own classes, check if you inject bean(s) by type (as is usually the case), but have two or more beans of that type in your application context. You can verify the "validity" of the warning by e.g. changing the parameter name, and then creating the application context should fail. If you have e.g.

@Configuration
class MyDbConfig {
    @Bean
    MyDataAccessObject myDataAccessObject(DataSource dataSource) {
        ...
    }
}

And you get the warning for the MyDbConfig class, then you probably have several beans of type DataSource, and one of them has the name "dataSource", thus making the injection work, but it must fall back to the deprecated mechanism. Fix it by adding an appropriate @Qualifier:

    @Bean
    MyDataAccessObject myDataAccessObject(@Qualifier("dataSource") DataSource dataSource) {

Another alternative, if appropriate, is to set one of the DataSource-beans as @Primary, which is telling Spring that anywhere a bean requires any DataSource, this is the one to use.

Warn about JdbcHttpSessionConfiguration

This is a very specific case, but still related to the root cause explained above. And the example may be applicable for other cases where the warn is issued about not your own classes.

I also get a warning for org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration, for what I assume is the same reason as above. We use Spring Session and @EnableJdbcHttpSession, and this includes JdbcHttpSessionConfiguration configuration bean in the application context, which also depends on a DataSource (which we have two of). For this case, Spring Session provides the annotation @SpringSessionDataSource which you can annotate the DataSource you wish to be used by Spring Session for persistance.

@vishalsingh2972
Copy link

@runeflobakk could you check and try solving vishalsingh2972/Spring-Framework#1 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

10 participants