I am using Spring-boot 3.2.1 and getting the above error message which started coming after the upgrade.

I have the below in my Pom But still seeing the error.

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <parameters>true</parameters>
                </configuration>
            </plugin>
        </plugins>

Any suggestion on what else needs to be added? My spring-boot-parent version is below.

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
        <relativePath /> <!-- lookup parent from repository -->
</parent>

Comment From: bclozel

Is the offending class compiled with your Spring Boot application or does it come from a dependency? Is that dependency compiled with -parameters?

Otherwise, please provide a minimal sample application that reproduces the problem.

Comment From: Kryptonian-C

The offending class Is coming from the application directly. It is a controller method in the Application taking input as

@QueryParam(β€œcategories”) Optional categories

On Thu, 11 Jan 2024 at 6:20β€―PM, Brian Clozel @.***> wrote:

Is the offending class compiled with your Spring Boot application or does it come from a dependency? Is that dependency compiled with -parameters?

Otherwise, please provide a minimal sample application that reproduces the problem.

β€” Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-boot/issues/39095#issuecomment-1887100308, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKC23P2WEJLPTAXMRUVU4TDYN7N3HAVCNFSM6AAAAABBWNW7K6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBXGEYDAMZQHA . You are receiving this because you authored the thread.Message ID: @.***>

Comment From: wilkinsona

Then, as Brian already requested, please provide a minimal sample that reproduces the problem.

Comment From: Kryptonian-C

The error is coming up at random instances. That's what is confusing, the same api with the same parameters works for 100 requests and fails for 2 or 3 that too only when the application is deployed to AKS. I don't see the error on my local instance. Still trying to figure out the root cause so that I can provide a sample application.

On Thu, 11 Jan 2024 at 19:04, Andy Wilkinson @.***> wrote:

Then, as Brian already requested, please provide a minimal sample that reproduces the problem.

β€” Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-boot/issues/39095#issuecomment-1887174147, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKC23P57KPPLMAHUWOU6J53YN7S5DAVCNFSM6AAAAABBWNW7K6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBXGE3TIMJUG4 . You are receiving this because you authored the thread.Message ID: @.***>

Comment From: williejay2017

Overview

Hi Spring team, @bclozel - I just want to piggy back off this issue as I to am walking into this. I can move to my own issue if need be but figured this was fresh enough to jump on. I upgraded our API from 3.1.5 -> 3.2.1 and ran into this same issue on one of our controllers that utilizes the QueryParam annotation. The service is simple as it just sends a filename to an s3 bucket so it can be retrieved later. Nothing special. This endpoint works on 3.1.5 with but breaks on 3.2.0+. I tested locally and get the error below and I also see this error in our stage k8s cluster logs from the api pod when hitting that endpoint. Method is below.

