Some lessons learned in upgrading from Java 11 to Java 17.
Java 17 is far more strict in enforcement of class encapsulation. For example, in previous Java releases, it was possible for a developer to set Java system properties as well as environment variables by using Java Reflection, as in the following code example:
try{ Map<String, String> env = System.getenv(); Class<?> cl = env.getClass(); Field field = cl.getDeclaredField("m"); field.setAccessible(true); Map<String, String> writableEnv = (Map<String, String>) field.get(env); writableEnv.put(SDNC_CONFIG_DIR, "./src/test/resources"); } catch (Exception e) { throw new IllegalStateException("Failed to set environment variable", e); }
This is no longer permitted in Java 17 and will throw an IllegalAccessException.
In our code, we were only using this within our jUnit tests. Instead, we updated our design to set system properties and environment variables within the surefire-maven-plugin section of our project pom.xml, as in the following example:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <environmentVariables> <SDNC_CONFIG_DIR>src/test/resources</SDNC_CONFIG_DIR> </environmentVariables> </configuration> </plugin>
- Older versions of the maven lombok plugin use similar "tricks" that lead to IllegalAccessExceptions in Java 17. If you are using lombok in Java 17, be sure to use at least version 1.18.24