'Throwing java.lang.IllegalAccessException module java.base does not open java.util.concurrent when running Corretto on Java

I have 2 microservices: serviceBFF, serviceCore.

Stack

  • Spring Boot 2.6.6
  • Amazon Corretto 17 (Docker)
  • OpenJDK 17 (local)
  • Docker (latest)

serviceBFF calls a REST service in serviceCore that returns a CompletableFuture. When running the 2 services as standalone Java applications in IntelliJ, the request succeed without any issue.

But when I containerized the 2 services, run them in a compose file, and make a request I got:

2022-04-22 00:34:40.652 ERROR [service-be,6cee3eed8fdff76a,6cee3eed8fdff76a] 1 --- [nio-8000-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dis
patcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class java.util.c
oncurrent.CompletableFuture: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.IllegalAccessException-->module java.base does not open java.util.concurrent to unnamed module @449b2d27] with root cause

Here are my docker related files:

Dockerfile

FROM amazoncorretto:17-alpine-jdk

ENV TZ="UTC"

ADD app/target/*.jar /application/
ADD docker/docker-entrypoint.sh ./

RUN set -xe; \
    adduser -D -u 2001 app.user; \
    chmod a+x /docker-entrypoint.sh

USER app.user

EXPOSE 8001

ENTRYPOINT [ "/docker-entrypoint.sh" ]

docker-entrypoint

#!/bin/sh -e

cd /application

JMX_OPTS=""
JMX_PORT=9875

JAVA_OPTS="${JAVA_OPTS} ${JMX_OPTS}"

exec java -jar $JAVA_OPTS *.jar "$@"

Drilling down, I found the error on serviceBFF, in the part that converts the DTO to EntityModel:

@PostMapping(
      path = EndpointConstants.PATH_USERS,
      produces = MediaTypes.HAL_JSON_VALUE)
  @ResponseStatus(HttpStatus.OK)
  @Transactional
  public CompletableFuture<PlatformUserOutboundDto> mapUpdateOrCreateIfAbsent(
      @Valid @RequestBody PlatformUserInboundDto platformUserInboundDto) {

    log.debug("Check if user with externalRef={} exists", platformUserInboundDto.getExternalRef());

    return platformUserProxyAsync.mapUpdateOrCreateIfAbsent(platformUserInboundDto);
        // converts to hal
//        .thenApply(platformUserOutboundDto -> toEntityModel(platformUserInboundDto, platformUserOutboundDto));
  }

  private EntityModel<PlatformUserOutboundDto> toEntityModel(PlatformUserInboundDto platformUserInboundDto,
      PlatformUserOutboundDto platformUserOutboundDto) {

    log.debug("converting to hal document {}", platformUserOutboundDto);

    Link dtoLink = WebMvcLinkBuilder.linkTo(

// error is generated here

WebMvcLinkBuilder.methodOn(PlatformUserController.class).mapUpdateOrCreateIfAbsent(platformUserInboundDto)) // the error happen on this line
        .withSelfRel()
        .expand();

    return EntityModel.of(platformUserOutboundDto, dtoLink);
  }


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source