Using S3 Bucket as Maven private repository with gradle - maven

I am trying to use AWS S3 as a maven private repo..below is my build.gradle looks like-:
import java.util.regex.Matcher
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.amazonaws:aws-java-sdk-core:1.11.5'
}
}
plugins {
id "java"
id "idea"
id "eclipse" //run "./gradlew cleanEclipse eclipse" after importing to eclipse
id "maven-publish"
id "maven"
id 'base'
id 'signing'
id 'jacoco'
id "net.researchgate.release" version "2.4.1"
id "org.springframework.boot" version "1.5.2.RELEASE"
}
def fetchAwsCredentials = {
try {
return new ProfileCredentialsProvider().getCredentials()
} catch (Exception e) {
logger.debug('Unable to retrieve AWS credentials from profile, publishing to S3 will not be available.', e)
return null
}
}
AWSCredentials awsCredentials = fetchAwsCredentials()
repositories {
mavenCentral()
maven {
url 'xxxxxxxx/<Bucket-Name>/snapshots/'
credentials(AwsCredentials) {
accessKey awsCredentials.AWSAccessKeyId
secretKey awsCredentials.AWSSecretKey
}
}
}
publish {
dependsOn assemble
}
publishing {
publications {
maven(MavenPublication) {
groupId this.properties['group']
artifactId this.properties['mavenArtifactId']
from components.java
}
}
repositories {
maven {
name 'repo'
credentials(AwsCredentials) {
accessKey awsCredentials.AWSAccessKeyId
secretKey awsCredentials.AWSSecretKey
}
if (project.version.endsWith('-SNAPSHOT')) {
url "xxxxxxxx/<Bucket-Name>/snapshots/"
} else {
url "xxxxxxxx/<Bucket-Name>/releases/"
}
}
}
}
But I am getting below error
Caused by: java.lang.IllegalArgumentException: Credentials must be an instance of: org.gradle.api.artifacts.repositories.PasswordCredentials
at org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory.convertPasswordCredentials(RepositoryTransportFactory.java:87)
at org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory.access$100(RepositoryTransportFactory.java:39)
at org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory$DefaultResourceConnectorSpecification.getCredentials(RepositoryTransportFactory.java:136)
at org.gradle.internal.resource.transport.http.HttpConnectorFactory.createResourceConnector(HttpConnectorFactory.java:36)
at org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory.createTransport(RepositoryTransportFactory.java:101)
at org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory.createTransport(RepositoryTransportFactory.java:79)
at org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository.getTransport(DefaultMavenArtifactRepository.java:122)
at org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository.createResolver(DefaultMavenArtifactRepository.java:109)
at org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository.createRealResolver(DefaultMavenArtifactRepository.java:100)
at org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository.createResolver(DefaultMavenArtifactRepository.java:91)
at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ResolveIvyFactory.create(ResolveIvyFactory.java:92)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:92)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:90)
at org.gradle.internal.Transformers$4.transform(Transformers.java:137)
at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:61)
at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:39)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver.resolve(DefaultDependencyResolver.java:90)
at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver$1.run(CacheLockingArtifactDependencyResolver.java:42)
at org.gradle.internal.Factories$1.create(Factories.java:22)
at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:192)
at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:175)
at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:106)
at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:187)
at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:64)
at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver.resolve(CacheLockingArtifactDependencyResolver.java:40)
at org.gradle.api.internal.artifacts.ivyservice.SelfResolvingDependencyResolver.resolve(SelfResolvingDependencyResolver.java:45)
at org.gradle.api.internal.artifacts.ivyservice.ShortcircuitEmptyConfigsArtifactDependencyResolver.resolve(ShortcircuitEmptyConfigsArtifactDependencyResolver.java:58)
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.resolve(ErrorHandlingArtifactDependencyResolver.java:47)
... 81 more
Looks like it failing because of incorrect condition added in gradle jar-:
https://github.com/gradle/gradle/blob/master/subprojects/resources-http/src/main/java/org/gradle/internal/resource/transport/http/HttpClientConfigurer.java
Any Clue ?

The problem you are facing is for wrong S3 Url pattern.
There are two interfaces extends from base Credentials interface.
AwsCredentials
PasswordCredentials
When you used url 'xxxxxxxx/<Bucket-Name>/snapshots/', it detects the maven repo as just normal url. That is why it was asking for PasswordCredentials.
You should use s3://<bucket-name>.s3-eu-west-1.amazonaws.com. Here it will ask for AwsCredentials.
IMHO you should use two different buckets for releases and snapshots.
repositories {
maven {
name 'repo'
credentials(AwsCredentials) {
accessKey awsCredentials.AWSAccessKeyId
secretKey awsCredentials.AWSSecretKey
}
if (project.version.endsWith('-SNAPSHOT')) {
url "s3://<bucket-name>-snapshots.s3-eu-west-1.amazonaws.com"
} else {
url "s3://<bucket-name>-releases.s3-eu-west-1.amazonaws.com"
}
}
}

