Skip to content

Moved Jackson from being an external SDK dependency to an internal dependency. #2522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-9e94920.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"category": "AWS SDK for Java v2",
"contributor": "",
"type": "feature",
"description": "Moved Jackson from being an external SDK dependency to an internal dependency.\n\nCustomers will see a change in artifact sizes. Customers which do not use Jackson-databind outside of the SDK today will see a ~1 MB artifact size decrease. Customers which do use Jackson-databind outside of the SDK will see a ~0.5 MB artifact size increase.\n\nThis change required breaking inter-module (protected) APIs, so customers will not be able to use older client versions with this version of the core libraries."
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
# Maven
target/

# JEnv
.java-version

# Shade
**/dependency-reduced-pom.xml

*.pyc
Expand Down
2 changes: 2 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ This software includes third party software subject to the following copyrights:
- PKCS#1 PEM encoded private key parsing and utility functions from oauth.googlecode.com - Copyright 1998-2010 AOL Inc.
- Apache Commons Lang - https://github.com/apache/commons-lang
- Netty Reactive Streams - https://github.com/playframework/netty-reactive-streams
- Jackson-core - https://github.com/FasterXML/jackson-core
- Jackson-dataformat-cbor - https://github.com/FasterXML/jackson-dataformats-binary

The licenses for these third party components are included in LICENSE.txt

