[GRADLE-1618] file.encoding System property (and GRADLE_OPTS) not passed to Daemon Created: 15/Jun/11  Updated: 04/Jan/13  Resolved: 14/Feb/12

Status: Resolved
Project: Gradle
Affects Version/s: 1.0-milestone-3
Fix Version/s: 1.0-milestone-9

Type: Bug
Reporter: David Fogel Assignee: Luke Daley
Resolution: Fixed Votes: 2


 Description   

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?



 Comments   
Comment by Szczepan Faber [ 11/Aug/11 ]

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 << {
  println "file.encoding sys property = " + System.properties["file.encoding"]
  println "foo env variable = " + 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).

Comment by David Fogel [ 11/Aug/11 ]

Hi Szczepan-

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:

task printSys <<

{ println "file.encoding sys property = " + System.properties["file.encoding"] println "GRADLE_OPTS env variable = " + System.getenv("GRADLE_OPTS") println "JAVA_TOOL_OPTIONS env variable = " + System.getenv("JAVA_TOOL_OPTIONS") println "UTF-8 test: ↓" }

(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!

Comment by Szczepan Faber [ 11/Aug/11 ]

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

Comment by Adam Murdoch [ 14/Aug/11 ]

We should probably come up with a general solution for jvm settings which can only be applied at startup. For example:

  • java version
  • memory settings
  • certain system properties, such as file.encoding

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.

Comment by Luke Daley [ 14/Feb/12 ]

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.

Generated at Wed Jun 30 12:00:08 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.