Gradle - generate pom without dependencies - maven

I want to generate a pom file that does not include dependencies. I have tried clearing the dependencies using the code below, however the dependencies are still listed in the generated pom.
install.doFirst {
repositories.mavenInstaller {
pom.dependencies.clear()
}
}
Why I need this: I need a pom file to be included with my jar when I upload it to a "home brewed" service, however the service blows up when it reads '+' as the version for the dependencies (I am using dynamic dependencies).

uploadArchives {
repositories {
mavenDeployer {
// Do not write any dependencies into the POM
pom*.whenConfigured { pom -> pom.dependencies.clear() }
}
}
}

I ended up using the solution below calling gradle cleanPom. Basically I use an XML parser to edit the generated POM.
apply plugin: 'maven'
pomFileLocation="build/poms/noDeps.pom"
/**
* Creates pom with dependencies
*/
task writeNewPom << {
pom {}.writeTo(pomFileLocation)
}
/**
* Reads and Overwrites POM file removing dependencies
*/
task cleanPom(dependsOn: writeNewPom) << {
def xml = new XmlParser().parse(pomFileLocation)
def nodes = []
xml.dependencies[0].each {
nodes.add(it)
}
def parrent = nodes.first().parent()
nodes.each {
parrent.remove(it)
}
new XmlNodePrinter(new PrintWriter(new FileWriter(pomFileLocation))).print(xml)
}

Related

I got an error using this build.grafle file and don't know how to fix it

Here's the Error:
FAILURE: Build failed with an exception.
Where: Build file '/home/wieland/GitGradlePackaging/build.gradle' line: 22
What went wrong: A problem occurred evaluating root project 'GitGradlePackaging'.
Could not get unknown property 'org' for object of type org.gradle.api.internal.initialization.DefaultScriptHandler.
And Here's my build.gradle File:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at https://docs.gradle.org/4.6/userguide/tutorial_java_projects.html
*/
//From example: http://mrhaki.blogspot.co.at/2015/04/gradle-goodness-use-git-commit-id-in.html
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
}
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building an application
id 'application'
// Apply the groovy plugin to also add support for Groovy (needed for Spock)
id 'groovy'
id 'distribution'
}
// Set version
project.version = mainProjectVersion + " - " + githash
project.ext.set("wholeVersion", "$project.version - $githash")
project.ext.set("buildtimestamp", "2000-01-01 00:00")
def versionfilename = "versioninfo.txt"
def GROUP_DEBUG = 'Debug'
// Task to print project infos
task debugInitialSettings {
group = GROUP_DEBUG
doLast {
println 'Version: ' + project.wholeVersion
println 'Timestamp: ' + project.buildtimestamp
println 'Filename: ' + project.name
}
}
// To add the githash to zip
task renameZip {
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.zip")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.zip")
}
}
distZip.finalizedBy renameZip
// To add the githash to tar
task renameTar{
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.tar")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.tar")
}
}
distTar.finalizedBy renameTar
// Define the main class for the application
mainClassName = 'App'
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:23.0'
// Use the latest Groovy version for Spock testing
testCompile 'org.codehaus.groovy:groovy-all:2.4.13'
// Use the awesome Spock testing and specification framework even with Java
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile 'junit:junit:4.12'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
//To generate Testreports as HTML
test {
reports {
junitXml.enabled = false
html.enabled = true
}
}
distributions {
main {
contents {
from { 'build/docs' }
into ('reports') {
from 'build/reports'
}
}
}
}
//To make sure that test and javadoc ran before zip and tar
distTar.dependsOn test
distZip.dependsOn test
distTar.dependsOn javadoc
distZip.dependsOn javadoc
Please keep in mind I have not much knowledge about gradle as I'm just starting to learn it!
Thanks in advance :)
You have to move the githash definition outside the buildscript block
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
The reason is that when the buildscript block is evaluated line by line, its dependencies are not yet loaded. When the rest of the script is evaluated, the dependencies of the buildscript block have already been loaded. This is actually the reason for the buildscript block existence: to be run before the rest of the build and prepare the setup.

