// Copyright 2017 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[build_environment]]
= Build Environment

TIP: Interested in configuring your Build Cache to speed up builds? https://gradle.com/training/build-cache-deep-dive/?bid=docs-build-environment[Register here] for our Build Cache training session to learn some of the tips and tricks top engineering teams are using to increase build speed.

[.lead]
Gradle provides multiple mechanisms for configuring behavior of Gradle itself and specific projects. The following is a reference for using these mechanisms.

When configuring Gradle behavior you can use these methods, listed in order of highest to lowest precedence (first one wins):

* <<command_line_interface.adoc#command_line_interface, Command-line flags>> such as `--build-cache`. These have precedence over properties and environment variables.
* <<#sec:gradle_system_properties, System properties>> such as `systemProp.http.proxyHost=somehost.org` stored in a `gradle.properties` file.
* <<#sec:gradle_configuration_properties, Gradle properties>> such as `org.gradle.caching=true` that are typically stored in a `gradle.properties` file in a project root directory or `GRADLE_USER_HOME` environment variable.
* <<#sec:gradle_environment_variables, Environment variables>> such as `GRADLE_OPTS` sourced by the environment that executes Gradle.

Aside from configuring the build environment, you can configure a given project build using <<#sec:project_properties, Project properties>> such as `-PreleaseType=final`.

[[sec:gradle_configuration_properties]]
== Gradle properties

Gradle provides several options that make it easy to configure the Java process that will be used to execute your build. While it's possible to configure these in your local environment via `GRADLE_OPTS` or `JAVA_OPTS`, it is useful to store certain settings like JVM memory configuration and Java home location in version control so that an entire team can work with a consistent environment.

Setting up a consistent environment for your build is as simple as placing these settings into a `gradle.properties` file. The configuration is a combination of all your `gradle.properties` files, but if an option is configured in multiple locations, the _first one wins_:

* system properties, e.g. when `-Dgradle.user.home` is set on the command line.
* `gradle.properties` in `GRADLE_USER_HOME` directory.
* `gradle.properties` in project root directory.
* `gradle.properties` in Gradle installation directory.

The following properties can be used to configure the Gradle build environment:

`org.gradle.caching=(true,false)`::
When set to true, Gradle will reuse task outputs from any previous build, when possible, resulting is much faster builds. Learn more about <<build_cache.adoc#build_cache, using the build cache>>.

`org.gradle.caching.debug=(true,false)`::
When set to true, individual input property hashes and the build cache key for each task are logged on the console. Learn more about <<build_cache.adoc#sec:task_output_caching, task output caching>>.

`org.gradle.configureondemand=(true,false)`::
Enables incubating <<multi_project_builds.adoc#sec:configuration_on_demand, configuration on demand>>, where Gradle will attempt to configure only necessary projects.

`org.gradle.console=(auto,plain,rich,verbose)`::
Customize console output coloring or verbosity. Default depends on how Gradle is invoked. See <<command_line_interface.adoc#sec:command_line_logging, command-line logging>> for additional details.

`org.gradle.daemon=(true,false)`::
When set to `true` the <<gradle_daemon.adoc#gradle_daemon, Gradle Daemon>> is used to run the build. Default is `true`.

`org.gradle.daemon.idletimeout=(# of idle millis)`::
Gradle Daemon will terminate itself after specified number of idle milliseconds. Default is `10800000` (3 hours).

`org.gradle.debug=(true,false)`::
When set to `true`, Gradle will run the build with remote debugging enabled, listening on port 5005. Note that this is the equivalent of adding `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005` to the JVM command line and will suspend the virtual machine until a debugger is attached. Default is `false`.

