Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use gradle to embed dependency information into manifest

I would like to embed dependency information into my manifest file, so that I can expose this information at runtime. i.e. I can see which version of a library is used by a particular running instance of my service.

I'm using gradle to build my 'fatjar':

shadowJar {
  mergeServiceFiles()
  archiveName "service.jar"
  exclude "META-INF/*.SF"
  exclude "META-INF/*.DSA"
  exclude "META-INF/*.RSA"
  manifest {
    attributes('Main-Class': "service.Service",
               'Built-By': System.getProperty('user.name'),
               'Built-Date': new Date(),
               'Built-JDK': System.getProperty('java.version'),
               'Implementation-Version': version,
               'Implementation-Title': project.name)
  }
}

And I have dependencies on various other libraries:

dependencies {
  compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.39'
  ...
}

How can I add the dependency information into my manifest file? For example:

Manifest-Version: 1.0
Implementation-Title: service
Implementation-Version: Local Build
Built-By: me
Built-Date: Wed Jun 22 14:13:53 BST 2016
Built-JDK: 1.8.0_91
Main-Class: service.Service
Dependency-mysql-connector-java: mysql:mysql-connector-java:5.1.39
like image 209
Daniel Scott Avatar asked Jun 22 '16 13:06

Daniel Scott


People also ask

How do I add a dependency in Gradle?

To add a dependency to your project, specify a dependency configuration such as implementation in the dependencies block of your module's build.gradle file.

What is the difference between implementation and API in Gradle?

The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.

Can Gradle use Maven dependency?

Gradle can consume dependencies available in the local Maven repository. Declaring this repository is beneficial for teams that publish to the local Maven repository with one project and consume the artifacts by Gradle in another project. Gradle stores resolved dependencies in its own cache.

What is API dependency in Gradle?

Gradle adds the dependency to the compile classpath and build output. When a module includes an api dependency, it's letting Gradle know that the module wants to transitively export that dependency to other modules, so that it's available to them at both runtime and compile time.


1 Answers

It can be done in the following way:

buildscript {
  repositories {
    maven {
      url 'https://plugins.gradle.org/m2/'
    }
  }

  dependencies {
    classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
  }
}

apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'

repositories {
  mavenCentral()
}

dependencies {
  compile 'com.google.guava:guava:19.0'
  compile 'com.google.inject:guice:4.1.0'
}

shadowJar {
  mergeServiceFiles()
  archiveName "service.jar"
  exclude "META-INF/*.SF"
  exclude "META-INF/*.DSA"
  exclude "META-INF/*.RSA"
  manifest {
    attributes(
               [
               'Main-Class': "service.Service",
               'Built-By': System.getProperty('user.name'),
               'Built-Date': new Date(),
               'Built-JDK': System.getProperty('java.version'),
               'Implementation-Version': 'version',
               'Implementation-Title': project.name,
               ] +
               project.configurations.compile.allDependencies.collect { d ->
                 [
                  ("dependency-${d.group.replaceAll('\\.','-')}".toString()):"$d.group:$d.name:$d.version"
                 ]
               }.sum()
    )
  }
}

The script above produces the following MANIFEST.MF:

Manifest-Version: 1.0
Main-Class: service.Service
Built-By: opal
Built-Date: Mon Jul 04 17:27:05 CEST 2016
Built-JDK: 1.8.0_91
Implementation-Version: version
Implementation-Title: 37969253
dependency-com-google-guava: com.google.guava:guava:19.0
dependency-com-google-inject: com.google.inject:guice:4.1.0

Since attributes takes Map as an argument, you need to collect them dependencies, transform them to Map and sum the maps.

like image 161
Opal Avatar answered Sep 19 '22 13:09

Opal