I switched to gradle 7.0 recently and now cannot build my projects jar, with the error
Could not get unknown property 'runtime' for configuration container of type org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.
`
Here is my build.gradle:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet-core', version: '2.7'
implementation group: 'org.eclipse.jetty.aggregate', name: 'jetty-all', version: '9.3.0.M1'
//
implementation 'javax.xml.bind:jaxb-api:2.3.0'
// testImplementation group: 'junit', name: 'junit', version: '4.11'
implementation group: 'org.json', name: 'json', version: '20200518'
implementation group: 'com.jolbox', name: 'bonecp', version: '0.8.0.RELEASE'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
implementation group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.12.0'
implementation "org.slf4j:slf4j-simple:1.7.9"
}
version = '1.0'
jar {
manifest {
attributes(
'Main-Class': 'classes.RestServer',
)
}
}
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/.SF"
exclude "META-INF/.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
artifacts {
archives fatJar
}
Gradle removed the runtime configuration after Gradle 6.x.
You can either change your fatJar task in build.gradle to refer to runtimeConfiguration (as per the Java plugin documentation):
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
// change here: runtimeClasspath instead of runtime
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/.SF"
exclude "META-INF/.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
Alternatively use a plugin that deals with fat jar building for you. I've tried Shadow a few years ago. This should also take care of files with the same names from different jars (like META-INF/LICENSE) that you may run into with your approach.
Support for runtime configuration has been stopped gradle-7.0, so configurations.runtime is not working.
Task copyAllDependencies worked for me in gradle-7.0.
Here is the example to copy dependencies into ${buildDir}/output/libs:
Add following to build.gradle.
task copyAllDependencies(type: Copy) {
from configurations.compileClasspath
into "${buildDir}/output/libs"
}
build.dependsOn(copyAllDependencies)
I hope it helps.
Related
I created spring-boot gradle multi-module project which consisted of 3 modules: controller, service, repository. Main file was situated in Controller-module and named MySpringBootApplication.
I could build this project (using gradle build) and could get jar-file. But after starting this jar in command line I took the next error:
Error: Could not find or load main class com.epam.esm.config.MySpringBootApplication Caused by: java.lang.ClassNotFoundException: com.epam.esm.config.MySpringBootApplication.
To fix this bug I added Main-Class attributte to MANIFEST.MF file in main build.gradle but this action didn't help. So could anybody help?
MAIN BUILD.GRADLE FILE
plugins {
id 'java'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.springframework.boot' version '2.4.3'
id 'application'
}
group = 'com.myproject'
version = 'snapshot-1.0.0'
repositories {
mavenCentral()
}
bootJar {
enabled = false
}
jar {
enabled = true
manifest {
attributes(
"Main-Class": "com.myproject.config.MySpringBootApplication")
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-parent', version: '2.4.3', ext: 'pom'
}
test {
useJUnitPlatform()
}
subprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
group = 'com.epam.esm'
version = '1.0.0'
repositories {
mavenCentral()
}
bootJar {
enabled = false
}
jar {
enabled = true
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation group: 'org.hibernate', name: 'hibernate-envers', version: '5.4.27.Final'
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
implementation group: 'org.openidentityplatform.commons', name: 'json-web-token', version: '2.0.11'
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.18'
annotationProcessor 'org.projectlombok:lombok'
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-parent', version: '2.4.3', ext: 'pom'
}
test {
useJUnitPlatform()
}
}
SETTINGS.GRADLE
rootProject.name = 'module'
include('repository', 'service', 'controller')
The Spring Boot application executable jar file is built by bootJar task, so adding the main-class information via jar won't work either.
The bootJar task tries to create an executable jar, and that
requires a main() method. As a result, you need to disable the
bootJar task and enable the jar task (which creates an ordinary jar
rather than an executable jar) only for your no executable jar
modules.
Since you did it under subprojects section, the controller module will produce a standard jar as well. You may produce standard jars for all modules but excluding the controller module as follows:
subprojects {
if (it.name != 'controller') {
bootJar {
enabled = false
}
jar {
enabled = true
}
}
}
In addition you have to remove the jar section below
jar {
enabled = true
manifest {
attributes(
"Main-Class": "com.myproject.config.MySpringBootApplication")
}
}
and replace
bootJar {
enabled = false
}
with
bootJar {
mainClassName = 'com.myproject.config.MySpringBootApplication'
}
Reference
Creating a Multi Module Project
I tried to generate the exe using the gradle plugin gradle-launch4j with the following configuration of the build.gradle:
plugins {
id 'java'
id 'edu.sc.seis.launch4j' version '2.4.6'
id 'application'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
// lib via maven
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.15'
compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.28.0'
}
jar {
manifest {
attributes 'Main-Class': 'Main'
}
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
application {
mainClassName = 'Main'
}
launch4j {
mainClassName = 'Main'
outfile = 'Gymnasium.exe'
icon = "${projectDir}/src/main/resources/view/img/icona.ico"
jreMinVersion = "1.8.0"
}
Exe is generated but trying to run, it not starts. I noticed that it starts if I launch it from terminal using java -jar Gymnasium.exe command.
Is there something of wrong in my configuration? I tried to search if someone had a similiar issue but I didn't find anything.
Note: If I try to generate the exe from Launch4j application it works perfectly.
It was working fine when external dependencies were in the separate lib folder, but due to change in requirements jar should contain all external dependencies in it, not in a separate folder.
Can anyone Guide me how can I execute the jar file
here is my Gradle file
apply plugin: 'java-library-distribution'
group = 'com.MyCompany'
version = '0.0.1-SNAPSHOT'
description = "data-purge-service"
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
dependencies {
compile group: 'commons-configuration', name: 'commons-configuration', version:'1.6'
compile group: 'log4j', name: 'log4j', version:'1.2.17'
compile group: 'log4j', name: 'apache-log4j-extras', version:'1.2.17'
compile group: 'org.quartz-scheduler', name: 'quartz', version:'2.2.1'
compile group: 'org.json', name: 'json', version:'20151123'
compile group: 'com.google.inject', name: 'guice', version:'3.0'
compile group: 'commons-codec', name: 'commons-codec', version:'1.10'
compile group: 'org.apache.velocity', name: 'velocity', version:'1.7'
compile group: 'javax.mail', name: 'mail', version:'1.4'
compile group: 'org.jsoup', name: 'jsoup', version:'1.8.3'
runtime group: 'mysql', name: 'mysql-connector-java', version:'6.0.6'
testCompile group: 'junit', name: 'junit', version:'3.8.1'
}
jar {
manifest {
attributes "Main-Class": "com.MyCompany.datapurge.service.App"
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
sourceSets {
main {
output.resourcesDir = "build/libs/resources"
}
}
}
When I execute generated jar it is unable to locate dependencies.
What is the way to execute it?
For my case, with gradle version 5 , dependencies were only added when i used configurations.runtimeClasspath instead configurations.compile, as posted in many places.
Here the full task example:
task BuildJar(type: Jar) {
manifest {
attributes(
'Main-Class': 'org.mycompany.mainclass'
)
}
classifier = 'all'
baseName = 'MyJar'
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
{
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
It will create a single jar with everything.
To run the task do:
gradle task BuildJar //use gradew.bat for windows
It will place the jar at ./build/libs
To run just do:
java -jar MyJar.jar
Use Java Decompile to analise the jar.
"In this tutorial, we will show you how to use Gradle build tool to create a single Jar file with dependencies."
I have the following build.gradle file for my project
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.guava:guava:23.6-jre';
testCompile group: 'junit', name: 'junit', version: '4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Runner.ClientRunner'
}
}
However, when I run "gradle jar" and attempt to run the given jar, I get the error:
java.lang.NoClassDefFoundError: com/google/common/base/Preconditions
I can't seem to nail down what I've done wrong here, guava is included in the dependencies for gradle and the jar file appears to build fine otherwise (it only crashes when it gets to the first class that depends on guava). Any assistance appreciated.
If it helps I'm doing this from IntelliJ.
I solved my problem using the solution at https://discuss.gradle.org/t/how-to-include-dependencies-in-jar/19571
My build.gradle now looks like
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
configurations {
// configuration that holds jars to include in the jar
extraLibs
}
dependencies {
compile 'com.google.guava:guava:23.6-jre';
extraLibs group: 'com.google.guava', name: 'guava', version: '23.6-jre'
testCompile group: 'junit', name: 'junit', version: '4.12'
configurations.compile.extendsFrom(configurations.extraLibs)
}
jar {
manifest {
attributes 'Main-Class': 'Runner.ClientRunner'
}
from {
configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
}
}
I've been looking for a solution for this for 4 days now with no success,
first doing the normal Gradle build task produced a tiny 7kB jar files which obviously didn't work, then i added the jar configuration for the main class:
jar {
manifest {
attributes 'Main-Class': 'Main'
}
}
It's 2MB now!
Still not good enough,
then i found the fatJar/uberJar/shadow tasks, said to be synonymous to the same thing so i tried clean then fatJar tasks on another small RMI app that will run on the server and it worked great, copied it to the main app, it produces and 60MB jar file which looks good but it won't work for some reason,
The app runs perfectly from my IDE (IntelliJIDEA) but the jar produced just does nothing.
So my last option is to consult experts so here we go:
This's the result of the clean task:
6:11:10 PM: Executing external task 'clean'...
:clean
BUILD SUCCESSFUL
Total time: 0.774 secs
6:11:11 PM: External task execution finished
'clean'.
This's the result of the fatJar task:
6:13:13 PM: Executing external task 'fatJar'...
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:compileJava
:processResources
:classes
:fatJar
BUILD SUCCESSFUL
Total time: 24.831 secs
6:13:37 PM: External task execution finished 'fatJar'.
This's my build.gradle file
group 'Yasmeena'
version '1.0-SNAPSHOT'
apply plugin: 'java'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
jar {
manifest {
attributes 'Main-Class': 'Main'
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar',
'Implementation-Version': version,
'Main-Class': 'Main'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
allprojects {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.mchange:c3p0:0.9.5.2'
compile 'commons-beanutils:commons-beanutils:1.9.3'
// compile 'org.apache.commons:commons-collections3:2.2-SNAPSHOT'
compile 'commons-digester:commons-digester:2.1'
compile 'commons-logging:commons-logging:1.2'
compile 'commons-validator:commons-validator:1.6'
compile 'org.controlsfx:controlsfx:8.40.13'
compile 'com.jfoenix:jfoenix:1.7.0'
compile 'com.mchange:mchange-commons-java:0.2.11'
compile 'com.github.PlusHaze:TrayNotification:-SNAPSHOT'
compile 'com.google.firebase:firebase-admin:5.3.0'
compile 'org.jetbrains:annotations:15.0'
compile 'org.slf4j:slf4j-simple:1.7.25'
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
compile group: 'com.impossibl.pgjdbc-ng', name: 'pgjdbc-ng', version: '0.6'
compile group: 'org.eclipse.jdt.core.compiler', name: 'ecj', version: '4.6.1'
compile group: 'de.jensd', name: 'fontawesomefx', version: '8.9'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
compile group: 'com.lowagie', name: 'itext', version: '2.1.7'
compile group: 'org.olap4j', name: 'olap4j', version: '1.2.0'
compile fileTree(dir: 'lib', include: 'ReportUtilities.jar')
compile('net.sf.jasperreports:jasperreports:6.4.1') {
exclude group: 'com.itextpdf'
}
runtime 'com.itextpdf:itextpdf:5.5.0'
runtime 'com.itextpdf:itext-pdfa:5.5.0'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
my Main.java class which holds my main method exists directly in the main -> java directory
This's my settings.gradle file:
rootProject.name = 'Yasmeena'
My main method is a simple method that launches the JavaFX application:
public static void main(String[] args) {
launch(args);
}
This's my project structure
UPDATE:
Current state of build.gradle file:
group 'Yasmeena'
version '1.0-SNAPSHOT'
apply plugin: 'java'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
jar {
manifest {
attributes 'Main-Class': 'activities.Main'
}
}
allprojects {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.mchange:c3p0:0.9.5.2'
compile 'commons-beanutils:commons-beanutils:1.9.3'
compile 'commons-digester:commons-digester:2.1'
compile 'commons-logging:commons-logging:1.2'
compile 'commons-validator:commons-validator:1.6'
compile 'org.controlsfx:controlsfx:8.40.13'
compile 'com.jfoenix:jfoenix:1.7.0'
compile 'com.mchange:mchange-commons-java:0.2.11'
compile 'com.github.PlusHaze:TrayNotification:-SNAPSHOT'
compile 'com.google.firebase:firebase-admin:5.3.0'
compile 'org.jetbrains:annotations:15.0'
compile 'org.slf4j:slf4j-simple:1.7.25'
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
compile group: 'com.impossibl.pgjdbc-ng', name: 'pgjdbc-ng', version: '0.6'
compile group: 'org.eclipse.jdt.core.compiler', name: 'ecj', version: '4.6.1'
compile group: 'de.jensd', name: 'fontawesomefx', version: '8.9'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
compile group: 'com.lowagie', name: 'itext', version: '2.1.7'
compile group: 'org.olap4j', name: 'olap4j', version: '1.2.0'
compile fileTree(dir: 'lib', include: 'ReportUtilities.jar')
compile('net.sf.jasperreports:jasperreports:6.4.1') {
exclude group: 'com.itextpdf'
}
runtime 'com.itextpdf:itextpdf:5.5.0'
runtime 'com.itextpdf:itext-pdfa:5.5.0'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'eu.appsatori:gradle-fatjar-plugin:0.3'
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar',
'Implementation-Version': version,
'Main-Class': 'activities.Main',
'Class-Path': ". ${configurations.compile.collect { it.getName() }.join(' ')}"
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
Current state of project structure
Inside the jar file there's an activities folder which contains a Main.class file
UPDATE:
jar file -> META-INF -> MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: Gradle Jar
Implementation-Version: 1.0-SNAPSHOT
Class-Path: . ReportUtilities.jar c3p0-0.9.5.2.jar commons-beanutils-1
.9.3.jar commons-digester-2.1.jar commons-logging-1.2.jar commons-val
idator-1.6.jar controlsfx-8.40.13.jar jfoenix-1.7.0.jar mchange-commo
ns-java-0.2.11.jar TrayNotification--SNAPSHOT.jar firebase-admin-5.3.
0.jar annotations-15.0.jar slf4j-simple-1.7.25.jar postgresql-42.1.4.
jar pgjdbc-ng-0.6.jar ecj-4.6.1.jar fontawesomefx-8.9.jar commons-col
lections-3.2.2.jar itext-2.1.7.jar olap4j-1.2.0.jar jasperreports-6.4
.1.jar google-api-client-1.22.0.jar google-api-client-gson-1.22.0.jar
google-http-client-1.22.0.jar json-20160810.jar guava-20.0.jar googl
e-cloud-storage-1.2.1.jar slf4j-api-1.7.25.jar netty-all-4.0.32.Final
.jar bcmail-jdk14-138.jar bcprov-jdk14-138.jar xercesImpl-2.11.0.jar
jcommon-1.0.23.jar jfreechart-1.0.19.jar castor-xml-1.3.3.jar jackson
-core-2.1.4.jar jackson-databind-2.1.4.jar jackson-annotations-2.1.4.
jar lucene-core-4.5.1.jar lucene-analyzers-common-4.5.1.jar lucene-qu
eryparser-4.5.1.jar core-3.2.1.jar icu4j-57.1.jar google-oauth-client
-1.22.0.jar google-http-client-jackson2-1.22.0.jar google-http-client
-gson-1.22.0.jar httpclient-4.0.1.jar google-cloud-core-1.2.1.jar goo
gle-cloud-core-http-1.2.1.jar google-api-services-storage-v1-rev100-1
.22.0.jar castor-core-1.3.3.jar commons-lang-2.6.jar javax.inject-1.j
ar stax-1.2.0.jar stax-api-1.0-2.jar lucene-queries-4.5.1.jar lucene-
sandbox-4.5.1.jar guava-jdk5-17.0.jar httpcore-4.0.1.jar commons-code
c-1.3.jar joda-time-2.9.2.jar api-common-1.1.0.jar gax-1.4.1.jar prot
obuf-java-util-3.3.0.jar proto-google-common-protos-0.1.12.jar proto-
google-iam-v1-0.1.12.jar google-auth-library-credentials-0.7.0.jar go
ogle-auth-library-oauth2-http-0.7.0.jar google-http-client-appengine-
1.21.0.jar google-http-client-jackson-1.21.0.jar stax-api-1.0.1.jar j
akarta-regexp-1.4.jar auto-value-1.2.jar threetenbp-1.3.3.jar protobu
f-java-3.3.0.jar jackson-core-asl-1.9.11.jar bctsp-jdk14-1.38.jar bcp
rov-jdk14-1.38.jar bcmail-jdk14-1.38.jar xml-apis-1.4.01.jar jsr305-3
.0.0.jar gson-2.7.jar
Main-Class: activities.Main
As per the comments here is what was tried.
Making sure a main class is set
Making sure the main class has the same full class name as the one defined
Checking the manifest is valid
Checking the class exists
JavaFX may need a plugin
In the end the last one fixed the issue this was the plugin that fixed the issue.
This was the last comment in the chain:
#jrtapsell Well, this's embarrassing but i'v found the problem, i was unaware that JavaFX apps need a special plugin for Gradle, Using the FiberFox Plugin solved my issue, Thanks for your efforts and may you post answers so that i could upvote you if you like