error-prone
error-prone copied to clipboard
v2.12.0: java.lang.IndexOutOfBoundsException
Tried to upgrade from v2.9.0 > v2.15.0, and found the following error (which started with v2.12.0):
StubbedUnitsEndpoint.java:[25] error: An unhandled exception was thrown by the Error Prone static analysis plugin. error-prone version: 2.12.0 BugPattern: UnusedMethod Stack Trace: java.lang.IndexOutOfBoundsException: Range [6114, 5981) out of bounds for length 6240
Java 18, maven 3.8.5
The error occurred for the following class:
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ConditionalOnProperty(name = "stubbed.endpoints.enabled", havingValue = "true")
@RestController
@RequestMapping("/bonus")
public class StubbedUnitsEndpoint {
private static final Logger LOGGER = LogManager.getLogger();
private static final int NO_UNITS = 0;
private final Map<String, Integer> unitsByUserAndPasskey = new HashMap<>();
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<UnitsResponse>> getUserUnits(@RequestParam("user") final String foldingUserName,
@RequestParam("passkey") final String passkey) {
LOGGER.debug("Getting units for '{}:{}'", foldingUserName, passkey);
return ResponseEntity
.ok()
.body(createResponse(foldingUserName, passkey));
}
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> updateUserUnits(@RequestParam("user") final String foldingUserName,
@RequestParam("passkey") final String passkey,
@RequestParam("units") final int units) {
LOGGER.debug("Adding {} units for '{}:{}'", units, foldingUserName, passkey);
final String key = foldingUserName + passkey;
if (units == NO_UNITS) {
// Remove all units from the user
unitsByUserAndPasskey.put(key, NO_UNITS);
} else {
unitsByUserAndPasskey.put(key, unitsByUserAndPasskey.getOrDefault(key, NO_UNITS) + units);
}
return ResponseEntity
.status(HttpStatus.CREATED)
.build();
}
@DeleteMapping
public ResponseEntity<Void> deleteUserUnits() {
LOGGER.debug("Deleting all units: {}", unitsByUserAndPasskey);
unitsByUserAndPasskey.clear();
return ResponseEntity
.ok()
.build();
}
private Collection<UnitsResponse> createResponse(final String foldingUserName, final String passkey) {
final String key = foldingUserName + passkey;
if (unitsByUserAndPasskey.containsKey(key)) {
return List.of(UnitsResponse.create(unitsByUserAndPasskey.get(key)));
}
return Collections.emptyList();
}
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Accessors(fluent = false) // Need #get*()
@Getter
@Setter
@EqualsAndHashCode
@ToString(doNotUseGetters = true)
private static class UnitsResponse {
private int finished;
static UnitsResponse create(final int finished) {
return new UnitsResponse(finished);
}
}
}
And my configuration of the maven-compiler-plugin:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>${java-release}</release>
<!-- Configuration for errorprone compiler checks -->
<annotationProcessorPaths>
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${errorprone.version}</version>
</path>
<!-- The errorprone checks will fail unless Lombok is also added -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-Xdoclint:all</arg>
<!-- Configuration for ErrorProne -->
<arg>-XDcompilePolicy=simple</arg>
<arg>-Xplugin:ErrorProne</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
</compilerArgs>
<fork>true</fork>
</configuration>
<inherited>true</inherited>
</plugin>```