aws / aws-sdk-java-v2

The official AWS SDK for Java - Version 2
Apache License 2.0
2.21k stars 855 forks source link

Allow setting platform specific classifier for aws-crt-client #5425

Open maschnetwork opened 4 months ago

maschnetwork commented 4 months ago

Describe the feature

The aws-crt package is a large JAR that contains all compiled C libraries for many different platforms (Windows, Linux, etc). However, it provides the possiblity to build platform specific JARs by setting a classifier (Reference).

Example:

<!-- Platform-specific Linux x86_64 JAR -->
<dependency>
    <groupId>software.amazon.awssdk.crt</groupId>
    <artifactId>aws-crt</artifactId>
    <version>0.29.20</version>
    <classifier>linux-x86_64</classifier>
</dependency>

Why:

The size of an example project generated with the AWS SDK Maven Archetype + AWS CRT Client as an Uber-Jar as well as a GraalVM native image is significantly smaller with the classifier as it only includes the needed C libraries for the target platform:

Artifact Type Default Artifact Size With Platform Classifier (osx-x86_64) Reduction in %
Uber JAR 24.7 MB 8.5 MB 65.59%
GraalVM native image 175 MB 92.7 MB 47.21%

Problem:

When using the AWS SDK it is not possible to set the classifier on the aws-crt-client dependency directly:

<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>aws-crt-client</artifactId>
  <classifier>linux-x86_64</classifier> <!-- Does NOT work -->
</dependency>

The current workaround is to exlude the aws-crt dependency and override it including the classifier. However, then also the aws-crt version has to be set:

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>aws-crt-client</artifactId>
    <exclusions>
        <exclusion>
            <groupId>software.amazon.awssdk.crt</groupId>
            <artifactId>aws-crt</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>software.amazon.awssdk.crt</groupId>
    <artifactId>aws-crt</artifactId>
    <version>0.29.20</version>
    <classifier>linux-x86_64</classifier> 
</dependency>

Proposed Solution

TBD

Other Information

No response

Acknowledgements

AWS Java SDK version used

2.26.3

JDK version used

21

Operating System and version

OSX

debora-ito commented 4 months ago

Acknowledged. We added the feature request to our backlog.

maschnetwork commented 4 months ago

Thank you. In the meantime I did a few experiments and a simple solution that wouldn't require much implementation effort would be the use of a maven profile that can be activated as a system property:

Code in aws-crt-client project pom.xml:

<profiles>
  <!-- Default includes all the binaries  -->
  <profile>
      <id>all</id>
      <activation>
          <activeByDefault>true</activeByDefault>
      </activation>
      <dependencies>
          <dependency>
              <groupId>software.amazon.awssdk.crt</groupId>
              <artifactId>aws-crt</artifactId>
              <version>0.30.0</version>
          </dependency>
      </dependencies>
  </profile>
  <!-- Activate this if a Maven System Property is set like mvn clean package -Dcrt.platform=linux-x86_64  -->
  <profile>
      <id>crt-classifier</id>
      <activation>
          <property>
              <name>crt.platform</name>
          </property>
      </activation>
      <dependencies>
          <dependency>
              <groupId>software.amazon.awssdk.crt</groupId>
              <artifactId>aws-crt</artifactId>
              <version>0.30.0</version>
              <classifier>${crt.platform}</classifier>
          </dependency>
      </dependencies>
  </profile>
</profiles>

When someone is using the aws-crt-client package the only thing that they need to do is to build their application with the property:

mvn clean package -Dcrt.platform=linux-x86_64

maschnetwork commented 3 months ago

Update: While this works with Maven, Gradle does not have a way to activate Maven profiles based on system properties when resolving the POM (See: https://blog.gradle.org/maven-pom-profiles).