Generate a shadow jar by feature, with Gradle in a Java project - gradle

I try to use the java plugin feature (https://docs.gradle.org/5.3-rc-1/userguide/feature_variants.html) to declare 2 versions of the same dependency, and generate at the end, 2 jars:
java {
registerFeature('v1') {
usingSourceSet(sourceSets.main)
}
registerFeature('v2') {
usingSourceSet(sourceSets.main)
}
}
dependencies {
compileOnly project(':djobi-core')
v1Implementation(group: 'org.elasticsearch', name: 'elasticsearch-spark-13_' + scalaVersion, version:'6.2.2') {
exclude group: "org.scala-lang"
}
v2Implementation(group: 'org.elasticsearch', name: 'elasticsearch-spark-13_' + scalaVersion, version:'6.3.2') {
exclude group: "org.scala-lang"
}
}
ShadowJar {
}
But it generates only 1, is it a good way to use feature feature like this?

The default task shadowJar uses the runtime configuration, see the docs-
In order to shadow configurations v1 and v2 we can define two new tasks, of type ShadowJar (they need to be configured).
Actually, v1 and v2 could be defined as "normal" configurations, that is, avoiding to use the feature-variants (it is simpler; moreover when trying to use shadowJar and the v1Implementation above, we have an error (Resolving configuration 'v1Implementation' directly is not allowed).
See the edited example below; it can be built with gradle shadowJar1 shadowJar2.
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:5.0.0"
}
}
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: 'java'
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
mavenCentral()
}
configurations {
v1 {
extendsFrom(implementation)
}
v2 {
extendsFrom(implementation)
}
}
dependencies {
// tweaking deps here
v1('ant:ant:1.6')
v2('junit:junit:4.12')
}
task shadowJar1(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar ) {
classifier = 'v1'
configurations=[project.configurations.v1]
}
task shadowJar2(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar ) {
classifier = 'v2'
configurations=[project.configurations.v2]
}

Related

Define the generator code location using gradle to build xtext and xtend

I'm trying to create a first project using xText and xTend building with gradle.
I created the grammar following the guidance in the xText documentation and also created the xtend generators.
In eclipse the code generates to src-gen folder as expected.
When I created the gradle script, also following the http://xtext.github.io/xtext-gradle-plugin/xtext-builder.html to build my code instead of generating the code in 'src-gen' folder it generates in 'build' folder.
Is there any way to change this folder from build to src-gen in the gradle? I tried a lot of things and I got always errors.
Complete code of grade script:
apply plugin: 'org.xtext.builder'
dependencies {
xtextLanguages 'com.example.mylang:mylang:1.0.0-SNAPSHOT'
}
xtext {
languages {
mylang{
setup = 'com.example.MyLangStandaloneSetup'
generator.outlet.producesJava = true
}
}
sourceSets {
main {
srcDir 'src/main/xtext'
xtendOutputDir 'src-gen'
}
}
}
you can configure that in the source set
sourceSets {
main.xtendOutputDir = 'xtend-gen'
}
e.g.
plugins {
id "org.xtext.xtend" version "1.0.21"
}
apply plugin: 'java'
apply plugin: 'org.xtext.xtend'
sourceSets {
main.java.srcDirs = ['src','xtend-gen']
main.xtendOutputDir = 'xtend-gen'
}
repositories {
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
compile 'org.eclipse.xtext:org.eclipse.xtext.xbase.lib:2.13.0'
}
or for the xtxt builder plugin
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'org.xtext:xtext-gradle-plugin:1.0.21'
}
}
plugins {
id "org.xtext.builder" version "1.0.21"
}
repositories {
mavenLocal()
jcenter()
}
dependencies {
xtextLanguages 'org.xtext.example.mydslfoo:org.xtext.example.mydslfoo:1.0.0-SNAPSHOT'
}
xtext {
version '2.13.0'
languages {
mydslfoo {
setup = 'org.xtext.example.mydslfoo.MyDslFooStandaloneSetup'
generator {
outlets {
HEROES {
}
}
}
}
}
sourceSets {
main {
srcDir 'src'
output {
dir(xtext.languages.mydslfoo.generator.outlet, 'src-gen')
}
}
}
}