How to set packaging to pom in Gradle instead of defaulting to jar

I have a project that generates a Bill of Materials (BOM). When I execute gradle build it generates an empty jar, containing only a META-INF folder.
However I am able to publish the pom (BOM) to Nexus correctly, with the side effect of also uploading the empty jar.
According to the maven plugin doc https://docs.gradle.org/current/userguide/maven_plugin.html we should be able to set the packaging:
packaging archiveTask.extension
Here, uploadTask and archiveTask refer to the tasks used for uploading
and generating the archive
How can I set the packaging to pom?
Example of Gradle uploaded pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ttt.a</groupId>
<artifactId>my-bom</artifactId>
<version>Something-SNAPSHOT</version>
When I upload it with maven instead of gradle, there is an additional:
<packaging>pom</packaging>
UPDATE:
Full build.gradle config:
buildscript {
repositories {
maven {
url "http://myrepo"
}
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5"
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7'
} }
apply plugin: 'java' apply plugin: 'maven' apply plugin: "io.spring.dependency-management" apply plugin: "jacoco" apply plugin: 'org.asciidoctor.convert' apply plugin: 'org.sonarqube'
group = project.properties['groupId'] version = project.properties['version'].toString()
description = """Bill of Materials"""
sourceCompatibility = 1.8 targetCompatibility = 1.8
ext {
xxx = '1.0.0'
yyy = '1.2.0'
... }
repositories {
maven {
url "http://myrepo"
} }
dependencyManagement {
dependencies {
dependency "com.myorg:xxx:${xxx}"
dependency "com.myorg:yyy:${yyy}"
...
} }
uploadArchives {
repositories {
mavenDeployer {
snapshotRepository(url: 'http://myrepo') {
authentication(userName: "$System.env.NEXUS_USER", password: "$System.env.NEXUS_PASSWORD")
}
}
} }
asciidoctor {
sourceDir = file('src/docs/asciidoc/')
sources {
include '*.adoc'
}
outputDir = file("build/docs/${version}") }
task generateDummyBom {
doLast {
project.buildDir.mkdirs()
new File("$project.buildDir/dummy.pom").write("<project></project>\n")
}
ext.bomFile = file("$project.buildDir/dummy.pom") }
artifacts {
archives(generateDummyBom.bomFile) {
builtBy generateDummyBom
} }
jar.enabled = false
I found that the maven plugin seems to ignore the packaging property. After some experimentation, I found that it sets the packaging property to the extension of the file in your artifact. So, the way to get the packaging property set to pom is to create a dummy artifact with a file having a .pom extension, as below.
// The real file that we want to publish is the pom generated implicitly by the
// maven publishing plugin.
//
// We need to generate at least one file that we can call an archive so that the
// maven plugin will actually publish anything at all. Luckily, if the file
// that we call an archive is a .pom file, it's magically discarded, and we are
// only left with the implicitly-generated .pom file.
//
// We need the extension of the file to be `.pom` so that the maven plugin will
// set the pom packaging to `pom` (i.e. `<packaging>pom</packaging>`). Otherwise,
// packaging would be set to `xml` if our only file had an `.xml` extension.
task generateDummyBom {
doLast {
// Since we don't depend on anything else, we have to create the build dir
// ourselves.
project.buildDir.mkdirs()
// The file actually has to have xml in it, or Sonatype will reject it
new File("$project.buildDir/${project.artifactId}.pom").write("<project></project>\n")
}
ext.bomFile = file("$project.buildDir/${project.artifactId}.pom")
}
artifacts {
archives(generateDummyBom.bomFile) {
builtBy generateDummyBom
}
}
jar.enabled = false
Update: If you apply the java plugin, you will need to remove the jar archive from your archives.
// Remove the default jar archive which is added by the 'java' plugin.
configurations.archives.artifacts.with { archives ->
def artifacts = []
archives.each {
if (it.file =~ 'jar') {
// We can't just call `archives.remove(it)` here because it triggers
// a `ConcurrentModificationException`, so we add matching artifacts
// to another list, then remove those elements outside of this iteration.
artifacts.add(it)
}
}
artifacts.each {
archives.remove(it)
}
}
Second update: Replaced "dummy.pom" with "${project.artifactId}" above.
I couldn't get Garrett's solution to work, but I did have success like this:
dependencies {
// ...Omitted...
}
tasks.named('generatePomFileForMavenJavaPublication') {
pom.with {
description = 'Parent BOM'
withXml {
// ...Omitted...
}
}
}
// Removing all jar artifacts from the mavenJava publication
// appears to automagically cause packaging to be set to 'pom'!
publishing.publications.named('mavenJava') {
artifacts.removeIf { artifact ->
artifact.extension == 'jar'
}
}

