Gradle error with lack of mainClassName property in gradle build - java

I have graddle configuration with two subprojects and when I want do build the project the following error is thrown:
Executing external task 'build'...
:core:compileJava
:core:processResources UP-TO-DATE
:core:classes
:core:jar
:core:startScripts FAILED
FAILURE: Build failed with an exception.
* What went wrong:
A problem was found with the configuration of task ':core:startScripts'.
> No value has been specified for property 'mainClassName'.
My configuration:
ROOT - build.gradle:
subprojects {
apply plugin: 'java'
apply plugin: 'application'
group = 'pl.morecraft.dev.morepianer'
repositories {
mavenLocal()
mavenCentral()
}
run {
main = project.getProperty('mainClassName')
}
jar {
manifest {
attributes 'Implementation-Title': project.getProperty('name'),
'Implementation-Version': project.getProperty('version'),
'Main-Class': project.getProperty('mainClassName')
}
}
}
task copyJars(type: Copy, dependsOn: subprojects.jar) {
from(subprojects.jar)
into project.file('/jars')
}
ROOT - setting.gradle:
include 'app'
include 'core'
APP PROJECT - build.gradle:
EMPTY
CORE PROJECT - build.gradle:
dependencies {
compile 'com.google.dagger:dagger:2.4'
compile 'com.google.dagger:dagger-compiler:2.4'
}
AND BOTH SUBPROJECTS (SIMILAR) - gradle.properties:
version = 0.1-SNAPSHOT
name = MorePianer Core Lib
mainClassName = pl.morecraft.dev.morepianer.core.Core
I've tried to add the mainClassName property in many places, but it does not work. This is even stranger, that It worked a couple days ago as it is. I'm using gradle for first time and I'm thinking about switching back to maven.

The application plugin needs to know the main class for when it bundles the application.
In your case, you apply the application plugin for each subproject without specifying the main class for each of those subprojects.
I had the same problem and fixed it by specifying "mainClassName" at the same level as apply plugin: 'application' :
apply plugin: 'application'
mainClassName = 'com.something.MyMainClass'
If you want to specify it in the gradle.properties file you might have to write it as : projectName.mainClassName = ..

Instead of setting up mainClassName try to create
task run(type: JavaExec, dependsOn: classes) {
main = 'com.something.MyMainClass'
classpath = sourceSets.main.runtimeClasspath
}
Please look at Gradle fails when executes run task for scala

Whenever we bind a gradle script with the application plugin, Gradle expects us to point out the starting point of the application. This is neccessary because, Gradle will start bundling your application (jar/zip) using the given location as the entry point.
This error is thrown simply because Gradle knows that you want to bundle your application but is clueless about where to start the bundling process.

One can specify the mainClassName as a project extended property:
ext {
mainClassName = 'com.something.MyMainClass'
}

I faced the same issue in my project and solved it by excluding from gradle.properties:
#ogr.gradle.configurationdemand = true

Related

Gradle building Spring Boot library without Main Class

I am trying to build a Spring Boot/Gradle project and create a jar without a main class. My purpose is that this project is a library that will be pulled in by other projects therefore the library project does not require a main class to run. Unfortunately, no matter what kind of gradle config I write I keep getting errors when I try to build install about not having a main class or not being able to find the bootJar task.
Here's what my gradle file looks like:
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE' apply false
}
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven'
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
repositories {
mavenCentral()
}
jar {
enabled = true
}
bootJar.dependsOn fooTask
But when I run this I get the following error:
Could not get unknown property 'bootJar' for root project
'foo-library' of type org.gradle.api.Project.
What in my configuration needs to change?
Disable bootJar in your build.gradle
bootJar {
enabled = false
}

How to run shadow jar with a gradle task?

