Gradle task for Java playground

I am still new to Docker and Gradle, but I am trying to setup a Gradle build that builds a Docker image.

I just finished setting up a Dockerfile which locally deploys and runs the jar as expected. I have this in my build.gradle:

  • Docker registry image won't start - “exec format error”
  • Start mysql automatically when running a Docker container
  • Restoring to a neo4j docker container
  • Can't connect to MySQL container on AWS ECS
  • how docker containers can communicate in a Mesos/Marathon setup
  • docker expose ports only on host
  • buildscript {
        repositories {
            mavenCentral()
        }
    
        dependencies {
            classpath 'se.transmode.gradle:gradle-docker:1.2'
        }
    }
    
    plugins {
        id 'com.github.johnrengelman.shadow' version '1.2.3'
    }
    
    apply plugin: 'docker'
    
    jar {
        manifest {
            attributes 'Main-Class': 'com.myapp.Main'
        }
    }
    
    
    task buildDocker(type: Docker, dependsOn: shadowJar) {
        push = false
    
        applicationName = jar.baseName
    
        tagVersion = 'latest'
        dockerfile = file('src/main/docker/Dockerfile')
    
        copy {
            from shadowJar
            into stageDir
        }
    }
    

    I run ./gradlew build buildDocker to build the image. I am happy with this so far.

    Usually I create a throwaway class (e.g. Playground.java) with a main method that I can run and disregard. Usually I just run this in the IDE, but now I would like to be able to connect to the other Docker containers that I know will be running.

    I know I could try changing the sourceSets I’m using by excluding com.myapp.Main, but I was imagining there might be a more elegant solution resembling this:

    task buildDockerPlayground(type: Docker, dependsOn: shadowJar) {
        main = 'com.myapp.Playground'
    
        push = false
    
        applicationName = jar.baseName
    
        tagVersion = 'latest'
        dockerfile = file('src/main/docker/Dockerfile')
    
        copy {
            from shadowJar
            into stageDir
        }
    }
    

    Another approach might be to have another task that I use to replace build when I call ./gradlew build buildDocker, e.g. ./gradlew playground buildDocker. Is this more practical?

  • How to run GPGPU inside docker image with different from host kernel and GPU driver version
  • How to properly set VOLUME and CMD instructions in Postgres Dockerfile?
  • Docker - Updating Environment Variables of a Container
  • How to run mvn sonar:sonar using jhipster and sonar in docker containers
  • Docker container link for mysql to redmine fails with timeout “waiting for database server to accept connections”
  • Setting nginx reverse proxy to serve from another docker container
  • One Solution collect form web for “Gradle task for Java playground”

    I would suggest replacing your hard coded main class with a gradle project property.

    jar {
        manifest {
            attributes 'Main-Class': main
        }
    }
    

    Set that default property in your gradle.properties file.

    main=com.myapp.Main
    

    Finally, when you need to build your docker container that uses a jar running
    com.myapp.Playground you can invoke gradle with:

    ./gradlew buildDocker -Pmain=com.myapp.Playground
    

    Edit: To achieve the same thing in a task

    project.ext.main = 'com.myapp.Main'
    
    task play(){
        project.main = 'com.myapp.Playground'
        finalizedBy buildDocker
    }
    
    jar {
        manifest {
            attributes 'Main-Class': project.main
        }
    }
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.