gradle.properties settings not considered - gradle

As a starter in gradle I am converting a project from maven to gradle. When running tests I get an OutOfMemoryError: Java heap space. If I add
tasks.withType(Test) {
jvmArgs = ['-Xmx2g']
}
to build.gradle then it works. However, if that is configured only in gradle.properties as org.gradle.jvmargs=-Xmx2g then it doesn't.
Same for the encoding. There is one test which is only running successful if GRADLE_OPTS=-Dfile.encoding=UTF-8 is set. But if I set systemProp.file.encoding=UTF-8 in gradle.properties it doesn't.
Why is that?

The answer is described in the Gradle DSL documentation for the Test task.
Test are always run in (one or more) separate JVMs.
Whatever you configure in gradle.properties environment variable applies to the Gradle JVM process only.
Maximum heap size is configured like you did via jvmArgs or, preferably, via maxHeapSize.
Regarding file encoding & GRADLE_OPTS, I don't have a definite answer. My best guess is that it has just not been implemented this way. You can set the file encoding on a per project basis for compilation tasks like this:
tasks.withType(Compile) {
options.encoding = 'UTF-8'
}
From: Gradle Goodness: Set Java Compiler Encoding

Related

List all properties contributed by BOM to gradle 5

Is there a way to list all properties contributed by a given bom to gradle using gradlew/gradle
Suppose I have the following build script
dependencies {
//*** bill of materials
springBom platform("org.springframework.boot:spring-boot-dependencies:2.1.2.RELEASE")
}
I would like to list all properties that are available as part of the bom, how can I do that?
I know it contributes a property called micrometer.version because the source says so
Ref: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-dependencies/pom.xml
io.spring.dependency-managementplugin makes all of the properties from imported BOMs available for use in your Gradle build.
So, basically, you can write your custom gradle task to print all of them.
tasks.register("spring-boot-properties") {
group = 'Introspection'
description = 'Print properties from all BOMs'
doLast {
println dependencyManagement.importedProperties
}
}
Then just execute the task: ./gradlew spring-boot-properties
Maven BOM support in Gradle does not expose that information. The properties are effectively inlined when parsing the POM hierarchy and thus no longer available in the dependency metadata format of Gradle.
As commented in the other answer, using the Spring dependency-management-plugin gives you access to these values.

How to pass system properties to the tests in gradle in the smart way?

