Running Gradle ShadowJar Plugin only on specific subproject - groovy

Please note: Even though my myapp-server is a DropWizard app, this is strictly a Gradle question; I only mention DropWizard for good measure.
I have a multi-project build that I am building with Gradle:
myapp/
myapp-client/
myapp-shared/
myapp-server/
build.gradle
settings.gradle
Where settings.gradle looks like:
include ':myapp-shared'
include ':myapp-client'
include ':myapp-server'
I have successfully got Gradle to compile my Groovy source code, run unit tests, generate GroovyDocs, and package both binary and source JARs for all 3 subprojects. The build invocation for which is: gradle clean build groovydoc sourcesJar -Pversion=<whatever version I specify>.
The myapp-server is actually a project that I need to run the Shadow JAR plugin on, which is usually executed via gradle clean build shadowJar.
Here is my myapp-server/build.gradle:
import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer
apply plugin: 'application'
apply plugin: 'shadow'
mainClassName = 'com.me.myapp.server.MyAppServer'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:0.8'
}
}
dependencies {
compile project(':myapp-shared')
compile (
'io.dropwizard:dropwizard-core:0.7.1'
)
}
shadow {
outputFile new File(destinationDir, "${outputJarBaseName}.${extension}")
transformer(ServiceFileTransformer)
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
}
jar {
manifest {
attributes 'Main-Class': mainClassName
}
}
run {
args 'server', 'config.json'
if (System.getProperty('debug', 'false') == 'true') {
jvmArgs '-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005'
}
}
artifacts {
shadowJar
}
My question: How do I configure Gradle to only run the shadowJar task on my myapp-server subproject, and not on any of the others? Ideally, I could just have my build invocation be something like:
gradle clean build groovyDoc sourceJar shadowJar -Pversion=<blah>
And then somehow configure Gradle to ignore running shadowJar on everything except myapp-server. Ideas?
Update
When I run gradle clean build groovyDoc sourceJar shadowJar -Pversion=0.1.3 I see a bunch of Gradle output that ends with:
:myapp-shared:groovydoc
:myapp-client:sourcesJar
:myapp-server:sourcesJar
:myapp-shared:sourcesJar
:myapp-server:copySignedLibs UP-TO-DATE
:myapp-server:shadowJar
BUILD SUCCESSFUL
Total time: 16.315 secs
However when I drill down into myapp-server/build/libs/myapp-server-0.1.3.jar and open it (extracting it like a ZIP), I only see my compiled classes inside of it, not all the classes from all of its dependent JARs (it should be a "Fat JAR"). For instance, myapp-server depends on DropWizard. All the DropWizard classes should be inside this JAR. All of DropWizard's transitive dependencies should have class files inside this JAR, etc.

I've just checked out the project located here.
After fetching the sources I've run: gradle clean shadowJar in myapp directory. As far as I see, there is a jar file created under myapp/myapp-server/build/distributions that seesm to be the fat jar You're looking for (also when file size is taken into consideration). After entering the mentioned distributions directory and running java -jar myapp-server.jar the server is started. It seems that it's all working fine. Am I right?
Also running curl -v -X GET http://localhost:8080/myapp/dosomething gives the following output:
* Hostname was NOT found in DNS cache
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /myapp/dosomething HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 05 Jan 2015 14:59:50 GMT
< Content-Type: application/json
< Content-Length: 0
<
* Connection #0 to host localhost left intact

If you were looking to only reference one sub project to shadowJar you could do it as follows.
gradle clean build groovyDoc sourceJar :myapp-server:shadowJar -Pversion=<1.0>
You can drill down to your subprojects tasks via :<project name>:<task name>
Reference:
https://gradle.org/docs/current/userguide/multi_project_builds.html
57.4. Running tasks by their absolute path

Related

I received an error on the first run of flutter project! `Finished with error: Gradle task assembleDebug failed with exit code 1`

