Getting spring boot jar files through gradle - spring

The spring framework wants users to use dependency tools to download the framework, so I am trying to use gradle. I got this sample from their website http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto
buildscript {
repositories {
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.0.BUILD-SNAPSHOT")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
jar {
baseName = 'root'
version = '0.0.1-SNAPSHOT'
}
repositories {
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
I saved this to a file called build.gradle. Then in the CMD I went to the directory where the build.gralde file is located and type:
gradle build
It seemed to run fine but towards the building it's not working, here is the last logs I got from the command prompt:
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:jar
:bootRepackage FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootRepackage'.
Unable to find main class
* 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: 9.664 secs
I don't understand this "> Unable to find main class". I only want to get all the jar files and put them inside WEB-INF/lib of my eclipse projects. I am extremely new at gradle. What should I do?

It's not really clear to me, acoording to your comments, what are you trying to achieve, if you don't have a project sources, but for some reason wants to download dependent libraries. Gradle doesn't work this way, all the libraries are dowloded on demand, that means, they are dowloaded then you, for example, try to build your source files.
The exception you get, means, that gradle spring boot plugin's task bootRepackage Didn't find a main class in your project. This main class is mandatory for this task, since the task creates a standalone executable jar.
Sure, it is possble to dowload deps by custom task, like:
task getDeps(type: Copy) {
from sourceSets.main.runtimeClasspath
into 'runtime/'
}
But it seems, that you don't properly understand, how does it work. You should try to read gradle user guide first and let gradle to build your project for you, but not just combine some libs.

Related

Gradle: Invalid publication 'maven': artifact file does not exist

Java 11 and Gradle 7.2 here. I am trying to build a reusable library that I can (eventually) publish to a Maven repository and pull into other projects. But first I just want to get it publishing to my local m2 repo.
The project directory structure looks like:
mylib/
lib/
src/
build.gradle
Where build.gradle is:
plugins {
id 'java-library'
id 'maven-publish'
id 'io.freefair.lombok' version "6.5.0-rc1"
}
sourceCompatibility = 1.11
targetCompatibility = 1.11
archivesBaseName = 'mylib'
version = '1.0.0-RC1'
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
// omitted for brevity
)
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
}
publishing {
publications {
maven(MavenPublication) {
artifact("build/libs/${archivesBaseName}-${version}.jar") {
extension 'jar'
}
}
}
}
tasks.named('test') {
useJUnitPlatform()
}
publishToMavenLocal.configure {
mustRunAfter build
}
When I run gradle publishToMavenLocal I get:
% ./gradlew clean build publishToMavenLocal
> Task :lib:publishMavenPublicationToMavenLocal FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':lib:publishMavenPublicationToMavenLocal'.
> Failed to publish publication 'maven' to repository 'mavenLocal'
> Invalid publication 'maven': artifact file does not exist: '/Users/myuser/workspace/mylib/lib/build/libs/mylib-1.0.0-RC1.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 833ms
6 actionable tasks: 6 executed
So it looks like even though I'm specifying (on the command line) to run clean then build then publishToMavenLocal, and even though I'm even specifying (in build.gradle) that publishToMavenLocal must run after build, it seems what is happening is:
publishToMavenLocal insists on running first (before clean or build)
Since the JAR hasn't been built yet, no JAR file exists at the location specified ("build/libs/${archivesBaseName}-${version}.jar")
The build fails because the artifact doesn't exist
So I think I just need to get build to run before publishToMavenLocal but I'm out of ideas.
You're mixing the plugins DSL (plugins { }) with legacy plugin application (apply plugin). That's not a big deal, but you should go with #sean's answer and use the plugins DSL instead which will solve your issue.
To your problem at hand
Could not get unknown property 'plugin'
That happens because you missed the : in apply plugin
apply plugin: 'maven-publish'
Try placing your plugins in this way. Not sure if that resolves your issue though.
plugins {
id 'java-library'
id 'maven-publish'
}

Gradle: Use a sibling subproject as plugin

I have a project with two subprobjects: gradle-plugin and plugin-consumer. I want to apply the plugin from gradle-plugin to plugin-consumer. I tried to do this:
// plugin-consumer/build.gradle
buildscript {
dependencies {
classpath project(':gradle-plugin')
}
}
apply plugin: 'my.plugin.id'
But I was greeted with the following error:
A problem occurred configuring project ':plugin-consumer'.
> Cannot use project dependencies in a script classpath definition.
I assume this is not supported because it'd require fully building gradle-plugin before plugin-consumer can be configured.
Fortunately I can use a fileTree dependency to accomplish my goal:
// plugin-consumer/build.gradle
buildscript {
dependencies {
classpath fileTree(includes: ['*.jar'], dir: '../gradle-plugin/build/libs')
}
}
apply plugin: 'my.plugin.id'
This works, but it feels like a massive hack and leads to "bootstrapping problems".
For example, I can't clean gradle-plugin because the (deleted) jar file is necessary for configuring plugin-consumer, which must be done to (re)build gradle-plugin.
Fortunately this can be avoided by always running build immediately after clean (in the same 'run' so to speak). This can be done manually (gradle clean build) or automatically (with clean.finalizedBy(build)). Again, this works, but feels like a hack.
At last, my actual question: is there a better way to do this?
Please note that gradle-plugin is an independent plugin that's not only used by plugin-consumer, therefore buildSrc is unfortunately not an appropriate solution here.
You can publish the plugin to your local Maven repository with the Maven Publish plugin. Then simply consume it like any other artifact.
Assuming you have something similar in your plugin project:
plugins {
`maven-publish`
`java-gradle-plugin`
}
Simply publish it locally:
./gradlew :my-plugin-project:publishToMavenLocal
Then in your consuming project, something like:
buildscript {
repositories {
mavenLocal()
}
dependencies {
"classpath"("com.example:my-plugin-gav:1.0.0-SNAPSHOT")
}
}
// apply plugin

Unable to create a JAR of my JDA project because of pom dependency

I have a Kotlin project with JDA API which I need to deploy on Heroku environment. To achieve that I created a JAR task in my build.gradle file.
jar {
baseName = 'discord-stats-bot'
version = 'v1'
manifest {
attributes('Main-Class': 'com.vchernogorov.discordbot.BotKt')
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
But I was unable to build this JAR file because of the following error.
16:02:03 vchernogorov $ ./gradlew jar
:kaptGenerateStubsKotlin UP-TO-DATE
:kaptKotlin UP-TO-DATE
:compileKotlin UP-TO-DATE
:compileJava UP-TO-DATE
:copyMainKotlinClasses UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:inspectClassesForKotlinIC UP-TO-DATE
:jar
FAILURE: Build failed with an exception.
* What went wrong:
Could not expand ZIP '/Users/vchernogorov/.gradle/caches/modules-2/files-2.1/club.minnced/opus-java/1.0.4/596995aaf2f5b5091c4d251fdc11fa62680cc59e/opus-java-1.0.4.pom'.
> archive is not a ZIP archive
* 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: 6.784 secs
This library is a dependency in a JDA project. So I need help with configuring this jar task in order to correctly build my executable and deploy it to Heroku.
Edit: Here's my dependencies block in build.gradle.
dependencies {
compile 'com.google.guava:guava:23.0'
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.16"
compile "org.jsoup:jsoup:1.10.3"
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "net.dv8tion:JDA:3.8.0_436"
compile "khttp:khttp:0.1.0"
compile 'com.google.code.gson:gson:2.8.1'
}
In maven there's a special artifact of type pom. It is also published and downloaded as a dependency. In jar's from is neither a directory nor a jar file, that's why processing fails. To solve it you need to exclude the *.pom before collecting, so:
from {
configurations
.compile
.findAll { !it.name.endsWith('pom') }
.collect { it.isDirectory() ? it : zipTree(it) }
}
Next time you can use gradle shadow plugin or similar - a plugin that builds uber jar, since it probably handles it correctly.

Gradle's publishToMavenLocal task is not executed correctly

I'm trying to create a gradle based multi-module project. There is also an project that contains different gradle scripts that enables pluggable build configurations. One of those scripts is for publishing artifacts to maven repository. This is the content of that script:
apply plugin: 'maven-publish'
configure(subprojects.findAll()) {
if (it.name.endsWith('web')) {
publishing {
publications {
mavenWeb(MavenPublication) {
from components.web
}
}
}
} else {
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
}
build.dependsOn publishToMavenLocal
This script is included in the build gradle file of other project.
apply from: '../../food-orders-online-main/artifact-publish.gradle'
When I run build task it always shows that publishToMavenLocal task is up to date and I cannot find the artifacts in the local repository. Am I doing something wrong?
By adapting answer from here, it works for me.
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
mavenLocal()
}
}
I think this could be a manifestation of a bug with gradle, that modules can lose the publishMavenJavaPublicationToMavenLocal task when they are depended upon in a certain way.
If gradle determines that there is no publishMavenJavaPublicationToMavenLocal task for a module then the publishToMavenLocal task will always report that it is up to date.
The specific case I have found occurs in a multimodule setup, with multiple levels of nested modules. It can be summarised as follows, where shared:domain loses its publishMavenJavaPublicationToMavenLocal when depended upon by A
root
root gradle build file
->A
own gradle build file with dependency on shared:domain
-> shared
gradle build file for shared modules
-> shared:domain
-> shared:B
I have created a small example project demonstrating this behaviour available here - https://github.com/piersy/Gradle2MavenPublishBug
I have also logged a bug with gradle here - http://forums.gradle.org/gradle/topics/the-publishmavenjavapublicationtomavenlocal-task-disappears-from-a-project-when-that-project-is-depended-upon-in-a-specific-way
For now the workarounds I have found are to
Remove A's dependency on shared:domain
Make A a submodule with its configuration specified in its parent module build file
Give shared:domain its own gradle build file

Gradle Plugin not found when using wrapper

I have a small gradle build which is using a 3rd party plugin it works great while running gradle commands I then added the wrapper task so I could distribute the code and it could be built with non gradle users. When I went to test the gradlew command I can not even run gradlew tasks it fails saying the plugin is missing.
Is there some other configuration that needs to happen?
My wrapper task:
task wrapper(type: Wrapper) {
gradleVersion = '1.0-milestone-2'
jarFile = 'wrapper/wrapper.jar'
}
Full build file: https://github.com/beckje01/Multi-Combobox/blob/master/build.gradle
Based on the documentation of this plugin you got to build it from the source code and put it into the directory lib/plugins of your Gradle distribution. My guess is that's what you did before you switched to the Gradle wrapper. Whenever you use the Gradle wrapper your locally installed distribution is not used anymore. Gradle downloads the distribution and puts it under ~/.gradle/wrapper/dists/gradle-1.0-milestone-2. One way to get this running would be to put the plugin in there as you did before. However, this won't make it running for somebody else that checks out your code and runs the build. This is the whole point of using the Gradle wrapper.
What I would do in your case is to upload the plugin artifact to a central repository and refer to it in your build script. It doesn't look like it would be available on Maven Central though. You can upload it to your GitHub project and refer to it in your build script like this:
buildscript {
repositories {
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
name = 'GitHub'
addArtifactPattern 'http://cloud.github.com/downloads/[organisation]/[module]/[module]-[revision].[ext]'
}
mavenCentral()
}
dependencies {
classpath 'beckje01:jslib:0.5'
classpath 'com.google.javascript:closure-compiler:r706'
}
}

Resources