Code

  @RequestMapping(value = '/sign', method = RequestMethod.POST)
  ResponseEntity<S3SignedUrlResponse> getSignedUrl(
    @QueryParam(value = "filename") String filename
  ) {
    new ResponseEntity<S3SignedUrlResponse>(service.serviceMethod(filename), HttpStatus.OK)
  }
  ```

### Error
`
Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.] with root cause
java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.
`

### Relevant Dependencies

`groovyVersion = '4.0.15'`
`springBootVersion = '3.2.1'`
`springCloudVersion = '2023.0.0'`
`Java 17`

### Compiler Options / Args

I set this (below snippet) in our build.gradle to try and _force_ the args but didn't work. I also added it to the settings, no success. Intellij team also has an open [issue](https://youtrack.jetbrains.com/issue/IDEA-339211/Parameter-Name-Reflection-Fails-in-IntelliJ-Builds-with-Spring-Boot-3) in regards to arguments not getting picked up. 


tasks.withType(JavaCompile).configureEach { options.compilerArgs.add("-parameters") }


### Workarounds

@Kryptonian-C  - I switched out the QueryParam to a PathVariable and that is working. Unfortunately I have to make code changes in the UI to support this as well. No biggue but maybe you can find a workaround that works for you for the time being until the Spring team can resolve the issue :)

@RequestMapping(value = '/sign/{filename}', method = RequestMethod.POST) ResponseEntity getSignedUrl( @PathVariable(value = 'filename') String filename...)...}




**Comment From: bclozel**

@williejay2017 If you can provide a minimal sample we can have a look. This still very much points to a build configuration problem unfortunately, so not a Spring Boot bug.

**Comment From: williejay2017**

> @williejay2017 If you can provide a minimal sample we can have a look. This still very much points to a **build configuration** problem unfortunately, so not a Spring Boot bug.

πŸ€” This could be the case but if I downgrade my Spring Boot version to 3.1.5 and supported SC version, I don't get the error. I only get this error once upgraded to 3.2.0+ and supported SC version. I also seeing the same log in our k8s cluster which runs on azure public cloud.

**Comment From: bclozel**

@williejay2017 with Spring Boot 3.1.5, your application is not compiled with `-parameters` but this works because a fallback is still present. This fallback [has been removed in Spring Framework 6.1](https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention) and Spring Boot 3.2 upgrades to that version.

Even if you're not getting the error with 3.1.x, you should be getting WARN logs similar to:

> Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead:

**Comment From: spring-projects-issues**

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.


**Comment From: spring-projects-issues**

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.


**Comment From: aldpuzz**

I just read that there is a connection to the QueryParam parameter. I remember when I updated spring boot, I also updated the following dependency:

     <dependency>
         <groupId>jakarta.activation</groupId>
         <artifactId>jakarta.activation-api</artifactId>
  • 1.2.2
  • 2.1.2

which forced me to:

-import javax.ws.rs.DefaultValue; -import javax.ws.rs.QueryParam; +import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.QueryParam;


over all files. Unfortunately, I can't come to a clue, but I think it's helpful to mention the package name and not only `QueryParam` if we talk about it..

Update: there's also org.springframework.web.bind.annotation.RequestParam instead of QueryParam


**Comment From: pwpuser**

We are getting the same error and don't have QueryParam anywhere. It doesn't make sense as we aren't doing anything out of the ordinary in our return from our controllers. But it only happens if we upgrade to Boot 3.2.x. Since it is unknown what causes it, it is impossible to upload a small sample. 

**Comment From: scottfrederick**

@pwpuser Can you confirm that that all code in your code path is compiled with `-parameters` as [Brian mentioned above](https://github.com/spring-projects/spring-boot/issues/39095?notification_referrer_id=NT_kwDN7PWwOTA0NjUxNTU0Mzo2MDY2MQ&notifications_query=is%3Aunread#issuecomment-1887100308)? This is required starting with Spring Framework 6.1, which is the default version used with Spring Boot 3.2. 

**Comment From: pwpuser**

Thanks Scott. Yeah I just read that in the docs and trying to add it to our maven pom. but we aren't using the maven-compiler-plugin, we are coding in Groovy, so I am tryin to add <configuration><parameters> to  gmavenplus-plugin and see if that does the trick. 

And that didn't work either. So we can't automate the compiler to compile with -parameters in all our environments and developer machines.

**Comment From: aldpuzz**

Btw in my case it was finally working without -parameters. I tried two different approaches in the maven file first, but finally ended without such options but taking another docker image for it. With maven:3-openjdk-18-slim for building and eclipse-temurin:21-jre as runtime, I was good.

**Comment From: pwpuser**

Added -parameters both to the Groovy Plugin as well as in IJ settings for Java Compiler, but still get the same error. Is there code changes I can make instead. A way to find all the places where the naming convention was being used and put in an Annotation there instead? This is really, bad, completely breaks backwards compatibility with no real solution for every case. I saw in a comment above that even third party libraries that you include has to be compiled with -parameters,  and if they don't you're code will never work. We need a better solution.

**Comment From: pwpuser**

Is this basically anywhere we have things like

`@RequestParam String id, @PathVariable String otherVariable` does't work and it requires that the name is populated

`@RequestParam("id") String id, @PathVariable("otherVariable") String otherVariable?`

**Comment From: bclozel**

@pwpuser yes, that is correct. For further questions on build configuration please use StackOverflow.

**Comment From: timkingman**

@pwpuser I had to add this snippet to my `build.gradle` in an all-groovy project:

tasks.withType(GroovyCompile).configureEach { groovyOptions.parameters = true }

The `JavaCompile` snippet referenced earlier doesn't affect compiling groovy files.
The [Spring 6.1 upgrade guide](https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention) includes this now, but I don't think it did when I ran into this.


**Comment From: zhukunqian**

> https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention

Maven users need to configure the maven-compiler-plugin for Java source code:

```xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <parameters>true</parameters>
    </configuration>
</plugin>

Gradle users need to configure the JavaCompile task for Java source code, either with the Kotlin DSL:

tasks.withType<JavaCompile>() {
    options.compilerArgs.add("-parameters")
}

Or the Groovy DSL:

tasks.withType(JavaCompile).configureEach {
    options.compilerArgs.add("-parameters")
}

Similarly, Gradle users need to configure the GroovyCompile task for Groovy source code, either with the Kotlin DSL:

tasks.withType<GroovyCompile>() {
    groovyOptions.parameters = true
}

Or the Groovy DSL:

tasks.withType(GroovyCompile).configureEach {
    groovyOptions.parameters = true
}

IMPORTANT: Sometimes it is also necessary to manually configure your IDE.

In IntelliJ IDEA, open Settings and add -parameters to the following field.

Build, Execution, Deployment β†’ Compiler β†’ Java Compiler β†’ Additional command line parameters

In Eclipse IDE, open Preferences and activate the following checkbox.

Java β†’ Compiler β†’ Store information about method parameters (usable via reflection)

Comment From: cozyCodr

I experienced the same thing with my @PathVariable annotation and simply passing an argument for the param name resolved the issue. @PathVariable(name = "path-variable-name")

Comment From: douglasjunior

