Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning printed after migrating to Spring Boot 3.0 & Spring Integration 6.0

After migrating a project from Spring Boot v2.7 to v3.0 (and thus from Spring Integration v5.5 to v6.0), the following warnings are printed out:

WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.foobar.MyClassA
WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.foobar.MyClassB
WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.foobar.MyClassC
WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.foobar.MyClassD

MyClassA extends IntegrationFlowAdapter, and is annotated with @Component:

package com.foobar;

@Component
class MyClassA extends IntegrationFlowAdapter {
  // …
}

MyClassB is annotated with @ConfigurationProperties:

package com.foobar;

@ConfigurationProperties("my-config")
class MyClassB {
  // …
}

MyClassC is annotated with @Configuration:

package com.foobar;

@Configuration
class MyClassC {
  // …
}

And this particular one not even extending anything, nor annotated:

package com.foobar;

class MyClassD {
  // …
}

I didn’t see any relevant information in the Spring Boot and Spring Integration migration guides. There is a section about name resolution in the Spring Boot migration guide, but it is related to Gradle, and I’m using Maven. I’m not even sure what this name resolution is all about.

I’m puzzled with the class LocalVariableTableParameterNameDiscoverer, and I’m not sure what migration task I’m supposed to do.

like image 734
Morgan Courbet Avatar asked Jan 22 '26 12:01

Morgan Courbet


2 Answers

Morgan's answer provides the correct fix, but I want to show some code to explain why this happens.

Given the following @Configuration class:

@Configuration
public class AppConfig {

    @Bean
    public SomeBean someBean(FooBar foo, FooBar bar) {
        return new SomeBean(foo, bar);
    }

    @Bean
    public FooBar foo() {
        return new FooBar();
    }

    @Bean
    public FooBar bar() {
        return new FooBar();
    }
}

When creating the bean someBean, Spring must know which beans to use for each of the two parameters of the someBean() method. It does this by looking at the parameter names of the method (i.e. foo and bar) and compares it with the name of existing beans. The deprecated LocalVariableTableParameterNameDiscoverer is used to resolve the parameter names of the method.

However, the parameter names are only kept after the compilation of the Java classes if the -debug flag is passed to the javac compiler. By default, the Maven compiler plugin does pass this flag to javac. That's why LocalVariableTableParameterNameDiscoverer can do its job and why the warning is emitted.

With the code above, one can try to change the configuration of the Maven compiler plugin not to pass the debug flag to javac:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <debug>false</debug>
            </configuration>
        </plugin>
    </plugins>
</build>

After compiling and executing the app, the warning will be replaced by the error:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'edu.self.nyg.example.app.FooBar' available: expected single matching bean but found 2: foo,bar

For parameters names to be retained after compilation without the use of the debug flag, the -parameters flag must be used. This will allow Spring's StandardReflectionParameterNameDiscoverer to replace LocalVariableTableParameterNameDiscoverer and correctly find the proper beans for the foo and bar parameters of someBean().

The use of -parameters seems to be recommended, but to get rid of the warning one can also do the following if needed:

@Bean
public SomeBean someBean(
        @Qualifier("foo") FooBar foo,
        @Qualifier("bar") FooBar bar) {
    return new SomeBean(foo, bar);
}

Note that it's ok to have both debug and parameters flags set to true, Spring will use StandardReflectionParameterNameDiscoverer and won't emit a warning.

like image 170
nyg Avatar answered Jan 25 '26 01:01

nyg


As pointed by @m-deinum in the question’s comments, the problem is not related to Spring Boot or Spring Integration, but to Spring Framework itself. I needed to add the -parameters option to javac.

If you are using Maven, adding the following in the pom.xml should solve the problem:

<project>
  
  <!-- … -->

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.11.0</version>
          <configuration>
            <parameters>true</parameters>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <!-- … -->

</project>
like image 38
Morgan Courbet Avatar answered Jan 25 '26 00:01

Morgan Courbet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!