Not Publishing the mentioned file(war/tar/zip) to artifactory in gradle script

I wrote a gradle script where I am creating the zip and war file and then I need to upload/publish it to the artifactory but the issue is I specified the war file in my artifact task even after that it is publishing everything to the artifactory zip,tar and war instead of only war file.
apply plugin: 'war'
apply plugin: 'java'
apply plugin: 'distribution'
//-- set the group for publishing
group = 'com.xxx.discovery'
/**
* Initializing GAVC settings
*/
def buildProperties = new Properties()
file("version.properties").withInputStream {
stream -> buildProperties.load(stream)
}
//add the jenkins build version to the version
def env = System.getenv()
if (env["BUILD_NUMBER"]) buildProperties.coveryadBuildVersion += "_${env["BUILD_NUMBER"]}"
version = buildProperties.coveryadBuildVersion
println "${version}"
//name is set in the settings.gradle file
group = "com.aaa.covery"
version = buildProperties.discoveryadBuildVersion
println "Building ${project.group}:${project.name}:${project.version}"
repositories {
maven {
url "http://cxxxxt.tshaaaaa.tho.com:9000/artifactory/libselease"
}
maven {
url "http://cxxxxt.tshaaa.tho.com:9000/artifactory/cache"
}
}
dependencies {
compile ([
"com.uters.omni:HermesSessionAPI:1.2",
"com.uters.proxy:ProxyResources:1.1",
"com.uters.omni:SeshataDirectory:1.0.1" ,
"com.euters.omni:CybeleInfrastructure:1.1.2",
"com.euters:JSONBus:1.4.1",
"javaee:javaee-api:5"
])
}
distributions {
main {
contents {
from {
war.outputs
}
}
}
}
// for publishing to artifactory
artifacts {
archives war
}
According to gradle distribution plugin documentation:
All of the files in the “src/$distribution.name/dist” directory will automatically be included in the distribution.
And also,
The distribution plugin adds the distribution archives as candidate for default publishing artifacts.
In other words, by default all the files will be published so this explains the behavior you're experiencing.
What you can probably do in order to workaround this behavior is to define the contents copySpec more accurately by explicitly exclude the unwanted files, i.e.:
distributions {
main {
contents {
exclude('**/.zip')
exclude('**/.tar')
from {
war.outputs
}
}
}
}
Note that I didn't try the above by myself though so some fine tuning might be needed. However I believe that you can find the data you need in the CopySpec Interface documentation

Getting the pom for a dependency in Gradle

In resolving a dependency from a Maven-repository, Gradle has to download the corresponding pom-file. I would like to access this file from within the Gradle-script and save it somewhere. How can I do this?
Take a look at Artifact Query API. Here is the sample code (Groovy):
def componentIds = configurations.compileClasspath.incoming.resolutionResult.allDependencies.collect { it.selected.id }
def result = project.dependencies.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(MavenModule, MavenPomArtifact)
.execute()
for (component in result.resolvedComponents) {
component.getArtifacts(MavenPomArtifact).each { println "POM file for ${component.id}: ${it.file}" }
}
I'm using the same API in my plugin in Kotlin.
You could simply declare a dependency on the POM itself.
configurations {
pom
}
dependencies {
pom 'org.foo:some-lib:1.0.0#pom'
}
task copyPom(type: Copy) {
into "${buildDir}/poms"
from configurations.pom
}

