Gradle Builds an Empty Jar File - java

I converted a project to gradle using gradle init from maven after updating the dependencies. gradle test works as expected. However, when I run gradle build, the jar file that's generated is entirely empty.
I've attempted to tweak the source set to make something happen, but that doesn't seem to solve the problem. The directory structure matches what gradle expects from what I can tell everything is nested in src/main/groovy
The project's full code is available on Github.
In general what causes no files to be added to a build? Is there additional configuration I need to add besides whatever gradle init creates?
Gradle build file:
plugins {
id 'java'
id 'maven-publish'
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:3.0.5'
implementation 'com.github.javafaker:javafaker:1.0.2'
testImplementation 'org.spockframework:spock-core:2.0-M3-groovy-3.0'
testCompileOnly 'org.projectlombok:lombok:1.18.12'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.12'
}
group = 'nl.topicus.overheid'
version = '0.2.0'
description = 'java-factory-bot'
sourceCompatibility = '1.8'
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

What going on now is the project is try to build as Java project and get src from src/main/java as it is default from Java project. So, you need id 'groovy' not id 'java' in plugins section to make it look into src/main/groovy and build both .java and .groovy files in there.

Related

Clojure (clara rule) file not generated when gradle build

I have a Spring application that integrates a clara rule engine (clojure) file that is triggered from a java class. When building the app with gradle, the clojure file is not generated as part of the JAR.
So, when running ther jar, it throws the following exception:
Caused by: java.io.FileNotFoundException: Could not locate au/com/acme/mti/mec/runtime/rules/mec__init.class or au/com/acme/mti/mec/runtime/rules/mec.clj on classpath.
What is the best way (or at least a way) to make gradle generates the clj file when building/generating the jar?
I have already include a task in the build.gradle file to copy the clj file from src path to the build path. It copies the file under the build path, but it does not in the jar.
build.gradle:
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'jacoco'
}
group = 'au.com.acme.mti.mec'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
mavenLocal()
maven {
url "http://clojars.org/repo"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.clojure:clojure:1.9.0'
implementation 'com.cerner:clara-rules:0.20.0'
implementation 'org.projectlombok:lombok'
}
}
task copyRules(type: Copy){
from 'src/main/resources/au.com.acme.mti.mec.runtime.rules/'
into 'build/classes/java/main/au/com/acme/mti/mec/runtime/rules/'
}
test {
test.dependsOn copyRules
useJUnitPlatform()
finalizedBy jacocoTestReport
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
}
Putting the Clojure files (the Clara rules) in a place, where they end up in the correct place inside the JAR, would make the copy task obsolute (which is not used for building the JAR -- at least from the part of the build.gradle we can see in the question.
Move the files from src/main/resources/au.com.acme.mti.mec.runtime.rules to src/main/resources/au/com/acme/mti/mec/runtime/rules
Get rid of the copyRules task (and it's dependsOn)
edit:
Added a repository that shows a minimal working example, that puts the clj files just into resources https://github.com/christoph-frick/try-java-clara

Difficult Gradle multiproject build for given structure

I need to setup a Gradle multiproject java build with a fixed build folder.
The structure needs to be like this:
--projectRoot/
----build/ (shared for both subprojects)
----javaApp1/
----javaApp2/
After the build there should be two shell scripts for starting the applications:
--projectRoot/
----build/
------javaApp1
------javaApp2
------libs/
--------javaApp1.jar
--------javaApp2.jar
so far my settings.gradle is in the projectRoot:
rootProject.name = 'com.example.project'
include 'javaApp1'
include 'javaApp2'
and the build.gradle in the projectRoot:
allprojects {
repositories {
jcenter()
}
buildDir = new File(projectDir, "../build")
}
subprojects {
group 'com.example.project'
apply plugin: 'java'
apply plugin: 'application'
dependencies {
testImplementation 'junit:junit:4.12'
}
}
with this I'm already able to build from the projectRoot and with gradle installDist I get the wanted shell scripts in projectRoot/build/install/javaApp1/bin/javaApp1 but not in the build folder directly.
So to recap: the shell scripts should end up in projectRoot/build.

Gradle multi-module. Check context of first module with EventListener from another module

I have two modules, first runs Spring boot Application and second it is EventListener which loads files from resources when context starts. All this modules works well separately but I wanna to include event listener module to my first module (Spring boot module) to get all files from resource of my first module when it runs context.
My main module with setting.gradle:
allprojects {
buildDir = file("${rootDir}/build")
group = 'com.example'
version = "0.1.1"
}
subprojects {
apply plugin: 'java'
apply plugin: 'maven'
}
setting.gradle
rootProject.name = 'test-application'
include 'bootApplication'
include 'eventListener'
project(":eventListener").projectDir = file("C:/examples/eventListener")
My bootApplication.gradle:
plugins {
id 'org.springframework.boot' version '2.2.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group 'com.example.bootApplication'
version = "0.1.1"
sourceCompatibility = '11'
targetCompatibility = '11'
repositories {
jcenter()
mavenLocal()
mavenCentral()
}
bootJar {
baseName("bootApplication")
}
jar {
enabled = true
}
dependencies {
compile project(":eventListnere")
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.springfox:springfox-swagger2:+'
implementation 'io.springfox:springfox-swagger-ui:+'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
And my eventListener:
plugins {
id 'org.springframework.boot' version '2.2.1.RELEASE'`enter code here`
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group 'com.example.eventlistener'
version '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
targetCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
ext {
spring_boot_version = '2.2.1.RELEASE'
}
implementation "org.springframework.boot:spring-boot-starter:$spring_boot_version"
compileOnly 'org.projectlombok:lombok:1.18.8'
annotationProcessor 'org.projectlombok:lombok:1.18.8'
testImplementation "org.springframework.boot:spring-boot-starter-test:$spring_boot_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
jar.enabled = true
When I run my bootApplication main class it creates a eventlistener-.jar file in root build directory. But eventlistener module doesn't check the resource folder, I guess it doesn't see a bootApplication context. Maybe it should be collect to one jar file? It looks like I missed something in gradle build files.
I will just prefix this by saying I don't know if the stuff below is the actual cause of your problems. But you should probably change a few things related to the jar configuration no matter what.
The Spring Boot Gradle plugin is used to create a fat jar out of the project. By default it disables the normal jar task.
You are re-enabling the normal jar task through jar.enabled = true, which is fine. But you also need to give it another name as one will otherwise override the other. For instance, for your eventListener project, you could do this:
// eventListener/build.gradle
bootJar {
classifier = 'boot'
}
However, if the eventListener is not actually a stand-alone executable, there is no need to create a boot jar from it. So unless you are using the plugin for other things, I would remove it from the eventListener completely:
// eventListener/build.gradle
plugins {
// id 'org.springframework.boot' version '2.2.1.RELEASE'`enter code here` <-- Remove this
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
You can still use the Spring Boot starters in the project, you just don't need the plugin for repackaging the jar.
The same thing applies to your bootApplication project: you are both trying to create a fat executable jar at the same time as a normal jar. One will override the other. In this case, you probably don't need the normal jar, so you should disable the jar task again:
// eventListener/build.gradle
// jar.enabled = true <-- Remove this
Lastly, replace compile project(":eventListnere") with implementation project(":eventListener") and testCompile with testImplementation to avoid some deprecation warnings. The maven plugin is deprecated as well in favor of maven-publish. You can probably also get rid of mavenLocal() unless you are integrating with local Maven projects that you build yourself with mvn install.
The eventListener, if packaged correctly as a normal jar inside the fat jar of the bootApplication, should be able to access resources in both its own resource folder as well as the one from bootApplication when you run the latter.

Java jar file won't recognize external libraries added from gradle

Yo folks basically I'm using gradle in java project and can't export the libraries in jar file that I'm using.
Tried a few solutions but nothing worked.
Do you know what I'm missing in the gradle file or I need to specify some things when I'm exporting. I'm using Eclipse
Thanks, here is my gradle file
enter code here
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
repositories {
// Use jcenter for resolving your 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:27.0.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
implementation "redis.clients:jedis:3.0.1"
implementation 'org.pixsee.java-fcm:Java-fcm:1.0.0'
implementation 'com.google.firebase:firebase-admin:6.10.0'
compile "org.slf4j:slf4j-api:1.6.1"
implementation 'org.slf4j:slf4j-simple:1.7.25'
implementation "com.google.maps:google-maps-services:0.9.4"
implementation 'io.vertx:vertx-core:3.8.1'
}
sourceCompatibility = 1.8
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'GeofenceServer',
'Implementation-Version': version
}
}
apply plugin: "eclipse"
Finally solved it , the answer from Sterconium got me on the right track
answer but the problem was when I try to create the fatJar it says cannot find the main class ,the reason was because my files are in src/test/java instead of src/main/java and somehow when I tried to run fatJar it compiled It but could not find still the dependencies, so I change the implementation to compile in build.gradle file and now it works .So here is my final build.gradle file how it looks like .
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/5.4/userguide/java_library_plugin.html
*/
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
apply plugin: "java"
apply plugin: "eclipse"
version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'Server.Test'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
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:27.0.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
implementation "redis.clients:jedis:3.0.1"
implementation 'com.google.firebase:firebase-admin:6.10.0'
implementation 'org.slf4j:slf4j-simple:1.7.25'
implementation 'com.google.maps:google-maps-services:0.10.0'
compile 'io.vertx:vertx-core:3.8.1'
implementation 'com.google.code.gson:gson:2.8.5'
}

Gradle custom plugin jar with dependencies

I'm trying to build a jar for a custom gradle plugin to be used by other gradle projects. I'm using java to write the plugin. I'm having a problem including dependencies in my jar. If I build the jar using the below build.gradle
plugins {
id 'groovy'
}
repositories{
mavenCentral()
}
dependencies {
compile gradleApi()
compile localGroovy()
compile 'com.google.guava:guava:27.0-jre'
testCompile 'junit:junit:4.12'
//compile 'org.apache.commons:commons-lang3:3.8.1'
}
group = 'com.mine'
version = '1.0'
I get a NoClassDefFound exception for guava classes when applying the plugin on a project. If I include a task to create a jar with dependencies like below in the build.gradle
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)}
}
}
It says Plugin with Id 'my-plugin' not found. How do I include dependencies in a gradle plugin jar?
Your plugin project should be configured as a standalone Plugin project and then published to a maven repository, which will make dependencies resolution work; there is good documentation about writing custom plugin here, specially the following part : using Gradle plugin development plugin
There is also a good example of writing/publishing/consuming a custom Plugin in the Gradle examples here : https://github.com/gradle/gradle/tree/master/subprojects/docs/src/samples/plugins (see the two subprojects publishing and consuming )
And here is a working example with a plugin that has dependency on external library (commons-lang for example):
Plugin project
build.gradle
plugins {
id 'java-gradle-plugin'
id 'groovy'
id 'maven-publish'
}
group 'org.gradle.sample.plugin'
version '0.1'
// pugin metadata configuration
gradlePlugin {
plugins {
myplugin {
id = "org.gradle.sample.plugin.myplugin"
implementationClass = "org.gradle.sample.plugin.MyPlugin"
}
}
}
// publish to local maven repo for testing
publishing {
repositories {
maven {
url "../repos/maven-repo"
}
}
}
// repo for dependences resolution
repositories{
jcenter()
}
// dependencies of this plugin
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
}
Plugin implementation : src/main/groovy/org/gradle/sample/plugin/MyPLugin.groovy
package org.gradle.sample.plugin
import org.apache.commons.lang3.StringUtils
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyPlugin implements Plugin<Project> {
#Override
void apply(final Project project) {
println "Applying custom plugin... "
project.tasks.create('testPlugin'){
doLast{
println " custom plugin task executing."
println "Result: " + StringUtils.capitalize("stringtotest")
}
}
}
}
Build and publish this plugin ./gradlew publish : the plugin jar and "plugin marker artefacts" will be published to local maven repo in ../repos/maven-repo
Consumer project
build.gradle
plugins {
id 'java'
// import/apply your custom plugin
id 'org.gradle.sample.plugin.myplugin' version '0.1'
}
group 'org.gradle.sample.plugin'
version '0.1'
repositories{
maven {
url "../repos/maven-repo"
}
jcenter()
}
To test the plugin, try to execute the plugin task testPlugin
> Task :testPlugin
custom plugin task executing.
Result: Stringtotest
Sorry to add this as an answer but I don't have enough points to comment (yes it is a bit late in coming but I found this in a search and it came so close, maybe this will help someone else).
The answer by #M.Ricciuti is correct, just missing one file, namely a settings.gradle in the referencing project (not the plugin) directory:
pluginManagement {
repositories {
maven {
url '../repos/maven-repo'
}
gradlePluginPortal()
ivy {
url '../repos/ivy-repo'
}
}
}
Many thanks, I have tried many things that didn't work before finding this, even the examples by gradle didn't work (or more likely I didn't run them correctly). Anyway I merged what I saw in the answers with M. Ricciuti's answer and saw that file in the sample.
My complete project is at https://github.com/reddierocket/sampleGradlePlugin
The readme has instructions to run it. (Note I did not include the wrapper but I am using gradle version 5.3.1.)

Categories