A bit of Context first:
I am working on migrating my companies projects to be built by Gradle.
One thing, that this results in, is having redundancy in my build.gradle files,
as I am configuring the same Skeleton over and over again.
This includes:
Setting the java-,maven-publish- and org.sonarcube-plugin
Configuring the repositories to be mavenCentral and our private Artifactory Repo
Configuring the publishing block, that is all the same, except for the artifactId
Building a Manifest inside the Jar block (using helper Methods, to correctly build the Manifests classpath)
Helper Methods
two Tasks
two dependsOn statements
build.gradle file as of now:
plugins {
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id "org.sonarqube" version "3.2.0"
id 'maven-publish'
id 'java'
}
group = 'group'
version = 'version'
sourceCompatibility = '11'
ext.artifactName = 'ProjectName'
// Where to look for dependencies:
repositories {
mavenCentral()
maven{
credentials{
username = "${artifactory_user}"
password = "${artifactory_password}"
}
url "${artifactory_contextUrl}"
allowInsecureProtocol = true
}
}
// Where to publish what Artifacts to:
publishing {
publications {
maven(MavenPublication) {
groupId = 'group'
artifactId = 'ProjectName'
String buildEnvVar = System.env.BUILDENVIRONMENT
if(buildEnvVar == null){
version = 'LOCAL BUILD'
}else{
version = 'version'
}
from components.java
}
}
repositories {
maven {
// change to point to your repo, e.g. http://my.org/repo
name = "gradle-dev"
url = "${artifactory_contextUrl}"
allowInsecureProtocol = true
credentials{
username = "${artifactory_user}"
password = "${artifactory_password}"
}
}
}
}
dependencies {...}
jar {
// configuration of variables
String dateString = new Date().format("yyyy-MM-dd HH:mm:ss ")
String localBuild = "LOCAL BUILD by " + System.getProperty("user.name") + " on " + dateString
String buildEnvVar = System.env.BUILDENVIRONMENT
String buildEnvironment
String classpath = createCP()
if(buildEnvVar == null){
buildEnvironment = localBuild
archiveName = "ProjectName"
}else{
buildEnvironment = buildEnvVar
archiveFileName= "ProjectName_" + version + ".jar"
delete fileTree("build/libs") {
include('*')
}
}
manifest {
attributes (
"Main-Class": "org.example.foo",
"Specification-Title" : "ProjectName",
"Specification-Vendor" : "blab",
"Specification-Version" : "Spec-version",
"Implementation-Title" : "$System.env.JOB_NAME",
"Implementation-Version" : "Impl-version",
"Implementation-Vendor" : "blub",
"Implementation-Vendor-Id" : "blob",
"Implementation-Url" : "bleb",
"Build-By" : buildEnvironment,
'Class-Path': classpath
)
}
}
String createCP () {
// super secret can't share
}
// will suffix the jars with release or debug, depending on it being compiled with or without debug-information
project.gradle.taskGraph.whenReady{
boolean isDebug = project.gradle.taskGraph.getAllTasks().join(' ').contains('debugJar')
compileJava.options.debug = isDebug
String suffix = isDebug? "debug" : "release"
String fullJarName = "$artifactName-$suffix" + ".jar"
jar.setProperty('archiveName', fullJarName)
}
tasks.named('test') {
useJUnitPlatform()
}
task debugJar() {}
debugJar.dependsOn(jar)
//Downloads all Jars the project depends on, and saves them in buildDirectory/output/libs if the gradle build command is executed.
task copyToLib(type: Copy) {
into "${buildDir}/output/libs"
from configurations.runtimeClasspath
}
build.dependsOn(copyToLib)
what I want to achive:
plugins {
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id "org.sonarqube" version "3.2.0"
id 'maven-publish'
id 'java'
id 'mySuperPlugin'
}
// Configure mySuperPlugin
mySuperPlugin {
artifactId = 'xyz'
mainClass = 'org.example.foo'
version = 'version'
stuffFromOtherTasks = ...
}
// Where to look for dependencies:
repositories {
mavenCentral()
maven{
credentials{
username = "${artifactory_user}"
password = "${artifactory_password}"
}
url "${artifactory_contextUrl}"
allowInsecureProtocol = true
}
}
dependencies {...}
Most of the values are the same.
The ones that aren't are passed in via Environment-Variables (Jenkins-JobName,...),
or get determined through helper Methods.
I reckon, that i will most likely not end up with a buildfile like the one above,
but atleast some of the buildfile must be outsourceable.
I know as of now, that i can create seperate Tasks in a plugin, like comparing two files, that have been passed. What I didn't find a solution to yet:
Can I modify the Jar Task of the project applying the plugin, inside the plugin?
How do I pass Outputs from other Tasks into my plugins tasks?
How do I access the applying projects data (i.e. the runtimeClasspath)
Is a plugin even what i want to do, or is there another way of cutting down the build.gradle file?
I am relatively unexperienced with gradle. I have read through quite a bit of the docs and other postings, but chances are i just overlooked some best-practice way of doing certain things.
Therefore, feel free to criticize my buildfile aswell as my approach!
You can do this in a couple of ways. And this comes down to if your project is composed of multiple sub-projects or if they are stand alone projects. For stand alone projects you can do the following in your settings.gradle file:
includeBuild("../common-project/build.gradle")
The common project would just house the common build.gradle file, and you'd declare all of the items you want to share in there. It would look like a normal build.gradle file.
That would require that each project share the common configuration from another project, but wouldn't require any additional projects be checked out. Just the common project and the project itself. For more details see:
https://docs.gradle.org/current/userguide/composite_builds.html
If you have more of a multi-project build like say many micro-services or subprojects that make up a larger project then using multi-project setup and declare the common pieces in the allprojects closure in the root build.gradle:
allprojects {
plugin: java
plugin: web
repositories {
....
}
dependencies {
....
}
}
In the multi-project case you'd have to check out the top level project and all subprojects. Your folder layout might look like this:
- my-project
- service-1
src
build.gradle
- service-2
src
build.gradle
- service-3
src
build.gradle
build.gradle
settings.gradle
In the multi-project setup service1, service2, and service3 would be declared in the settings.gradle file using include like so:
rootProject.name = 'my-project'
include `service1`
include `service2`
include `service3`
In a multi-project setup you'd typically house that in a single source repository as oppose to using includeBuild where each project would belong to a separate source code repo. The former way forces you to checkout the appropriate number of projects in the multi-project case. But, in the includeBuild case the developer would have to know to check out minimum of 2 projects.
Related
I was implementing the cuberto liquid swipe animation in my app and after adding the github.properties and the dependencies as I added the code to build.gradle inside the app module that will be using the library. Then compile and run the app, it was giving an error - Could not GET 'https://maven.pkg.github.com/Cuberto/liquid-swipe-android/com/cuberto/liquid-swipe/1.0.0/liquid-swipe-1.0.0.aar'. Received status code 400 from server: Bad Request
Disable Gradle 'offline mode' and sync project ..
here is my build.gradel code -
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
def githubProperties = new Properties()
githubProperties.load(new FileInputStream(rootProject.file("github.properties")))
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Cuberto/liquid-swipe-android")
credentials {
/** Create github.properties in root project folder file with
** gpr.usr=GITHUB_USER_ID & gpr.key=PERSONAL_ACCESS_TOKEN
** Or set env variable GPR_USER & GPR_API_KEY if not adding a properties file**/
username = githubProperties['gpr.usr'] ?: System.getenv("GPR_USER")
password = githubProperties['gpr.key'] ?: System.getenv("GPR_API_KEY")
}
}
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
here is the ss of the actual code given in the github.
enter image description here
and this the link to the github page of cuberto - https://github.com/Cuberto/liquid-swipe-android
Please help me I am unable to solve this past 3 days
Okay, thanks for waiting. I have modified some Gradle files for easy importing in which you no need to generate tokens etc. Here is my forked and modified library. Any clarification feel free to comment and contact me.
Update based on your comment,
Step 1:
Make sure you have removed following code from root build.gradle,
def githubProperties = new Properties()
githubProperties.load(new FileInputStream(rootProject.file("github.properties")))
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Cuberto/liquid-swipe-android")
credentials {
/** Create github.properties in root project folder file with
** gpr.usr=GITHUB_USER_ID & gpr.key=PERSONAL_ACCESS_TOKEN
** Or set env variable GPR_USER & GPR_API_KEY if not adding a properties file**/
username = githubProperties['gpr.usr'] ?: System.getenv("GPR_USER")
password = githubProperties['gpr.key'] ?: System.getenv("GPR_API_KEY")
}
}
}
Step 2:
In Android Studio->File->Invalidate Caches/Restart...->Invalidate and Restart(From popup dialouge)
I am trying to figure out how to consume the *.{so,jar} files listed in https://repo1.maven.org/maven2/org/sosy-lab/javasmt-solver-z3/4.8.10/ (see also the corresponding entry on mvnrepository.com) as exemplified (with Maven) here, with Gradle 6.8.3 and a Kotlin configuration. Relevant parts of my code are
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation(group = "org.sosy-lab", name = "javasmt-solver-z3", version = "4.8.10", classifier = "com.microsoft.z3", ext = "jar")
implementation(group = "org.sosy-lab", name = "javasmt-solver-z3", version = "4.8.10", classifier = "libz3", ext = "so")
implementation(group = "org.sosy-lab", name = "javasmt-solver-z3", version = "4.8.10", classifier = "libz3java", ext = "so")
}
The output I get is
Could not resolve org.sosy-lab:javasmt-solver-z3:4.8.10.
I already tried (1.) commenting out any two out of the three dependencies, (2.) reordering the repositories. The output is the same. What am I doing wrong here?
Gradle searches for a pom.xml per default and it fails because some of the JavaSMT artifacts don't have any (or no useful ones).
You can however tell Gradle to search for artifacts directly.
To do this you need to add a metadataSource to your repo like so:
repositories {
jcenter()
mavenCentral {
metadataSources {
artifact()
}
}
}
I'm new to Gradle and attempting to publish a simple project to Maven Central. My build.gradle script is nearly identical to the example in their documentation but my primary/compiled JAR is not being uploaded. Source JAR, Javadoc JAR, etc. are uploading fine but not the compiled one.
When publishing local via publishToMavenLocal everything works as expected. I'll note that I'm using version 6.0.1 and using publishMavenJavaPublicationToMavenRepository to publish to Central.
What am I missing? How can I get my compiled JARs to Central?
Update: I just realized that the POM isn't being uploaded either.
Here is the complete build.gradle:
plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.0.1'
implementation 'com.squareup.moshi:moshi:1.9.1'
implementation 'com.squareup.moshi:moshi-adapters:1.9.1'
implementation 'com.google.guava:guava:28.0-jre'
api 'org.apache.commons:commons-math3:3.6.1'
testImplementation 'junit:junit:4.12'
}
group = 'com.acme'
version = '0.0.1-SNAPSHOT'
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
java {
withJavadocJar()
withSourcesJar()
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'thttpd'
from components.java
pom {
name = 'thttpd'
licenses {
license {
name = 'The MIT License (MIT)'
url = 'https://opensource.org/licenses/MIT'
}
}
scm {
connection = 'scm:git:https://acme.com'
developerConnection = 'scm:git:https://acme.com'
url = 'https://acme.com'
}
}
}
}
repositories {
// Maven Central
maven {
def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
url = isReleaseVersion ? releasesRepoUrl : snapshotsRepoUrl
credentials {
username = nexusUsername
password = nexusPassword
}
}
}
}
signing {
required { isReleaseVersion && gradle.taskGraph.hasTask("publish") }
if( required ) {
sign publishing.publications.mavenJava
}
}
I had the same issue that Alexis mentions above, on the GitHub Packages web UI the sources and java-doc where not showing up. But on s01.oss.sonatype.org I was able to see them. Using Gradle 6.7
I'm compiling a 1.12.2 minecraft mod with ./gradlew build and when "running" (not sure what to call it) :reobfJar an error comes up
* What went wrong:
Execution failed for task ':reobfJar'.
> java.util.zip.ZipException: duplicate entry: assets/rm/textures/blocks/copper_ore.png
My build.gradle file is as follows
buildscript {
repositories {
jcenter()
maven { url = "http://files.minecraftforge.net/maven" }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "1.0"
group = "com.foxModing.Rome_Mod" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "rm"
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
}
minecraft {
version = "1.12.2-14.23.5.2768"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "snapshot_20171003"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}
dependencies {
// you may put jars on which you depend on in ./libs
// or you may define them like so..
//compile "some.group:artifact:version:classifier"
//compile "some.group:artifact:version"
// real examples
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
// except that these dependencies get remapped to your current MCP mappings
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// for more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
sourceSets {
main { output.resourcesDir = output.classesDir }
}
Is there anything I can do? I have tried to delete the build file and try again. The mod runs fine when testing in eclipse. I cannot find anyone else with the same exact error. I am totally confused and need help.
I had to reinstall forge and it works!
I am trying to generate classes from multiple .xsds in gradle. Tried like below, but it does not work and i get error that file not exists.
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.github.jacobono:gradle-jaxb-plugin:1.3.6")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
apply plugin: 'com.github.jacobono.jaxb'
version = '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
configurations.all {
exclude module: 'spring-boot-starter-logging'
}
configurations {
jaxb
}
task createDirs {
file("$buildDir/generated-sources").mkdirs()
}
xjc.dependsOn createDirs
jaxb {
xsdDir = "src/main/resources/xsd"
xjc {
destinationDir = "$buildDir/generated-sources"
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
generatePackage = "com.test.generated1"
args = ["-Xinheritance", "-Xannotate"]
}
}
compileJava {
dependsOn(xjc)
}
compileTestJava {
dependsOn(xjc)
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-log4j2')
compile('org.springframework.boot:spring-boot-starter-actuator')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.6.5')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics:0.6.4')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics-annotate:0.6.4')
jaxb('com.sun.xml.bind:jaxb-xjc:2.2.7-b41')
jaxb('com.sun.xml.bind:jaxb-impl:2.2.7-b41')
}
If i remove destinationDir = file("build/generated-sources"), it generates classes inside src/main/java which i do not want.
I get error .../build/generated-sources: non-existent directory
Any help is appreciated :)
NOTE: Gradle Version 3.2.1
Try using a variable for build directory "$buildDir/generated-sources"
Like vampire noticed you need to create the directory first.
I would suggest creating a task for it with doFirst() which will execute sooner on the execution phase.
task createDirs {
doFirst{
file("$buildDir/generated-sources").mkdirs()
}
}
and then run if before xjc:
xjc.dependsOn createDirs
And in this task particular task try to just pass the raw /build path because it seems like destinationDir already points to the root. Not sure what is going on here. Other than that I strongly sugest usign the variables $buildDir
jaxb {
xsdDir = "src/main/resources/xsd"
xjc {
destinationDir = "build/generated-sources"
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
generatePackage = "com.test.generated1"
args = ["-Xinheritance", "-Xannotate"]
}
}
Another thing is you could watch on the directory changes if you don't want to run expensive xjc task all the time.
xjc {
inputs.dir ("$projectDir/src/main/resources/xsd")
outputs.dir ("$buildDir/generated-sources")
}
One point is that you should use the variable buildDir instead of using hard-coded 'build'.
That's not your problem though. Your problem is, that the plugin you are using does not create a non-existent target directory. So add the creation action to the task like
jaxb {
doFirst {
file("$buildDir/generated-sources").mkdirs()
}
}
Or if you prefer, create a separate task that does only the directory creation and then add a dependency from jaxb to your directory creation task.