diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/initialization/DefaultScriptHandler.java b/subprojects/core/src/main/java/org/gradle/api/internal/initialization/DefaultScriptHandler.java index 9b5b1e987b2f..9cb94f169399 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/initialization/DefaultScriptHandler.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/initialization/DefaultScriptHandler.java @@ -39,6 +39,7 @@ import org.gradle.groovy.scripts.ScriptSource; import org.gradle.internal.classloader.ClasspathUtil; import org.gradle.internal.classpath.ClassPath; +import org.gradle.internal.logging.util.Log4jBannedVersion; import org.gradle.internal.metaobject.BeanDynamicObject; import org.gradle.internal.metaobject.DynamicObject; import org.gradle.internal.resource.ResourceLocation; @@ -98,9 +99,6 @@ public ClassPath getNonInstrumentedScriptClassPath() { @Override public DependencyHandler getDependencies() { defineConfiguration(); - if (dependencyHandler == null) { - dependencyHandler = dependencyResolutionServices.getDependencyHandler(); - } return dependencyHandler; } @@ -128,6 +126,9 @@ private void defineConfiguration() { if (configContainer == null) { configContainer = dependencyResolutionServices.getConfigurationContainer(); } + if (dependencyHandler == null) { + dependencyHandler = dependencyResolutionServices.getDependencyHandler(); + } if (classpathConfiguration == null) { classpathConfiguration = configContainer.create(CLASSPATH_CONFIGURATION); // should ideally reuse the `JvmEcosystemUtilities` but this code is too low level @@ -139,6 +140,11 @@ private void defineConfiguration() { attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, instantiator.named(Bundling.class, Bundling.EXTERNAL)); attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, Integer.parseInt(JavaVersion.current().getMajorVersion())); attributes.attribute(GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, instantiator.named(GradlePluginApiVersion.class, GradleVersion.current().getVersion())); + + classpathConfiguration.getDependencyConstraints().add(dependencyHandler.getConstraints().create(Log4jBannedVersion.LOG4J2_CORE_COORDINATES, constraint -> constraint.version(version -> { + version.strictly(Log4jBannedVersion.LOG4J2_CORE_STRICT_VERSION_RANGE); + version.prefer(Log4jBannedVersion.LOG4J2_CORE_PREFERRED_VERSION); + }))); } } diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/initialization/DefaultScriptHandlerTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/initialization/DefaultScriptHandlerTest.groovy index b3435c37b092..1df5d8a47bb1 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/initialization/DefaultScriptHandlerTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/initialization/DefaultScriptHandlerTest.groovy @@ -17,6 +17,8 @@ package org.gradle.api.internal.initialization import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.DependencyConstraintSet +import org.gradle.api.artifacts.dsl.DependencyConstraintHandler import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.RepositoryHandler import org.gradle.api.attributes.Bundling @@ -35,6 +37,8 @@ import spock.lang.Specification class DefaultScriptHandlerTest extends Specification { def repositoryHandler = Mock(RepositoryHandler) def dependencyHandler = Mock(DependencyHandler) + def dependencyConstraintHandler = Mock(DependencyConstraintHandler) + def dependencyConstraintSet = Mock(DependencyConstraintSet) def configurationContainer = Mock(ConfigurationContainer) def configuration = Mock(Configuration) def scriptSource = Stub(ScriptSource) @@ -57,11 +61,16 @@ class DefaultScriptHandlerTest extends Specification { then: 1 * depMgmtServices.configurationContainer >> configurationContainer + 1 * depMgmtServices.dependencyHandler >> dependencyHandler 1 * configurationContainer.create('classpath') >> configuration 1 * configuration.attributes >> attributes 1 * attributes.attribute(Usage.USAGE_ATTRIBUTE, _ as Usage) 1 * attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, _ as Bundling) 1 * attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, _) + 1 * configuration.getDependencyConstraints() >> dependencyConstraintSet + 1 * dependencyConstraintSet.add(_) + 1 * dependencyHandler.getConstraints() >> dependencyConstraintHandler + 1 * dependencyConstraintHandler.create(_, _) 0 * configurationContainer._ 0 * depMgmtServices._ } @@ -73,12 +82,16 @@ class DefaultScriptHandlerTest extends Specification { then: 1 * depMgmtServices.configurationContainer >> configurationContainer + 1 * depMgmtServices.dependencyHandler >> dependencyHandler 1 * configurationContainer.create('classpath') >> configuration 1 * configuration.attributes >> attributes 1 * attributes.attribute(Usage.USAGE_ATTRIBUTE, _ as Usage) 1 * attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, _ as Bundling) 1 * attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, _) - 1 * depMgmtServices.dependencyHandler >> dependencyHandler + 1 * configuration.getDependencyConstraints() >> dependencyConstraintSet + 1 * dependencyConstraintSet.add(_) + 1 * dependencyHandler.getConstraints() >> dependencyConstraintHandler + 1 * dependencyConstraintHandler.create(_, _) 0 * configurationContainer._ 0 * depMgmtServices._ } @@ -107,11 +120,16 @@ class DefaultScriptHandlerTest extends Specification { and: 1 * depMgmtServices.configurationContainer >> configurationContainer + 1 * depMgmtServices.dependencyHandler >> dependencyHandler 1 * configurationContainer.create('classpath') >> configuration 1 * configuration.attributes >> attributes 1 * attributes.attribute(Usage.USAGE_ATTRIBUTE, _ as Usage) 1 * attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, _) 1 * attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, _ as Bundling) + 1 * configuration.getDependencyConstraints() >> dependencyConstraintSet + 1 * dependencyConstraintSet.add(_) + 1 * dependencyHandler.getConstraints() >> dependencyConstraintHandler + 1 * dependencyConstraintHandler.create(_, _) 1 * classpathResolver.resolveClassPath(configuration) >> classpath } @@ -151,6 +169,10 @@ class DefaultScriptHandlerTest extends Specification { 1 * attributes.attribute(Usage.USAGE_ATTRIBUTE, _ as Usage) 1 * attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, _ as Bundling) 1 * attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, _) + 1 * configuration.getDependencyConstraints() >> dependencyConstraintSet + 1 * dependencyConstraintSet.add(_) + 1 * dependencyHandler.getConstraints() >> dependencyConstraintHandler + 1 * dependencyConstraintHandler.create(_, _) 1 * dependencyHandler.add('config', 'dep') } } diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ScriptDependencyResolveIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ScriptDependencyResolveIntegrationTest.groovy index 7252b0b17815..56259604d1b2 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ScriptDependencyResolveIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ScriptDependencyResolveIntegrationTest.groovy @@ -89,4 +89,33 @@ rootProject.name = 'testproject' fails "help" failureHasCause("Conflict(s) found for the following module(s):") } + + def 'carries implicit constraint for log4j-core'() { + given: + mavenRepo().module('org.apache.logging.log4j', 'log4j-core', '2.15.0').publish() + + and: + settingsFile << """ + buildscript { + repositories { maven { url "${mavenRepo().uri}" } } + dependencies { + classpath "org.apache.logging.log4j:log4j-core" + } + } + + rootProject.name = 'testproject' + """ + + buildFile << """ + buildscript { + repositories { maven { url "${mavenRepo().uri}" } } + dependencies { + classpath "org.apache.logging.log4j:log4j-core" + } + } + """ + + expect: + succeeds 'help' + } } diff --git a/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/groovy/build.gradle b/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/groovy/build.gradle index 641548db6adb..b9ba5e7fb59d 100644 --- a/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/groovy/build.gradle +++ b/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/groovy/build.gradle @@ -5,7 +5,7 @@ repositories { url "https://repo.spring.io/release" } maven { - url "https://maven.restlet.com" + url "https://repository.jboss.org/maven2" } } // end::multiple-repositories[] @@ -15,7 +15,7 @@ configurations { } dependencies { - libs "com.restlet.client:commons:2.0.0" + libs 'jboss:jboss-system:4.2.2.GA' } tasks.register('copyLibs', Copy) { diff --git a/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/kotlin/build.gradle.kts index 7891dae93108..70a9e0f9f568 100644 --- a/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/dependencyManagement/declaringRepositories-multipleRepositories/kotlin/build.gradle.kts @@ -5,7 +5,7 @@ repositories { url = uri("https://repo.spring.io/release") } maven { - url = uri("https://maven.restlet.com") + url = uri("https://repository.jboss.org/maven2") } } // end::multiple-repositories[] @@ -13,7 +13,7 @@ repositories { val libs by configurations.creating dependencies { - libs("com.restlet.client:commons:2.0.0") + libs("jboss:jboss-system:4.2.2.GA") } tasks.register("copyLibs") { diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/RepoScriptBlockUtil.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/RepoScriptBlockUtil.groovy index 1451485b05f1..bc5aa86ed1bc 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/RepoScriptBlockUtil.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/RepoScriptBlockUtil.groovy @@ -55,7 +55,6 @@ class RepoScriptBlockUtil { LIGHTBEND_IVY("https://repo.lightbend.com/lightbend/ivy-releases", System.getProperty('org.gradle.integtest.mirrors.lightbendivy'), "ivy"), SPRING_RELEASES('https://repo.spring.io/release', System.getProperty('org.gradle.integtest.mirrors.springreleases'), 'maven'), SPRING_SNAPSHOTS('https://repo.spring.io/snapshot/', System.getProperty('org.gradle.integtest.mirrors.springsnapshots'), 'maven'), - RESTLET('https://maven.restlet.com', System.getProperty('org.gradle.integtest.mirrors.restlet'), 'maven'), GRADLE('https://repo.gradle.org/gradle/repo', System.getProperty('org.gradle.integtest.mirrors.gradle'), 'maven'), JBOSS('https://repository.jboss.org/maven2/', System.getProperty('org.gradle.integtest.mirrors.jboss'), 'maven'), GRADLE_PLUGIN("https://plugins.gradle.org/m2", System.getProperty('org.gradle.integtest.mirrors.gradle-prod-plugins'), 'maven'), diff --git a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractJavaGroovyIncrementalCompilationSupport.groovy b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractJavaGroovyIncrementalCompilationSupport.groovy index b2a8b60ca4cd..ce258588813d 100644 --- a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractJavaGroovyIncrementalCompilationSupport.groovy +++ b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractJavaGroovyIncrementalCompilationSupport.groovy @@ -29,7 +29,7 @@ abstract class AbstractJavaGroovyIncrementalCompilationSupport extends AbstractI File source(String... classBodies) { File out for (String body : classBodies) { - def className = (body =~ /(?s).*?(?:class|interface|enum) (\w+) .*/)[0][1] + def className = (body =~ /(?s).*?(?:class|interface|enum) ([\w$]+) .*/)[0][1] assert className: "unable to find class name" def f = file("src/main/${language.name}/${className}.${language.name}") f.createFile() diff --git a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractSourceIncrementalCompilationIntegrationTest.groovy b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractSourceIncrementalCompilationIntegrationTest.groovy index 97a7539bad8e..a444eefec00d 100644 --- a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractSourceIncrementalCompilationIntegrationTest.groovy +++ b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractSourceIncrementalCompilationIntegrationTest.groovy @@ -492,4 +492,21 @@ sourceSets { then: failureCauseContains('Compilation failed') } + + @Issue("https://github.com/gradle/gradle/issues/19257") + def "recompiles classes with \$ in class name after rename"() { + def firstSource = source "class Class\$Name {}" + source "class Main { public static void main(String[] args) { new Class\$Name(); } }" + outputs.snapshot { run language.compileTaskName } + + when: + firstSource.delete() + source "class Class\$Name1 {}", + "class Main { public static void main(String[] args) { new Class\$Name1(); } }" + run language.compileTaskName + + then: + outputs.deletedClasses("Class\$Name") + outputs.recompiledClasses("Class\$Name1", "Main") + } } diff --git a/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/recomp/FileNameDerivingClassNameConverter.java b/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/recomp/FileNameDerivingClassNameConverter.java index 250cc77bdc60..f1475c750ac3 100644 --- a/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/recomp/FileNameDerivingClassNameConverter.java +++ b/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/recomp/FileNameDerivingClassNameConverter.java @@ -56,9 +56,23 @@ public Set getRelativeSourcePaths(String className) { return sourcePaths; } + Set paths = fileExtensions.stream() + .map(fileExtension -> classNameToRelativePath(className, fileExtension)) + .collect(Collectors.toSet()); + + // Classes with $ may be inner classes int innerClassIdx = className.indexOf("$"); - String baseName = innerClassIdx > 0 ? className.substring(0, innerClassIdx) : className; - return fileExtensions.stream().map(fileExtension -> baseName.replace('.', '/') + fileExtension).collect(Collectors.toSet()); + if (innerClassIdx > 0) { + String baseName = className.substring(0, innerClassIdx); + fileExtensions.stream() + .map(fileExtension -> classNameToRelativePath(baseName, fileExtension)) + .forEach(paths::add); + } + + return paths; } + private String classNameToRelativePath(String className, String fileExtension) { + return className.replace('.', '/') + fileExtension; + } } diff --git a/subprojects/logging/src/main/java/org/gradle/internal/logging/util/Log4jBannedVersion.java b/subprojects/logging/src/main/java/org/gradle/internal/logging/util/Log4jBannedVersion.java new file mode 100644 index 000000000000..f919d27615f9 --- /dev/null +++ b/subprojects/logging/src/main/java/org/gradle/internal/logging/util/Log4jBannedVersion.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.internal.logging.util; + +/** + * This class contains references to log4j-core which had a critical vulnerability, + * see CVE-2021-44228. + */ +public class Log4jBannedVersion { + public static final String LOG4J2_CORE_COORDINATES = "org.apache.logging.log4j:log4j-core"; + public static final String LOG4J2_CORE_STRICT_VERSION_RANGE = "[2.15, 3["; + public static final String LOG4J2_CORE_PREFERRED_VERSION = "2.15.0"; +} diff --git a/subprojects/samples/src/integTest/groovy/org/gradle/integtests/samples/dependencymanagement/SamplesDeclaringRepositoriesIntegrationTest.groovy b/subprojects/samples/src/integTest/groovy/org/gradle/integtests/samples/dependencymanagement/SamplesDeclaringRepositoriesIntegrationTest.groovy index ca4981493bd7..54ad643510e7 100644 --- a/subprojects/samples/src/integTest/groovy/org/gradle/integtests/samples/dependencymanagement/SamplesDeclaringRepositoriesIntegrationTest.groovy +++ b/subprojects/samples/src/integTest/groovy/org/gradle/integtests/samples/dependencymanagement/SamplesDeclaringRepositoriesIntegrationTest.groovy @@ -20,9 +20,7 @@ import org.gradle.integtests.fixtures.AbstractIntegrationSpec import org.gradle.integtests.fixtures.Sample import org.gradle.integtests.fixtures.UsesSample import org.junit.Rule -import spock.lang.Ignore -@Ignore("Ignored as repository used in test has expired certificate") class SamplesDeclaringRepositoriesIntegrationTest extends AbstractIntegrationSpec { @Rule @@ -40,9 +38,9 @@ class SamplesDeclaringRepositoriesIntegrationTest extends AbstractIntegrationSpe succeeds('copyLibs') then: - sample.dir.file("$dsl/build/libs/commons-2.0.0.jar").isFile() + sample.dir.file("$dsl/build/libs/jboss-system-4.2.2.GA.jar").isFile() where: - dsl << ['groovy'] + dsl << ['groovy', 'kotlin'] } } diff --git a/subprojects/scala/build.gradle.kts b/subprojects/scala/build.gradle.kts index 25c939207470..350be31447c9 100644 --- a/subprojects/scala/build.gradle.kts +++ b/subprojects/scala/build.gradle.kts @@ -27,7 +27,9 @@ dependencies { implementation(libs.guava) implementation(libs.inject) - compileOnly("org.scala-sbt:zinc_2.12:1.3.5") + compileOnly("org.scala-sbt:zinc_2.12:1.3.5") { + exclude(module="log4j-core") // Because not needed and vulnerable + } testImplementation(project(":base-services-groovy")) testImplementation(project(":files")) diff --git a/subprojects/scala/src/integTest/groovy/org/gradle/scala/ScalaPluginIntegrationTest.groovy b/subprojects/scala/src/integTest/groovy/org/gradle/scala/ScalaPluginIntegrationTest.groovy index c10d90606fd8..834b770dd59a 100644 --- a/subprojects/scala/src/integTest/groovy/org/gradle/scala/ScalaPluginIntegrationTest.groovy +++ b/subprojects/scala/src/integTest/groovy/org/gradle/scala/ScalaPluginIntegrationTest.groovy @@ -242,4 +242,22 @@ task someTask succeeds("assemble") succeeds("dependencyInsight", "--configuration", "zinc", "--dependency", "zinc") } + + @ToBeFixedForConfigurationCache(because = ":dependencies") + def 'show that log4j-core, if present, is 2_15_0 at the minimum'() { + given: + file('build.gradle') << """ + apply plugin: 'scala' + + ${mavenCentralRepository()} + """ + + def versionPattern = ~/.*-> 2\.(\d+).*/ + expect: + succeeds('dependencies', '--configuration', 'zinc') + def log4jOutput = result.getOutputLineThatContains("log4j-core:{strictly [2.15, 3[; prefer 2.15.0}") + def matcher = log4jOutput =~ versionPattern + matcher.find() + Integer.valueOf(matcher.group(1)) >= 15 + } } diff --git a/subprojects/scala/src/main/java/org/gradle/api/plugins/scala/ScalaBasePlugin.java b/subprojects/scala/src/main/java/org/gradle/api/plugins/scala/ScalaBasePlugin.java index eae507345595..1b38244f3ec5 100644 --- a/subprojects/scala/src/main/java/org/gradle/api/plugins/scala/ScalaBasePlugin.java +++ b/subprojects/scala/src/main/java/org/gradle/api/plugins/scala/ScalaBasePlugin.java @@ -56,6 +56,7 @@ import org.gradle.api.tasks.scala.ScalaCompile; import org.gradle.api.tasks.scala.ScalaDoc; import org.gradle.internal.deprecation.DeprecatableConfiguration; +import org.gradle.internal.logging.util.Log4jBannedVersion; import org.gradle.jvm.tasks.Jar; import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.jvm.toolchain.JavaToolchainSpec; @@ -154,6 +155,11 @@ private void configureConfigurations(final Project project, final Usage incremen }); }); + zinc.getDependencyConstraints().add(dependencyHandler.getConstraints().create(Log4jBannedVersion.LOG4J2_CORE_COORDINATES, constraint -> constraint.version(version -> { + version.strictly(Log4jBannedVersion.LOG4J2_CORE_STRICT_VERSION_RANGE); + version.prefer(Log4jBannedVersion.LOG4J2_CORE_PREFERRED_VERSION); + }))); + final Configuration incrementalAnalysisElements = project.getConfigurations().create("incrementalScalaAnalysisElements"); incrementalAnalysisElements.setVisible(false); incrementalAnalysisElements.setDescription("Incremental compilation analysis files");