Skip to content

Commit 0b67d4f

Browse files
committed
Fixed NullPointerException with IBM SDK 8
The steps to replicate the issue are pretty simple: 1. create a new Maven project (e.g. `ibm-jdk-bug`); 2. add as a dependency `yacl4j-core`, version `0.9.1`; 3. in the same project, create a main class (e.g. `Main.java`) as follows: ```java import com.yacl4j.core.ConfigurationBuilder; import yacl4j.repackaged.com.fasterxml.jackson.databind.JsonNode; public class Main { public static void main(String[] args) { JsonNode jsonNode = ConfigurationBuilder.newBuilder() .source().fromFileOnClasspath("config.yaml") .build(JsonNode.class); System.out.println(jsonNode); } } ``` 4. from command line, run the following Docker command: ```docker docker run -it --rm --name ibm-jdk-bug -v "$PWD":/ibm-jdk-bug ibmcom/ibmjava:8-sdk /bin/bash -c 'cd ibm-jdk-bug && ./mvnw exec:java -Dexec.mainClass="Main"' ``` 5. wait for the unbelievable exception to blow on your face: ```java java.lang.NullPointerException at com.yacl4j.core.util.ConfigurationUtils.emptyConfiguration(ConfigurationUtils.java:33) at com.yacl4j.core.ConfigurationBuilder.mergeConfigurationSources(ConfigurationBuilder.java:73) at com.yacl4j.core.ConfigurationBuilder.build(ConfigurationBuilder.java:64) at Main.main(Main.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) at java.lang.reflect.Method.invoke(Method.java:508) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:282) at java.lang.Thread.run(Thread.java:785) ``` This is the incriminated yacl4j code: ```java public class ConfigurationUtils { private ConfigurationUtils() { } private static final ObjectMapper DEFAULT_OBJECT_MAPPER = Yaml.YAML_OBJECT_MAPPER; private static ObjectMapper objectMapper(JsonFactory jsonFactory) { return new ObjectMapper(jsonFactory) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } public static JsonNode emptyConfiguration() { return DEFAULT_OBJECT_MAPPER.createObjectNode(); } // ... public static class Yaml { private Yaml() { } private static final ObjectMapper YAML_OBJECT_MAPPER = objectMapper(new YAMLFactory()); // ... } // ... } ``` For some reason I can't really explain, with the IBM SDK 8, the static variable `DEFAULT_OBJECT_MAPPER` is null! The same works perfectly with Oracle JDK and OpenJDK.
1 parent 3167cdb commit 0b67d4f

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

yacl4j-core/src/main/java/com/yacl4j/core/util/ConfigurationUtils.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,32 @@ public class ConfigurationUtils {
2020

2121
private ConfigurationUtils() { }
2222

23-
private static final ObjectMapper DEFAULT_OBJECT_MAPPER = Yaml.YAML_OBJECT_MAPPER;
23+
private static ObjectMapper defaultObjectMapper() {
24+
return Yaml.YAML_OBJECT_MAPPER;
25+
}
2426

25-
private static ObjectMapper objectMapper(JsonFactory jsonFactory) {
27+
private static ObjectMapper buildObjectMapper(JsonFactory jsonFactory) {
2628
return new ObjectMapper(jsonFactory)
2729
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
2830
.registerModule(new MrBeanModule())
2931
.registerModule(new Jdk8Module());
3032
}
3133

3234
public static JsonNode emptyConfiguration() {
33-
return DEFAULT_OBJECT_MAPPER.createObjectNode();
35+
return defaultObjectMapper().createObjectNode();
3436
}
3537

3638
public static JsonNode fromString(String configuration) {
3739
try {
38-
return DEFAULT_OBJECT_MAPPER.readValue(configuration, JsonNode.class);
40+
return defaultObjectMapper().readValue(configuration, JsonNode.class);
3941
} catch (Exception exception) {
4042
return TextNode.valueOf(configuration);
4143
}
4244
}
4345

4446
public static <T> T toValue(JsonNode configuration, Class<T> configurationClass) {
4547
try {
46-
return DEFAULT_OBJECT_MAPPER.treeToValue(configuration, configurationClass);
48+
return defaultObjectMapper().treeToValue(configuration, configurationClass);
4749
} catch (Exception exception) {
4850
throw new IllegalStateException(exception);
4951
}
@@ -70,7 +72,7 @@ public static class Yaml {
7072

7173
private Yaml() { }
7274

73-
private static final ObjectMapper YAML_OBJECT_MAPPER = objectMapper(new YAMLFactory());
75+
private static final ObjectMapper YAML_OBJECT_MAPPER = buildObjectMapper(new YAMLFactory());
7476

7577
public static JsonNode fromInputStream(InputStream configuration) {
7678
try {
@@ -98,7 +100,7 @@ public static class Json {
98100

99101
private Json() { }
100102

101-
private static final ObjectMapper JSON_OBJECT_MAPPER = objectMapper(null);
103+
private static final ObjectMapper JSON_OBJECT_MAPPER = buildObjectMapper(null);
102104

103105
public static JsonNode fromInputStream(InputStream configuration) {
104106
try {

0 commit comments

Comments
 (0)