I want to run my app after building it with the shadow jar plugin.
build.gradle:
plugins {
id 'java'
id "org.jetbrains.kotlin.jvm" version "1.3.21"
id "com.github.johnrengelman.shadow" version "5.0.0"
}
group 'org.example.java'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
repositories {
jcenter()
}
dependencies {
compile "io.ktor:ktor-server-netty:1.1.3"
}
I also have a global init.gradle:
gradle.projectsLoaded {
rootProject.allprojects {
buildDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
}
So now the fat jar can be built to my global build directory with the shadowJar task. But I want to be able to run and build it with just one run configuration in IntelliJ. How do I do that?
Maybe there is another way to let gradle redirect all my output to a global build directory. I don't want to configure each IntelliJ project with the same output path manually. Suggestions are welcome.
Thank you :)
You should not touch the buildDir property for achieving what you want.
Instead, you should create a JavaExec task that will start the application from the shadow jar.
If you want that execution to be at a different place than the default location of the generated jar, you should either change the output of the shadow task itself, and only that output or make your execution task depend on a copy task that would move the shadow jar around.
Something like:
shadowJar {
destinationDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
task runApp(type: JavaExec) {
main = "your.main.Class
classpath = shadowJar.archiveFile // use archivePath before Gradle 5.1
}

Make gradle compileJava dependsOn spotlessApply

I have a Gradle project with several submodules. In my project there is a spotless task configured. Now I want to make a compileJava task dependent on spotlessApply task. I try it in this way:
subprojects {
apply plugin: 'java'
apply plugin: 'com.diffplug.gradle.spotless'
spotless {
java {
target 'src/**/*.java'
licenseHeaderFile "$rootDir/buildSrc/CopyrightHeader.java"
importOrder(['java', 'javax', 'org', 'com'])
eclipseFormatFile "$rootDir/buildSrc/formatter.xml"
}
format 'misc', {
target 'src/**/*.md', 'src/**/*.xml', 'src/**/*.xsd', 'src/**/*.xsl'
indentWithSpaces()
trimTrailingWhitespace()
endWithNewline()
}
}
compileJava.dependsOn spotlessApply
}
But it produces an error:
Could not get unknown property 'spotlessApply' for project (...) of
type org.gradle.api.Project.
I also tried something like this:
compileJava.dependsOn project.tasks.findByName('spotlessApply')
But it doesn't work.
The Spotless plugin creates its tasks in an project.afterEvaluate block to allow you to configure the extension before it creates the task(s) - see here
To solve this, simply depend on the task's name (i.e. as a string) instead and Gradle will resolve the task when its needed.
compileJava.dependsOn 'spotlessApply'

Cannot execute jar built with gradle with correct Manifest

I have a JavaFx application and I cannot run it from both command line and windows explorer.I built the jar using Gradle, and checked for the manifest and it is correct. I tried everything from StackOverflow but it always complains that it cannot find the entry point from Manifest:
My main is located in src/main/java and it is called Main.
Here is the configuration for gradle:
group 'com'
version '1.0'
apply plugin: 'java'
apply plugin: 'application'
sourceCompatibility = 1.8
mainClassName = 'Main'
repositories {
mavenCentral()
}
jar {
manifest {
attributes('Main-Class': 'Main')
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Please ignore the dependecies (I build an uber jar).
And here is the content of my manifest(created by gradle with the new line at the end):
Manifest-Version: 1.0
Main-Class: Main
When I try to run it i get all the time this:
Error: Could not find or load main class Main
Because you apply the application plugin, none of the customisations of the jar tasks are required.
So I recommend you remove them and check if it creates a valid jar then.
While I did not confirm by running it locally, I believe the customisation done in from is wrong and creates a busted jar.

using Kotlin with Gradle

I'm new to Kotlin and Gradle, and tried to follow these steps, so I got the following 2 files:
after running gradle init I changed the build.gradle to be:
// set up the kotlin-gradle plugin
buildscript {
ext.kotlin_version = '1.1.2-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
// apply the kotlin-gradle plugin
apply plugin: "kotlin"
apply plugin: 'application'
mainClassName = "hello.main"
// add kotlin-stdlib dependencies.
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
Hello.kt:
package hello
fun main(args: Array<String>) {
println("Hello World!")
}
Then I run the gradle build and got the build\classes\main\hello\HelloKt.class
my question is: Why the file generated is .class not .jar and how to get the .jar file and how to run it, I tried running the generated file using kotlin -classpath HelloKt.class main but got an error error: could not find or load main class hello.main
The classes are the direct output of the Kotlin compiler, and they should be packaged into a JAR by Gradle afterwards. To build a JAR, you can run the jar task, just as you would in a Java project:
gradle jar
This task is usually run during gradle build as well, due to the task dependencies.
This will pack the Kotlin classes into a JAR archive (together with other JVM classes, if you have a multi-language project), normally located at build/libs/yourProjectName.jar.
As to running the JAR, see this Q&A for a detailed explanation: (link)
Thanks for #hotkey answer, it helped me going the correct way.
First of all there is a mistake in the main class declaration, as it should follow the new methodology, that is in the below format:
mainClassName = '[your_namespace].[your_arctifact]Kt'
namespace = package name
arctifact = file name
so, considering the names given in the example above where filename is: Hello.kt, and the namespace is hello, then:
mainClassName = `[hello].[Hello]Kt`
using the previous method, that contains:
apply plugin: 'application'
mainClassName = 'hello.HelloKt'
the generated .jar file is not including the kotlin runtime, so the only way to execute it, is by:
d:/App/build/libs/kotlin -cp App.jar hello.HelloKt
but in order to generate a self contained jar that can be self-executed, and contains the kotlin runtime then the build.gradle should be written as:
// set up the kotlin-gradle plugin
buildscript {
ext.kotlin_version = '1.1.2-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
// apply the kotlin-gradle plugin
apply plugin: "kotlin"
// add kotlin-stdlib dependencies.
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
jar {
manifest {
//Define mainClassName as: '[your_namespace].[your_arctifact]Kt'
attributes 'Main-Class': 'hello.HelloKt'
}
// NEW LINE HERE !!!
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
followed by gradle build, the [your_working_folder].jar file will be generated at the build/libs folder, assuming the working folder name is app, then file app.jar will be generated.
To run this file, one of the following 2 commands can be used:
D:\App\build\libs\java -jar App.jar
OR
D:\App\build\libs\kotlin App.jar hello.HelloKt

Categories

Resources