Skip to content

Commit

Permalink
Fix class cast exception when release flag is not a string
Browse files Browse the repository at this point in the history
Fixes #13351
  • Loading branch information
melix committed Jun 9, 2020
1 parent 00128a6 commit 9eb29a8
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
Expand Up @@ -17,10 +17,10 @@
package org.gradle.api.internal.tasks.compile;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.JavaVersion;
import org.gradle.api.tasks.compile.ForkOptions;
import org.gradle.internal.Cast;
import org.gradle.util.GUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -29,6 +29,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class JavaCompilerArgumentsBuilder {
public static final Logger LOGGER = LoggerFactory.getLogger(JavaCompilerArgumentsBuilder.class);
Expand Down Expand Up @@ -77,7 +78,11 @@ public JavaCompilerArgumentsBuilder noEmptySourcePath() {
public List<String> build() {
args = new ArrayList<>();
// Take a deep copy of the compilerArgs because the following methods mutate it.
List<String> compArgs = Lists.newArrayList(spec.getCompileOptions().getCompilerArgs());
List<Object> compilerArgs = Cast.uncheckedCast(spec.getCompileOptions().getCompilerArgs());
List<String> compArgs = compilerArgs
.stream()
.map(Object::toString)
.collect(Collectors.toList());

validateCompilerArgs(compArgs);

Expand Down
Expand Up @@ -93,6 +93,16 @@ class JavaCompilerArgumentsBuilderTest extends Specification {
builder.build() == defaultOptions + ['--release', '7']
}

def "can use a GString for the value of the release flag"() {
when:
spec.compileOptions.compilerArgs += ['--release', "${ -> 7}"]
spec.sourceCompatibility = '1.7'
spec.targetCompatibility = '1.7'

then:
builder.build() == defaultOptions + ['--release', '7']
}

def "generates -d option"() {
def file = new File("/project/build")
spec.destinationDir = file
Expand Down
Expand Up @@ -23,6 +23,7 @@ import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution
import org.gradle.test.fixtures.file.ClassFile
import org.gradle.util.Requires
import org.gradle.util.TestPrecondition
import spock.lang.Unroll

abstract class BasicJavaCompilerIntegrationSpec extends AbstractIntegrationSpec {
def setup() {
Expand Down Expand Up @@ -143,12 +144,13 @@ public class FxApp extends Application {
}

@Requires(TestPrecondition.JDK9_OR_LATER)
@Unroll
def "compile with release option"() {
given:
goodCode()
buildFile << """
java.targetCompatibility = JavaVersion.VERSION_1_7
compileJava.options.compilerArgs.addAll(['--release', '8'])
compileJava.options.compilerArgs.addAll(['--release', $notation])
compileJava {
doFirst {
assert configurations.apiElements.attributes.getAttribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE) == 8
Expand All @@ -162,6 +164,13 @@ compileJava {
expect:
succeeds 'compileJava'
bytecodeVersion() == 52

where:
notation << [
"'8'",
'8', // Integer, see #13351
'"${8}"' // GString, see #13351
]
}

@Requires(TestPrecondition.JDK9_OR_LATER)
Expand Down
Expand Up @@ -277,7 +277,9 @@ public static Action<ConfigurationInternal> configureDefaultTargetPlatform(JavaP
private static int getReleaseOption(List<String> compilerArgs) {
int flagIndex = compilerArgs.indexOf("--release");
if (flagIndex != -1 && flagIndex + 1 < compilerArgs.size()) {
return Integer.parseInt(compilerArgs.get(flagIndex + 1));
// Using String.valueOf because despite the type signature being List<String>
// a user can put anything in that list, including Groovy's GString
return Integer.parseInt(String.valueOf(compilerArgs.get(flagIndex + 1)));
}
return 0;
}
Expand Down

0 comments on commit 9eb29a8

Please sign in to comment.