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:

  • boot2docker: what does poweroff do to all my docker containers?
  • how to find MAX memory from docker stats?
  • How to automatically start services inside a docker container
  • Running 2 services
  • Docker swarm load balancing on AWS not working
  • Why doesn't my newly-created docker have a digest?
  • 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?

  • Setting environment variables when running docker in detached mode
  • What happens when a volume links an existing populated host and container dir
  • Docker - set DNS from inside container - for VPN?
  • How to provision Docker images in Vagrant?
  • Accessing docker container from iOS Simulator
  • Use docker-compose with docker swarm
  • 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.