I am using a VSCode devcontainer to write a Java application. I put it down for about a month, came back to work on it and now I'm getting some unfamiliar errors.
Configuration
Here I'll provide my relevant configuration files for my devcontainer environment.
My Dockerfile is as below:
FROM openjdk:16-slim-buster
# Install things
RUN apt-get update \
&& apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
#
# Verify git, process tools, lsb-release (common in install instructions for CLIs) installed
&& apt-get -y install curl git openssh-client vim less iproute2 procps lsb-release
# Install Maven CLI things
ARG MAVEN_VERSION=3.6.3
ARG MAVEN_SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
&& curl -fsSL -o /tmp/apache-maven.tar.gz https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
&& echo "${MAVEN_SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - \
&& tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
ENV MAVEN_HOME /usr/share/maven
ENV MAVEN_CONFIG /root/.m2
# Allow for a consistant java home location for settings - image is changing over time
RUN if [ ! -d "/docker-java-home" ]; then ln -s "${JAVA_HOME}" /docker-java-home; fi
And my devontainer JSON is here:
{
"name": "Java Development",
"dockerFile": "Dockerfile",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"java.home": "/docker-java-home"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"vscjava.vscode-java-pack",
"redhat.vscode-xml"
]
}
Problem
When I had previously stopped working on this app, everything compiled and ran just fine and I was able to launch my configurations through VSCode for testing. Now, I'm running into two issues, and I think they're related. First, when I try to run my application using a launch configuration, it does not work and I get this strange error:
So I can't launch anything through VSCode. Next, I tried a mvn package
and my tests failed with errors such as below:
com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: Unable to load cache item
at com.insurexcel.poipoi.input.InputProcessorTest.setup(InputProcessorTest.java:34)
Caused by: java.lang.IllegalStateException: Unable to load cache item
at com.insurexcel.poipoi.input.InputProcessorTest.setup(InputProcessorTest.java:34)
Caused by: java.lang.ExceptionInInitializerError
at com.insurexcel.poipoi.input.InputProcessorTest.setup(InputProcessorTest.java:34)
Caused by: com.google.inject.internal.cglib.core.$CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @523fa30b
at com.insurexcel.poipoi.input.InputProcessorTest.setup(InputProcessorTest.java:34)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @523fa30b
at com.insurexcel.poipoi.input.InputProcessorTest.setup(InputProcessorTest.java:34)
So it looks related to some reflection. I'm using GSON and Guice, here's the relevant part of the pom.xml
:
<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.inject/guice -->
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.3</version>
</dependency>
I tried updating Guice to 5.0.0-BETA-1
and that fixed the errors in the tests and made things compile successfully. However, now I get runtime errors when doing some serialization. Here's what the errors look like:
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @523fa30b
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
at com.google.gson.internal.reflect.UnsafeReflectionAccessor.makeAccessible(UnsafeReflectionAccessor.java:44)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:159)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.Gson.toJson(Gson.java:696)
at com.google.gson.Gson.toJson(Gson.java:683)
at com.google.gson.Gson.toJson(Gson.java:638)
at com.google.gson.Gson.toJson(Gson.java:618)
...
So obviously it's related to GSON. It appears unable to access a private field? The object I'm attempting to serialize looks like this:
public class MapContainer {
private MyMapObject map;
private String status;
private Exception errorInformation;
public MapContainer(MyMapObject map) {
this.map = map;
this.status = "okay";
this.errorInformation = null;
}
public MapContainer(Exception error) {
this.map = null;
this.status = "error";
this.errorInformation = error;
}
...
getters and setters
...
}
And based on the error, it appears to be having a hard time with the Exception field in my object. I've looked all over and can't really find a good reason that this may be happening. I checked the Docker image I'm running this in and it does appear to have been updated recently. My java --version
in the container returns this:
openjdk 16-ea 2021-03-16
OpenJDK Runtime Environment (build 16-ea+30-2130)
OpenJDK 64-Bit Server VM (build 16-ea+30-2130, mixed mode, sharing)
If anybody can provide any clues or ideas as to where this may be coming from I would greatly appreciate it!