Today I started to learn flutter.
I created new flutter project from Flutter Application in android studio 3.5.3.
I created new android virtual device and then tried to run main.dart.
I remember that my project freezed during initializing gradle in the first run so I had to stop and rerun main.dart and after that it raises following error:
Launching lib\main.dart on AOSP on IA Emulator in debug mode...
Running Gradle task 'assembleDebug'...
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'android'.
> Could not resolve all artifacts for configuration ':classpath'.
> Could not find sdk-common.jar (com.android.tools:sdk-common:26.5.0).
Searched in the following locations:
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.5.0/sdk-common- 26.5.0.jar
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
Finished with error: Gradle task assembleDebug failed with exit code 1
build.gradle file contains:
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
and settings.gradle contains:
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
I guess that freezing was because of poor connection at the moment of initializing and sdk-common.jar didn`t download correctly.
As I mentioned above, I'm new to flutter and I don't know how to clean build the project so I repeated step by step several times but error persists.
I have no idea about this problem.
Can anyone kindly help me?
Please tell me if details are not clear enough to understand.
What went wrong:
A problem occurred configuring root project 'android'.
Could not resolve all artifacts for configuration ':classpath'.
Could not find sdk-common.jar (com.android.tools:sdk-common:26.5.0).
add maven to your gradle file to solve this as follows
maven { url 'https://maven.google.com' }
although i would suggest you use API 28
I don't know how to clean build the project
run flutter clean in your project root folder

Android studio, gradle tries to download non existed sha1 from maven url

I am trying to add library to my project (this one)
I added proper url to build.gradle
repositories {
maven {
url "http://drgames.fr/maven2/"
}
mavenCentral()
}
Then I am trying to use it in project
implementation ('com.ramimartin.multibluetooth:AndroidMultiBluetoothLibrary:2.0.4-SNAPSHOT') {
exclude group: 'com.android.support'
exclude module: 'appcompat-v7'
exclude module: 'support-v4'
}
However, every time I sync project with gradle files, it tries to download metadata for all files under this maven url:
Metadata of http://drgames.fr/maven2/com/android/support/test/espresso/espresso-core/3.0.2/espresso-core-3.0.2.pom 186 ms
Download http://drgames.fr/maven2/com/android/support/test/espresso/espresso-core/3.0.2/espresso-core-3.0.2.pom.sha1 80 ms
Download http://drgames.fr/maven2/com/android/support/test/espresso/espresso-core/3.0.2/espresso-core-3.0.2.pom 71 ms
And the result is tons of errors, during downloading sha1 (but I still can run my app which uses described library and it works):
java.lang.NumberFormatException: For input string: "<html"
When I run building from command line (./gradlew build) there is no errors.
My questions are:
1) What is this magic sha1 file? Why it can't be downloaded and why gradle tries to do it everytime?
2) How to get rid off this errors?
this sha1 file most likely is a HTTP 404 page. just exclude com.android.support.test.espresso from that dependency and substitute it with the default one, from repository mavenCentral():
implementation "com.android.support.test.espresso:espresso-core:3.0.2"
implementation ("com.ramimartin.multibluetooth:AndroidMultiBluetoothLibrary:2.0.4-SNAPSHOT") {
exclude group: "com.android.support.test.espresso", module: "espresso-core"
exclude group: "com.android.support", module: "appcompat-v7"
exclude group: "com.android.support", module: "support-v4"
}

How to clear specific gradle cache files when running the "Clean project" command?

I have added the following task in my project's build.gradle file:
task('clearLibCache', type: Delete, group: 'MyGroup',
description: "Deletes any cached artifacts with the domain of com.test in the Gradle or Maven2 cache directories.") << {
def props = project.properties
def userHome = System.getProperty('user.home')
def domain = props['domain'] ?: 'com.test'
def slashyDomain = domain.replaceAll(/\./, '/')
file("${userHome}/.gradle/caches").eachFile { cacheFile ->
if (cacheFile.name =~ "^$domain|^resolved-$domain") delete cacheFile.path
}
delete "${userHome}/.m2/repository/$slashyDomain"
}
I'd like this task to be executed when I hit the "Clean project" menu, and only in this case.
How to do that ?
That "Clean project" menu item under the hood appears to do a couple of things (based on the output of the Gradle Console window when you click it):
A gradle clean, the equivalent of calling ./gradlew clean
Generate sources and dependencies for a debug build, including a mockable Android sources jar if needed.
I would make your task a dependency for the Gradle clean task, so that whenever the project is cleaned, this task is also invoked. This can be achieved by adding the line clean.dependsOn clearLibCache in your build.gradle after you declare the task.

Orchestrating Gradle build invocations with custom tasks

I’m trying to define two new Gradle tasks, buildAll and pubLocal, to run other tasks in a specific order.
When gradle buildAll is invoked, I want Gradle to do the same thing as if I had executed gradle clean build writePom (see below for writePom).
When gradle pubLocal is executed, I want Gradle to do the same thing as if gradle buildAll install had been executed.
Here’s my best attempt thus far:
// build.gradle
task writePom << {
pom {
project {
groupId 'mygroup'
artifactId 'mylib'
version version
inceptionYear '2015'
licenses {
license {
name 'Blah'
url 'blah'
distribution 'blah'
}
}
}
}.writeTo("build/libs/pom.xml")
}
task buildAll(dependsOn: clean, build, writePom)
task pubLocal(dependsOn: buildAll, install)
When I run gradle buildAll on this, I get:
myuser#mymachine:~/tmp/myapp$./gradlew buildAll
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/myuser/tmp/myapp/build.gradle' line: 67
* What went wrong:
A problem occurred evaluating root project 'myapp'.
> Could not find method buildAll() for arguments [{dependsOn=task ':clean'}, task ':build', task ':writePom'] on root project 'myapp'.
Any ideas as to where I’m going awry?
This may be a left-over from copy-pasting, but your strings are not quoted consistently using standard single- or double-quotes. Example:
}.writeTo(“build/libs/pom.xml")
does not quote the string properly, as it opens with the “ character instead of ". Same with the single-quotes above it.
You can see from the way your code is highlighted, that everything in red is interpreted as a string. If this is the case in your actual code, the buildAll and pubLocal tasks will not be recognized, as they are part of a string rather than code.
UPDATE:
Since the above answer is irrelevant now, here is another possibility. The error message shows that only the "clean" task is listed in the dependsOn parameter. The buildAll task dependencies should be declared like this:
task buildAll(dependsOn: [clean, build, writePom])
Similar with the pubLocal task.
I'm using Gradle 2.4. The following file includes the Maven plugin, uses a list [] in the dependsOn, and ensures that clean must be executed before build:
apply plugin: 'maven'
task writePom << {
pom {
project {
groupId 'mygroup'
artifactId 'mylib'
version version
inceptionYear '2015'
licenses {
license {
name 'Blah'
url 'blah'
distribution 'blah'
}
}
}
}.writeTo("build/libs/pom.xml")
println "TRACER writePom"
}
task clean << { println "TRACER clean" }
task build << { println "TRACER build" }
build.mustRunAfter clean
task install << { println "TRACER install" }
task buildAll(dependsOn: [clean, build, writePom])
task pubLocal(dependsOn: [buildAll, install])
I get this output (minus Gradle 3 warnings):
bash-3.2$ gradle buildAll
:clean
TRACER clean
:build
TRACER build
:writePom
TRACER writePom
:buildAll
BUILD SUCCESSFUL
and this:
bash-3.2$ gradle pubLocal
:clean
TRACER clean
:build
TRACER build
:writePom
TRACER writePom
:buildAll
:install
TRACER install
:pubLocal
BUILD SUCCESSFUL

Fixing Gradle Artifactory plugin publishing issue

I have a multi-project build that I am building with Gradle:
myapp/
myapp-client/
myapp-shared/
myapp-server/
build.gradle
settings.gradle
Where settings.gradle looks like:
include ':myapp-shared'
include ':myapp-client'
include ':myapp-server'
I have successfully got Gradle to compile my Groovy source code, run unit tests, generate GroovyDocs, and package both binary and source JARs for all 3 subprojects. The build invocation for which is: gradle clean build groovydoc sourcesJar -Pversion=<whatever version I specify>.
I am now attempting to add the Gradle-Artifactory plugin such that:
All 3 subprojects get POMs generated for them; and
All 3 subproject binary JARs, POMs and source JARs get published to my locally-running Artifactory; and
The artifactoryPublish task executes whenever gradle build is invoked
Here's my best attempt (my complete build.gradle):
allprojects {
buildscript {
repositories {
maven {
url 'http://localhost:8081/artifactory/plugins-release'
credentials {
username = "admin"
password = "password"
}
name = "maven-main-cache"
}
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
}
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: "com.jfrog.artifactory"
version="0.0.1"
group = "mygroup"
repositories {
mavenCentral()
add buildscript.repositories.getByName("maven-main-cache")
maven {
url "http://localhost:8081/artifactory/mydev-snapshots"
}
}
artifactory {
contextUrl = "http://localhost:8081/artifactory"
publish {
repository {
repoKey = 'mydev-snapshots'
username = "admin"
password = "password"
maven = true
}
defaults {
publications ('mavenJava')
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
rootProject {
artifactoryPublish.skip=true
}
subprojects {
apply plugin: 'groovy'
apply plugin: 'eclipse'
sourceCompatibility = '1.7'
targetCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
repositories {
mavenLocal()
mavenCentral()
maven {
url "https://repository.apache.org/content/repositories/snapshots"
}
maven {
url "http://localhost:8081/artifactory/mydev-snapshots"
}
maven {
url "https://code.google.com/p/guava-libraries/"
}
}
dependencies {
compile (
'org.codehaus.groovy:groovy-all:2.3.7'
)
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
build(dependsOn: 'artifactoryPublish')
}
When I run gradle clean build groovydoc sourcesJar -Pversion=0.1.1, I get the following command line exception:
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\Users\myuser\sandbox\eclipse\workspace\myapp\build.gradle' line: 14
* What went wrong:
A problem occurred evaluating root project 'myapp'.
> You can't change a configuration which is not in unresolved state!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.589 secs
My question: what is going on here, and what do I need to do (specifically) to fix it and get the Artifactory plugin publishing?
Bonus question: I'm specifying version number in 2 places (the build invocation as well as inside the build.gradle file. I want to specify version number only via the build invocation. How do I configure artifactoryPublish (or rather, the Gradle-Artifactory plugin) to accept the version I specify from the command-line?
Number of issues here:
buildscript should be top-level block, not inside allprojects
When using Artifactory, you don't need to specify any other repositories except of Artifactory (don't need mavenCentral())
If you want to use artifactoryPublish you need to configure the Artifactory plugin. Here are the docs and here are two fully working examples of multi-module Gradle projects: 1 and 2. Some highlights:
You need to apply maven or maven-publish plugin.
You need to add the produced artifacts to configuration or publication accordingly.
You need to configure the plugin with Artifactory instance you are working with, provide resolution and deployment repository names, credentials (usually for deployment only) and specify which configuration or publication you want to publish.

Resources