- Gradle java file encoding
- rponte / build.gradle
- Sourcefile Encoding with Gradle
- Java files
- Groovy files
- Eclipse integration
- Intellij IDEA integration
- Gradle java file encoding
- getMinHeapSize
- setMinHeapSize
- getMaxHeapSize
- setMaxHeapSize
- getJvmArgs
- setJvmArgs
- setJvmArgs
- jvmArgs
- jvmArgs
- getJvmArgumentProviders
- getBootstrapClasspath
- setBootstrapClasspath
- bootstrapClasspath
- getEnableAssertions
- setEnableAssertions
- getDebug
- setDebug
- getDebugOptions
- debugOptions
- getAllJvmArgs
- setAllJvmArgs
- setAllJvmArgs
- copyTo
Gradle java file encoding
Certain tasks in our build were messing up character encodings of our source files (which all start out as UTF-8).
What we finally discovered is that when the Gradle Daemon is started (in org.gradle.launcher.DaemonConnector.java), it doesn’t copy in any of the program or VM arguments from the originating gradle command, or the existing environment settings that are set using GRADLE_OPTS or JAVA_OPTS. Among other things, we had been setting GRADLE_OPTS to set the file.encoding Java system property. But when the Gradle Daemon executed our gradle builds, the JVM was set to use the platform default, which is, for instance, Mac Roman on Mac OS X.
Obviously it isn’t a great idea to rely on the platform default encoding, but we’re calling into 3rd-party ant scripts from our builds (in this case to concatenate and compress javascript source files), and those ant scripts made use of tasks which used the platform default (for instance the LoadFile Ant task does this).
I can see there’s an argument against passing on command-line args from the gradle command to the Daemon, but shouldn’t the Daemon make use of environment settings like GRADLE_OPTS and JAVA_OPTS in a same way that the gradle shell command does?
I cannot reproduce this issue with 1.0-milestone-3. Are you sure the version is correct?
Here’s how I performed the tests (passing sys props from GRADLE_OPTS and explicitly from terminal). It worked fine regardless of —daemon
task printSys "file.encoding sys property code-object">System.properties["file.encoding"] println "foo env variable code-object">System.getenv("foo") >
Is this how you would expect the env/sys props are honored by gradle?
There’s one gotcha with env. variables, though. Since the daemon process is long-living and you cannot change the env variables in java, you need to restart the daemon if you change the environment variable. At least that’s the behavior at the moment (in theory we could fix it by restarting the process in case env variable has changed).
So, one of the confusing things about the file.encoding system property is that the JVM only checks this property once when it’s starting up. Changing that system property at a later date doesn’t effect the encoding used by code depending on the default encoding.
So, if you instead use this task:
(If it doesn’t come through, I used a UTF-8 character on the last println. )
What will happen is that even when GRADLE-OPTS is set to be «-Dfile.encoding=UTF-8», when the build is executed by the Daemon the special UTF-8 character won’t print correctly, even though the file.encoding property will show up as «UTF-8».
Certain system properties like file.encoding need to be set on the command line when the java command is executed, not later.
Thanks for looking at this!
Thanks for info. We will try to address it. The simple solution would be to pass those ‘special’ system properties at process bootstrap. However, this will not solve the problem in case some wants to change the file.encoding when daemon is already running
We should probably come up with a general solution for jvm settings which can only be applied at startup. For example:
When these value have changed since the daemon has started, we could:
- kill the existing daemon and start a new one with the new settings.
- start a new daemon, leaving the old one to expire some point in the future.
- run the build in the client process.
Option 2. is a good one, I think, provided we tweak the expiry algorithm to take into account things such as how many daemon are already running.
The daemon now properly respects file.encoding as an immutable property that needs to be correct on startup.
It has also for sometime correctly managed mutable system properties.
There may be other immutable properties like file.encoding, but as they are not known right now I’m going to close this off and we can open new tickets for them as needed.
rponte / build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
apply plugin : ‘ java ‘ |
apply plugin : ‘ eclipse ‘ |
sourceCompatibility = JavaVersion . VERSION_1_8 |
targetCompatibility = JavaVersion . VERSION_1_8 |
eclipseJdt |
ant . propertyfile( file : » .settings/org.eclipse.core.resources.prefs » ) |
ant . entry( key : » eclipse.preferences.version » , value : » 1 » ) |
ant . entry( key : » encoding/ » , value : » utf-8 » ) |
> |
> |
/** |
* 1st approach: Setting encoding during compilation in Java and Test classes |
*/ |
compileJava . options . encoding = » UTF-8 « |
compileTestJava . options . encoding = » UTF-8 « |
/** |
* 2nd approach: Setting encoding during compilation in Java and Test classes |
* |
tasks.withType(JavaCompile) |
options.encoding = «UTF-8» |
> |
tasks.withType(Test) |
systemProperty «file.encoding», «UTF-8» |
> |
*/ |
repositories |
jcenter() |
maven |
url » https://oss.sonatype.org/content/groups/public/ « |
> |
> |
def springVersion = » 4.3.2.RELEASE « |
def dbunitVersion = » 2.5.1 « |
dependencies |
/** |
* Dependências das classes de produção |
*/ |
compile » org.slf4j:slf4j-api:1.7.21 « |
compile » org.slf4j:jul-to-slf4j:1.7.21 « |
compile » org.slf4j:jcl-over-slf4j:1.7.21 « |
compile » org.slf4j:slf4j-log4j12:1.7.21 « |
/** |
* Spring |
*/ |
compile » org.springframework:spring-core: $ < springVersion >« |
compile » org.springframework:spring-context: $ < springVersion >« |
compile » org.springframework:spring-tx: $ < springVersion >« |
compile » org.springframework:spring-jdbc: $ < springVersion >« |
/** |
* Dependências dos testes automatizados |
*/ |
testCompile » junit:junit:4.12 « |
testCompile » org.dbunit:dbunit: $ < dbunitVersion >« |
testCompile » br.com.triadworks:dbunitmanager:1.0.1-SNAPSHOT « |
testCompile » org.springframework:spring-test: $ < springVersion >« |
/** |
* Dependências fixas |
*/ |
compile fileTree( dir : » lib/oracle » , include : ‘ *.jar ‘ ) |
> |
task wrapper ( type : Wrapper ) |
description = » Generates gradlew[.bat] scripts « |
gradleVersion = » 2.14.1 « |
> |
Sourcefile Encoding with Gradle
Source file encoding is another example of a tiny problem that needs a surprisingly big amount of Gradle code. There is a pretty old issue for this, so if you think that the code below is too complicated (like I do), please vote for it.
Java files
Gradle uses the platform encoding as default encoding for Java files (like the Java compiler does), which is a bad choice for platform-independent applications. To change this, add the following snipplet to your build.gradle file:
apply plugin: "java" tasks.withType(JavaCompile) options.encoding = "UTF-8" >
This is because we have at least two instances of a JavaCompile task (“compileJava” and “compileTestJava”), and the encoding must be applied to all of them. Note that early versions of Gradle use type Compile instead.
Groovy files
GroovyCompile tasks have different encoding settings for Java and Groovy files:
apply plugin: "groovy" tasks.withType(GroovyCompile) options.encoding = "UTF-8" // for Java compilation groovyOptions.encoding = "UTF-8" // for Groovy compilation >
In the current case, the groovyOptions.encoding line is optional, since UTF-8 is the default encoding for Groovy files.
Eclipse integration
The Eclipse Plugin ignores the encoding settings, so we must create the corresponding configuration file manually, as documented in the issue mentioned above:
apply plugin: "eclipse" eclipseJdt file(".settings/org.eclipse.core.resources.prefs").text = "eclipse.preferences.version=1\nencoding/=UTF-8" >
Intellij IDEA integration
Again, no out-of-the-box encoding support with the IDEA plugin. We must add a new XML node to the XML project file:
apply plugin: "idea" idea project ipr withXml xmlProvider -> def encoding = xmlProvider.asNode().component.find it.@name == "Encoding" > encoding.appendNode("file", [url: "PROJECT", charset: "UTF-8"]) > > > >
The sample code is based on this Gradle goodness posting and tested with IDEA 14.
Gradle java file encoding
Sets the default character encoding to use. Note: Many JVM implementations support the setting of this attribute via system property on startup (namely, the file.encoding property). For JVMs where this is the case, setting the file.encoding property via setSystemProperties(java.util.Map) or similar will have no effect as this value will be overridden by the value specified by getDefaultCharacterEncoding() .
getMinHeapSize
@Nullable @Optional @Input java.lang.String getMinHeapSize()
setMinHeapSize
void setMinHeapSize(@Nullable java.lang.String heapSize)
Sets the minimum heap size for the process. Supports the units megabytes (e.g. «512m») and gigabytes (e.g. «1g»).
getMaxHeapSize
@Nullable @Optional @Input java.lang.String getMaxHeapSize()
setMaxHeapSize
void setMaxHeapSize(@Nullable java.lang.String heapSize)
Sets the maximum heap size for the process. Supports the units megabytes (e.g. «512m») and gigabytes (e.g. «1g»).
getJvmArgs
@Nullable @Optional @Input java.util.List getJvmArgs()
Returns the extra arguments to use to launch the JVM for the process. Does not include system properties and the minimum/maximum heap size.
setJvmArgs
void setJvmArgs(@Nullable java.util.List arguments)
Sets the extra arguments to use to launch the JVM for the process. System properties and minimum/maximum heap size are updated.
setJvmArgs
void setJvmArgs(@Nullable java.lang.Iterable arguments)
Sets the extra arguments to use to launch the JVM for the process. System properties and minimum/maximum heap size are updated.
jvmArgs
JavaForkOptions jvmArgs(java.lang.Iterable arguments)
jvmArgs
JavaForkOptions jvmArgs(java.lang.Object. arguments)
getJvmArgumentProviders
getBootstrapClasspath
@Classpath FileCollection getBootstrapClasspath()
Returns the bootstrap classpath to use for the process. The default bootstrap classpath for the JVM is used when this classpath is empty.
setBootstrapClasspath
Sets the bootstrap classpath to use for the process. Set to an empty classpath to use the default bootstrap classpath for the specified JVM.
bootstrapClasspath
JavaForkOptions bootstrapClasspath(java.lang.Object. classpath)
getEnableAssertions
@Input boolean getEnableAssertions()
setEnableAssertions
void setEnableAssertions(boolean enabled)
getDebug
Determines whether debugging is enabled for the test process. When enabled — debug = true — the process is started in a suspended state, listening on port 5005. You should disable parallel test execution when debugging and you will need to reattach the debugger occasionally if you use a non-zero value for Test.getForkEvery() . Since Gradle 5.6, you can configure the port and other Java debug properties via debugOptions(Action) .
setDebug
void setDebug(boolean enabled)
Enable or disable debugging for the process. When enabled, the process is started suspended and listening on port 5005. The debug properties (e.g. the port number) can be configured in debugOptions(Action) .
getDebugOptions
Returns the Java Debug Wire Protocol properties for the process. If enabled then the -agentlib:jdwp=. will be appended to the JVM arguments with the configuration from the parameter.
debugOptions
Configures Java Debug Wire Protocol properties for the process. If setDebug(boolean) is enabled then the -agentlib:jdwp=. will be appended to the JVM arguments with the configuration from the parameter.
getAllJvmArgs
@Internal java.util.List getAllJvmArgs()
Returns the full set of arguments to use to launch the JVM for the process. This includes arguments to define system properties, the minimum/maximum heap size, and the bootstrap classpath.
setAllJvmArgs
void setAllJvmArgs(java.util.List arguments)
Sets the full set of arguments to use to launch the JVM for the process. Overwrites any previously set system properties, minimum/maximum heap size, assertions, and bootstrap classpath.
setAllJvmArgs
void setAllJvmArgs(java.lang.Iterable arguments)
Sets the full set of arguments to use to launch the JVM for the process. Overwrites any previously set system properties, minimum/maximum heap size, assertions, and bootstrap classpath.
copyTo
JavaForkOptions copyTo(JavaForkOptions options)