build.gradle
tasks.withType(Test){
systemProperties=System.properties
println systemProperties['param']
}
Now I can either pass parameters in the command line:
gradle test -Dparam=10
or put them in gradle.properties:
systemProp.param=15
Ideally I would like to put the defaults in the gradle.properties, and be able to overwrite them from the command line. Unfortunately if I do that, the gradle.properties has precedence, and -Dparam=10 is ignored.
Could you offer any solutions on that?
https://issues.gradle.org/browse/GRADLE-2122
It works since 2.12 or 2.13 "the smart way" already!
The example above is working, the command line -D option overdrives the defaults in gradle.properties
I am using gradle 2.12 and sharing how I used it:
test {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
I have JUnit tests that I wanted to skip unless a property was used to include such tests. Using JUnit Assume for including the tests conditionally:
//first line of test
assumeThat(Boolean.parseBoolean(System.getProperty("deep.test.run","false"),true)
Doing this with gradle required that the system property provided at the time of running gradle build, shown here,
gradle build -Ddeep.test.run=true
was indeed passed through to the tests.
Hope this helps others trying out this approach for running tests conditionally.

How do I copy a file into my WAR based on profile?

I’m using Gradle 2.7 on Mac Yosemite. I have the following files:
src/main/environment/dev/context.xml
src/main/environment/qa/context.xml
src/main/environment/prod/context.xml
What I would like is if I run a build gradle -Pqa build, the appropriate context.xml file above is copied into my WAR (into the WEB-INF/classes directory is fine). How do I set this up with gradle?
There're many ways of solving the problem. You can configure sourceSets, or include or exclude particular resources when building war file. You can also have single context.xml and perform resource filtering with ReplaceTokens filter.
I've chosen sourceSets:
apply plugin: 'war'
ext.env = project.hasProperty('env') ? project.env : 'dev'
sourceSets {
main {
resources {
srcDir "src/main/environment/$env"
}
}
}
The trick is to include/process only the env being passed. If no env is passed dev will be picked for further processing. Have a look a the demo.
You would have to do that using the environment variable. Have the system properties in a file. Read them in the build.gradle and based on it include the context.xml into the war.

How to pass system property to Gradle task

I'm using Gradle spring-boot plugin and I need to select a spring active profile for the test run.
How do I pass spring.profiles.active system property to the bootRun plugin's task?
What has already failed:
task bootRunLocal {
systemProperty "spring.profiles.active", "local"
System.setProperty("spring.profiles.active", "local")
tasks.bootRun.execute() // I suspect that this task is executed in a separate JVM
}
and some command line magic also fails:
./gradle -Dspring.profiles.active=local bootRun
Could someone kindly help me solve my troubles?
Update from the answers and comments:
I'm able to set the systemProperty and pass it to the spring container by doing :
run {
systemProperty "spring.profiles.active", "local"
}
However, when I do this, the local profile is being set for both bootRun task and bootRunLocal task. I need a way to set this property for bootRunLocal task and call booRun task from bootRunLocal.
That might sound very simple, but I come with peace from the structured world of Maven.
I know I'm late here... but I recently faced this exact issue. I was trying to launch bootRun with spring.profiles.active and spring.config.location set as system properties on the command line.
So, to get your command line "magic" to work, simply add this to your build.gradle
bootRun {
systemProperties System.properties
}
Then running from the command line...
gradle -Dspring.profiles.active=local bootRun
Will set local as the active profile, without needing to define a separate task simply to add the env variable.
task local {
run { systemProperty "spring.profiles.active", "local" }
}
bootRun.mustRunAfter local
Then run gradle command as:
gradle bootRun local
There is no generic way to pass system properties to a task. In a nutshell, it's only supported for tasks that fork a separate JVM.
The bootRunLocal task (as defined above) will not execute in a separate JVM, and calling execute() on a task isn't supported (and would have to happen in the execution phase in any case). Tests, on the other hand, are always executed in a separate JVM (if executed by a Test task). To set system properties for test execution, you need to configure the corresponding Test task(s). For example:
test {
systemProperty "spring.profiles.active", "local"
}
For more information, see Test in the Gradle Build Language Reference.
SPRING_PROFILES_ACTIVE=local gradle clean bootRun
This is according to this and this and it works.
According to the spring-boot-gradle-plugin documentation you should be able to pass arguments like this
./gradlew bootRun --args='--spring.profiles.active=dev'
Seems like this is a new gradle feature since 4.9. I used it in my project and it worked out of the box.
For gradle 2.14 below example works.
I have added as below.
When System.properties['spring.profiles.active'] is null then default profile is set.
bootRun {
systemProperty 'spring.profiles.active', System.properties['spring.profiles.active']
}
command line example
gradle bootRun -Dspring.profiles.active=dev
Just for reference if anyone will have this issue:
Vlad answer didn't quite worked for me but this one works great with 2.4,
task local <<{
bootRun { systemProperty "spring.profiles.active", "local" }
}
local.finalizedBy bootRun
then gradle local
Responding to OP's exact request here ...
How do I pass spring.profiles.active system property to the bootRun plugin's task?
And assuming by "pass" the OP meant "pass from commandline" or "pass from IDE invocation" ... This is how I like to do it.
Add this to build.gradle:
/**
* Task from spring-boot-gradle-plugin, configured for easier development
*/
bootRun {
/* Lets you pick Spring Boot profile by system properties, e.g. gradle bootRun -Dspring.profiles.active=dev */
systemProperties = System.properties
}
Then when you invoke it, use the familiar Java flag for setting a system property
gradle bootRun -Dspring.profiles.active=local
There is one main advantage of sticking to system properties, over the environment variables option (SPRING_PROFILES_ACTIVE=local gradle bootRun) ... and that's easy portability between Linux/OS X (bash, etc.) and Windows (cmd.exe anyway).
I learned this way from this blog post.
(UPDATE: Ah somehow I had missed #Erich's response with same recommendation. Oops! I'm leaving my answer, because of the additional details about portability, etc.)
You can create a new task (in discussed case with name bootRunLocal), that would extend org.springframework.boot.gradle.run.BootRunTask and setup properties before task execution. You can create such a task with following code:
task bootRunLocal(type: org.springframework.boot.gradle.run.BootRunTask) {
doFirst() {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
systemProperty "spring.profiles.active", "local"
}
}
More details can be found here:
https://karolkalinski.github.io/gradle-task-that-runs-spring-boot-aplication-with-profile-activated/
Starting from SpringBoot 2.0.0-M5 setSystemProperties() is no longer a method of the task bootRun.
The build.gradle needs to be updated to
bootRun {
execSpec {
// System.properties["spring.profiles.active"]
systemProperties System.properties
}
}
This is as springBoot's run task uses org.gradle.process.JavaExecSpec
This works for me using Gradle 4.2
This works:
SPRING_PROFILES_ACTIVE=production ./gradlew app-service:bootRun
with run command you can add to build file run { systemProperties = System.properties } and start with gradle run -Dspring.profiles.active=local
Another way which doesn't require any support from the gradle task: Set the JAVA_TOOL_OPTIONS environment variable:
JAVA_TOOL_OPTIONS='-Dfoo=bar' gradle ...
Or if the variable might already contain anything useful:
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Dfoo=bar" gradle ...
// defualt value
def profiles = 'dev'
bootRun {
args = ["--spring.profiles.active=" + profiles]
}
Then you can simply pick a specific version when starting a gradle task, like
./gradlew bootRun -P dev
"dev" is gonna to take place "prod"

OSGi bundle build issue in Gradle

I have a simple use case of building an OSGi bundle using Gradle build tool. The build is successful if there are java files present in the build path, but it fails otherwise.
I am using 'osgi' plugin inside the gradle script and trying to build without any java files. The build always fails with following error:
Could not copy MANIFEST.MF to
I am sure there must be some way to do it in Gradle but not able to fine. Any idea what can be done to resolve this depending on your experience.
I ran into this today as well, and #Peter's fix didn't work for me (I hadn't applied the java plugin in the first place...). However, after hours of Googling I did find this thread, which helped me find the problem.
Basically, it seems that the error occurs (as Peter stated) when no class files are found in the jar - my guess is because the plugin then cannot scan the classes for package names on which to base all the Import and Export information.
My solution was to add the following to the manifest specification:
classesDir = theSourceSet.output.classesDir
classpath = theSourceSet.runtimeClasspath
In my actual build code, I loop over all source sets to create jar tasks for them, so then it looks like this:
sourceSets.each { ss ->
assemble.dependsOn task("jar${ss.name.capitalize()}", type: Jar, dependsOn: ss.getCompileTaskName('Java')) {
from ss.output
into 'classes'
manifest = osgiManifest {
classesDir = ss.output.classesDir
classpath = ss.runtimeClasspath
// Other properties, like name and symbolicName, also set based on
// the name of the source set
}
baseName = ss.name
}
}
Running with --stacktrace indicates that the osgi plugin doesn't deal correctly with the case where both the osgi and the java plugins are applied, but no Java code is present. Removing the java plugin should solve the problem.
I had the same issue also when java code was present.
Adding these two lines to the osgiManifest closure fixed the problem:
classesDir = sourceSets.main.output.classesDir
classpath = sourceSets.main.runtimeClasspath
-- erik

Resources