Gradle doesn't use repositories from "allprojects"

If I comment "repositories" on my buildscript, I get an error - even though the repositories are already declared on my "allprojects".
allprojects {
//...
buildscript {
repositories {
maven {
url "http://www.exemple.com/repositories"
}
}
}
}
}
buildscript {
// repositories {
// maven {
// url "http://www.exemple.com/repositories"
// }
// }
dependencies {
classpath group: 'com.exemple', name: 'exemple', version: '1.2.3'
}
}
Why does gradle not use the repositories defined on allprojects ? The error that I get:
> Could not resolve all dependencies for configuration ':classpath'.
> Cannot resolve external dependency com.exemple:exemple:1.2.3 because no repositories are defined.
buildscript block refers to the classpath for the current script, not a project. You can use it only for a Gradle script. For example:
example.gradle
buildscript {
repositories {
maven {
url "http://www.example.com/repositories"
}
}
dependencies {
classpath group: 'com.example', name: 'example', version: '1.2.3'
}
}
}
}
// do something, add tasks, etc.
build.gradle
subprojects {
apply from: 'example.gradle'
}

Gradle remove specific dependency configuration from generated pom

I need to ignore some dependencies defined in the configuration "configurations.nonDistributable" when using gradles plugin maven-publish to generate pom files, I haven't found a reliable way of doing this, except for manually parsing the XML to remove them. Am I missing something, does gradle allow for an easier way of doing this?
build.gradle example:
configurations{
nonDistributable
}
dependencies {
nonDistributable ('org.seleniumhq.selenium:selenium-java:2.52.0'){
exclude group:'com.google.guava' // included in elasticsearch
}
nonDistributable ('com.assertthat:selenium-shutterbug:0.3') {
transitive = false
}
nonDistributable 'mysql:mysql-connector-java:5.1.40'
nonDistributable fileTree(dir: 'non-distributable-libs', include: '*.jar')
}
// generate subprojects pom
subprojects {
apply plugin: 'maven-publish'
model {
tasks.generatePomFileForMavenJavaPublication {
destination = file("$buildDir/../../$distDir/build/pom/$project.name-pom.xml")
}
}
afterEvaluate { project ->
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
}
// generate root project pom
model {
tasks.generatePomFileForMavenJavaPublication {
destination = file("$buildDir/../$distDir/build/pom/$project.name-pom.xml")
}
}
afterEvaluate { project ->
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
You can create your own publication pom. It would look something like this:
customMaven(MavenPublication) {
artifactId 'myArtifactId'
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
configurations.specialConfiguration.getResolvedConfiguration().getFirstLevelModuleDependencies().each {
def dependency = dependencies.appendNode('dependency')
dependency.appendNode('groupId', it.moduleGroup)
dependency.appendNode('artifactId', it.moduleName)
dependency.appendNode('version', it.moduleVersion)
}
}
}
Then you can create a special configuration that extends from only those configurations that you want to include.
I am using this to create a special pom that contains all testRuntime dependencies to be used for integration tests separated from the main project.

When using gradle with maven-publish, I get Cannot find wagon which supports the requested protocol: scp

The error I get - ""
The property uploadURL is defined as scp://user#host/data/apps/repo/m2
Here are the relevant sections
configurations {
deployerJars
}
// Apply the java plugin to add support for Java
apply plugin: 'java'
//----------------------
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'net.researchgate:gradle-release:2.0.2'
}
}
//----------------------
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
//uploadURL is defined in a properties file. It is properly recognied
//by gradle
repository(url:upLoadURL)
uniqueVersion = false
}
}
}
//----------------------
apply plugin: 'net.researchgate.release'
//----------------------
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'maven central' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral()
}
// In this section you declare the dependencies for your production and test code
dependencies {
deployerJars "org.apache.maven.wagon:wagon-ssh:2.2"
compile 'org.springframework:spring-context:4.1.6.RELEASE'
compile 'org.springframework:spring-webmvc:4.1.6.RELEASE'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.11'
}
You created a configuration called deployJars that is unnecessary.
You are missing the wagon dependency for the archives configuration:
dependencies {
archives "org.apache.maven.wagon:wagon-ssh-external:3.4.0"
}
So change deployJars to archives.
Then for uploadArchives, you need to specify the configuration:
uploadArchives {
repositories {
mavenDeployer {
configuration = configurations.archives // <-- missing
repository(url: "scpexe://yourhost/yourdir/")
uniqueVersion = false
}
}
}

