Skip to content

Commit

Permalink
Register jackson module Jdk8Module to make Optional work
Browse files Browse the repository at this point in the history
Seems jackson has changed so you now have to explicitly register the
module
  • Loading branch information
at055612 committed Nov 5, 2024
1 parent 7e2469f commit 5cffa5a
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 47 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ ext.libs = [
jackson_core : "com.fasterxml.jackson.core:jackson-core", // version controlled by dropwizard-dependencies
jackson_databind : "com.fasterxml.jackson.core:jackson-databind", // version controlled by dropwizard-dependencies // files('libs/jackson-databind-2.10.5.1.jar'),//
jackson_dataformat_yaml : "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", // version controlled by dropwizard-dependencies
jackson_datatype_jdk8 : "com.fasterxml.jackson.datatype:jackson-datatype-jdk8", // version controlled by dropwizard-dependencies
jackson_datatype_jsr310 : "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", // version controlled by dropwizard-dependencies
jakarta_activation : "jakarta.activation:jakarta.activation-api", // version controlled by dropwizard-dependencies
jakarta_annotation_api : "jakarta.annotation:jakarta.annotation-api", // version controlled by dropwizard-dependencies
Expand Down Expand Up @@ -306,7 +307,7 @@ ext.libs = [
simple_java_mail : "org.simplejavamail:simple-java-mail:${versions.simple_java_mail}",
simple_java_mail_batch_module : "org.simplejavamail:batch-module:${versions.simple_java_mail}",
slf4j_api : "org.slf4j:slf4j-api", // version controlled by dropwizard-dependencies
snake_yaml : "org.yaml:snakeyaml:2.2",
snake_yaml : "org.yaml:snakeyaml:2.3",
solrj : "org.apache.solr:solr-solrj:8.2.0",
sqlite : "org.xerial:sqlite-jdbc:3.43.2.2",
stax_api : "stax:stax-api:1.0.1",
Expand Down
1 change: 1 addition & 0 deletions stroom-config/stroom-config-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ dependencies {
testImplementation project(':stroom-test-common')

testImplementation libs.assertj_core
testImplementation libs.jackson_datatype_jdk8
testImplementation libs.junit_jupiter_api
testImplementation libs.mbknor_jackson_jsonSchema
testImplementation libs.java_diff_utils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.dropwizard.configuration.ConfigurationSourceProvider;
import jakarta.validation.constraints.NotNull;

Expand Down Expand Up @@ -67,7 +66,7 @@ public InputStream open(final String path) throws IOException {
try (final InputStream in = delegate.open(path)) {
// This is the yaml tree after passing though the delegate
// substitutions
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
final ObjectMapper mapper = YamlUtil.getNoIndentMapper();
final JsonNode rootNode = mapper.readTree(in);

Objects.requireNonNull(rootNode, () ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import stroom.util.logging.LambdaLogger;
import stroom.util.logging.LambdaLoggerFactory;
import stroom.util.logging.LogUtil;
import stroom.util.yaml.YamlUtil;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import io.dropwizard.configuration.ConfigurationException;
import io.dropwizard.configuration.ConfigurationFactory;
import io.dropwizard.configuration.ConfigurationFactoryFactory;
Expand Down Expand Up @@ -108,9 +110,9 @@ public static AppConfig readDropWizardSubstitutedAppConfig(final String yamlStr)

// fail on unknown so it skips over all the drop wiz yaml content that has no
// corresponding annotated props in DummyConfig
final ObjectMapper mapper = new ObjectMapper()
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory())
.registerModule(new Jdk8Module()) // Needed to deal with Optional<...>
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

try {
final DummyConfig dummyConfig = mapper.convertValue(obj, DummyConfig.class);
return dummyConfig.getAppConfig();
Expand All @@ -120,8 +122,7 @@ public static AppConfig readDropWizardSubstitutedAppConfig(final String yamlStr)
}

public static void writeConfig(final Config config, final OutputStream outputStream) throws IOException {
final YAMLFactory yf = new YAMLFactory();
final ObjectMapper mapper = new ObjectMapper(yf);
final ObjectMapper mapper = YamlUtil.getVanillaObjectMapper();
// wrap the AppConfig so that it sits at the right level
mapper.writeValue(outputStream, config);

Expand All @@ -134,8 +135,7 @@ public static void writeConfig(final AppConfig appConfig, final OutputStream out
}

public static void writeConfig(final Config config, final Path path) throws IOException {
final YAMLFactory yf = new YAMLFactory();
final ObjectMapper mapper = new ObjectMapper(yf);
final ObjectMapper mapper = YamlUtil.getVanillaObjectMapper();
mapper.writeValue(path.toFile(), config);
}

Expand All @@ -151,11 +151,22 @@ public static void writeConfig(final AppConfig appConfig, final Path path) throw
*/
public static void writeAppConfig(final AppConfig appConfig, final Path path) throws IOException {
final DummyConfig config = new DummyConfig(appConfig);
final YAMLFactory yf = new YAMLFactory();
final ObjectMapper mapper = new ObjectMapper(yf);
final ObjectMapper mapper = createObjectMapper();
mapper.writeValue(path.toFile(), config);
}

private static ObjectMapper createObjectMapper() {
final YAMLFactory yamlFactory = new YAMLFactory();
return new ObjectMapper(yamlFactory)
.registerModule(new Jdk8Module()); // Needed to deal with Optional<...>
// .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
// mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
}


// --------------------------------------------------------------------------------


/**
* Used to simulate the {@link Config} class that wraps {@link AppConfig} when we are not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
import stroom.util.logging.LambdaLogger;
import stroom.util.logging.LambdaLoggerFactory;
import stroom.util.logging.LogUtil;
import stroom.util.yaml.YamlUtil;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import io.dropwizard.configuration.ConfigurationException;
import io.dropwizard.configuration.ConfigurationFactory;
import io.dropwizard.configuration.ConfigurationFactoryFactory;
Expand Down Expand Up @@ -61,11 +62,14 @@ public static Config readConfig(final Path configFile) throws IOException {
final ConfigurationFactoryFactory<Config> configurationFactoryFactory =
new DefaultConfigurationFactoryFactory<>();

final ObjectMapper objectMapper = Jackson.newObjectMapper()
.registerModule(new Jdk8Module());

final ConfigurationFactory<Config> configurationFactory = configurationFactoryFactory
.create(
Config.class,
io.dropwizard.jersey.validation.Validators.newValidator(),
Jackson.newObjectMapper(),
objectMapper,
"dw");

Config config = null;
Expand All @@ -90,8 +94,7 @@ public static ConfigurationSourceProvider createConfigurationSourceProvider(
}

public static void writeConfig(final Config config, final OutputStream outputStream) throws IOException {
final YAMLFactory yf = new YAMLFactory();
final ObjectMapper mapper = new ObjectMapper(yf);
final ObjectMapper mapper = YamlUtil.getVanillaObjectMapper();
// wrap the AppConfig so that it sits at the right level
mapper.writeValue(outputStream, config);

Expand All @@ -104,8 +107,7 @@ public static void writeConfig(final ProxyConfig proxyConfig, final OutputStream
}

public static void writeConfig(final Config config, final Path path) throws IOException {
final YAMLFactory yf = new YAMLFactory();
final ObjectMapper mapper = new ObjectMapper(yf);
final ObjectMapper mapper = YamlUtil.getVanillaObjectMapper();
// wrap the AppConfig so that it sits at the right level
mapper.writeValue(path.toFile(), config);
}
Expand Down
41 changes: 35 additions & 6 deletions stroom-util/src/main/java/stroom/util/yaml/YamlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;

import java.io.IOException;
import java.nio.file.Files;
Expand All @@ -26,6 +26,10 @@

public class YamlUtil {

private static final ObjectMapper VANILLA_OBJECT_MAPPER = createVanillaObjectMapper();
private static final ObjectMapper OBJECT_MAPPER = createYamlObjectMapper(true);
private static final ObjectMapper NO_INDENT_MAPPER = createYamlObjectMapper(false);

private static final LambdaLogger LOGGER = LambdaLoggerFactory.getLogger(YamlUtil.class);

public static Path getYamlFileFromArgs(final String[] args) {
Expand All @@ -43,7 +47,7 @@ public static Path getYamlFileFromArgs(final String[] args) {
// NOTE if you are getting here while running in IJ then you have probable not run
// local.yaml.sh
LOGGER.warn("YAML config file [{}] from arguments [{}] is not a valid file.\n" +
"You need to supply a valid stroom configuration YAML file.",
"You need to supply a valid stroom configuration YAML file.",
yamlFile, Arrays.asList(args));
}
}
Expand Down Expand Up @@ -216,13 +220,38 @@ private static void mergeNodeTrees(final JsonNode jsonNode,
}
}

public static ObjectMapper createYamlObjectMapper() {
final YAMLFactory yamlFactory = new YAMLFactory();
public static ObjectMapper getMapper() {
return OBJECT_MAPPER;
}

public static ObjectMapper getNoIndentMapper() {
return NO_INDENT_MAPPER;
}

public static ObjectMapper getVanillaObjectMapper() {
return VANILLA_OBJECT_MAPPER;
}

private static ObjectMapper createYamlObjectMapper() {
return createYamlObjectMapper(false);
}

/**
* No configurations apart from registering {@link Jdk8Module} for {@link java.util.Optional}
* use.
*/
private static ObjectMapper createVanillaObjectMapper() {
return new ObjectMapper(new YAMLFactory())
.registerModule(new Jdk8Module()); // Needed to deal with Optional<...>
}

private static ObjectMapper createYamlObjectMapper(final boolean indent) {
final YAMLFactory yamlFactory = new YAMLFactory();
return new ObjectMapper(yamlFactory)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new Jdk8Module()) // Needed to deal with Optional<...>
// .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
.configure(SerializationFeature.INDENT_OUTPUT, false)
.configure(SerializationFeature.INDENT_OUTPUT, indent)
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
// mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
.setSerializationInclusion(Include.NON_NULL);
Expand Down
53 changes: 29 additions & 24 deletions stroom-util/src/test/java/stroom/util/yaml/TestYamlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import org.junit.jupiter.api.Test;

import java.io.IOException;
Expand All @@ -28,7 +31,9 @@ void testAddingDefaultsToYaml() throws IOException {

final ImmutablePojo immutablePojoDefault = new ImmutablePojo();

final ObjectMapper yamlObjectMapper = YamlUtil.createYamlObjectMapper();
final ObjectMapper yamlObjectMapper = new ObjectMapper(new YAMLFactory())
.registerModule(new Jdk8Module())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

final String defaultYaml = yamlObjectMapper.writeValueAsString(immutablePojoDefault);

Expand Down Expand Up @@ -75,7 +80,7 @@ void testMergeYamlNodeTrees_empty() throws JsonProcessingException {
@Test
void testMergeYamlNodeTrees_noChange() throws JsonProcessingException {
final ImmutablePojo immutablePojoDefault = new ImmutablePojo();
final ObjectMapper yamlObjectMapper = YamlUtil.createYamlObjectMapper();
final ObjectMapper yamlObjectMapper = YamlUtil.getMapper();
// sparse is identical to default
final String sparseYaml = yamlObjectMapper.writeValueAsString(immutablePojoDefault);

Expand Down Expand Up @@ -144,7 +149,7 @@ private <T> void doYamlMergeTest(final String sparseYaml,
final BiConsumer<T, T> objectsConsumer)
throws JsonProcessingException {
final T defaultObject = defaultObjectSupplier.get();
final ObjectMapper yamlObjectMapper = YamlUtil.createYamlObjectMapper();
final ObjectMapper yamlObjectMapper = YamlUtil.getMapper();

LOGGER.debug("default yaml:\n{}", yamlObjectMapper.writeValueAsString(defaultObject));

Expand Down Expand Up @@ -245,13 +250,13 @@ public ImmutableChildPojo getImmutableChild() {
@Override
public String toString() {
return "ImmutablePojo{" +
"myTrueBoolean=" + myTrueBoolean +
", myFalseBoolean=" + myFalseBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
", immutableChild=" + immutableChild +
", nonPublicString='" + nonPublicString + '\'' +
'}';
"myTrueBoolean=" + myTrueBoolean +
", myFalseBoolean=" + myFalseBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
", immutableChild=" + immutableChild +
", nonPublicString='" + nonPublicString + '\'' +
'}';
}

@Override
Expand All @@ -264,11 +269,11 @@ public boolean equals(final Object o) {
}
final ImmutablePojo that = (ImmutablePojo) o;
return myTrueBoolean == that.myTrueBoolean
&& myFalseBoolean == that.myFalseBoolean
&& myInt == that.myInt
&& Objects.equals(myString, that.myString)
&& Objects.equals(immutableChild, that.immutableChild)
&& Objects.equals(nonPublicString, that.nonPublicString);
&& myFalseBoolean == that.myFalseBoolean
&& myInt == that.myInt
&& Objects.equals(myString, that.myString)
&& Objects.equals(immutableChild, that.immutableChild)
&& Objects.equals(nonPublicString, that.nonPublicString);
}

@Override
Expand Down Expand Up @@ -341,11 +346,11 @@ public ImmutableChildPojo2 getImmutableGrandChild() {
@Override
public String toString() {
return "ImmutableChildPojo{" +
"myBoolean=" + myBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
", grandChild=" + immutableGrandChild +
'}';
"myBoolean=" + myBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
", grandChild=" + immutableGrandChild +
'}';
}

@Override
Expand Down Expand Up @@ -417,10 +422,10 @@ public String getMyString() {
@Override
public String toString() {
return "ImmutableChildPojo{" +
"myBoolean=" + myBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
'}';
"myBoolean=" + myBoolean +
", myInt=" + myInt +
", myString='" + myString + '\'' +
'}';
}

@Override
Expand Down

0 comments on commit 5cffa5a

Please sign in to comment.