I'm compiling my artifact with Java 8, and using the Error Prone compiler plugin. It's generating a warning because of the following generated code:
MockMvcRequestSpecification request = given()
.body(new String(fileToBytes(this, "shouldReturnRenderResponseSuccess_request_renderRequest.json")));
The corresponding section of the contract looks like this:
request {
method POST()
url "/render"
body(file("renderRequest.json")) // this generates the code that fails the error-prone check
The error-prone warning looks like this:
[WARNING] /Users/steve.kingsland/.../My_contractTest.java:[46,11] [DefaultCharset] Implicit use of the platform default charset, which can result in differing behaviour between JVM executions or incorrect behavior if the encoding of the data source doesn't match expectations.
(see https://errorprone.info/bugpattern/DefaultCharset)
Did you mean '.body(new String(fileToBytes(this, "shouldReturnRenderResponseSuccess_request_renderRequest.json"), UTF_8));' or '.body(new String(fileToBytes(this, "shouldReturnRenderResponseSuccess_request_renderRequest.json"), Charset.defaultCharset()));'?
I've configured the Maven Java compiler plugin to fail the build if there are warnings, so this fails the build.
I've identified the following options to solve this problem:
1) don't use spring cloud contract;
1) don't use the error prone compile plugin;
2) use a different charset in the contract than the system default (e.g. ASCII), so it will pass the charset to the new String() call and thus won't trigger an error prone warning;
3) configure error prone to ignore the generated source code from spring cloud contract (e.g. via -XepExcludedPaths:.*/generated-test-sources/.*);
4) configure error prone to ignore all generated source code, via -XepDisableWarningsInGeneratedCode
Has anyone else run into this problem? I think option 5) is probably my best bet, but it requires that the SCC generated classes are annotated with @javax.annotation.Generated or @javax.annotation.processing.Generated. Is that reasonable?
We could link it with https://github.com/spring-cloud/spring-cloud-contract/issues/1401 and automatically add the Generated annotation to be added.
Until then as a workaround you can check this issue #1074 and work with the with the replacer plugin to add the annotation yourself.
Until then as a workaround you can check this issue #1074 and work with the with the replacer plugin to add the annotation yourself.
Yeah, this is the workaround that I've been using so far (should have mentioned this), but it's ~30 lines of maven plugin configuration:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>target/generated-test-sources/**/*.java</include>
</includes>
<regex>true</regex>
<regexFlags>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
<replacements>
<replacement>
<!-- there is already a warning suppression added, we need to add an additional one -->
<token>^@SuppressWarnings\("rawtypes"\)$</token>
<value>@SuppressWarnings({"DefaultCharset", "rawtypes"})</value>
</replacement>
</replacements>
</configuration>
</plugin>
Not wanting to have that in my pom is what lead me to the error prone -XepExcludedPaths flag, and _then_ I discovered the -XepDisableWarningsInGeneratedCode flag which might be even better, if only the generated code had the @Generated annotation.
Thanks for considering this feature!
Ah, actually I've forgotten that you do have another option to make this work!
Instead of:
request {
method POST()
url "/render"
body(file("renderRequest.json")) // this generates the code that fails the error-prone check
call
request {
method POST()
url "/render"
body(file("renderRequest.json", Charset.forName("UTF-8"))) // this generates the code that fails the error-prone check
since file(...,...) can take a second parameter with Charset.
/**
* Read file contents as String with the given Charset.
* @param relativePath of the file to read
* @param charset to use for converting the bytes to String
* @return String file contents
*/
public FromFileProperty file(String relativePath, Charset charset) {
return new FromFileProperty(fileLocation(relativePath), String.class, charset);
}
Yeah, I actually considered doing exactly that, thanks! That's what I was referring to when I wrote:
- use a different charset in the contract than the system default (e.g. ASCII), so it will pass the charset to the new String() call and thus won't trigger an error prone warning;
I didn't do that because it feels like a workaround that's a bit hacky, and also I wasn't sure if there would be any characters in the various renderRequest.json files that we use in this test that aren't in the UTF-8 character set, and there might be more than one place . So I ended up using the -XepExcludedPaths:.*/generated-test-sources/.* approach instead, and that's working great.
Most helpful comment
Yeah, I actually considered doing exactly that, thanks! That's what I was referring to when I wrote:
I didn't do that because it feels like a workaround that's a bit hacky, and also I wasn't sure if there would be any characters in the various
renderRequest.jsonfiles that we use in this test that aren't in the UTF-8 character set, and there might be more than one place . So I ended up using the-XepExcludedPaths:.*/generated-test-sources/.*approach instead, and that's working great.