I have the following build.gradle file:
apply plugin: "java"
version '1.0'
sourceCompatibility = 1.8
sourceSets.main.java.srcDirs = ["src"]
allprojects {
repositories {
mavenCentral()
jcenter()
maven { url "https://jitpack.io" }
}
}
dependencies{
compileOnly 'com.github.Recessive:repo:v0.5'
implementation 'mysql:mysql-connector-java:8.0.12'
}
jar{
archiveFileName = "${project.archivesBaseName}.jar"
from{
configurations.runtimeClasspath.collect{it.isDirectory() ? it : zipTree(it)}
}
from(rootDir){
include "plugin.json"
}
}
That isn't working and returning the error
LocalRepo1:main: Could not find com.github.Recessive.repo:v0.5:.
To add salt to the wound, I released a v0.2 three months ago, and this works perfectly fine. Changing the line
compileOnly 'com.github.Recessive:repo:v0.5'
to
compileOnly 'com.github.Recessive:repo:v0.2'
will build with the older version no problem. I've released v0.3 to v0.5 as troubleshooting just to try and get jitpack to work, they are all functionally the same. I tried using the master-SNAPSHOT as well but this stopped working when I made the v0.3 release for unknown reasons.
The only error I will get regardless of the issue is the one stated before, making it basically impossible to know what is going on without significant knowledge of jitpack and gradle, hence the question here.
If anyone has any idea why this error might have suddenly popped up help would be greatly appreciated
EDIT: Also I know jitpack is returning the v0.2 version properly as I checked the link manually. While gradle is just building from the cached version jitpack is also behaving as expected
90% sure this was caused by the git history being too long (ie, over 500mb). To fix this I did the following:
git checkout --orphan <orphan-branch-name>
git commit
git push <remote-name> <orphan-branch-name>
This created an orphan branch with no commit history. Then in the build file I replaced the version with:
dependencies{
compileOnly "com.github.Recessive:repo:orphan-SNAPSHOT"
}
And it started working. Gradle/Jitpack has a horrendous lack of proper error reporting, as is evident but the most common error message from Jitpack having 10 different answers
We are looking to migrate from Maven to Gradle, and have worked through most of the challenges you would expect for replacing the parent POM concept. There is one sticky point that we haven't figured out yet. We need to specify the version of Spring Boot we are using globally, but I run into invalid build file problems with both of the solutions I've tried:
I tried putting the plugins { id 'org.springframework.boot' version '2.1.17.RELEASE' } declaration in the common build script. Build error, "Only Project and Settings build scripts can contain plugins {} blocks."
I tried calling the common build file to specify the springBootVersion parameter and using that in the plugins declaration. Build Error, "only buildscript {} and other plugins {} script blocks are allowed before plugins {} blocks, no other statements are allowed"
All of this would be easier if I could simply apply plugin: 'org.springframework.boot' but then Gradle can't find the plugin. All but one microservice are on a single version of Spring Boot, and we want to be able to upgrade globally if possible.
Additional Information
I have ~40 microservices plus some libraries used by those services
Separate repository for each of them, so the normal parent/child approach does not work
Maven parent POMs allowed you to publish that POM as it's own resource, and there is no 1:1 equivalent feature in Gradle
Gradle pluginManagement concept also doesn't work for us because it resolves the Spring Boot plugin but the dependency management plugin now can't be found.
My common build script is included here:
repositories {
mavenLocal()
/* Removed our internal repositories */
jcenter()
mavenCentral()
}
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'
group = 'nedl-unified-platform'
/* Required to publish Spring Boot microservices to publish to repository */
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
it.outgoing.artifact(bootJar)
}
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
withJavadocJar()
withSourcesJar()
}
ext {
set('springBootVersion', '2.1.17.RELEASE')
set('springCloudVersion', "Greenwich.SR6")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
jacoco {
toolVersion = "0.8.5"
reportsDir = file("$buildDir/reports/jacoco")
}
test {
finalizedBy jacocoTestReport // report is always generated after tests run
}
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 0.2
}
}
}
}
jacocoTestReport {
dependsOn test // tests are required to run before generating the report
reports {
xml.enabled true
html.destination file("${reportsDir}/jacocoHtml")
xml.destination file("${reportsDir}/jacocoReport.xml")
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
repositories {
/* excluded for privacy and brevity's sake, our internal Maven repo */
}
}
And that is called by our project build script that I want to parameterize:
plugins {
id 'org.springframework.boot' version springBootVersion
}
apply from: "https://mycentral.repo/project-common/develop/build.gradle"
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
implementation 'ch.qos.logback:logback-classic'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
implementation 'org.glassfish.jaxb:jaxb-runtime:2.4.0-b180830.0438'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
version = '0.0.2-SNAPSHOT'
I think the gap here is that in maven you have the concept of a parent pom, whereas in Gradle you don't. There is no 1:1 mapping to this like you say, but you can have plugins in Gradle, and apply a plugin.
The closest thing you would have is if you developed your own Gradle plugin, which each of your projects could apply. Your custom plugin would then configure Spring Boot among whatever else is common to all your projects. This plugin would define the version of Spring Boot you want all your other projects to use.
You wouldn't get much benefit to a custom plugin if it's only concern is configuring Spring Boot, it would need to do other things as well. It can be difficult to create a Gradle plugin when you don't have allot of experience in it. You lose all the familiar syntax to the build.gradle and you literally have to write code, (there are some similarities but I have found it difficult), I would avoid it if possible.
I would suggest you start off by applying the spring boot plugin directly to one of your microservices projects, get that working, then do another. After you have done a number of them you will then be able to see what is common between them, and if it is indeed worth investing into developing a global plugin. You really need to be careful though because your global plugin has the potential to be both a blessing and curse. It may take away allot of manual work for maintainers, but if you get it wrong it will cause them grief, and then they will want to go back to maven.
I'm not sure if I understand your globally defined Spring version requirement. Unless you are using SNAPSHOT dependencies/plugins (bad don't do that), (or a black magic settings.gralde outside of your repo), you will have to put some version somewhere. As an alternative you could create your own custom task which runs on the check lifecycle which will check the version of spring (or your plugin) and print a warning if it's not the latest version, and encourage the developer to upgrade.
Extra Info
Parameterizing plugins with properties can be done putting your property in gradle.properties as springBootVersion=2.1.17.RELEASE .
I'm not sure I understood your issue perfectly but you should use the Gradle way for sharing configuration : the root project config.
Instead of including the common build script in every project, create a global project and set the configuration here.
root
|
| --- projectA
| --- projectB
| --- projectC
With the according settings.gradle
include 'projectA'
include 'projectB'
include 'projectC'
In the root build.gradle, set up the version
ext.springBootVersion = '2.1.17.RELEASE'
In subprojects using springBoot, let's say projectB, apply the plugin in the sub build.gradle
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
}
apply plugin: 'org.springframework.boot'
This example works for me, though I may not understand all of the constraints.
If we abstract the version of Spring Boot behind a fixed URI (e.g. on an internal CI/CD server), then consider this in each project/repo's build.gradle:
buildscript {
repositories {
jcenter()
}
def SPRING_BOOT_VERSION_URI = 'http://localhost:5151/api-server/spring-boot.txt'
ext.springBootVersion = new URL(SPRING_BOOT_VERSION_URI).getText().trim()
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
}
apply plugin: 'org.springframework.boot'
apply from: "../common/build.gradle"
I realize the original question states that the apply plugin doesn't work, but it's not clear to me if that precludes this method.
Finally, note that it is easy to expand this beyond a simple text-file to be a more formal JSON specification (tailored to the teams' needs).
If you add this to the root project, all child projects should be able to just import from the same set of Spring Boot dependencies. The magic ingredient is the allprojects block:
buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
ext {
springBootVersion = '2.3.4.RELEASE'
}
allprojects {
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
}
}
}
apply plugin: 'org.springframework.boot'
I am new to both Gradle and JavaFX. I have added the JavaFX plugin to my build.gradle following this and this. However, my main class Library.java is not able to detect the Application class of JavaFX when I am trying to extend it.
build.gradle
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Chess.Library'
}
}
mainClassName = 'Chess.Library'
Screenshot of Library Class
There's no Application from javafx package at all. What am I missing here?
I am using Spring Tool Suite 4.0 as my IDE with Buildship Gradle plugin if that's of any help. I am also running on Oracle Java 13
Edit 1:
I have added the changes suggested and this is how my build.gradle now looks
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Chess.Library'
}
}
javafx {
version = "13"
modules = [ 'javafx.controls' ]
}
mainClassName = 'Chess.Library'
But the problem is still there
I also checked my Project and External Dependencies, there are all the libraries except for javafx
I fixed the issue myself although not sure what was causing it, but my project's buildpath had an unbounded Java 13. Fixing that and restarting the IDE took care of it
I'm looking into migrating from maven to gradle, in this case, gradle itself seems to be working fine, but Idea isn't recognizing the source code that Immutables is generating.
I've read this blog post on APT, it's how I got this for.
/*
* This build file was generated by the Gradle 'init' task.
*
* This generated file contains a commented-out 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.3/userguide/tutorial_java_projects.html
*/
// Apply the java plugin to add support for Java
apply plugin: 'java-library'
apply plugin: 'idea'
buildscript {
repositories {
maven {
url 'https://d3vfm0n2cffdwd.cloudfront.net'
}
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
}
}
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom 'com.xenoterracide:platform:0.1.39-SNAPSHOT'
}
}
repositories {
maven {
url 'https://d3vfm0n2cffdwd.cloudfront.net'
}
jcenter()
}
configurations {
apt
aptCompile
}
// In this section you declare the dependencies for your production and test code
dependencies {
implementation 'com.google.guava:guava'
aptCompile 'org.immutables:value'
compileOnly 'org.immutables:value'
apt 'org.immutables:builder'
// The production code uses the SLF4J logging API at compile time
implementation 'org.slf4j:slf4j-api'
// 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.
testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.hamcrest:hamcrest-library'
}
compileJava {
options.annotationProcessorPath = configurations.aptCompile
}
for more code see bitbucket
one of the things that's getting me, is that depending on what I've tried the generated java either ends up in an out directory, or build on the classpath, of course so far neither of these solves the problem.
how do I fix this so that Idea can see the source for the generated types (so that it's not all highlighted in red)?
#CrazyCoder's links helped me get closer to a solution, this seems to resolve it though.
idea {
module {
sourceDirs += file("out/production/classes/generated")
}
}
I'm pretty new to Gradle and am having an issue getting my a module that is dependant on another module to build properly.
So I have the following configuration for my modules.
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.10'
}
}
project(':web-service') {
apply plugin: 'war'
dependencies {
compile project(':core')
compile('com.sun.jersey:jersey-server:1.7')
compile('com.googlecode.json-simple:json-simple:1.1.1')
}
}
project(':core') {
dependencies {
compile('log4j:log4j:1.2.17')
}
}
If I try to build my core project everything succeeds as expected.
However, if I try to build the web-service project with the following command:
gradle :web-service:build
It appears to build the core project first as expected but then encounter build errors that indicate that classes that exist in the core module cannot be found.
What gives?
Turns out this was completely my fault. I dug deeper on the error messages that I was getting and found some package does not exist messages at the top. Turns out that my directory structure was not inline with my package names.