Related

Unable to start EmbeddedWebApplicationContext - not a web app

Here is the build.gradle file. I have removed comments and sensitive data.
Still receiving the "missing EmbeddedServletContainerFactory Bean" error.
buildscript {
ext {
springBootVersion = '1.5.9.RELEASE'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
maven { url "https://plugins.gradle.org" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-
plugin:${springBootVersion}")
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.5.4")
classpath("gradle.plugin.de.gliderpilot.gradle.semantic-
release:gradle-semantic-release-plugin:1.3.1")
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('org.springframework.boot:spring-boot-starter-mail')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
{
exclude module: 'spring-boot-starter-tomcat'
}
runtime files ('/libs/ojdbc8.jar')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
plugins {
id "org.sonarqube" version "2.5"
id "com.gorylenko.gradle-git-properties" version "1.4.17"
id "de.gliderpilot.semantic-release" version "1.3.1"
}
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'idea'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
sourceCompatibility = 1.8
group = 'com.usps.informed-delivery'
dependencies {
compile('org.springframework.boot:spring-boot-starter-activemq')
compile('org.springframework.boot:spring-boot-actuator-docs')
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.springframework.boot:spring-boot-starter-batch')
compile('org.springframework.boot:spring-boot-starter-cache')
compile('org.springframework.boot:spring-boot-starter-data-cassandra')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-redis')
compile('org.springframework.boot:spring-boot-starter-integration')
compile('org.springframework.batch:spring-batch-integration')
compile('org.springframework.integration:spring-integration-xml')
compile('org.springframework.integration:spring-integration-mail')
compile('org.springframework.integration:spring-integration-test')
compile('org.slf4j:slf4j-api')
compile('org.springframework.integration:spring-integration-java-dsl')
compile("org.springframework:spring-oxm")
compile("joda-time:joda-time")
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
compile('org.liquibase:liquibase-core')
compile('libs/ojdbc8.jar')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.batch:spring-batch-test')
testCompile('org.springframework.integration:spring-integration-test')
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
artifactory {
contextUrl = 'http:whatever'
publish {
repository {
if (version.toString().endsWith("-SNAPSHOT")) {
repoKey = 'snapshots'
} else {
repoKey = 'releases'
}
username = ""
password = ""
}
defaults {
publications('mavenJava')
publishArtifacts = true
properties = ['qa.level': 'basic', 'dev.team': 'core']
publishPom = true
}
}
resolve {
repoKey = 'jcenter'
username = ""
password = ""
}
}
sonarqube {
properties {
property "sonar.sourceEncoding", "UTF-8"
property "sonar.projectKey", "readers-digest-generator"
property "sonar.projectName", "Readers Digest Generator"
}
}
Posting the build.gradle file per request. I have tried to resolve by putting
spring.main.web-environment-=false in aplication.properties file and app.setWebEnvironment(false) in BatchApplication.java
Spring Boot assumes it's a web app unless you configure it otherwise. The documentation (found here https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-boot-application.html#howto-create-a-non-web-application) illustrates that you can either configure your application to not be a web app either programatically via calling SpringApplication#s setWebEnvironment(false) or via setting the property spring.main.web-environment=false

Gradle is not able to use dependencies from artifactory

This is the code I have written: Please be notified that the code is working when I enable the flatDir section (commented one in the code), but not working when I want to use Remote Artifactory repository (Means comment the flatDir part):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'distribution'
buildDir = new File("$buildPath", project.name)
ext.distributionDir = new File(project.buildDir, 'distribution')
sourceSets {
//SourceSets
}
ext.sharedManifest = manifest {
//Manifests
}
tasks.withType(Jar) {
//Code to generate Jar Artifacts
}
// repositories {
// flatDir {
// dirs file("$dependencyPath"),
// }
// }
allprojects {
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'gradle-dev-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
resolve {
repository {
repoKey = 'gradle-dev'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
}
}
project(':projectName:ProjectComponent') {
sourceSets {
main {
java { include '/pathToCode/*' }
}
}
dependencies { compile (group: 'jcifs', name: 'jcifs', version: '1.1.11')}
//******* Publishing Component Jar (Build artifacts on Remote Repository) ********//
publishing.publications {
mavenJava(MavenPublication) {
groupId 'GroupID'
artifactId project.name
version = projVersion
from components.java
}
}
artifactoryPublish {
publications(publishing.publications.mavenJava)
}
}
Please suggest the solution.
Thanks! :-)

How to use the default AWS credentials chain for an S3 backed Maven repository in a Gradle build?

According to Gradle documention (Example 50.27), we can use S3 backed Maven repositories with Gradle 2.4. However, the only example given in the docs passes explicit AWS credentials to the S3 repository declaration:
repositories {
maven {
url "s3://someS3Bucket/maven2"
credentials(AwsCredentials) {
accessKey "someKey"
secretKey "someSecret"
}
}
}
I need to do the same thing, but I want Gradle to use the DefaultAWSCredentialsProviderChain, from the AWS JDK, instead of explicit credentials. Something like:
repositories {
maven {
url "s3://someS3Bucket/maven2"
credentials(AwsCredentials) {
// Default AWS chain here?
}
}
}
This way, it would find the Instance Profile Credentials that I have configured for my EC2 instances where the Gradle build would be running.
Is there a way to accomplish this? Or, is Gradle only capable of authenticating against S3 with explicit credentials given in the build file?
More recent versions of Gradle provide a built-in way to use credentials from the default provider chain, eg:
maven {
url "s3://myCompanyBucket/maven2"
authentication {
awsIm(AwsImAuthentication) // load from EC2 role or env var
}
}
This avoids the need to manually create an instance of the provider chain and pass in the credential values.
I managed to accomplish the pom.xml generation, as well as the upload to S3, with the following build.gradle:
apply plugin: 'java'
apply plugin: 'maven-publish'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.amazonaws:aws-java-sdk:1.10.58'
}
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId 'com.acme'
artifactId 'sample-gradle-dependency'
version '1.0'
from components.java
}
}
repositories {
maven {
url "s3://my-bucket/releases"
credentials(AwsCredentials) {
def defaultCredentials = new com.amazonaws.auth.DefaultAWSCredentialsProviderChain().getCredentials()
accessKey defaultCredentials.getAWSAccessKeyId()
secretKey defaultCredentials.getAWSSecretKey()
}
}
}
}
This one requires apply plugin: maven-publish, which apparently is the new version of apply plugin: maven.
This one runs with:
$ gradle publish
Untested, but I would try:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.amazonaws:aws-java-sdk:1.10.58'
}
}
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain
repositories {
maven {
url "s3://someS3Bucket/maven2"
credentials(AwsCredentials) {
def defaultCredentials = new DefaultAWSCredentialsProviderChain().getCredentials()
accessKey defaultCredentials.getAWSAccessKeyId()
secretKey defaultCredentials.getAWSSecretKey()
}
}
}

