this is my build.gradle
plugins {
// Apply the java-library plugin for API and implementation separation.
id 'java-library'
id 'java'
id 'application'
}
mainClassName = 'myproject.Main'
sourceCompatibility = 1.8
targetCompatibility = 1.8
version = '1.0'
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
// 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:31.1-jre'
implementation 'com.google.api-client:google-api-client:1.18.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
implementation 'com.google.apis:google-api-services-sheets:v4-rev20220927-2.0.0'
}
jar {
exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF', 'META-INF/LICENSE', 'META-INF/LICENSE.txt', 'META-INF/DEPENDENCIES', 'META-INF/NOTICE', 'META-INF/NOTICE.txt'
manifest {
attributes 'Main-Class':'myproject.Main'
}
from{
configurations.runtimeClasspath.collect{ it.isDirectory()? it : zipTree(it) }
}
}
after i export my project using eclipse, it got problem when i run it. It seems that it has problem with the dependencies.
i want to export it into runnable jar file that can get data from google spreadsheets
Related
I have a multi-module project with the following build.gradel files
core:
repositories {
mavenCentral()
}
dependencies {
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}
test-module:
dependencies {
implementation project(":core")
}
app:
repositories {
mavenCentral()
}
dependencies {
implementation project(":core")
implementation project(":test")
}
springBoot{
mainClassName = "com.yenovi.dev.Main"
}
and then the root :
buildscript {
repositories {
mavenCentral()
}
}
plugins {
id "io.spring.dependency-management" version "1.0.4.RELEASE"
id 'org.springframework.boot' version '2.3.3.RELEASE'
id 'war'
}
repositories {
mavenCentral()
}
subprojects {
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: "io.spring.dependency-management"
apply plugin: 'org.springframework.boot'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
}
The core module is supposed to represent the spring boot application, the test module provides extra functionality by creating a Service that is used in Core via dependency injection.
The app module has a main class that calls SpringApplication.run(Core.class, args);. I that app seems useless but at the end, this module will be replaced by separate projects that will use modules from this project.
The problem is that this way the compilation of test fails with an error saying that the package from core can not be found. After some googling I've found that applying the spring boot plugin to all modules causes this issue because it disables the jar task. However without that plugin, the build fails with an error that says that the spring boot starter web dependency can not be found but I need that in all my modules so I can use stuff like the #Service annotation.
How could I solve this?
In Gradle, if you don't specify a version number to the dependencies you use, they need to be supplied by something else. In your case, that something else is the io.spring.dependency-management plugin. However, it only knows about Spring Boot if you also have the org.springframework.boot plugin applied. So once you remove that, the dependency management plugin cannot supply versions for the dependencies anymore.
There are many ways to get around this. Here are the main ones I can think of. All are in Groovy DSL. I list each as a general case, so you will have to adapt it a bit for your project. More specifically, you should remove all plugins from the root (or set them to apply false) and add them to the relevant sub-projects instead. You also likely won't need the war and idea plugins.
(I personally prefer option B by the way.)
A. Use the Spring Dependency Management plugin in isolation
Have the Spring Boot plugin in the list, but don't apply it. This makes the plugin classes available on the project classpath so you can reference it. Then you can give the Spring Boot bom to the dependency management plugin:
plugins {
id 'org.springframework.boot' version '2.4.0' apply false // <- Apply false
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
See more here.
B. Don't use the Spring Dependency Management plugin
One of the strength of this plugin is if you are migrating from Maven as it mirrors the dependency management rules. There are also a few other features. However, if you are not using those features and are not migrating from Maven, you don't need it. Just use normal Gradle semantics:
plugins {
id 'org.springframework.boot' version '2.4.0' apply false // <- Apply false
id 'java'
}
dependencies {
implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
implementation 'org.springframework.boot:spring-boot-starter'
}
// OR:
plugins {
id 'java'
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.4.0")
implementation 'org.springframework.boot:spring-boot-starter'
}
C. Use both plugins, but disable the boot jar task.
The Spring Boot plugin disables the normal jar task, but you can just re-enable it. Because the jar file name is the same in both jar and bootJar, you can't have them both at the same time. So either also disable bootJar or give it a classifier. Here I have disabled it.
plugins {
id 'org.springframework.boot' version '2.4.0' // <- Apply true
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
jar {
enabled = true
}
bootJar {
enabled = false
}
See more here.
I apologize for the long answer. I got carried away :)
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.
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.
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'
}
I have been working on multi module gradle project for spring boot devtools. Here is the github repo - GitHub Repo
-spring-boot-dev-tools
-src/main
-java/com/jhooq/springboot/devtools
-resources
-spring-boot-dev-tools.gradle ====- subproject gradle
-.gitignore
-build.gradle ====- main gradle
-gradlew
-gradlew.bat
-settings.gradle
This how my build.gradle(main gradle)looks like : -
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
allprojects {
group 'com.jhooq'
version '1.0-SNAPSHOT'
}
subprojects{
repositories {
mavenCentral()
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile ("org.springframework.boot:spring-boot-starter")
compile ("org.springframework.boot:spring-boot-starter-test")
}
}
project(':spring-boot-dev-tools'){
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
compile project(':spring-boot-app')
compile ("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
}
So as you can see if i put compile ("org.springframework.boot:spring-boot-starter-web") inside project(':spring-boot-dev-tools') my spring boot application starts on port 8000 and keeps running
But i face issue when i move following gradle scripts inside spring-boot-dev-tools.gradle, then my spring boot application starts and shutdown just like normal spring boot application.
project(':spring-boot-dev-tools'){
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
compile project(':spring-boot-app')
compile ("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
So if i summarize my issue when i move spring spring-boot-starter-web and spring-boot-devtools dependencies inside submodule, spring boot doesn't work/run on port:8000 but instead it starts and shutdown like a normal spring boot application.
Is there a reason why you have defined main class in every separate Java package?
I recently made a modular monolith example which might help you:
modular monolith example
Also some tips to consider:
define a common gradle configuration instead of "allprojects" and "subprojects" keywords. Difference between these two comes down to composition over inheritance
use keyword implementation instead of compile. That way your dependencies do not leak into the compile classpath of consumers anymore. Otherwise use keyword api
I managed to get it working but still the solution is apparently does not feel good to me. But anyways here is what i did -
I moved sub project/module dependency to its own gradle file and removed it from build.gradle(main project gradle)
Instead of "compile project" i switched to "implementation"
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
implementation {
'org.springframework.boot:spring-boot-devtools'
':spring-boot-app'
'org.springframework.boot:spring-boot-starter-web'
}
}