avro gradle plugin sample usage

I am trying to use the avro-gradle-plugin on github, but have not gotten any luck getting it to work. Does anyone have any sample code on how they get it to work?
I figured out how to do it myself. The following is a snippet that I would like to share for people who might run into the same issues as I did:
apply plugin: 'java'
apply plugin: 'avro-gradle-plugin'
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
buildscript {
repositories {
maven {
// your maven repo information here
}
}
dependencies {
classpath 'org.apache.maven:maven-artifact:2.2.1'
classpath 'org.apache.avro:avro-compiler:1.7.1'
classpath 'org.apache.avro.gradle:avro-gradle-plugin:1.7.1'
}
}
compileAvro.source = 'src/main/avro'
compileAvro.destinationDir = file("$buildDir/generated-sources/avro")
sourceSets {
main {
java {
srcDir compileAvro.destinationDir
}
}
}
dependencies {
compileAvro
}
I found "com.commercehub.gradle.plugin.avro" gradle plugin to work better.
use the folllowing:
// Gradle 2.1 and later
plugins {
id "com.commercehub.gradle.plugin.avro" version "VERSION"
}
// Earlier versions of Gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.commercehub.gradle.plugin:gradle-avro-plugin:VERSION"
}
}
apply plugin: "com.commercehub.gradle.plugin.avro"
more details at https://github.com/commercehub-oss/gradle-avro-plugin
When evaluating a plugin the following questions needs to be asked:
Are generated files included into source jar?
Is plugin fast? Good plugin use avro tools api instead of forking VM for every file. For large amount of files creating VM for every file can take 10min to compile.
Do you need intermediate avsc files?
Is build incremental (i.e. do not regenerate all files unless one of the sources changed)?
Is plugin flexible enough to give access to generated schema files, so further actions, such as registration schema in schema repository can be made?
It is easy enough to implement without any plugin if you are not happy with plugin or need more flexibility.
//
// define source and destination
//
def avdlFiles = fileTree('src/Schemas').include('**/*.avdl')
// Do NOT generate into $buildDir, because IntelliJ will ignore files in
// this location and will show errors in source code
def generatedJavaDir = "generated/avro/java"
sourceSets.main.java.srcDir generatedJavaDir
//
// Make avro-tools available to the build script
//
buildscript {
dependencies {
classpath group:'org.apache.avro', name:'avro-tools' ,version: avro_version
}
}
//
// Define task's input and output, compile idl to schema and schema to java
//
task buildAvroDtos(){
group = "build"
inputs.files avdlFiles
outputs.dir generatedJavaDir
doLast{
avdlFiles.each { avdlFile ->
def parser = new org.apache.avro.compiler.idl.Idl(avdlFile)
parser.CompilationUnit().getTypes().each { schema ->
def compiler = new org.apache.avro.compiler.specific.SpecificCompiler(schema)
compiler.compileToDestination(avdlFile, new File(generatedJavaDir))
}
}
}
}
//
// Publish source jar, including generated files
//
task sourceJar(type: Jar, dependsOn: buildAvroDtos) {
from sourceSets.main.allSource
// Package schemas into source jar
into("Schemas") { from avdlFiles }
}
// Clean "generated" folder upon "clean" task
clean {
delete('generated')
}
Configuration for avro with gradle as build tool need to add along with applying java plugin.
below changes in settings.gradle
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
below changes in build.gradle
plugins {
id "com.github.davidmc24.gradle.plugin.avro" version "1.3.0"
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.apache.avro:avro:1.11.0"
}
generateAvroJava {
source("${projectDir}/src/main/resources/avro")//sourcepath avrofile
}
if you want to generate setter methods too add this task too in build.gradle
avro {
createSetters = true
}
link for reference

Resources