Gradle: create a single JAR with dependencies - java

I am migrating our product's build from Ant to Gradle, having started from a single project and got the following error:
> Could not resolve all files for configuration ':Shared:serverbase:compileClasspath'.
> Could not find guava:guava:23.3-jre.
Searched in the following locations:
- https://jcenter.bintray.com/guava/guava/23.3-jre/guava-23.3-jre.pom
- file:/F:/pros/X/java/guava/guava-23.3-jre.xml
Required by:
project :Shared:serverbase
Why it is looking for xml-files instead of jar?
Here are my files:
build.gradle in project's root directory:
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6' // gwt compiler plugin
}
}
allprojects {
apply from: rootProject.file('libraries.gradle')
repositories {
jcenter()
ivy {
url "file://${rootProject.projectDir}/ThirdParty/java/"
patternLayout {
artifact "[organization]/[module](-[revision])(.[ext])"
}
}
}
}
subprojects {
apply plugin: 'java-library'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.debugOptions.debugLevel = "lines,vars,source"
compileJava.options.compilerArgs += ["-nowarn"]
compileJava.options.debug = true
}
build.gradle of this single project:
sourceSets.main.java.srcDirs = ['src']
dependencies {
implementation "guava:guava:${guavaVersion}"
implementation "slf4j:jul-to-slf4j:${slf4jVersion}"
implementation "logback:logback-classic:${logbackVersion}"
}
jar {
manifest {
attributes 'Class-Path': configurations.compileClasspath.collect { it.getName() }.join(' ')
}
}
settings.gradle:
rootProject.name = 'X'
include 'Shared:serverbase'
libraries.gradle:
ext {
...
guavaVersion = '23.3-jre'
...
}
(some content stripped)
And if I add file dependency to build.gradle as local file (How to add local .jar file dependency to build.gradle file?)
implementation files("guava-${guavaVersion}.jar")
I got tons of errors like 'error: package org.slf4j does not exist' so it seems that dependencies were not satisfied at all.
The outcome should be a single jar with compiled sources.
I am a novice in gradle, please forgive my unenlightenment.

Your Guava dependency is not correct.
Change from:
implementation "guava:guava:${guavaVersion}"
To:
implementation "com.google.guava:guava:${guavaVersion}"

Related

External libraries are not found in the final build

I been working on a project that uses an external jar file. Whenever, I build my project using build.grade, and the external files does not get added to the final jar file. Inside my workspace, I have a "libs" folder which holds the external jar file (Discord Rich Presence). Can anyone help me sort this out?
buildscript {
repositories {
jcenter()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
version = "1.0"
group= "com.yourname.modid"
archivesBaseName = "example"
minecraft {
version = "1.8.9-11.15.1.1722"
runDir = "run"
mappings = "stable_20"
}
repositories {
flatDir {
dirs "libs"
}
}
dependencies {
compile name: 'discord-rpc'
}
processResources {
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
expand 'version':project.version, 'mcversion':project.minecraft.version
}
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
The default task jar only packages the files of project source code. To include all the dependencies inside the JAR file, you could try https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow:
plugins {
...
id "com.github.johnrengelman.shadow" version "7.0.0"
}
...
Run this command to package all:
$ ./gradlew shadowJar

How to deploy a Jar from a library project

I have a library project in Java which is several folders, each one doing specific parts and having its own dependencies.
Since I am working locally I would like to deploy this library locally and get the Jar to import to another project.
For this reason I am using gradle and what I did was going to the directory where I have all the folders of the library and gradle init and then gradle build.
Since I want the files locally, I saw that I can use gradle publishToMavenLocal, which I did and it created a jar file under ~/.m2/..... Now the issue is that this jar file appear to only contain a META-INF folder and inside of it a manifest.mf file.
This is the build.gradle file used.
What am I doing wrong? Should I do something different?
check gradle docs
there is also a complete example.
be sure to add your sourceSets that you want to compile and build in the jar.
build.gradle
plugins {
id 'java'
id 'maven-publish'
}
repositories {
mavenLocal()
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceSets {
main {
java { srcDir 'src/main/java' }
resources {
srcDirs 'src/main/resources'
}
}
test {
java { srcDir 'src/test/java' }
resources {
srcDirs 'src/test/resources'
}
}
}
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.gradle.sample'
artifactId = 'project1-sample'
version = '1.1'
from components.java
}
}
}
You could also add your library project to your main project like this :
build.gradle
dependencies {
compile project(':library_project')
}
settings.gradle
rootProject.name = 'Project'
include ":library_project"
project(':library_project').projectDir = new File(settingsDir, '../library_project')

