Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you get Gradle to fail the build when there's a non-UTF8 character in the source code?

Tags:

gradle

javac

It's a rare enough problem, but I'd really like for it to fail the build when this happens:


/Users/jundai/perforce/trunk/service/test/com/mycompany/PriceFormattingTests.java:93: error: unmappable character for encoding UTF-8
       return new CurrencyModel("373959", new Price("10.20", "EUR"), "�10.20", new Price("12.10", "USD"), "$12.10");

With Ant or running javac on the command-line, using -source 1.6 or -source 1.7 will cause this to fail. Using Gradle, it prints out as an error: (if sourceCompatibility is set to 6 or higher), but the build is still successful.

I've tried various ways of getting the -source argument into the javac command for the compileJava task, but nothing I've tried seems to be able to get Gradle to report this as a failure.

Has anyone else run into this?

EDIT: some more details:

If I have a file encoded in winansi: src/main/java/Test.java:


public class Test {
  public static void main(String[] args) {
    System.out.println("Testing UTF-8 compilation: C’est drôle, tout à coup je ne sais pas quoi dire.");
  }
}

then this passes with no errors or warnings using this build.gradle, Gradle 1.3, and Java 1.7:


apply plugin: 'java'

tasks.withType(Compile) {
  options.encoding = "iso-8859-1"
}

Output is:


[1.9.3-p327] gradle$ gradle build
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
:check
:build

BUILD SUCCESSFUL

If I remove the options.encoding, or set it to UTF-8, I get this:


[1.9.3-p327] gradle$ gradle build
:compileJava
/Users/jbateskobashigawa/play/gradle/src/main/java/Test.java:3: error: unmappable character for encoding UTF8
    System.out.println("Testing UTF-8 compilation: C�est dr�le, tout � coup je ne sais pas quoi dire.");
                                                    ^
/Users/jbateskobashigawa/play/gradle/src/main/java/Test.java:3: error: unmappable character for encoding UTF8
    System.out.println("Testing UTF-8 compilation: C�est dr�le, tout � coup je ne sais pas quoi dire.");
                                                           ^
/Users/jbateskobashigawa/play/gradle/src/main/java/Test.java:3: error: unmappable character for encoding UTF8
    System.out.println("Testing UTF-8 compilation: C�est dr�le, tout � coup je ne sais pas quoi dire.");
                                                                     ^
:processResources UP-TO-DATE
... (more stuff)
BUILD SUCCESSFUL

Setting the sourceTypeCompatibility between 1.5, 1.6, and 1.7 doesn't seem to do much. 1.5, when using -source on javac turns the error into a warning:. With Gradle, it's still an error:, but interestingly it doesn't get recompiled on the next build, whereas with 1.6 and 1.7 it does.

I've tried all sorts of ways to try to pass -source into javac when Gradle is building, but none of them seem to work:

Doesn't build:


    options.compilerArgs < '-source 1.7'

Builds, but doesn't error out (same as without the flag):


    options.compilerArgs << '-source'
    options.compilerArgs << '1.7'

All of this seems to have something to do with the fact that Gradle isn't actually using the javac executable to compile—it's using some sort of JVM compile API that has a lot of very convoluted code in it. If I try to replicate what Gradle seems to be doing, I can create a class to compile my class that looks like this: javax/tools/CompileTest.java

You can reproduce the problem using this mini project: https://github.com/Jun-Dai/gradle_utf8_compilation_issue

Does anyone know of a way around this problem, short of parsing the Gradle build output and failing the build based on that particular error message?

like image 724
Jun-Dai Bates-Kobashigawa Avatar asked Oct 07 '13 12:10

Jun-Dai Bates-Kobashigawa


2 Answers

It seems like this will allow it to fail the build:


    options.fork = true
    options.forkOptions.executable = 'javac'

Not sure if that has other ramifications, however, but I'll give it a go.

like image 92
Jun-Dai Bates-Kobashigawa Avatar answered Nov 15 '22 03:11

Jun-Dai Bates-Kobashigawa


//ignoreFailures = true

Insert and Uncomment the above line if you want it to fail, put this statement under the following section, see if it works.

tasks.withType(Compile) {
     options.debug = true
     options.compilerArgs = ["-g"]
   }
like image 39
AKS Avatar answered Nov 15 '22 03:11

AKS