Gradle build multi modules project with transitive dependencies - java

I have problem with building my simple app. It contains 3 modules, ejb, rest and ear in which rest should be included. To achieve it I wrote build.gradle as one below. But I still have problems. Built ear looks like:
ear-1.0.ear
|--ejbs-1.0.jar
|--rest-1.0.jar
|--lib
|--ejbs-1.0.jar
|--other libs..
As you can see, I have here duplicated ejbs-1.0.jar. It's no something I want so I have tried to work this around. I have tried 2 approaches I found on web but neither of them worked. First one (comments with label 1) excluded all rest dependencies from going into lib dir. Second (label 2) did the same but also included rest-1.0.jar into lib, making it even worse.
Now I have no idea how to write my build.gradle so it puts jars made from subprojects in root dir, and their dependencies in lib dir. I have also tried to write something like comments with label 3, but this makes script fail. Is there easy way to excluded it like that with similar syntax?
project(":ejbs") {
apply plugin: "java"
dependencies {
compile group: 'javax.ejb', name: 'javax.ejb-api', version: '3.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.2'
}
}
project(":rest") {
apply plugin: "java"
dependencies {
compile project(':ejbs')
compile group: 'javax.ejb', name: 'javax.ejb-api', version: '3.2'
compile group: 'javax.ws.rs', name: 'jsr311-api', version: '0.11'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.2'
}
}
project(":ear") {
apply plugin: "java"
apply plugin: "ear"
dependencies {
//1: def nonTransitive = {transitive = false}
deploy project(":ejbs")
deploy project(":rest")
earlib project(path:":ejbs", configuration:"compile")
earlib project(path:":rest", configuration:"compile")//1: , nonTransitive
//2: add('earlib', project(':rest')) {
// transitive = false
//}
//3: earlib project(path:":rest", configuration:"compile") {
// exlude project(':ejbs')
//}
}
}

I finally found a solution. I made it this way:
project(":ear") {
apply plugin: "java"
apply plugin: "ear"
dependencies {
deploy project(":ejbs")
deploy project(":rest")
earlib project(path:":ejbs", configuration:"compile")
earlib(project(path:":rest", configuration:"compile")) {
exclude module: 'ejbs'
}
}
}

Related

Apache Camel Timer Nullpointer exception at Fat Jar