Expand Down
5 changes: 0 additions & 5 deletions bom-internal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.ion</groupId>
<artifactId>ion-java</artifactId>
<version>${ion.java.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
Expand Down
20 changes: 15 additions & 5 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,37 @@
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>auth</artifactId>
<artifactId>json-utils</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-core</artifactId>
<artifactId>third-party-jackson-core</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>profiles</artifactId>
<artifactId>third-party-jackson-dataformat-cbor</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-cbor-protocol</artifactId>
<artifactId>auth</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-core</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>profiles</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-ion-protocol</artifactId>
<artifactId>aws-cbor-protocol</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
Expand Down
11 changes: 0 additions & 11 deletions bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,31 +70,20 @@
<include>com.fasterxml.jackson.jr:*</include>
<include>io.netty:*</include>
<include>com.typesafe.netty:*</include>
<include>com.fasterxml.jackson.core:*</include>
<include>com.fasterxml.jackson.dataformat:jackson-dataformat-cbor</include>
<include>org.apache.httpcomponents:*</include>
<include>org.reactivestreams:*</include>
<include>org.slf4j:*</include>
<include>commons-codec:commons-codec</include>
<include>software.amazon.ion:ion-java</include>
<include>software.amazon.awssdk:*</include>
<include>software.amazon:*</include>
<include>commons-logging:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>software.amazon.awssdk.thirdparty.com.fasterxml.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache</pattern>
<shadedPattern>software.amazon.awssdk.thirdparty.org.apache</shadedPattern>
</relocation>
<relocation>
<pattern>software.amazon.ion</pattern>
<shadedPattern>software.amazon.awssdk.thirdparty.ion</shadedPattern>
</relocation>
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>software.amazon.awssdk.thirdparty.io.netty</shadedPattern>
Expand Down
13 changes: 8 additions & 5 deletions codegen/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@
<artifactId>aws-cbor-protocol</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-ion-protocol</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-query-protocol</artifactId>
Expand Down Expand Up @@ -143,6 +138,14 @@
<groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-stree</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,17 +499,12 @@ public Metadata withJsonVersion(String jsonVersion) {
return this;
}

public boolean isIonProtocol() {
return protocol == Protocol.ION;
}

public boolean isCborProtocol() {
return protocol == Protocol.CBOR;
}

public boolean isJsonProtocol() {
return protocol == Protocol.CBOR ||
protocol == Protocol.ION ||
protocol == Protocol.AWS_JSON ||
protocol == Protocol.REST_JSON;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public enum Protocol {
REST_JSON("rest-json"),
CBOR("cbor"),
QUERY("query"),
REST_XML("rest-xml"),
ION("ion");
REST_XML("rest-xml");

private String protocol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@ static ProtocolSpec getProtocolSpecs(PoetExtensions poetExtensions, Intermediate
case AWS_JSON:
case REST_JSON:
case CBOR:
case ION:
return new JsonProtocolSpec(poetExtensions, model);
default:
throw new RuntimeException("Unknown protocol: " + protocol.name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import software.amazon.awssdk.core.http.HttpResponseHandler;
import software.amazon.awssdk.core.protocol.VoidSdkResponse;
import software.amazon.awssdk.protocols.cbor.AwsCborProtocolFactory;
import software.amazon.awssdk.protocols.ion.AwsIonProtocolFactory;
import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory;
Expand Down Expand Up @@ -119,8 +118,6 @@ private CodeBlock customErrorCodeFieldName() {
private Class<?> protocolFactoryClass() {
if (model.getMetadata().isCborProtocol()) {
return AwsCborProtocolFactory.class;
} else if (model.getMetadata().isIonProtocol()) {
return AwsIonProtocolFactory.class;
} else {
return AwsJsonProtocolFactory.class;
}
Expand Down Expand Up @@ -377,7 +374,6 @@ public Optional<MethodSpec> createErrorResponseHandler() {
private String protocolEnumName(software.amazon.awssdk.codegen.model.intermediate.Protocol protocol) {
switch (protocol) {
case CBOR:
case ION:
case AWS_JSON:
return AWS_JSON.name();
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ private MarshallerProtocolSpec getProtocolSpecs(software.amazon.awssdk.codegen.m
switch (protocol) {
case REST_JSON:
case CBOR:
case ION:
case AWS_JSON:
return getJsonMarshallerSpec();

Expand Down
5 changes: 3 additions & 2 deletions core/auth/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<groupId>software.amazon.awssdk</groupId>
<artifactId>json-utils</artifactId>
<version>${awsjavasdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.eventstream</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@

package software.amazon.awssdk.auth.credentials;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.util.json.JacksonUtils;
import software.amazon.awssdk.protocols.jsoncore.JsonNode;
import software.amazon.awssdk.protocols.jsoncore.JsonNodeParser;
import software.amazon.awssdk.regions.util.HttpResourcesUtils;
import software.amazon.awssdk.regions.util.ResourcesEndpointProvider;
import software.amazon.awssdk.utils.ComparableUtils;
Expand All @@ -40,6 +40,11 @@
*/
@SdkProtectedApi
public abstract class HttpCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable {
private static final JsonNodeParser SENSITIVE_PARSER =
JsonNodeParser.builder()
.removeErrorLocations(true)
.build();

private final Optional<CachedSupplier<AwsCredentials>> credentialsCache;

protected HttpCredentialsProvider(BuilderImpl<?, ?> builder) {
Expand Down Expand Up @@ -73,7 +78,7 @@ private RefreshResult<AwsCredentials> refreshCredentials() {
try {
String credentialsResponse = HttpResourcesUtils.instance().readResource(getCredentialsEndpointProvider());

JsonNode node = JacksonUtils.sensitiveJsonNodeOf(credentialsResponse);
Map<String, JsonNode> node = SENSITIVE_PARSER.parse(credentialsResponse).asObject();
JsonNode accessKey = node.get("AccessKeyId");
JsonNode secretKey = node.get("SecretAccessKey");
JsonNode token = node.get("Token");
Expand All @@ -83,8 +88,8 @@ private RefreshResult<AwsCredentials> refreshCredentials() {
Validate.notNull(secretKey, "Failed to load secret key.");

AwsCredentials credentials =
token == null ? AwsBasicCredentials.create(accessKey.asText(), secretKey.asText())
: AwsSessionCredentials.create(accessKey.asText(), secretKey.asText(), token.asText());
token == null ? AwsBasicCredentials.create(accessKey.text(), secretKey.text())
: AwsSessionCredentials.create(accessKey.text(), secretKey.text(), token.text());

Instant expiration = getExpiration(expirationNode).orElse(null);
if (expiration != null && Instant.now().isAfter(expiration)) {
Expand All @@ -98,11 +103,6 @@ private RefreshResult<AwsCredentials> refreshCredentials() {
.build();
} catch (SdkClientException e) {
throw e;
} catch (JsonMappingException e) {
throw SdkClientException.builder()
.message("Unable to parse response returned from service endpoint.")
.cause(e)
.build();
} catch (RuntimeException | IOException e) {
throw SdkClientException.builder()
.message("Unable to load credentials from service endpoint.")
Expand All @@ -114,7 +114,7 @@ private RefreshResult<AwsCredentials> refreshCredentials() {
private Optional<Instant> getExpiration(JsonNode expirationNode) {
return Optional.ofNullable(expirationNode).map(node -> {
// Convert the expirationNode string to ISO-8601 format.
String expirationValue = node.asText().replaceAll("\\+0000$", "Z");
String expirationValue = node.text().replaceAll("\\+0000$", "Z");

try {
return DateUtils.parseIso8601Date(expirationValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package software.amazon.awssdk.auth.credentials;

import com.fasterxml.jackson.databind.JsonNode;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
Expand All @@ -25,11 +24,8 @@
import java.util.Collections;
import java.util.List;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.core.util.json.JacksonUtils;
import software.amazon.awssdk.protocols.jsoncore.JsonNode;
import software.amazon.awssdk.protocols.jsoncore.JsonNodeParser;
import software.amazon.awssdk.utils.DateUtils;
import software.amazon.awssdk.utils.IoUtils;
import software.amazon.awssdk.utils.Platform;
Expand Down Expand Up @@ -58,6 +54,10 @@
*/
@SdkPublicApi
public final class ProcessCredentialsProvider implements AwsCredentialsProvider {
private static final JsonNodeParser PARSER = JsonNodeParser.builder()
.removeErrorLocations(true)
.build();

private final List<String> command;
private final Duration credentialRefreshThreshold;
private final long processOutputLimit;
Expand Down Expand Up @@ -129,14 +129,14 @@ private RefreshResult<AwsCredentials> refreshCredentials() {
* Parse the output from the credentials process.
*/
private JsonNode parseProcessOutput(String processOutput) {
JsonNode credentialsJson = JacksonUtils.sensitiveJsonNodeOf(processOutput);
JsonNode credentialsJson = PARSER.parse(processOutput);

if (!credentialsJson.isObject()) {
throw new IllegalStateException("Process did not return a JSON object.");
}

JsonNode version = credentialsJson.get("Version");
if (version == null || !version.isInt() || version.asInt() != 1) {
JsonNode version = credentialsJson.get("Version").orElse(null);
if (version == null || !version.isNumber() || !version.asNumber().equals("1")) {
throw new IllegalStateException("Unsupported credential version: " + version);
}
return credentialsJson;
Expand Down Expand Up @@ -174,21 +174,10 @@ private Instant credentialExpirationTime(JsonNode credentialsJson) {
}

/**
* Get a textual value from a json object, throwing an exception if the node is missing or not textual.
* Get a textual value from a json object.
*/
private String getText(JsonNode jsonObject, String nodeName) {
JsonNode subNode = jsonObject.get(nodeName);

if (subNode == null) {
return null;
}

if (!subNode.isTextual()) {
throw new IllegalStateException(nodeName + " from credential process should be textual, but was " +
subNode.getNodeType());
}

return subNode.asText();
return jsonObject.get(nodeName).map(JsonNode::text).orElse(null);
}

/**
Expand Down
Loading