`org.gradle.java.home=(path to JDK home)`::
Specifies the Java home for the Gradle build process. The value can be set to either a `jdk` or `jre` location, however, depending on what your build does, using a JDK is safer. A reasonable default is derived from your environment (`JAVA_HOME` or the path to `java`) if the setting is unspecified. This does not affect the version of Java used to launch the Gradle client VM (<<#sec:gradle_environment_variables, see Environment variables>>).

`org.gradle.jvmargs=(JVM arguments)`::
Specifies the JVM arguments used for the Gradle Daemon. The setting is particularly useful for <<#sec:configuring_jvm_memory,configuring JVM memory settings>> for build performance. This does not affect the JVM settings for the Gradle client VM.

`org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)`::
When set to quiet, warn, lifecycle, info, or debug, Gradle will use this log level. The values are not case sensitive. The `lifecycle` level is the default. See <<logging.adoc#sec:choosing_a_log_level,Choosing a log level>>.

`org.gradle.parallel=(true,false)`::
When configured, Gradle will fork up to `org.gradle.workers.max` JVMs to execute projects in parallel. To learn more about parallel task execution, see link:https://guides.gradle.org/performance/#parallel_execution[the Gradle performance guide].

`org.gradle.priority=(low,normal)`::
Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Default is `normal`. See also <<command_line_interface.adoc#sec:command_line_performance, performance command-line options>>.

`org.gradle.unsafe.watch-fs=(true,false)`::
Toggles <<gradle_daemon.adoc#sec:daemon_watch_fs,watching the file system>>.
Allows Gradle to re-use information about the file system in the next build.
_Default is off_.

`org.gradle.warning.mode=(all,fail,summary,none)`::
When set to `all`, `summary` or `none`, Gradle will use different warning type display. See <<command_line_interface.adoc#sec:command_line_logging,Command-line logging options>> for details.

`org.gradle.workers.max=(max # of worker processes)`::
When configured, Gradle will use a maximum of the given number of workers. Default is number of CPU processors. See also <<command_line_interface.adoc#sec:command_line_performance, performance command-line options>>.

The following example demonstrates usage of various properties.

.Setting properties with a gradle.properties file
====
include::sample[dir="snippets/tutorial/properties/groovy",files="gradle.properties[]"]
====

====
include::sample[dir="snippets/tutorial/properties/groovy",files="build.gradle[]"]
include::sample[dir="snippets/tutorial/properties/kotlin",files="build.gradle.kts[]"]
====

----
$ gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps
include::{snippetsPath}/tutorial/properties/tests/properties.out[]
----

[[sec:gradle_system_properties]]
== System properties

Using the `-D` command-line option, you can pass a system property to the JVM which runs Gradle. The `-D` option of the `gradle` command has the same effect as the `-D` option of the `java` command.

You can also set system properties in `gradle.properties` files with the prefix `systemProp.`

.Specifying system properties in `gradle.properties`
----
systemProp.gradle.wrapperUser=myuser
systemProp.gradle.wrapperPassword=mypassword
----

The following system properties are available. Note that command-line options take precedence over system properties.

`gradle.wrapperUser=(myuser)`::
Specify user name to download Gradle distributions from servers using HTTP Basic Authentication. Learn more in <<gradle_wrapper.adoc#sec:authenticated_download,Authenticated wrapper downloads>>.
`gradle.wrapperPassword=(mypassword)`::
Specify password for downloading a Gradle distribution using the Gradle wrapper.
`gradle.user.home=(path to directory)`::
Specify the Gradle user home directory.

In a multi project build, “`systemProp.`” properties set in any project except the root will be ignored. That is, only the root project's `gradle.properties` file will be checked for properties that begin with the “`systemProp.`” prefix.

[[sec:gradle_environment_variables]]
== Environment variables

The following environment variables are available for the `gradle` command. Note that command-line options and system properties take precedence over environment variables.

`GRADLE_OPTS`::
Specifies JVM arguments to use when starting the Gradle client VM. The client VM only handles command line input/output, so it is rare that one would need to change its VM options.
The actual build is run by the Gradle daemon, which is not affected by this environment variable.
`GRADLE_USER_HOME`::
Specifies the Gradle user home directory (which defaults to `$USER_HOME/.gradle` if not set).
`JAVA_HOME`::
Specifies the JDK installation directory to use for the client VM. This VM is also used for the daemon, unless a different one is specified in a Gradle properties file with `org.gradle.java.home`.

[[sec:project_properties]]
== Project properties

You can add properties directly to your link:{groovyDslPath}/org.gradle.api.Project.html[Project] object via the `-P` command line option.

Gradle can also set project properties when it sees specially-named system properties or environment variables. If the environment variable name looks like `ORG_GRADLE_PROJECT___prop__=somevalue`, then Gradle will set a `prop` property on your project object, with the value of `somevalue`. Gradle also supports this for system properties, but with a different naming pattern, which looks like `org.gradle.project.__prop__`. Both of the following will set the `foo` property on your Project object to `"bar"`.

.Setting a project property via a system property
----
org.gradle.project.foo=bar
----

.Setting a project property via an environment variable
----
ORG_GRADLE_PROJECT_foo=bar
----

[NOTE]
====
The properties file in the user's home directory has precedence over property files in the project directories.
====

This feature is very useful when you don't have admin rights to a continuous integration server and you need to set property values that should not be easily visible. Since you cannot use the `-P` option in that scenario, nor change the system-level configuration files, the correct strategy is to change the configuration of your continuous integration build job, adding an environment variable setting that matches an expected pattern. This won't be visible to normal users on the system.

You can access a project property in your build script simply by using its name as you would use a variable.

[NOTE]
====
If a project property is referenced but does not exist, an exception will be thrown and the build will fail.

You should check for existence of optional project properties before you access them using the link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:hasProperty(java.lang.String)[Project.hasProperty(java.lang.String)] method.
====

[[sec:configuring_jvm_memory]]
== Configuring JVM memory

You can adjust JVM options for Gradle in the following ways:

The `org.gradle.jvmargs` Gradle property controls the VM running the build. It defaults to `-Xmx512m "-XX:MaxMetaspaceSize=256m"`

.Changing JVM settings for the build VM
----
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
----

The `JAVA_OPTS` environment variable controls the command line client, which is only used to display console output. It defaults to `-Xmx64m`

.Changing JVM settings for the client VM
----
JAVA_OPTS="-Xmx64m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8"
----

[NOTE]
====
There is one case where the client VM can also serve as the build VM:
If you deactivate the <<gradle_daemon.adoc#gradle_daemon, Gradle Daemon>> and the client VM has the same settings as required for the build VM, the client VM will run the build directly.
Otherwise the client VM will fork a new VM to run the actual build in order to honor the different settings.
====

Certain tasks, like the `test` task, also fork additional JVM processes. You can configure these through the tasks themselves.
They all use `-Xmx512m` by default.

.Set Java compile options for link:{groovyDslPath}/org.gradle.api.tasks.compile.JavaCompile.html[JavaCompile] tasks
====
include::sample[dir="snippets/buildEnvironment/javaCompileOptions/groovy",files="build.gradle[]"]
include::sample[dir="snippets/buildEnvironment/javaCompileOptions/kotlin",files="build.gradle.kts[]"]
====

See other examples in the link:{groovyDslPath}/org.gradle.api.tasks.testing.Test.html[Test] API documentation and <<java_testing.adoc#sec:test_execution, test execution in the Java plugin reference>>.

link:https://scans.gradle.com[Build scans] will tell you information about the JVM that executed the build when you use the `--scan` option.

[caption="Build Environment in build scans",link=https://scans.gradle.com/s/sample/cpp-parallel/infrastructure]
image::build-scan-infrastructure.png[Build Environment in build scan]

[[sec:configuring_task_using_project_properties]]
== Configuring a task using project properties

It's possible to change the behavior of a task based on project properties specified at invocation time.

Suppose you'd like to ensure release builds are only triggered by CI. A simple way to handle this is through an `isCI` project property.

.Prevent releasing outside of CI
====
include::sample[dir="snippets/tutorial/configureTaskUsingProjectProperty/groovy",files="build.gradle[]"]
include::sample[dir="snippets/tutorial/configureTaskUsingProjectProperty/kotlin",files="build.gradle.kts[]"]
====

----
$ gradle performRelease -PisCI=true --quiet
include::{snippetsPath}/tutorial/configureTaskUsingProjectProperty/tests/configureTaskUsingProjectProperty.out[]
----

[[sec:accessing_the_web_via_a_proxy]]
== Accessing the web through a HTTP proxy

Configuring an HTTP or HTTPS proxy (for downloading dependencies, for example) is done via standard JVM system properties. These properties can be set directly in the build script; for example, setting the HTTP proxy host would be done with `System.setProperty('http.proxyHost', 'www.somehost.org')`. Alternatively, the properties can be <<#sec:gradle_configuration_properties,specified in gradle.properties>>.

.Configuring an HTTP proxy using `gradle.properties`
----
systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=userid
systemProp.http.proxyPassword=password
systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost
----

There are separate settings for HTTPS.

.Configuring an HTTPS proxy using `gradle.properties`
----
systemProp.https.proxyHost=www.somehost.org
systemProp.https.proxyPort=8080
systemProp.https.proxyUser=userid
systemProp.https.proxyPassword=password
systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost
----

You may need to set other properties to access other networks. Here are 2 references that may be helpful:

* link:https://git-wip-us.apache.org/repos/asf?p=ant.git;a=blob;f=src/main/org/apache/tools/ant/util/ProxySetup.java;hb=HEAD[ProxySetup.java in the Ant codebase]
* link:http://download.oracle.com/javase/7/docs/technotes/guides/net/properties.html[JDK 7 Networking Properties]

=== NTLM Authentication

If your proxy requires NTLM authentication, you may need to provide the authentication domain as well as the username and password. There are 2 ways that you can provide the domain for authenticating to a NTLM proxy:

* Set the `http.proxyUser` system property to a value like `__domain__/__username__`.
* Provide the authentication domain via the `http.auth.ntlm.domain` system property.
