3

I have the following @RestController:

package io.github.paulmarcelinbejan.coandaairlines.reservationsystem.adapters.inbound.controller.rest;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.github.paulmarcelinbejan.coandaairlines.reservationsystem.adapters.inbound.impl.rest.CurrencyInboundAdapterRestImpl;
import io.github.paulmarcelinbejan.coandaairlines.reservationsystem.ports.currency.domain.CurrencyDTO;
import io.github.paulmarcelinbejan.davinci.adapters.api.DavinciApiResponse;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/currency")
public class CurrencyRestController {

    private final CurrencyInboundAdapterRestImpl currencyInboundAdapterRestImpl;

    @GetMapping(value = "/id/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<CurrencyDTO> findById(@PathVariable Integer id) {
        return currencyInboundAdapterRestImpl.findById(id);
    }

    @GetMapping(value = "/code/{code}", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<CurrencyDTO> findByCode(@PathVariable String code) {
        return currencyInboundAdapterRestImpl.findByCode(code);
    }

    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<List<CurrencyDTO>> findAll() {
        return currencyInboundAdapterRestImpl.findAll();
    }

}

but when I access Swagger, it doesn't show me the space to insert the pathVariable:

enter image description here

If I try to execute I have the following exception:

{
  "status": "KO",
  "errors": {
    "timestampUTC": "2024-04-02T11:24:45.416132Z",
    "exceptionType": "IllegalArgumentException",
    "message": "Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag."
  }
}

same issue also from postman:

enter image description here

If I remove the @PathVariable then on swagger I can see it:

enter image description here

but still same error:

{
  "status": "KO",
  "errors": {
    "timestampUTC": "2024-04-02T11:26:56.186060Z",
    "exceptionType": "IllegalArgumentException",
    "message": "Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag."
  }
}

On another project, I have similar @RestController:

package com.hyperbank.types.currency.controller;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.hyperbank.types.currency.dto.CurrencyResponse;
import com.hyperbank.types.currency.dto.CurrencySaveRequest;
import com.hyperbank.types.currency.dto.CurrencyUpdateRequest;
import com.hyperbank.types.currency.mapper.CurrencyMapper;
import com.hyperbank.types.currency.service.CurrencyService;

import io.github.paulmarcelinbejan.toolbox.exception.functional.FunctionalException;
import io.github.paulmarcelinbejan.toolbox.utils.validation.ValidatorUtils;
import io.github.paulmarcelinbejan.toolbox.web.response.OkResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/currency")
public class CurrencyRestController {

    private final CurrencyService currencyService;
    
    private final CurrencyMapper currencyMapper;

    @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody CurrencyResponse findById(@PathVariable Integer id) throws FunctionalException {
        return currencyMapper.toResponse(currencyService.findById(id));
    }

    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody List<CurrencyResponse> findAll() {
        return currencyMapper.toResponses(currencyService.findAll());
    }

}

and on that one, there are no issue:

enter image description here

any idea ?

4
  • 1
    The exception tells you whats wrong... Ensure that the compiler uses the '-parameters' flag. if you want to infer the name or explicitly declare the name in the @PathVariable like @PathVariable("id"). Commented Apr 2, 2024 at 11:46
  • @M.Deinum yes, that's working, but I don't understand, why on the second project is working without adding the name in the PathVariable Commented Apr 2, 2024 at 13:36
  • 3
    Depends on the Java / Spring Boot version. As of 3.2 it is required to add -parameters (unless using the spring boot starter parent with maven then it is always on already). If you use Gradle you need to add it, and on earlier versions there was a fallback option with reflection which has been removed as it didn't work reliably in native images. Commented Apr 2, 2024 at 13:39
  • ok, so that's the reason, Spring Boot 3.2, Thanks! Commented Apr 2, 2024 at 13:55

3 Answers 3

2

Reason : This problem arises because Swagger, a tool that helps you document your API, need to know the names of the variable you use in your code. But, sometimes ,the java compiler doesn't save this information by default.So, Swagger get confused and can't show the correct documentation for your API.

Solution : To fix that, you need to tell the java compiler to save this information. once you do that, Swagger will find the pathvariable name and display the correct documentation for your API.

Add (Maven pom.xml file)

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
Sign up to request clarification or add additional context in comments.

Comments

0

If you don't use Maven (in debug mode for example), you can configure your IDE and add the -parameters option. Everything is explained here :

Upgrading to Spring Framework 6.x

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)

Comments

0

(VS CODE USER) You can also use the "Java: Clean java Language Server Workspace" option:

Open the Command Palette with Ctrl+Shift+P (or Cmd+Shift+P on macOS). Type and select Java: Clean java Language Server Workspace. then (For Maven: mvn clean install For Gradle: ./gradlew clean build)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.