James Blewitt
James Blewitt

Reputation: 801

Deploy additional files in Gradle Application Plugin

I have a small Java/Gradle project. I'm using the Application plugin to create a zip distribution (using the distZip task). Using the standard configuration I get the following directories in my zip file:

/bin - The scripts to start the application go in here
/lib - Contains my project code in a JAR file and all dependency JAR files.

The trouble is that I would like a third directory: /conf where I can put my configuration files (instead of having them packaged inside my application JAR file.

I imagine that this is a pretty common requirement because things like log4j.xml and hibernate.properties would be better placed outside the JAR file. I just can't figure out how I can customise the behavior of the Application plugin to do this however.

Upvotes: 40

Views: 24033

Answers (5)

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24593

OP's self-answer may be good for his use case, but there are a few things I'd like to improve on:

  1. His answer suggests that he has a directory conf parallel to the build.gradle. There is no such thing in the Maven Standard Directory Layout. The general consensus is to have a src/main/conf as had been hinted to in the docs:

If there are other contributing sources to the artifact build, they would be under other subdirectories: for example src/main/antlr would contain Antlr grammar definition files.

  1. The target directory name is NOT project.name as had been pointed out in a comment.

  2. If resource filtering is required, and it often is, then having a separate task is desirable. During local development, this task can be run to generate the filtered files. The distribution would merely use the output of this task (and unlike OP's answer, this also makes conf available to the tar distribution).

    def props = new Properties()
    file("src/main/filters/application.properties")
        .withInputStream { props.load(it) }
    
    import org.apache.tools.ant.filters.ReplaceTokens
    
    task copyConf(type: Copy) {
        from("src/main/conf/")
        into("$buildDir/conf")
        filesMatching("**/*.y*ml") {
            filter(tokens: props, ReplaceTokens)
        }
    }
    distributions {
        main {
            contents {
                from(copyConf) {
                    into("conf")
                }
            }
        }
    }
    

Upvotes: 3

ferdy
ferdy

Reputation: 7716

For me, a simple

applicationDistribution.from("src/main/config/") {
    into "config"
}

did the job. Of course you need to have your properties loaded correctly from within code. Especially if you move them from src/main/resources where they have been usable via classpath, into the new location. I circumvented this by adding a command line parameter which points to the configuration file.

Upvotes: 19

Graham
Graham

Reputation: 291

Actually, create a dist dir under the src dir in your project. Anything in this dir is copied by the application plugin (under applicationDistribution) when installApp or distZip is run.

Or edit applicationDistribution to do other things, if a simple copy is not enough.

Upvotes: 29

James Blewitt
James Blewitt

Reputation: 801

I revisited this problem several months later and I finally have an elegant solution. The following code should be added to the gradle file:

distZip {
    into(project.name) {
        from '.'
        include 'conf/*'
    }
}

This adds an additional include to the distZip task. This copies the "conf" directory (including contents) into the Zip distribution.

The generated zip file contains a single directory which is the same as the project name. This is why the "into" part is required.

Upvotes: 40

c_maker
c_maker

Reputation: 20006

I am not sure whether you can customize the application plugin, I have never used it. There is however other ways to achieve what you want to achieve.

You may create a /conf directory like this:

confDir = new File("$buildDir/conf")

You can then copy the files you need into this directory like this:

task copyConfFiles(type: Copy) {
   from _wherever your files reside_
   into confDir
   include('**/*.properties') // your configuration files 
}

You may then hook this copy task into the process like this:

distZip.dependsOn copyConfFiles

And last if you do not want your configurations in the final zip, you can do this:

distZip {
   exclude('**/*.properties') // your configuration files
}

Again, there might be a better way. This is a way.

Upvotes: 7

Related Questions