Does anyone have a build.gradle file from a working 3.9 data-service?

I do think it’s suspicious it’s looking for 2.29.1 as I’m not sure that version even exists.

I have specified version 2.19.0, I think it might be an issue with the psdo.falc2on repo, it is the one they use for the forks. Is there a standard LEAF repo I can pull from?

I’m a little doubtful the repo is going to make a difference since it’s looking for 2.29.1 of log4j-core, but I actually don’t think that version of log4j exists. Could you do a project wide search for 2.29.1 to see if your project mentions that anywhere? It’s also possible one of your project’s dependencies does, so maybe we could use Gradle’s dependency tree to try to figure out why that version is being picked.

2.29.1 is not mentioned anywhere in the project.

I’d run ./gradlew dependencies (or ./gradlew :some-project:dependencies if using a multi-project build) and see if you can find anything in the output related to log4j-core being on 2.29.1. Once you have the output, you should see something like:

+--- project :core
|    +--- com.bbn:openmap:5.1.15
|    +--- com.fasterxml.jackson.core:jackson-core:2.13.4
|    |    \--- com.fasterxml.jackson:jackson-bom:2.13.4

And for example, if I wanted to know who put jackson-bom:2.13.4 on the classpath, I could see in the output it’s jackson-core, because it’s a child of that in the dependency tree.

Also the output can be quite large, so you can write it to a file like: ./gradlew dependencies > tmp.txt, and then just open the tmp.txt file in a text editor to search it.

attempting to run ./gradlew dependencies or ./gradlew :otter-metadata:dependencies still gives

