Stelios
Stelios Life-long learner, happy father, trying to do some software engineering on the side.

Problem with Spring's @PathVariable across builds

Problem with Spring's @PathVariable across builds

Some colleagues had a very strange problem today: their Spring REST endpoints would work fine when hitting a SNAPSHOT release.

They would fail though, when trying to test against a release. The error was something like

java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.

The failing method was something like

1
2
3
4
5
@RequestMapping(value={"/foo/{fromId}/action"}, 
    method={org.springframework.web.bind.annotation.RequestMethod.POST}, 
    headers={"content-type=application/json"})
  public ResponseEntity<SomeResponse> doAction(@PathVariable String fromId, @RequestBody TheBody theBody, HttpServletRequest request)
  {...}

But why??

The name of the argument matches the path variable, a nice little feature of Spring.

After some digging online, it appears that the “implicit PathVariable name” feature only works when debug information is on at compile time.

Or in other words, RTFM and don’t just jump from example to example; read the text in between!

Since it is a good practice to disable debug information in your released artifacts, our release build was doing exactly that

Something like the following in Maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
<profile>
    <id>used-by-default</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <debug>true</debug>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>
...
<profile>
    <id>used-for-release</id>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <debug>false</debug>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>
...

So, mystery solved and the morale of the story:

All @PathVariables MUST be explicit (and RTFM, RTFM, RTFM,…)

comments powered by Disqus