gradle java library plugin doesn't put files under src/main/resources to jar file

I use gradle java library plugin and maven publish plugin to create a jar file then publish it to a nexus repo. However, the generated jar file doesn't include the application.properties file under the src/main/resource path. I did some research and apparently gradle should add the files under src/main/resource path to the jar by default. so I have no idea why it's not added.
my project structure
src
--main
--java
--com.abc.bcd
--A.java
--B.java
--C.java
--resources
--application.properties
my build.gradle file is like this
/*
* This file was generated by the Gradle 'init' task.
*/
apply plugin: 'java-library'
apply plugin: 'maven-publish'
repositories {
mavenCentral()
}
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
classifier = 'sources'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
implementation 'com.google.guava:guava:27.0-jre'
api 'org.springframework.boot:spring-boot-starter-webflux:2.1.2.RELEASE'
testImplementation "org.assertj:assertj-core:3.11.1"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
testImplementation "com.github.tomakehurst:wiremock-standalone:2.19.0"
testImplementation "org.junit.platform:junit-platform-surefire-provider:1.3.2"
testImplementation "org.junit.platform:junit-platform-runner:1.3.2"
testImplementation "ru.lanwen.wiremock:wiremock-junit5:1.2.0"
}
group = 'com.abc.bcd'
version = '0.0.1'
publishing {
publications {
metrics(MavenPublication) {
from components.java
artifact sourcesJar
}
}
repositories {
maven {
credentials {
username = "${nexus_user}"
password = "${nexus_pass}"
}
url 'https://nexus.abc.io/repository/bcd-shared/content/repositories/snapshots'
}
}
}
jar {
into("META-INF/maven/$project.group/$project.name") {
from { generatePomFileForMetricsPublication }
rename ".*", "pom.xml"
}
}
the generated jar file now only includes java classes
com
--abc
--bcd
--A.class
--B.class
--C.class
META-INF
--MANIFEST.MF
--maven
--abc.bcd
--pom.xml

Trying to use tools.jar - gradle

I am using gradle to package some java code into a jar. I am using some classes from tools.jar. I have had success in gradle building it and making a jar, but when I run that jar using java -jar <package>.jar I get the folowing
java.lang.NoClassDefFoundError: com/sun/tools/attach/VirtualMachine.
Since tools.jar is something you get with a jdk, not a jre. Is there a way I can bundle tools.jar with my package.jar and have my jar work anywhere?
Here is my build.gradle so far.
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
}
description = "A java program"
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
flatDir {
dirs System.properties['java.home'] + '/../lib'
}
}
jar {
archiveName = "jProg.jar"
manifest {
attributes(
'Dependencies': 'com.sun.tools'
)
}
}
dependencies {
compile group: 'com.sun', name: 'tools'
}
Probably what you need is called 'fat jar' (Gradle packs all dependencies to single jar)

Include distribution folder of frontend build in the JAR with Gradle

I am a gradle beginner and I am struggling to include the frontend distribution build folder in the backend jar (I use Spring Boot and the frontend is an ionic app). In the backend.gradle, I configured the jar-Task that should include the frontend-build folder (called www) into build folder of the backend. The jar task runs through, but the desired artifacts are not present in the backend-build folder and therefore not in the final jar. Would be glad for any help.
project structure:
project
build.gradle
settings.gradle
backend
--> backend.gradle
frontend
--> frontend.gradle
settings.gradle
include 'backend'
include 'frontend'
rootProject.children.each {
it.buildFileName = it.name + '.gradle'
}
build.gradle
allprojects {
buildscript {
repositories {
mavenCentral()
}
}
apply plugin: 'idea'
repositories {
mavenCentral()
}
}
frontend.gradle
plugins {
id "com.moowork.node" version "1.2.0"
}
task clean(dependsOn: 'npm_run_clean') {
}
task build(dependsOn: 'npm_run_build') {
}
backend.gradle
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
group = 'ch.renewinkler'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
jar {
from('frontend/www') {
into('public')
}
}
processResources.dependsOn(':frontend:build')
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
You need to tell gradle that the jar task depends on the frontend's build task, otherwise it could run the jar file before the build task, and thus have nothing to include in the jar.
It's also a better idea to refer to projects by their name, instead of using absolute paths:
jar {
dependsOn(':frontend:build')
into('public') {
from "${project(':frontend').projectDir}/www"
}
}

Categories

Resources