Same problem here with Spring 3.2.3, but for me the problem only happens when testing with MockMvc.

My app:

@SpringBootApplication
@EnableCaching
@OpenAPIDefinition(
        servers = {
                @Server(url = "${server.servlet.context-path}",
                        description = "Default Server URL"
                ),
                @Server(
                        url = "{url}",
                        description = "Custom Server URL",
                        variables = {
                                @ServerVariable(name = "url", defaultValue = "/", description = "Server URL"),
                        }
                ),
        }
)
@SecurityScheme(
        name = "Authorization",
        scheme = "bearer",
        bearerFormat = "JWT",
        type = SecuritySchemeType.HTTP,
        in = SecuritySchemeIn.HEADER
)
public class MyApiApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApiApplication.class);
    }
}

My Controller:

@RestController
@RequestMapping("/my")
@AllArgsConstructor
public class MyController extends BaseController {

    @GetMapping("/report")
    @ApiResponses({
            @ApiResponse(
                    responseCode = "200",
                    headers = {
                            @Header(name = "Content-Disposition", description = "attachment; filename=file.pdf"),
                            @Header(name = "Accept", description = MediaType.APPLICATION_PDF_VALUE)
                    },
                    content = @Content(
                            schema = @Schema(type = "file", format = "binary"),
                            mediaType = MediaType.APPLICATION_PDF_VALUE
                    )
            ),
            @ApiResponse(
                    responseCode = "4XX,5XX",
                    headers = {
                            @Header(name = "Accept", description = MediaType.APPLICATION_JSON_VALUE)
                    }
            )
    })
    public ResponseEntity<StreamingResponseBody> report(
            @RequestHeader(name = "Authorization") @Schema(hidden = true) String authorization,
            @RequestAttribute("logged-user") LoggedUserDTO loggedUser,
            @RequestParam @NotNull @Min(1000) @Max(9999)
            Integer year,
            @RequestParam @Nullable @Min(1) @Max(4)
            Integer quarter
    ) {
        // ...
    }

}

My test:

class MyControllerTest {
    @InjectMocks
    private MyController myController;
    private MockMvc mockMvc;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);

        var errorHandler = new ErrorExceptionHandler();

        mockMvc = MockMvcBuilders.standaloneSetup(myController)
                .defaultRequest(get("/")
                        .header("authorization", "Bearer token123")
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                )
                .setControllerAdvice(errorHandler)
                .addFilter(new FakeAuthFilter(errorHandler))
                .build();
    }

    @Test
    void reportShouldReturnPdfFile() throws Exception {
        var loggedUser = // ...;
        var year = 2023;
        var quarter = 1;
        var pdfBytes = "pdf content".getBytes();

        mockMvc.perform(
                        get("/earnings/report")
                                .param("year", Integer.toString(year))
                                .param("quarter", Integer.toString(quarter))
                )
                .andExpect(
                        status().isOk()
                ).andReturn();
    }
}

If we add the name to the @RequestParam, everything works fine.

Comment From: bclozel

@douglasjunior Maybe your tests are not compiled with the parameters flag?

Comment From: douglasjunior

Sorry, adding this config to the end of build.gradle worked:

tasks.withType(GroovyCompile).configureEach {
    groovyOptions.parameters = true
}

Maybe some intellij cache didn't let it work the first time I tried.

Thanks!

Comment From: llama95

use this:

tasks.withType(JavaCompile) {
    options.compilerArgs << '-parameters'
}

Comment From: okonon

I had same issue in my project. If i used command line the application ran fine but if i used VSCode debug feature the issue was there. I cleaned java language server (command palette > Java: Clean Java Language Server Workspace) and it started to work. Hopefully this helps someone in the future.

Comment From: phfbonini

I'm using SpringBoot 3.2.5, Java 17 and Intellij, I just needed to add -parameters within Additional command line parameters: in the Java Compiler options and rebuild the project

Comment From: BrunoSola

Estou usando SpringBoot 3.3.1, Java 21 e Intellij Fiz o que o @phfbonini disse e funcionou. pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
           <parameters>true</parameters>
    </configuration>
</plugin>

SpringBoot Error :  Name for argument of type [java.util.Optional] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.

Comment From: brunoaduarte

None of the solutions above worked on latest STS 4.24.0.RELEASE with gradle project

Spring Tool Suite 4 

Version: 4.24.0.RELEASE
Build Id: 202407191504
Revision: bc5006ff14677eeda6540eaa02cafbf59de00c49
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.2'
    id 'io.spring.dependency-management' version '1.1.6'
}

In this case the solution is just to tick this option at the Java Compiler settings

SpringBoot Error :  Name for argument of type [java.util.Optional] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.

Comment From: hannahborje

The solution above (to tick this option at the Java Compiler settings) worked for me, so thanks a bunch!

Comment From: maelex

Image

I was getting java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag

And postman was showing 500 Internal Server Error

If you are using vs code (as me) open the Java: Configure Java Runtime using ctrl+ shift + P go to Compiler and check Store information about method Parameters.