> Could not resolve all files for configuration ':classpath'.
   > Could not find any version that matches org.apache.logging.log4j:log4j-core:{strictly [2.17, 3[; prefer 2.19.0}.
     Versions that do not match: 3.0.0-SNAPSHOT
     Searched in the following locations:
       - file:/home/docker/.m2/repository/org/apache/logging/log4j/log4j-core/
       - https://nexus.psdo.falc2on.com/repository/maven-public/org/apache/logging/log4j/log4j-core/maven-metadata.xml
       - https://nexus.psdo.falc2on.com/repository/maven-public/org/apache/logging/log4j/log4j-core/2.29.1-SNAPSHOT/maven-metadata.xml
       - https://nexus.psdo.falc2on.com/repository/maven-public/org/apache/logging/log4j/log4j-core/2.29.1-SNAPSHOT/log4j-core-2.29.1-SNAPSHOT.pom
     Required by:
         project : > com.leidos.leaf.base:com.leidos.leaf.base.gradle.plugin:3.9.0 > com.leidos.leaf.gradle:leaf-gradle-plugins:3.9.0 > com.leidos.leaf:framework-services-tools:3.9.0-rc.1

In your dependencies block of your build.gradle, if you don’t have these already, could you add them:

    implementation "org.apache.logging.log4j:log4j-core:${versions.log4j2}"
    implementation "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j2}"

and then in the ext {} block, add the log4j version:

ext {
    versions = [
        ...
        log4j2: "2.19.0",
        ...
    ]

And if you have

    implementation "org.apache.logging.log4j:log4j-1.2-api:${versions.log4j2}"

Note that it’s log4j-**1.2**-api

I think you can remove that unless your project specifically depends on it.

my build.gradle file has

ext {
    versions = [
        log4j2: "2.19.0",
    ]
}

and

    dependencies {
        api "com.leidos.leaf:framework-services-core"
        
        implementation "com.sun.xml.bind:jaxb-impl:2.3.2"
        implementation "com.sun.xml.bind:jaxb-core:3.0.0"
        implementation "com.github.ben-manes.caffeine:jcache:2.8.5"
        implementation "org.apache.logging.log4j:log4j-core:${versions.log4j2}"
        implementation "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j2}"
        implementation "org.apache.logging.log4j:log4j-1.2-api:${versions.log4j2}"
    }

Removing the last line with 1.2 did not fix it.

I was able to fix it by adding mavenCentral to the pluginManagment repos

pluginManagement {
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url settings.hasProperty('leafMavenUrl') ? settings.leafMavenUrl : System.getenv('LEAF_MAVEN_REPO') ?: 'https://nexus.psdo.falc2on.com/repository/maven-public/'
            name 'Leidos Maven Repo'
            credentials {
                username settings.hasProperty('nexusUsername') ? settings.nexusUsername : System.getenv('NEXUS_USR')
                password settings.hasProperty('nexusPassword') ? settings.nexusPassword : System.getenv('NEXUS_PSW')
            }
        }
    }
}

Is there a standard url to download the leaf files from? I’d like to use the official one instead of psdo. I’ve tried https://repo.leidos-leaf.com/repository/maven-group/ but it didn’t work.

1 Like

https://repo.leidos-leaf.com/repository/maven-group/ worked, I just had to clear the gradle cache: rm -rf ~/.gradle && leafctl creds -A --overwrite

1 Like

Yeah most public Java dependencies LEAF apps depend on can be pulled from Maven Central. LEAF uses maven-group in generated services by default, which mirrors and therefore caches dependencies from Maven Central. (That way we don’t have to worry about dependencies we rely on becoming unavailable and breaking our builds.) And that same maven-group repo also makes the LEAF framework’s and platform’s own jars available.

So if you don’t have mavenCentral() or LEAF’s maven group in the repositories section of your build.gradle, the assumption would be your project’s repo would have to mirror Maven Central. I was kind of ruling this problem out because I figured this only came up when upgrading, so I am curious how it might have worked before. But of course I’m definitely glad you’re past it!

I am getting an error that says

The method getOrCreate(Class<? extends T>, Map<?,?>...) in the type ConfigCache is not applicable for the arguments (Class<IServiceConfig>)

on the line

private static final IServiceConfig SERVICE_CONFIG = ConfigCache.getOrCreate(IServiceConfig.class);

What should I use instead?

We were using openjdk:11-jre-slim as our base image, what base image should we use for java 17?

Here’s the build.gradle from a recently generated and working data-service. I recommend looking through it and compare against what you currently have. Keep in mind the base image in this build.gradle is dependent on your system architecture (arm or amd).

build.gradle from 3.9.0 of @leaf-platform/data-service generator -

plugins {
    id "application"
    id "eclipse"
    id "com.google.cloud.tools.jib" version "3.1.4"
    id "com.leidos.leaf.base" version "3.9.0"
    id "com.leidos.leaf.metadata" version "3.9.0"
    id 'org.cyclonedx.bom' version "1.4.0"
}

version = "0.1.0"
group = "com.leidos.leaf.data"

repositories {
    leafMavenRepo()
    mavenLocal()
}

tasks.named('cyclonedxBom').configure {bomTask ->
    // Limit BOM to runtimeClasspath
    project.configurations.stream()
            .map {conf -> conf.name}
            .distinct()
            .forEach {
                if (it != 'runtimeClasspath') {
                    bomTask.skipConfigs += it
                }
            }
}

task copyBoms(type: Copy) {
    from 'build/reports/bom.xml'
    into "${rootProject.projectDir}/build/reports"
    rename { String fileName ->
        fileName.replace("bom", "${project.name}-bom")
    }
}

task createBoms(type: DependencyReportTask) {
    // Do nothing
}

cyclonedxBom.dependsOn assemble
copyBoms.dependsOn cyclonedxBom
createBoms.dependsOn copyBoms

leaf {
    frameworkVersion = "3.9.0"
    platformVersion = "3.9.0"
    metadata {
        dirs = [
            "src/main/resources/data_service/beanmetadata":
            "${buildDir}/generated/src/main/java/${project.group.replace('.', '/')}/generated/metadata"
        ]
        lookupListDirs = [
            "src/main/resources/data_service/lookuplists":
            "${buildDir}/generated/src/main/java/${project.group.replace('.', '/')}/generated/lookuplists"
        ]
        jar {
            enabled = true
        }
    }
}

ext {
    versions = [
        prometheus: "0.8.0",
        jettyMetrics: "4.1.0",
        log4j2: "2.19.0",
        junit: "5.7.1"
    ]
    arch = System.getenv("BASE_IMAGE_ARCH")
    if (!arch) {
        arch = System.properties['os.arch'].toLowerCase().equals("aarch64") ? "arm64" : "amd64"
    }
    switch (arch.toLowerCase()){
        case "arm64":
            baseImage = "eclipse-temurin:17-jre-jammy"
            break;
        case "amd64":
            //The original location of this image can be found here: registry1.dso.mil/ironbank/redhat/openjdk/openjdk17
            baseImage = "docker-group.leidos-leaf.com/ironbank/redhat/openjdk/openjdk17:1.17"
            break;
        default:
            throw new InvalidUserDataException("Invalid architecture: " + arch + " - Options: arm64, amd64")
            break;
    }
}

sourceSets {
    intTest {
        compileClasspath += sourceSets.main.output
        runtimeClasspath += sourceSets.main.output
        java {
            srcDirs("src/integration-test/java")
        }
    }
}

configurations {
    all*.exclude group: 'log4j', module: 'log4j'
    all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12'

    intTestImplementation.extendsFrom testImplementation
    intTestRuntimeOnly.extendsFrom testRuntimeOnly
}

dependencies {
    implementation "com.leidos.leaf:framework-services-rest-easy"
    implementation "com.leidos.leaf:framework-services-rest"
    implementation "com.leidos.leaf:framework-services-metrics"
    implementation "com.leidos.leaf:framework-services-prometheus"
    implementation "com.leidos.leaf:framework-services-jetty"
    implementation "com.leidos.leaf:framework-services-mongo"
    implementation "com.leidos.leaf:framework-services-kafka"
    implementation "com.leidos.leaf:platform-services-core"
    implementation "com.leidos.leaf:platform-services-message-handling"
    implementation "com.leidos.leaf:platform-services-service-discovery"
    implementation "org.apache.logging.log4j:log4j-core:${versions.log4j2}"
    implementation "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j2}"
    implementation "org.apache.logging.log4j:log4j-1.2-api:${versions.log4j2}"
    implementation "io.prometheus:simpleclient_hotspot:${versions.prometheus}"
    implementation "io.prometheus:simpleclient_dropwizard:${versions.prometheus}"
    implementation "io.prometheus:simpleclient_servlet:${versions.prometheus}"
    implementation "io.dropwizard.metrics:metrics-jetty9:${versions.jettyMetrics}"
    implementation "io.swagger.core.v3:swagger-jaxrs2:2.1.9"
    implementation "com.github.ben-manes.caffeine:jcache:2.8.5"
    testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junit}"
    testImplementation "org.mockito:mockito-core:3.5.0"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${versions.junit}"
}