QueryDSL, spring-boot & Gradle

I was hoping to bring querydsl into my spring-boot project via gradle. Despite finding a couple of examples online, none of them actually work for me because of issues with dependencies (I think). According to the QueryDSL support forum, gradle is not supported yet. But I was wondering with all the gradle & spring-boot being created if someone has managed to make it work yet?
Here is my build.gradle:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'war'
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
}
}
repositories {
mavenCentral()
maven { url: "http://repo.spring.io/libs-snapshot" }
// maven { url: "http://repo.spring.io/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RC5")
compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.0.RC5")
compile("org.springframework:spring-orm:4.0.0.RC1")
compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
compile("com.h2database:h2:1.3.172")
compile("joda-time:joda-time:2.3")
compile("org.thymeleaf:thymeleaf-spring4")
compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
compile('org.codehaus.groovy:groovy-all:2.2.1')
compile('org.jadira.usertype:usertype.jodatime:2.0.1')
// this line fails
querydslapt "com.mysema.querydsl:querydsl-apt:3.3.2"
testCompile('org.spockframework:spock-core:0.7-groovy-2.0') {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
testCompile("junit:junit")
}
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
sourceSets {
main {
generated {
java {
srcDirs = ['src/main/generated']
}
}
java {
srcDirs = []
}
groovy {
srcDirs = ['src/main/groovy', 'src/main/java']
}
resources {
srcDirs = ['src/main/resources']
}
output.resourcesDir = "build/classes/main"
}
test {
java {
srcDirs = []
}
groovy {
srcDirs = ['src/test/groovy', 'src/test/java']
}
resources {
srcDirs = ['src/test/resources']
}
output.resourcesDir = "build/classes/test"
}
}
configurations {
// not really sure what this is, I see it in examples but not in documentation
querydslapt
}
task generateQueryDSL(type: JavaCompile, group: 'build', description: 'Generates the QueryDSL query types') {
source = sourceSets.main.java
classpath = configurations.compile + configurations.querydslapt
options.compilerArgs = [
"-proc:only",
"-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
]
destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}
compileJava {
dependsOn generateQueryDSL
source generateQueryDSL.destinationDir
}
compileGeneratedJava {
dependsOn generateQueryDSL
options.warnings = false
classpath += sourceSets.main.runtimeClasspath
}
clean {
delete sourceSets.generated.java.srcDirs
}
idea {
module {
sourceDirs += file('src/main/generated')
}
}
But gradle fails with:
Could not find method querydslapt() for arguments [com.mysema.querydsl:querydsl-apt:3.3.2]
I have tried changing the querydsl-apt version to earlier ones but I get the same error.
Working configuration for Spring Boot 1.3.5 and supported QueryDSL, tested with gradle 2.14.
ext {
queryDslVersion = '3.6.3'
javaGeneratedSources = file("$buildDir/generated-sources/java")
}
compileJava {
doFirst {
javaGeneratedSources.mkdirs()
}
options.compilerArgs += [
'-parameters', '-s', javaGeneratedSources
]
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile "com.mysema.querydsl:querydsl-jpa:$queryDslVersion"
compileOnly "com.mysema.querydsl:querydsl-apt:$queryDslVersion:jpa"
}
Complete project source code: spring-boot-querydsl
You probably need to do at least 2 things:
Declare the "querydslapt" configuration before you use it
Add querydsl-jpa (or whatever flavours you need) to your "compile" configuration.
Then you will have the classpath set up, but the apt bit will not do anything without some more configuration (as you found no doubt from the querydsl support forum). The apt but is used to generate some code that you then need to compile and use in your application code (the "Q*" classes corresponding to your domain objects). You could drive that from a build task in gradle I imagine (it only has to run once for every change in the domain objects).

Resources