How to get version attribute from a gradle build to be included in runtime Swing application

34,156

Solution 1

I like creating a properties file during the build. Here's a way to do that from Gradle directly:

task createProperties(dependsOn: processResources) {
  doLast {
    new File("$buildDir/resources/main/version.properties").withWriter { w ->
        Properties p = new Properties()
        p['version'] = project.version.toString()
        p.store w, null
    }
  }
}

classes {
    dependsOn createProperties
}

Solution 2

You can always use brute force as somebody suggested and generate properties file during build. More elegant answer, which works only partially would be to use

getClass().getPackage().getImplementationVersion()

Problem is that this will work only if you run your application from generated jar - if you run it directly from IDE/expanded classes, getPackage above will return null. It is good enough for many cases - just display 'DEVELOPMENT' if you run from IDE(geting null package) and will work for actual client deployments.

Solution 3

Better idea is to keep the project version in gradle.properties file. All the properties from this file will be automatically loaded and can be used in build.gradle script.

Then if you need the version in your swing application, add a version.properties file under src/main/resources folder and filter this file during application build, here is a post that shows how it should be done.

version.properties will be included in the final jar, hence can be read and via ClassLoader and properties from this file can be displayed in application.

Solution 4

Simpler and updated solution of @Craig Trader (ready for Gradle 4.0/5.0)

task createProperties {
    doLast {
        def version = project.version.toString()
        def file = new File("$buildDir/resources/main/version.txt")
        file.write(version)
    }
}

war {
    dependsOn createProperties
}

Solution 5

I used @Craig Trader's answer, but had to add quite some changes to make it work (it also adds git-details):

task createProperties() {
    doLast {
        def details = versionDetails()
        new File("$buildDir/resources/main/version.properties").withWriter { w ->
            Properties p = new Properties()
            p['version'] = project.version.toString()
            p['gitLastTag'] = details.lastTag
            p['gitCommitDistance'] = details.commitDistance.toString()
            p['gitHash'] = details.gitHash.toString()
            p['gitHashFull'] = details.gitHashFull.toString() // full 40-character Git commit hash
            p['gitBranchName'] = details.branchName // is null if the repository in detached HEAD mode
            p['gitIsCleanTag'] = details.isCleanTag.toString()
            p.store w, null
        }
        // copy needed, otherwise the bean VersionController can't load the file at startup when running complete-app tests.
        copy {
            from "$buildDir/resources/main/version.properties"
            into "bin/main/"
        }
    }
}
classes {
    dependsOn createProperties
}

And load it from the constructor of class: VersionController

import static net.logstash.logback.argument.StructuredArguments.v;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.info.BuildProperties;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@RestController
public class VersionController {

    final static Logger log = LoggerFactory.getLogger(AppInfoController.class);

    private Properties versionProperties = new Properties();

    private String gitLastTag;
    private String gitHash;
    private String gitBranchName;
    private String gitIsCleanTag;

    VersionController()
    {
        String AllGitVersionProperties = "";
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("classpath:/version.properties");

        if(inputStream == null)
        {
            // When running unit tests, no jar is built, so we load a copy of the file that we saved during build.gradle.
            // Possibly this also is the case during debugging, therefore we save in bin/main instead of bin/test.
            try {
                inputStream = new FileInputStream("bin/main/version.properties");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        try {
            versionProperties.load(inputStream);
        } catch (IOException e) {
            AllGitVersionProperties += e.getMessage()+":";
            log.error("Could not load classpath:/version.properties",e);
        }

        gitLastTag = versionProperties.getProperty("gitLastTag","last-tag-not-found");
        gitHash = versionProperties.getProperty("gitHash","git-hash-not-found");
        gitBranchName = versionProperties.getProperty("gitBranchName","git-branch-name-not-found");
        gitIsCleanTag = versionProperties.getProperty("gitIsCleanTag","git-isCleanTag-not-found");

        Set<Map.Entry<Object, Object>> mainPropertiesSet = versionProperties.entrySet();
        for(Map.Entry oneEntry : mainPropertiesSet){
            AllGitVersionProperties += "+" + oneEntry.getKey()+":"+oneEntry.getValue();
        }
         log.info("All Git Version-Properties:",v("GitVersionProperties", AllGitVersionProperties));
    }
}
Share:
34,156
Domenic D.
Author by

Domenic D.

Updated on January 28, 2021

Comments

  • Domenic D.
    Domenic D. over 3 years

    I have a simple parent project with modules/applications within it. My build tool of choice is gradle. The parent build.gradle is defined below.

    apply plugin: 'groovy'
    dependencies {
        compile gradleApi()
        compile localGroovy()
    }
    
    
    allprojects {
        repositories {
            mavenCentral()
        }
    
        version "0.1.0-SNAPSHOT"
    }
    

    What I would like to do is utilize the version attribute (0.1.0-SNAPSHOT) within my swing application. Specifically, I'd like it to display in the titlebar of the main JFrame. I expect to be able to do something like this.setTitle("My Application - v." + ???.version);

    The application is a plain java project, but I'm not opposed to adding groovy support it it will help.