Accessing Teamcity build number in Gradle build script - properties

How can I access the build number and VCS checkout number in a Gradle script executed by Teamcity?
In Ant I can use ${build.number} and ${build.vcs.number.1} respectively.
Thank you.

These are simply JVM system properties that TeamCity sets for the Ant/Gradle JVM. You can access them with the usual Java means, for example System.getProperty("build.number").

If you are developing Android application you can access build.number to update apk file name accordingly:
defaultConfig {
applicationId "com.mydemoci"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "0.7"
ext.buildNumber = System.getProperty("build.number") ?: "Regular"
archivesBaseName = "$applicationId-v$versionName-b$buildNumber"
}
To test locally just run gradlew clean build -Dbuild.number=123

I tested with many cases with gradle and injecting build.number outside variables. In my case, I use docker as a build environment so teamcity-provided environment does not be injected successfully.
There are two possibilities to inject variables to gradle. Note that -D and -P differences in below example.
// 1. gradle build -Pbuild.number=555
aaa = rootProject.properties.get("build.number")
// 2. gradle bulid -Dbuild.number=444
bbb = System.getProperty("build.number")
gradle --help says [option] task as a command order but task [option] works.
An example build.gradle script is as below;
ext {
buildNumber = (rootProject.properties.get("build.number") as Integer) ?: 1
}
android {
defaultConfig {
versionCode project.buildNumber
versionName "1.3.7." + project.buildNumber.toString()
}
In my case, I want to use build.number as a android versionCode, so parsing to Integer is required with :? null treatment.

As of TeamCity 9.1.5 this is changed. "Properties" (both "system" and "teamcity" ) properties are set as project ext properties.
https://confluence.jetbrains.com/display/TCD9/Defining+and+Using+Build+Parameters+in+Build+Configuration
Very confusing when reading the overveiw page https://confluence.jetbrains.com/display/TCD9/Configuring+Build+Parameters#ConfiguringBuildParameters-ConfigurationParameters the use of "system" (in "system properties") had me thinking they were set as JVM System properites so I tried the Gradle mechanism as described here: https://docs.gradle.org/current/userguide/build_environment.html
which says to use "org.gradle.project." .. adding that with TeamCity that says to use "system." I tried to set a gradle property "repositoryUrl" as "system.org.gradle.project.repositoryUrl" ...
This didn't work. adding "properties" to the gradle command in team city showed that there was a gradle property called "org.gradle.project.repositoryUrl"
By trial and error I stumbled on the obvious ... and was about to report it as a docs bug .. but then found it in the documentation
Summary: In TeamCity 9.1.5+ use
system.<propertyName>
e.g.
system.repositoryUrl
In Gradle these are accessable as rootProject (or project) "properties" (not "system properties" ... e.g.
println repositoryUrl
println project.repositoryUrl
println rootProject.repositoryUrl
println project.properties["repositoryUrl"]
println rootProject.ext.repositoryUrl
println "${repositryUrl}"
assert hasProperty("repositoryUrl")
and the 500 other ways of doing the same thing.

Related

My react native android app is not running/working after new updates of android studio

I have a live react native app, which was working fine. But now I need to made some changes to it but I am unable to do so after new updates and new gradle version. I have tried on multiple PCs and workspaces but all are of no use same error on every system pops up. giving some errors which are as under and attached screenshot.
FAILURE: Build failed with an exception.
The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build.
This might happen in subprojects that apply the Kotlin plugins with the Gradle 'plugins { ... }' DSL if they specify explicit versions, even if the versions are equal.
Please add the Kotlin plugin to the common parent project or the root project, then remove the versions in the subprojects.
If the parent project does not need the plugin, add 'apply false' to the plugin line.
See: https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
The Kotlin plugin was loaded in the following projects: ':react-native-alarm-clock', ':react-native-webview'
What went wrong:
Execution failed for task ':invertase_react-native-apple-authentication:compileDebugKotlin'.
Screenshot of the error
another Screenshot of the error
I have a live react native app, which was working fine. But now I need to made some changes to it but I am unable to do so. I have tried on multiple PCs and workspaces but all are of no use same error on every system pops up.
add kotlin version in you android/build.gradle
buildscript {
ext {
...
kotlin_version='1.6.0' //add This change version with your installed kotlin version
...
}
repositories {
google()
mavenCentral()
}
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" //add This
...
}
}
Just go to build.gradle(Project:yourProjectName)
change
Plugin {
...
id 'org.jetbrains.kotlin.android' version '1.4.x' apply false
...
}
To
Plugin {
...
id 'org.jetbrains.kotlin.android' version '1.6.0' apply false
...
}

alternate way to set Build and run using IntelliJ IDEA

I am working with Java source code with TestNG and frequently see errors like no test found to run OR Test event were not received whenever I try to run test cases in IntelliJ IDEA.
Which I can fix with changing Build and run using IntelliJ IDEA from Gradle.
I am looking for alternative way using which can add this somewhere as configuration instead of going and changing this manually.
You can use gradle-idea-ext-plugin to set build and run actions right in the Gradle build script:
import static org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.CHOOSE_PER_TEST
plugins {
...
id "org.jetbrains.gradle.plugin.idea-ext" version "1.0"
...
}
idea.project.settings {
delegateActions {
delegateBuildRunToGradle = true // Delegate Run/Build to Gradle
testRunner = CHOOSE_PER_TEST // Test execution: PLATFORM, GRADLE or CHOOSE_PER_TEST
}
}
But actually, the fact that it works with IDE runner, but does not work with Gradle runner may indicate problems. I would first check if it works from the command line Gradle - make sure you run the same test with it as from the IDE. If it works in terminal but does not work in IDE, I would report a bug at YouTrack with reproducible sample.

NoClassDefFoundError: com/android/build/gradle/internal/ToolingRegistryProvider

I have an Android project that is now failing to build:
FAILURE: Build failed with an exception.
* Where:
Build file 'build.gradle' line: 28
* What went wrong:
A problem occurred evaluating root project 'X'.
> java.lang.NoClassDefFoundError: com/android/build/gradle/internal/ToolingRegistryProvider
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
The project was building fine with the following dependencies:
'com.android.tools.build:gradle:2.1.3'
'com.android.tools.build:gradle-experimental:0.7.3'
A coworker applied the updates offered by AndroidStudio. That changed the plugin versions to:
'com.android.tools.build:gradle:2.2.0'
'com.android.tools.build:gradle-experimental:0.8.0'
After this update, the project builds successfully on his development machine
(Windows 7) and on mine (Ubuntu 16.04). The error occurs on the Jenkins build
server (Ubuntu 16.04). I installed the available updates to the Android SDK components on the build server but the error persists.
A google search for "ToolingRegistryProvider" returns "Your search matches no documents".
The problem was resolved by deleting gradle's module cache on the build server and then letting the build re-download everything.
rm -r ~/.gradle/caches/modules-2
Adding my solution to this issue: I added jcenter() to the top-level repositories tag.
We use a Nexus server that hosts lots of libraries we use here at work. So when it tried to update the gradle plugin version, it tried to do so from the Nexus server and for some reason, the update pulled the correct version but with some changes, making the gradle version and the gradle plugin version not to be in sync. So by adding jcenter() the gradle plugin was updated correctly and this error vanished.
This error can come from not having the Google Maven Repository as a repository in your build.gradle file:
allprojects {
repositories {
google()
// If you're using a version of Gradle lower than 4.1, you must instead use:
// maven {
// url 'https://maven.google.com'
// }
// An alternative URL is 'https://dl.google.com/dl/android/maven2/'
}
}
See this link for more information.
I had the same experience with JetpackCompose compose multiplatform Project structure
android/
|
- build.gradle.kts
desktop/
|
- build.gradle.kts
common/
|
- build.gradle.kts
buildSrc/
|
- build.gradle.kts
Common required id("com.android.library")
But was getting NoClassFound errors
I had to add
buildSrc/build.gradle.kts
// ...
repositories{
mavenLocal()
mavenCentral()
google()
}
dependencies{
compileOnly("com.android.tools.build:gradle:7.0.4")
}
// ...
Also, make sure to have.
google() in the allprojects section or in specific build.gradle.kts files.
Class might actually be missing.

Gradle - Jacoco - JMockit - Tests are hanging not progressing

I'm using Gradle (Gradle 1.6 -upto 1.9) to build a Java project. Tried with both Java 1.6 or 1.7.
src/java - contains Java source code
test/java - contains test java code
Project compiles/builds successfully. During the build time, Junit UNIT test(s) runs successfully as well. I have only one test and it uses JMockit library. Please NOTE: This same jacoco code works fine in any other project where I don't have test which needs JMockit library.
JMockit groupid:artifactid:version is:
jmockit:jmockit:1.1
I wanted to have Jacoco code coverage enabled. Jacoco version that I have tried so far is shown in the code below, this code exists in my Gradle build script.
I added the following lines to my project's build.gradle file.
apply plugin: 'jacoco'
jacoco {
//toolVersion = "0.6.2.201302030002"
toolVersion = "0.7.0.201403182114"
//toolVersion = "0.7.1.201404171759" --- trying to find how to make version this working.
// reportsDir = file("$buildDir/customJacocoReportDir")
}
test {
ignoreFailures = true
testReportDir = file("$buildDir/reports/tests/UT")
testResultsDir = file("$buildDir/test-results/UT")
// Uncomment the following if you need more detailed output.
//testLogging.showStandardStreams = true
//onOutput { descriptor, event ->
// logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message )
//}
//Following Jacoco test section is required only in Jenkins instance extra common file
jacoco {
//The following vars works ONLY with 1.6 of Gradle
destPath = file("$buildDir/jacoco/UT/jacocoUT.exec")
classDumpPath = file("$buildDir/jacoco/UT/classpathdumps")
//Following vars works only with versions >= 1.7 version of Gradle
//destinationFile = file("$buildDir/jacoco/UT/jacocoUT.exec")
// classDumpFile = file("$buildDir/jacoco/UT/classpathdumps")
}
}
task integrationTest( type: Test) {
//Always run tests
outputs.upToDateWhen { false }
ignoreFailures = true
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
testReportDir = file("$buildDir/reports/tests/IT")
testResultsDir = file("$buildDir/test-results/IT")
//Following Jacoco test section is required only in Jenkins instance extra common file
jacoco {
//This works with 1.6
destPath = file("$buildDir/jacoco/IT/jacocoIT.exec")
classDumpPath = file("$buildDir/jacoco/IT/classpathdumps")
//Following works only with versions >= 1.7 version of Gradle
//destinationFile = file("$buildDir/jacoco/IT/jacocoIT.exec")
// classDumpFile = file("$buildDir/jacoco/IT/classpathdumps")
}
}
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
ignoreFailures = true
executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')
reports {
xml{
enabled true
//Following value is a file
destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
}
csv.enabled false
html{
enabled true
//Following value is a folder
destination "${buildDir}/reports/jacoco/html"
}
}
//sourceDirectories = files(sourceSets.main.allJava.srcDirs)
sourceDirectories = files('src/java')
classDirectories = files('build/classes/main')
//------------------------------------------
//additionalSourceDirs = files('test/java')
//additionalSourceDirs += files('src/java-test')
//additionalClassDirs = files('build/classes/test')
//additionalClassDirs += files('build/classes/integrationTest')
//additionalClassDirs += files('build/classes/acceptanceTest')
//------------------------------------------
}
My questions:
1. When I'm not using "apply plugin: 'jacoco'", then :test task runs successfully (I have only one test). BUT, when I enable apply plugin: 'jacoco', then during :test task, I see the following line during build output and the process just hangs there and sits for hours and doesn't proceed.
Starting process 'Gradle Worker 1'. Working directory: /production/jenkinsAKS/workspace/MyProjectSvc Command: /production/jdk1.6.0_03/bin/java -Djava.security.manager=jarjar.org.gradle.processinternal.child.BootstrapSecurityManager -javaagent:build/tmp/expandedArchives/org.jacoco.agent-0.7.0.201403182114.jar_2kiqpmj1hlqbuth11j0qnuarhs/jacocoagent.jar=destfile=build/jacoco/UT/jacocoUT.execappend=true,dumponexit=true,output=file,classdumpdir=build/jacoco/UT/classpathdumps,jmx=false -Dfile.encoding=UTF-8 -ea -cp /production/jenkins/.gradle/caches/1.6/workerMain/gradle-worker.jar jarjar.rg.gradle.process.internal.launcher.GradleWorkerMain
An attempt to initialize for well behaving parent process finished.
Successfully started process 'Gradle Worker 1'
Gradle Worker 1 executing tests.
> Building > :test
I googled around and it seems like there's some incompatibility between Jacoco and JMockit libraries in the current latest version and there's a fix coming to get this issue resolved. The new version of Jacoco 0.7.1.xxxxx has the fix but I don't know when it'll be available in Maven repository.
Any idea, how can I set the javaagent to ignore the test/test class file for JACOCO and still apply jacoco plugin. In my case, apply plugin: 'jacoco' will later exist in a global file i.e. inside /init.d/global-common.gradle file within allProjects { .... } section.
I tried the following but still, the build process hangs at :test task until I uncomment exclude below. If I comment out the whole jacoco subsection within test section, build process still hangs at :test task (seems like as apply plugin: 'jacoco' is there). If I uncomment exlude, then I don't see error but then no test runs i.e. index.html for test reports shows nothing ran.
test {
include "**/*"
jacoco {
//exclude "**/util/Test*"
}
}
2. How can I use the jacoco 0.7.1.xxxx version (non-release aka nightly release which has the fix for this issue) in my build.gradle file. When I used 0.7.1.xxx version after uncommenting it (as shown above), it errored out saying can't find dependency jacoco:0.7.1.xxxx
3. To get rid of this issue, I think I can set a jacoco agent parameter i.e. when it runs, it'll ignore the JMOckit/JUnit .jar library or something. See/Found the following links:
http://javaee.ch/2012/10/09/jmockit-with-maven-sonar-jacoco-and-jenkinshudson/
https://github.com/jacoco/jacoco/pull/35
Acc. to the second link:
A workaround which avoids the problem is to exclude the JUnit classes from JaCoCo's consideration. I used the following JVM initialization parameter in my testing, excluding both JUnit and TestNG classes: -javaagent:/jacoco-0.7.1/lib/jacocoagent.jar=excludes=junit.:org.junit.:org.testng.
The good news is that the fix I described in my previous comment also solves this deadlock problem, because then the JUnit classes will be ignored by JaCoCo as they get instrumented by JMockit.
I'm trying to find what variable in jacoco { ... } or within test { ... } I can set to do the same until I get the new version of Jacoco or JMockit (which has the fix). Seems like it's within test section i.e. test { ..here jvmArgs '...'will be set. jacoco { ... } .. }
http://stevendick.github.io/blog/2012/01/22/jacoco-and-gradle/
4. If I exclude the test class file by using "exclude "com/xxx/yyy/a/b/c/util/Testname.class", then it works and I don't see an error but then I found that due the this exclude, my test never run!!!
that's why it didn't hang. Well, I want the test to run and don't want Jacoco to process it.
Just by having apply plugin: 'jacoco' in build.gradle is hanging the build at :test task. I need jacoco as Development team would like to see the code coverage details as well.
At this time, I'm trying to find answers to the above ?s, appreciate your inputs.
Final answer:
Both Jmockit and Jacoco instruments the class files. Jmockit does it first during the build process and when jacoco tries the same (later in the process) it says "oh oh, can't instrument an already instrumented class file". This issue happened with older versions of jacoco and jmockit. To see this error, enable --stacktrace option during Gradle build or --debug.
Now, using the latest jacoco and jmockit versions, we can solve this issue easily.
If you use jacoco:
toolVersion="0.7.1.201405082137"
or
toolVersion="0.7.2.201409121644"
See this: changes that went in 0.7.1 version
http://www.eclemma.org/jacoco/trunk/doc/changes.html
For JMockit, you have to use jmockit version: 1.8 at least or later (1.9 to 1.13).
org.jmockit:jmockit:1.8
See this: changes that went under 1.8 version: http://jmockit.github.io/changes.html
Answer 1: Setting jacoco subsection (within test section) -- enabled field to "false" did the trick. I'm not getting the code coverage (which I can live with until I get the new versions out for both JMockit / Jacoco) but now I see valid test report index.html file (i.e. test ran successfully) and still apply plugin: 'jacoco' can stay effective in /init.d/global-common.gradle file ...
test {
jacoco {
enabled false
}
}
For Answer 2: NOT found so far, will share.
Answer 3: Didn't resolve the error - but how you set it up is given at the link: http://stevendick.github.io/blog/2012/01/22/jacoco-and-gradle/
I tried giving, may be I didn't use it correctly. jvmArgs '....: ,....:.. ,....:....,exclude="com.:org.gradle.;jmockit.:mockit.:junit.*"
Answer 4: Answer 1 will suffice.
I'm not too familiar with gradle, so I'm not sure I can help with questions 1, 3, or 4...
But question 2, I can help - the version string for JaCoCo 0.7.1 is not 0.7.1.201404171759 but rather 0.7.1.201405082137. This version has been formally released, in case you hadn't noticed.
If you want the latest nightly build, the convention is to simply refer as 0.7.2-SNAPSHOT (make sure you are pointing at the snapshot repository at https://oss.sonatype.org/content/repositories/snapshots/).

Android Studio: How to attach javadoc

It might be very trivial question, But I couldn't find any option to attach javadoc/source with local jar dependencies (in libs folder) in android project. I can't believe I have spent a hour on such simple stuff :(
Google search result just tells about adding android documentation or adding javadoc in eclipse. That's not What I am looking for!
I found a solution just now since I can't find any other solution for a long time.
suppose:
your lib name is: libxxx.jar
javadoc name is docs.zip
under folder .idea/libraries, you can find libxxx.xml. replace JAVADOC with
<JAVADOC>
<root url="jar://C:/yourpath/doc.zip!/" />
</JAVADOC>
then ctrl+alt+y to sync the project. (Don't do "Sync Project with Gradle files", it will delete the changes)
I've found & tested a way in which we can add the javadocs without loosing them after a gradle sync.
Right click in Project panel > External libraries > lib-name
Click Library properties
Click specify documentation URL
And specify an URL. For my machine it was file:///opt/android-sdk/extras/google/google_play_services/docs/reference
The result was:
And after a project sync I could browse the javadoc of the google play services
Note:
This placed the same JAVADOC entry in the xml identified by Jason but doesn't disappear after doing a sync with gradle
It is possible:
Open Project structure
Navigate to dependency that you want
Press button from the screenshot and provide folder or file
Another way to attach sources:
Step into class from library (Hover mouse over class name and do CMD + Left click or CMD + B)
You will see decompiled version of class there menu on the top right side of editor "Attach sources.."
I had problem with answer from Matyas that I wasn't seeing my local .jar library in the External Libraries list, because it only show maven attached libs.
Solution is mentioned here: https://code.google.com/p/android/issues/detail?id=73087#c26
Right click on the "Structure" tab and check "Split Mode" (so you can open both "Project" and "Structure" tabs at same time).
Open both "Project" and "Structure" tabs at the same time.
In "Project" tab select "Android" perspective and then select your module folder (e.g. "app")
In "Structure" window you should now see list of all libraries, including your local *.jar
Continue as in answer from Matyas:
Right click on wanted library and select "Library Properties..."
If you have *.jar with javadocs locally, you can press "add" button (green "+") and search for the file on your disk (you don't have to type "file://" path manually).
Still a current issue as of my posting it seems:
https://code.google.com/p/android/issues/detail?id=73087
After some investigation, I stumbled upon this:
https://github.com/xujiaao/AARLinkSources
Works like magic!
I wasted so much time on this too...
Here's a gradle task which finds source and javadoc by location/naming convention, and registers them in the .idea files on sync. It belongs in the root gradle file's allProjects section. As-is, it expects to find [projectname]/libs/lib.jar next to lib-sources.jar and/or lib-javadoc.jar. Also, as noted in comments, if your javadocs not pathed at "/" inside the jar, you may need to change the script to add "docs/html" (for example) at the end of "jar://$doc!/".
allprojects {
task addJavaDoc {
afterEvaluate {
// Specify paths, this will be run per non-root project
def projectDir = project.getProjectDir().getCanonicalPath()
def rootDir = project.getRootDir().getCanonicalPath()
def lib = projectDir + '/libs'
// println lib // Uncomment this to troubleshoot
// Get any jar dependencies register in the lib folder
fileTree(include: ['*.jar'], exclude: ['*-source.jar', '*-javadoc.jar'], dir: lib ).each { File jar ->
def jarName = jar.getName()
def moduleName = jarName.substring(0, jarName.lastIndexOf("."))
// IntelliJ does this to file names when making the xml files
def escapedName = moduleName.replace("-", "_").replace(".", "_")
def xmlFile = "$rootDir/.idea/libraries/${escapedName}.xml"
// println xmlFile // Uncomment this to troubleshoot
if (new File(xmlFile).exists()) {
['javadoc', 'sources'].each {String docType ->
// Get sources or java doc by naming convention, (expects name-sources or name-javadoc
def doc = "$lib/$moduleName-${docType}.jar"
// println doc // Uncomment this to troubleshoot
if(new File(doc).exists()) {
def xml = new XmlParser().parse(xmlFile);
def xmlTag = docType.toUpperCase()
// Perform xml replacement by convention
xml.library[xmlTag].replaceNode {
"$xmlTag" {
root(url: "jar://$doc!/")
}
}
// Write out changes
new XmlNodePrinter(new PrintWriter(new FileWriter(xmlFile))).print(xml)
// Notify that changes worked
println "Fixed up reference to $doc"
}
}
}
}
}
}
}
Also, if you are using jcenter or mavencentral, javadocs and sources should work for downloaded jars without using that task, but you may have to add this in each non-root gradle file:
apply plugin: 'idea'
idea{
module {
downloadJavadoc = true
downloadSources = true
}
}
Personally tested successfully!
1.Project Structure(ctrl+alt+shift+s)
2.SDK Location
3.JDK Location
4.UnCheck "Use embedded JDK(recommended)"
5.Select your own jdk path(My Path:C:\Program Files\Java\jdk1.8.0_111)
6.Synchronized(ctrl+alt+y)
success
in android studio if you use compileSdkVersion 23 in buidl.gradle and you have downloaded the SDK 23 document file and source file in SDK manager , the android API and java API doc and source will all show auto, you don't need to manual set.
There is a solution, This procedure take place through terminal ,
I have tested solution in MAC OS.
1) Move to your project folder
2) ls -al (to show hidden files)
3) Move to .idea folder , Command : cd .idea
4) Move to libraries folder , Command : cd libraries/
5) Now you can see list of all xml files for your libs or jars. Edit it like , vi open androidasync_2_1_7.xml
6) In the editor screen ,
For inserting
Press i
Now you see <SOURCES /> tag we have to provide a path here like,
<SOURCES>
<root url="file://$PROJECT_DIR$/androidasync/src/main/java" />
</SOURCES>
For exiting
Press Esc
:wq //for exiting and saving
:q! //for exiting without saving
7) Restart Android studio (Sometime it needed also sync gradle).