Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

430
Vistas
Spring Boot (Gradle & Kotlin) custom library not reading application.yml properties

I'm trying to make an SDK (a custom library) for my Spring Boot microservices using Gradle (with Kotlin DSL) and Kotlin to send emails, reusing most of the stuff and libraries, using AWS SES.

First of all, I don't have a lot of experience on building java libraries, so there could be a lot of stuff that I am not doing correctly. Any feedback is welcome.

Anyways, I want this library to take some properties from the application.yml file on the end application (the microservice app itself) to instantiate some of the Beans of the library.

This library uses JavaEmailService, and has some parameters to use the local email server when developing in local, or the AWS SES implementation for the deployed versions.

For example, in the Bean configuration of the library I have the following code:

@Configuration
internal class BeanConfig {
  // ... other properties

  @Value("\${sdk.mail.aws.access_key:}")
  private lateinit var awsMailAccessKey: String

  @Value("\${sdk.mail.aws.secret_key:}")
  private lateinit var awsMailSecretKey: String

  @Value("\${sdk.mail.aws.region:}")
  private lateinit var awsMailRegion: String

  @Value("\${sdk.mail.is_local:}")
  private var isLocal: Boolean? = null

  // ... other bean resolves

  @Bean
  fun amazonSimpleEmailService(): AmazonSimpleEmailService {
    if (isLocal == true) {
      return DummyAmazonSimpleEmailServiceImpl()
    }

    if (awsMailAccessKey.isEmpty() || awsMailSecretKey.isEmpty() || awsMailRegion.isEmpty()) {
      throw Exception("Missing AWS parameters (access_key, secret_key, region)")
    }

    return AmazonSimpleEmailServiceClientBuilder
      .standard()
      .withCredentials(
        AWSStaticCredentialsProvider(
          BasicAWSCredentials(
            awsMailAccessKey,
            awsMailSecretKey
          )
        )
      )
      .withRegion(Regions.fromName(awsMailRegion))
      .build()
    }
}

I want it to take the values from the application.yml file on the end application like so:

sdk:
  mail:
    is_local: false
    aws:
      access_key: ${AWS_MAIL_ACCESS_KEY:}
      secret_key: ${AWS_MAIL_SECRET_KEY:}
      region: ${${AWS_MAIL_REGION:}

I did a custom selection of the dependencies that should be included in the final jar file, as I was getting a lot of ClassNotFoundException (any recommendations on this part are also welcome, in the Java library jar generation). It includes in the final jar all the needed dependencies for it to work.

Here the relevant parts of the build.gradle.kts file for generation of the jar file when I run ./gradlew build:

plugins {
    id("org.springframework.boot") version "2.5.0"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    kotlin("jvm") version "1.5.10"
    kotlin("plugin.spring") version "1.5.10"
    `java-library`
    `maven-publish`
}

// ... library version, name and trivial info

dependencies {
    implementation(kotlin("stdlib"))
    implementation("org.springframework.boot:spring-boot-autoconfigure:2.5.0")
    implementation("org.springframework:spring-context-support:5.3.7")
    implementation("org.jetbrains.kotlin:kotlin-noarg:1.5.10")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.springframework.boot:spring-boot-starter-mail:2.5.0")
    implementation("org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE")
    implementation("com.amazonaws:aws-java-sdk-ses:1.12.131")
    testImplementation("org.junit.jupiter:junit-jupiter:5.7.2")
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2")
    testImplementation(platform("org.junit:junit-bom:5.7.2"))
    testImplementation("io.mockk:mockk:1.10.3-jdk8")
    testImplementation("org.junit.platform:junit-platform-launcher:1.7.2")
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.7.2")
    testImplementation("org.junit.vintage:junit-vintage-engine:5.7.2")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

val exportPackages: List<String> = listOf(
    "spring-boot-starter-mail",
    "jakarta.mail",
    "jakarta.activation",
    "spring-context-support",
    "spring-boot-starter/",

    "spring-cloud-starter-aws",
    "spring-cloud-aws-context",
    "spring-cloud-aws-core",
    "javax.mail-api",
    "javax.activation",

    "aws-java-sdk-ses",
    "aws-java-sdk-core",
    "httpclient",
    "httpcore",
    "joda-time"
)

// Here the custom part
tasks.getByName<Jar>("jar") {
    enabled = true
    from (
        configurations.compileClasspath.get().mapNotNull {
            if (exportPackages.any { exportPackage -> it.path.contains(exportPackage) }) {
                if (it.isDirectory) it else zipTree(it)
            } else null
        }
    )
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

When running ./gradlew build I get a "sdk-mail-0.0.1-plain.jar" file. This part works pretty well if I included in the final application with that file in the same repo, like so:

implementation(files("lib/sdk-mail-0.0.1-plain.jar"))

THE PROBLEM

When I publish it in our package repository and I import it in the final application like you would do with any other library:

implementation("com.organization:sdk-mail:0.0.1")

It gets imported correctly, and I can use all the classes during development, but when I run the application I found two problems:

  • It does not find the application.yml properties defined in the final application (it does find them when running the jar built locally)
  • It tries to reach EC2 to find AWS credentials (like a default region) but obviously it fails to do so. I guess it would not happen if the properties were found in the first place, so probably this will be fixed when the properties problem is fixed.

Here the publish configuration section in the library's build.gradle.kts:

publishing {
    repositories {
        // ... private repository settings
    }
    publications {
        create<MavenPublication>("default") {
            from(components["java"])
        }
    }
}

What I really don't understand is that, if I download the published jar in the package repository, and add it like if I generated it building the project locally, it works corretly. What I am gessing is that the published version that gradle downloads has some spring boot dependencies or something like that, but I really don't have any clue.

Could someone please help me with that?

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda