Compile dependencies dynamically based on spring.profiles.active - java

Can someone please guide me where to start this task?
I'd simply have to exclude spring-boot-starter-tomcat when deploying to jboss.
I imagine it will look something like:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web"){
if(getProperty "spring.profiles.active" == "qat")
exclude module: "spring-boot-starter-tomcat"
}
testCompile('org.springframework.boot:spring-boot-starter-test')
}
With the sample above, I get an error:
Could not get unknown property 'spring.profiles.active' for DefaultExternalModuleDependency{group='org.springframework.boot', name='spring-boot-starter-web', version='null', configuration='default'} of type org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency.
Maybe I could create a custom task to set spring.profiles.active on the task. HELP!

As Peter Ledbrook mentioned, gradle does not have access to spring-boot's application.yml at compile time. And the dependencies run very early in gradle's lifecycle that a task is never called before dependencies are resolved.
Even trying dependency resolution strategy was futile.
So I just had to do:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web") {
if(System.getProperty("spring.profiles.active") == "qat"){
exclude module: "spring-boot-starter-tomcat"
}
}
compile("org.springframework.boot:spring-boot-starter-security")
if(System.getProperty("spring.profiles.active") == "qat"){
providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
}
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Then I'll type gradle build -Dspring-profiles-active=qat when deploying to jboss. and gradle bootRun -Dspring-profiles-active=dev when I have to run locally.

Related

Gradle dependencies in JHipster format "groupId:artifact"

I am posting here to understand how does JHipster work with Gradle dependencies, in particular with regards to the fact that I am unable to copy some of them into a Gradle submodule I have created inside my JH project.
For example, the following doesn't work in a Gradle submodule
compile "junit:junit"
Error is
Could not resolve: junit:junit
However, the classic one copied from mvnrepository works great
compile group: 'junit', name: 'junit', version: '4.12'
Some additional information: I am creating a submodule that contains a set of classes related to testing, mainly a large load of custom Hamcrest matchers copied from another project from the Ant world. The original project had a lot of spaghetti code mess, so now I am refactoring into an isolated Gradle module. The testlib module shall depend on the testing frameworks and contain everything required for writing good tests. It can be compared to spring-test project you would use to write your own Spring-based tests.
At the moment, the gradle file looks like
plugins {
id "java"
}
configurations {
providedRuntime
implementation.exclude module: "spring-boot-starter-tomcat"
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
group 'org.example' //different from com.acme of super-project
version '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile group: 'org.assertj', name: 'assertj-core', version: '3.13.2'
compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'
compile group: 'org.hamcrest', name: 'hamcrest', version: '2.1'
compile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
compile group: 'org.springframework.boot', name: 'spring-boot', version: spring_boot_version
compile "junit:junit" //Fails
}
Question
So the question is in two parts:
why does the scope "orgId:name" syntax work in the JHipster-generated module but not in submodules? Is it part of standard Gradle syntax?
why is that not working in a sub-module? Does JHipster apply a custom plugin to apply the correct version number that is clearly missing? How I do the same in a sub-module that is supposed to contain only Java library code?
With regards to JHipster, a little of more investigation helped. According to this answer, there is a trick in Gradle called Bill Of Materials project, so...
TL;DR
Add the following to the sub-project
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
So that the whole block looks like
dependencies {
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
compile "org.assertj:assertj-core"
compile "org.junit.jupiter:junit-jupiter-api"
compile "org.hamcrest:hamcrest"
compile "org.mockito:mockito-core"
compile "org.springframework.boot:spring-boot"
compile "junit:junit"
}
Long answer
Maybe in the future when I will understand Gradle more. Or just edit this answer 😁 to contribute
The bom defines the versions (besides other things) of 3rd party dependencies to be used so you can omit the explicit version. If you do not use the bom you can also write compile "junit:junit:4.12" but keep in mind jhipster uses already junit5 for all tests by default.
Regarding the import of the bom you can do it like you proposed or try to apply that dependency to all gradle subprojects in your main gradle file.

SpringBoot test module doesn't search log4j2 configuration in the right classpath

I'm having some problems running tests in my SpringBoot project.
The project-structure is the following:
Project Structure Image
I can start the resourceService without issues, but if i even try to run the standard test of SpringBoot projects.....
package com.pcsystem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ResourceserviceApplicationTests {
#Test
public void contextLoads() {
}
}
the program respond with this error:
Logging system failed to initialize using configuration from 'resourceservice/log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\resourceservice\resourceservice\log4j2.xml (Unable to find the specified classpath)
So i tried to change the application.properties specific property from
logging.config=resourceservice/log4j2.xml
to
logging.config=log4j2.xml
After the change i've noticed that resourceserviceApplication will not start because it can't find the log4j2.xml:
Logging system failed to initialize using configuration from 'log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\log4j2.xml (Unable to find the specified classpath)
I've tried to resolve in many ways and doing a lot of researches but at the moment i'm still stuck here.
Any idea?
ps: it seems that the Authorizationservice module doesn't suffer the same problem, but simply because i haven't set the logging.config property in Authorizationservice's application.properties (there is no need for now)
Thanks in advance and have a great day.
-UPDATE 1-
Configuration file is about all the resourceService module, so i've done as you said Kostiantyn ( thanks for you response ) but the problem still persist.
Actual situation:
Project structure after your reply
Now resourceServiceApplication won't start , saying :
Logging system failed to initialize using configuration from 'log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\log4j2.xml
and the contextLoads() method from the test package says:
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\resourceservice\log4j2.xml
Let me show you configuration file:
server.port=8888
logging.config=log4j2.xml
spring.data.mongodb.host=localhost
spring.data.mongodb.database=jogging
#spring.data.mongodb.username=admin
#spring.data.mongodb.password=pass
spring.data.mongodb.port=27017
As requested from user1615664 , below you can see my gradle file
(that's the gradle file about the resourceService module;
AuthorizationService have one specific gradle file and lastly there is
a root gradle file, that i will show to you at the end of this update)
Exscuse me for the lenght, i'm using a large number of libraries here.
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
configurations {
compile.exclude group:'ch.qos.logback'
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
exclude module: "logback-classic"
}
compile('org.springframework.boot:spring-boot-starter-log4j2')
compile group: 'org.apache.tika', name: 'tika', version: '1.16', ext: 'pom'
compile group: 'org.apache.tika', name: 'tika-parsers', version: '1.16'
compileOnly('org.projectlombok:lombok')
compile("org.springframework.boot:spring-boot-starter-actuator")
//compile project(':authorizationservice')
// https://mvnrepository.com/artifact/org.springframework.hateoas/spring-hateoas
compile group: 'org.springframework.hateoas', name: 'spring-hateoas', version: '0.23.0.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.6'
compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.1.1.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-jwt', version: '1.0.8.RELEASE'
// https://mvnrepository.com/artifact/org.apache.axis/axis
compile group: 'org.apache.axis', name: 'axis', version: '1.4'
// https://mvnrepository.com/artifact/axis/axis-jaxrpc
compile group: 'axis', name: 'axis-jaxrpc', version: '1.4'
// https://mvnrepository.com/artifact/commons-discovery/commons-discovery
compile group: 'commons-discovery', name: 'commons-discovery', version: '0.5'
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
// https://mvnrepository.com/artifact/javax.xml/jaxrpc-api
compile group: 'javax.xml', name: 'jaxrpc-api', version: '1.1.1'
// https://mvnrepository.com/artifact/org.apache.xmlrpc/xmlrpc
compile group: 'org.apache.xmlrpc', name: 'xmlrpc', version: '3.1.3', ext: 'pom'
// https://mvnrepository.com/artifact/javax.activation/activation
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
// https://mvnrepository.com/artifact/javax.mail/mail
compile group: 'javax.mail', name: 'mail', version: '1.4.7'
// https://mvnrepository.com/artifact/wsdl4j/wsdl4j
compile group: 'wsdl4j', name: 'wsdl4j', version: '1.6.3'
testCompile('org.springframework.boot:spring-boot-starter-test')
}
PS: maybe is worthless , but in the root module ( baseProjectOauth2 )
we can admire this root gradle file
group 'com.pcsystem'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
You've missing src/test/resources folder in your project structure, and looks like current location of log4j2.xml in the project root is not under classpath at all
Rely on Gradle project convention and place your config files accordingly, i.e. create either src/test/resources and put file in there, if your logging configuration is test specific:
src
test
java
...
resources
log4j2.xml
Or, if logging configuration inside your log4j2.xml will be used by your application during live run (included into .jar deliverable), move this file to src/main/resources instead
that will bring your logging.config=log4j2.xml working.
Further reading about Gradle project structure & resources folders is here
I feel greedy replying to my own question, but i think i've solved.
I've done these things:
-> created resource folder under test module
src
main
test
java
resources
application.properties
In that properties file i've only put this setup
logging.config=log4j2.xml
And all i have to say now is
"explicative image here"
Simply i have to deep study spring structure (and even gradle one) about auto detect of properties files
You can try to put value classpath:log4j2.xml instead of just log4j2.xml into your application.properties (or application.y[a]ml) file.
All the resources, including this file, should be placed inside the src/main/resources (where application.properties file is also placed). Regardless of a few possible exceptions.
If you want a different configuration of logging for tests, than you should put adapted file inside of tests' resources directory (src/test/resources), but if you want these to be the same, then you can leave it as is (inside src/man/resources only)

Gradle won't import a bintray dependency, but doesn't throw any error

I'm creating a project which uses the Squash SQL Library for Kotlin. I've added the dependency to my build.gradle file. When running the update it just finishes without outputting any errors. But the library is not getting imported in my project and doesn't appear at all.
The dependencies shown in IntelliJ:
My build.gradle file:
//Kotlin Stuff, nothing changed here
repositories {
mavenCentral()
maven {
url "http://dl.bintray.com/kotlin/squash"
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'org.jetbrains.squash:squash:0.2.2'
}
//Kotlin Stuff
The dependency you've added is just the parent-pom which doesn't have any jar's in the repo. Here is the list of the squash projects (http://dl.bintray.com/kotlin/squash/org/jetbrains/squash/):
squash-core
squash-graph
squash-h2
squash-jdbc
squash-postgres
squash-sqlite
I guess you want to import the squash-core so change
compile 'org.jetbrains.squash:squash:0.2.2'
to
compile 'org.jetbrains.squash:squash-core:0.2.2'

Multiproject build: dependency to tests jar

I'm restructuring/refactoring build process for a big(ish) project. Currently it contains over a dozen separate modules built with standalone build scripts each. I want to integrate them all into a single multiproject build in Gradle.
After I integrated all sources into a single tree, fixed build.gradles, I came upon the following problem. Dependencies for many modules contain something like:
dependencies {
compile group: 'com.company', name: 'Module', version: '1.2.3'
// ...
testCompile group: 'com.company', name: 'Module', version: '1.2.3', classifier: 'tests'
}
I want the build to use jars from the subproject, not from a repository. I replaced compile ... with compile project(':Module') and it works fine. However, I cannot find the way to pass 'tests' specifier to the testCompile project... dependency.
Is there a way to pick up the tests jar as a dependency to testCompile?
In the producing project you will need to declare the "Test" JAR as outgoing artifact.
configurations {
testUtils
}
task testUtilsJar(type: Jar) {
...
}
artifacts {
testUtils testUtilsJar
}
In the consuming project you depend on it as such:
dependencies {
testCompile project(path: ':Module', configuration: 'testUtils')
}

How do I exclude all instances of a transitive dependency when using Gradle?

My gradle project uses the application plugin to build a jar file. As part of the runtime transitive dependencies, I end up pulling in org.slf4j:slf4j-log4j12. (It's referenced as a sub-transitive dependency in at least 5 or 6 other transitive dependencies - this project is using spring and hadoop, so everything but the kitchen sink is getting pulled in... no wait... that's there too :) ).
I want to globally exclude the slf4j-log4j12 jar from my built jar. So I've tried this:
configurations {
runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}
However, this seems to exclude all org.slf4j artifacts including slf4j-api. When running under debug mode I see lines such as:
org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).
I do not want to have to look up the source of each slf4j-log4j12 transitive dependency and then have individual compile foo { exclude slf4j... } statements in my dependencies block.
Update:
I did also try this:
configurations {
runtime.exclude name: "slf4j-log4j12"
}
Which ends up excluding everything from the build! As though I specified group: "*".
Update 2:
I'm using Gradle version 1.10 for this.
Ah, the following works and does what I want:
configurations {
runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}
It seems that an Exclude Rule only has two attributes - group and module.
Hence for excluding from only an individual dependency, we can do something like:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", module: "slf4j-log4j12"
}
}
However, the above syntax doesn't prevent you from specifying any arbitrary property as a predicate. When trying to exclude from an individual dependency you cannot specify arbitrary properties. For example, this fails:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", name: "slf4j-log4j12"
}
}
with
No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule
So even though you can specify a dependency with a group: and name: you can't specify an exclusion with a name:!?!
Perhaps a separate question, but what exactly is a module then? I can understand the Maven notion of groupId:artifactId:version, which I understand translates to group:name:version in Gradle. But then, how do I know what module (in gradle-speak) a particular Maven artifact belongs to?
For excluding one or more library globally add the following to your build.gradle
configurations.all {
exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
exclude group:"ch.qos.logback", module:"logback-core"
}
Now the exclude block has two properties group and module. For those of you coming from maven background, group is same as groupId and module is same as artifactId.
Example: To exclude com.mchange:c3p0:0.9.2.1 following should be exclude block
exclude group:"com.mchange", module:"c3p0"
Your approach is correct. (Depending on the circumstances, you might want to use configurations.all { exclude ... }.) If these excludes really exclude more than a single dependency (I haven't ever noticed that when using them), please file a bug at http://forums.gradle.org, ideally with a reproducible example.
in the example below I exclude
spring-boot-starter-tomcat
compile("org.springframework.boot:spring-boot-starter-web") {
//by both name and group
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
I was using spring boot 1.5.10 and tries to exclude logback, the given solution above did not work well, I use configurations instead
configurations.all {
exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
In addition to what #berguiga-mohamed-amine stated, I just found that a wildcard requires leaving the module argument the empty string:
compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
exclude group: 'org.apache.httpcomponents', module: ''
exclude group: 'org.slf4j', module: ''
}
compile is deprecated and it was replaced by implementation. Therefore, the solution for those running newer versions of gradle:
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
This is for Kotlin DSL (build.gradle.kts) which prevents you from using wrong properties.
Exclude the library from all configrations (implementation, runtimeOnly, etc.):
configurations.all {
exclude(group = "ir.mahozad.android", module = "pie-chart")
// OR exclude("ir.mahozad.android", "pie-chart")
}
// Another notation:
// configurations {
// all {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library from a single configuration (like implementation):
configurations.implementation {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
// Another notation:
// configurations {
// implementation {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library for a single dependency:
dependencies {
// ...
implementation("ir.mahozad.android:charts:1.2.3") {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
}

Categories

Resources