Gradle artifactory plugin cannot resolve dependency on configuration phase

I am trying to resolve dependency in configuration phase with artifactory gradle plugin.
apply plugin: 'java'
apply plugin: 'com.jfrog.artifactory'
artifactory {
contextUrl = "${artifactory_contextUrl}"
...
resolve {
repository {
repoKey = 'repo'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
dependencies {
compile 'commons-lang:commons-lang:+'
}
task testCustomResolve {
logger.quiet configurations.getByName('compile').singleFile.absolutePath
}
And it gives me
Could not resolve all dependencies for configuration ':compile'.
Cannot resolve external dependency commons-lang:commons-lang:+ because no repositories are defined.
It works as a charm in execution phase
task testCustomResolve << {
logger.quiet configurations.getByName('compile').singleFile.absolutePath
}
or when I use mavenCentral()
repositories {
mavenCentral()
}
In case you don't need to publish to Artifactory, I noticed that it works better if you don't use the artifactory {} syntax. Instead, try using:
plugins {
id "com.jfrog.artifactory" version "4.4.10"
}
repositories {
mavenLocal()
maven {
url "${artifactory_contextUrl}/${artifactory_repo}"
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
}
mavenCentral()
}

uploadArchives with mavenDeployer to multiple repos

I have a gradle project that acts like a common library for two other projects.
The other two projects each hosts an embedded maven repository that I want the common project to deploy to.
I've tried this:
uploadArchives {
repositories {
mavenDeployer {
repositories {
repository(url: '../../../project-web-service/repo')
repository(url: '../../../project-app/repo')
}
}
}
}
But this only deploys to the second repo.
I have read Configuring multiple upload repositories in Gradle build, but it doesn't cover the mavenDeployer, so I'm kind of stuck right now.
You can create two your own tasks (extends from Upload), just like this:
task uploadFirst(type: Upload) {
uploadDescriptor = true
repositories {
mavenDeployer {
repositories {
repository(url: '../../../project-web-service/repo')
}
}
}
}
task uploadSecond(type: Upload) {
uploadDescriptor = true
repositories {
mavenDeployer {
repositories {
repository(url: '../../../project-app/repo')
}
}
}
}
I had the same issue and was just able to solve it by giving the additional repositories names, but still leaving their own mavenDeployer closure.
For your example:
uploadArchives {
repositories {
mavenDeployer {
name = 'WebService'
repository(url: '../../../project-web-service/repo')
}
mavenDeployer {
name = 'App'
repository(url: '../../../project-app/repo')
}
}
}

Resources