I'm trying to implement a timer using Camel 3.5 at Gradle project with OpenJDK8 as next
from("timer://watchexpiration?fixedRate=true&period=600000&delay=0")...
But, after build the fat jar using ./gradlew build and run as java -jar build/libs/app.jar
I receive the next error at console
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: timer://watchexpiration?delay=0&fixedRate=true&period=600000 due to: Error binding property (delay=0) with name: delay on bean: timer://watchexpiration?delay=0&fixedRate=true&period=600000 with value: 0
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:888)
at org.apache.camel.impl.engine.AbstractCamelContext.getEndpoint(AbstractCamelContext.java:777)
at org.apache.camel.support.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:58)
at org.apache.camel.reifier.AbstractReifier.resolveEndpoint(AbstractReifier.java:177)
at org.apache.camel.reifier.RouteReifier.doCreateRoute(RouteReifier.java:250)
at org.apache.camel.reifier.RouteReifier.createRoute(RouteReifier.java:112)
But If I run using ./gradlew run then works fine as I expected.
I don't want to use any frameworks for this project. I feel this is just a config issue or something is wrong with my configuration I guess.
How can I fix it?
build.gradle
plugins {
id 'java'
id 'application'
id 'com.github.sherter.google-java-format' version '0.8'
}
repositories {
jcenter()
}
dependencies {
implementation 'com.google.guava:guava:29.0-jre'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
// Camel
compile group: 'org.apache.camel', name: 'camel-core', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-file', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-file-watch', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-xstream', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-gson', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-rest', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-servlet', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-http', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-jackson', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-quartz', version: '3.5.0'
compile group: 'org.apache.camel', name: 'camel-timer', version: '3.5.0'
compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.30'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
// Dev Libs
compileOnly("org.projectlombok:lombok:1.18.12")
annotationProcessor("org.projectlombok:lombok:1.18.12")
compile group: 'org.apache.commons', name: 'commons-csv', version: '1.4'
}
application {
mainClassName = 'com.eip.App'
}
configurations {
// configuration that holds jars to include in the jar
extraLibs
}
jar {
manifest {
attributes(
'Main-Class': 'com.beam.agent.App'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
test {
useJUnitPlatform()
}
googleJavaFormat {
exclude '**/App.java'
}
Shadowing jars can be tricky, because you need to handle duplicate entries. In Apache Camel there are many META-INF service files, which are getting overwritten with your simple jar approach. Use com.github.johnrengelman.shadow which is allowing you to customize the merging process.
plugins {
id 'java'
id 'application'
id 'com.github.sherter.google-java-format' version '0.8'
id "com.github.johnrengelman.shadow" version "6.0.0" // Added plugin
}
repositories {
jcenter()
}
dependencies {
// ...
}
application {
mainClassName = 'com.eip.App'
}
// Removed jar step
test {
useJUnitPlatform()
}
googleJavaFormat {
exclude '**/App.java'
}
// Added shadow plugin configuration
shadowJar {
mergeServiceFiles() // Tell plugin to merge duplicate service files
manifest {
attributes 'Main-Class': 'com.eip.App'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
Shaded executable jar will have suffix -all.jar
java -jar build/libs/app-all.jar

Dependency issues while using one gradle project in another

I am new to Gradle, basically from Maven background.
I have the following dependency in one project [Lets call it 'Project A']
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
Now I want to use 'Project A' in 'Project B'. I have done the following to refer Project A in Project B.
Updated the settings.gradle of Project B to include Project A
include ':project-a'
project(':project-a').projectDir = new File('path to Project A')
Following is added to Project B build.gradle
implementation project(":project-a")
While synchronizing, Project B complains the following.
Could not run phased build action using Gradle distribution
'https://services.gradle.org/distributions/gradle-6.6.1-bin.zip'.
Build file 'path to project A\build.gradle' line: 9 A problem occurred
evaluating project ':project-a'. Could not find method
implementation() for arguments [{group=org.apache.commons,
name=commons-lang3, version=3.0}] on object of type
org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
UPDATE*
Java plugin added as requested in comment
apply plugin: 'java'
//plugins {
// id 'java'
//}
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
implementation group: 'org.springframework', name: 'spring-context', version: "${spring_version}"
implementation group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: "${springboot_version}"
implementation group: 'org.springframework.cloud', name: 'spring-cloud-context'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-commons'
versions are declared in gradle.properties file
spring_version=5.2.5.RELEASE
springboot_version=2.2.6.RELEASE
servlet_version=3.1.0
Now none of the dependencies are getting downloaded.

NoClassDefFoundError on Spring application

Full error is in this image as I am running on virtual machine in cloud which is access via video feed so I cannot copy and paste.This is a fresh install of ubuntu where I have only installed JDK and nothing else so unaware if other setup needs to be done
https://imgur.com/a/egJ3d
It is a spring boot application.
My build.gradle
group 'com.haughon.daniel'
version '1.0-SNAPSHOT'
buildscript {
repositories{
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE'
}
}
// Apply the Spring Boot plugin
apply plugin: 'spring-boot'
// Apply the Java plugin (expects src/main/java to be source folder)
apply plugin: 'java'
apply plugin: 'idea'
// Specify the location where our dependencies will be found
repositories {
mavenCentral()
}
jar {
manifest {
attributes 'Main-Class': 'haughton.dvdstore.Application'
attributes 'addClasspath': 'true'
}
}
// Specify dependencies
dependencies {
compile 'org.hashids:hashids:1.0.1'
compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
compile 'org.springframework:spring-orm:4.3.7.RELEASE'
compile 'org.hibernate:hibernate-core:5.2.9.Final'
compile 'org.hibernate:hibernate-entitymanager:5.0.6.Final'
compile 'org.apache.tomcat:tomcat-dbcp:8.0.30'
compile 'org.springframework.boot:spring-boot-starter-security'
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')
//compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity:3.0.2.RELEASE'
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.1.RELEASE'
// https://mvnrepository.com/artifact/com.google.code.gson/gson
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.8'
runtime 'com.h2database:h2'
runtime 'javax.transaction:jta:1.1'
runtime 'org.aspectj:aspectjweaver:1.8.7'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
This is because your dependencies are not included in one jar file.
use ./gradlew clean build
please see this post:
java.lang.NoClassDefFoundError: when trying to run jar

Gretty: Duplicate fragment name: org_apache_jasper

I use gretty to easily run a dev server and webapp-runner for deployment to heroku.
The following is my gradle.build:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.akhikhl.gretty:gretty:+'
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'org.akhikhl.gretty'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.springframework:spring-webmvc:4.3.10.RELEASE'
compile 'org.springframework:spring-orm:4.3.10.RELEASE'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.0'
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.10.Final'
compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.1.1'
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
compile group: 'org.hibernate.validator', name: 'hibernate-validator', version: '6.0.1.Final'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
compile 'com.github.jsimone:webapp-runner:8.5.11.3'
}
gretty {
httpPort = 8080
servletContainer = 'jetty9'
contextPath = '/'
}
eclipse {
wtp {
component {
contextPath = '/'
}
}
}
///////// Tasks for deployment to heroku
task stage() {
dependsOn clean, war
}
war.mustRunAfter clean
task copyToLib(type: Copy) {
dependsOn war
into "$buildDir/server"
from(configurations.compile) {
include "webapp-runner*"
}
}
stage.dependsOn(copyToLib)
If I remove webapp-runner everything runs fine, but with it I get the following error when trying to start gretty:
java.lang.IllegalStateException: Duplicate fragment name: org_apache_jasper for jar
Not an expert but I figure its something to do with the fact that both gretty and webapp-runner download similar files and that's causing a clash?
Would really appreciate some info on this. How do I get past this? Is there a better way to have a dev server + be able to deploy to heroku? (maybe use webapp-runner for both?)
I recommend running locally the same way as Heroku runs your app, with these commands:
$ ./gradlew stage
$ heroku local web
If you want to use gretty for development, you'll need to exclude webapp-runner from your dev build (maybe with a stageDev task), and exclude gretty from your stage build.

Can't run individual tests within Intellij gradle

I am attempting to create a project with Gradle, when I run individual tests I get this error.
Information:26/10/16 11:22 - Compilation completed with 1 error and 0
warnings in 158ms Error:gradle-resources-test:Sunday-Sessions_test:
java.lang.NoSuchMethodError:
org.gradle.api.specs.AndSpec.getSpecsArray()[Lorg/gradle/api/specs/Spec;
I have tried refreshing the gradle project and have also done file->invalidate caches and restart, this has not helped. Here is my gradle file, can anyone see why this is happening?
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "io.ratpack:ratpack-gradle:1.3.3"
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.3"
}
}
ext {
// The drivers we want to use
drivers = ["chrome", "phantomJs"]
ext {
gebVersion = '0.13.1'
seleniumVersion = '2.52.0'
chromeDriverVersion = '2.19'
phantomJsVersion = '1.9.7'
}
}
apply plugin: "io.ratpack.ratpack-groovy"
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "idea"
apply plugin: "eclipse"
repositories {
jcenter()
}
dependencies {
// Default SLF4J binding. Note that this is a blocking implementation.
// See here for a non blocking appender http://logging.apache.org/log4j/2.x/manual/async.html
runtime 'org.slf4j:slf4j-simple:1.7.12'
// If using Spock, need to depend on geb-spock
testCompile("org.gebish:geb-spock:$gebVersion") {
exclude group: 'org.codehaus.groovy'
}
testCompile("org.spockframework:spock-core:1.0-groovy-2.4") {
exclude group: "org.codehaus.groovy"
}
// If using JUnit, need to depend on geb-junit (3 or 4)
testCompile("org.gebish:geb-junit4:$gebVersion") {
exclude group: "org.codehaus.groovy"
}
// http://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.52.0'
compile "org.shamdata:sham:0.3"
// Drivers
testCompile "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
// using a custom version of phantomjs driver for now as the original one does not support WebDriver > 2.43.1
testCompile("com.codeborne:phantomjsdriver:1.2.1") {
// phantomjs driver pulls in a different selenium version
transitive = false
}
testCompile('io.ratpack:ratpack-remote-test:1.3.0') {
exclude group: "org.codehaus.groovy"
}
// http://mvnrepository.com/artifact/com.google.inject/guice
compile group: 'com.google.inject', name: 'guice', version: '3.0'
compile 'io.ratpack:ratpack-handlebars:1.2.0'
compile 'com.fasterxml.jackson:jackson-parent:2.7-1'
compile 'postgresql:postgresql:9.1-901-1.jdbc4'
compile 'org.codehaus.groovy:groovy-all:2.4.4'
testCompile ratpack.dependency('test')
compile ratpack.dependency("remote")
testCompile ratpack.dependency("remote-test")
compile ratpack.dependency("hikari")
// https://mvnrepository.com/artifact/com.restfb/restfb
compile group: 'com.restfb', name: 'restfb', version: '1.26.0'
//Grab the user location with GeoIP2
compile 'com.maxmind.geoip2:geoip2:2.8.0-rc1'
}

Categories