application {
    mainClass = 'com.leidos.leaf.data.DataServiceApplication'
}

tasks.named('test') {
    useJUnitPlatform()
}

tasks.register('integrationTest', Test) {
    description = 'Runs integration tests.'
    group = 'verification'
    useJUnitPlatform()
    testClassesDirs = sourceSets.intTest.output.classesDirs
    classpath = sourceSets.intTest.runtimeClasspath
}

jib {
    from {
        image baseImage
        platforms {
            platform {
                architecture = arch
                os = 'linux'
            }
        }
    }
    container {
        creationTime = 'USE_CURRENT_TIMESTAMP'
        jvmFlags = ['-Xmx400m', '-XX:+HeapDumpOnOutOfMemoryError', '-XX:HeapDumpPath=/tmp/']
    }
}
1 Like

I think I need to use docker-group.leidos-leaf.com/ironbank/redhat/openjdk/openjdk17:1.17 but it requires authentication, how do I pass the username and password through skaffold?

If you log in using docker login then you should be able to build it using Skaffold.

docker login docker-group.leidos-leaf.com

Use your LEAF Workspace credentials (the same as the ones you use to authenticate to this discourse workspace).

otter-data-service requires kubectl, helm and skaffold clis. We have a Dockerfile to install these onto the base image

FROM openjdk:11-jre-slim

RUN apt update -yo="APT::Acquire::Retries=3"
RUN apt upgrade -yo="APT::Acquire::Retries=3"
RUN apt install curl sudo -yo="APT::Acquire::Retries=5"

RUN curl -kLO "https://dl.k8s.io/release/$(curl -kL -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 
RUN sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

RUN curl -kO https://get.helm.sh/helm-v3.9.3-linux-amd64.tar.gz
RUN sudo tar -zxvf helm-v3.9.3-linux-amd64.tar.gz \
    && mv linux-amd64/helm /usr/local/bin/helm

RUN curl -kLo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
RUN sudo install skaffold /usr/local/bin/

COPY build/distributions/otter-data-service-1.0.0.tar /otter-data-service.tar
RUN tar -xvf /otter-data-service.tar -C /
CMD /otter-data-service-1.0.0/bin/otter-data-service

But both eclipse-temurin:17-jre-jammy and docker-group.leidos-leaf.com/ironbank/redhat/openjdk/openjdk17:1.17 fail on apt update.

Might be wrong, but it seems like you’re moving from a base image that comes with more tools installed, to an iron bank (hardened) image. So it’s likely some tools you expect to be available will not be, or you might have limited ability to use them.

The old image didn’t have the tools so I had to install them during the build, but it is not working with the new images.