Publishing a JAR to S3

From Rest of What I Know
Revision as of 01:19, 12 March 2024 by Roshan (talk | contribs)

I couldn't find a single source of how to publish a JAR to S3. Here's an example of as minimal as I can imagine. You'll need a build.gradle that looks like this:

apply plugin: 'java'
apply plugin: 'maven-publish'

sourceCompatibility = 1.8
targetCompatibility = 1.8

group = 'dev.roshangeorge.my_package'
version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.google.protobuf:protobuf-java:3.25.2' // for example
}

sourceSets {
    main {
        java {
            srcDirs = ['src/main/java']
        }
    }
}

jar {
    manifest {
        attributes(
            'Implementation-Title': 'My Package',
            'Implementation-Version': version
        )
    }

    // Include the compiled classes from all subdirectories
    from sourceSets.main.output

    // Define the name of the JAR file
    archiveFileName = 'my-package.jar'
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'software.amazon.awssdk:s3:2.23.14'
    }
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java

            // Metadata configuration for the pom.xml
            pom {
                name = 'My Package'
                description = 'Full of class files'
            }
        }
    }

    repositories {
        maven {
          name = 's3'
          url = uri("s3://dev-roshangeorge/java/")

          credentials(AwsCredentials) {
                // Unfortunately there's no way to make the plugin resolve automatically
                // unless you've got an IAM role, so rather than use env-vars, we'll just
                // use the default credentials provider explicitly
                def defaultCredentials = software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.create().resolveCredentials();
                accessKey defaultCredentials.accessKeyId
                secretKey defaultCredentials.secretAccessKey
          }

        }
    }
}

and a settings.gradle that looks like this:

rootProject.name = 'my_package'

The hard part for me was that the AWS SDK wouldn't load my credentials from my ~/.aws/credentials file. Things would work with env vars, but I couldn't get them to work with the credentials file, which is what I normally use.

You should then be able to do the usual dependency stuff with:

    implementation 'dev.roshangeorge:my_package:1.0'

so long as your build.gradle has an entry like:

allprojects {

    repositories {
        mavenLocal()
        maven {
          url "s3://dev-roshangeorge/java/"
          credentials(AwsCredentials) {
                  def defaultCredentials = software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.create().resolveCredentials();
                  accessKey defaultCredentials.accessKeyId
                  secretKey defaultCredentials.secretAccessKey
          }
        }
    }

}

for which you'll need an entry like:

buildscript {
    repositories {
        jcenter()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        // get JARs from S3 (this is the important part)
        classpath 'software.amazon.awssdk:s3:2.23.14'

    }
}