1/* 2 * Copyright (C) 2017. Uber Technologies 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import net.ltgt.gradle.errorprone.CheckSeverity 17 18plugins { 19 id 'java-library' 20 id 'nullaway.java-test-conventions' 21} 22 23configurations { 24 // A configuration holding the jars for the oldest supported version of Error Prone, to use with tests 25 errorProneOldest 26} 27 28dependencies { 29 compileOnly project(":annotations") 30 compileOnly deps.apt.autoValueAnnot 31 annotationProcessor deps.apt.autoValue 32 compileOnly deps.apt.autoServiceAnnot 33 annotationProcessor deps.apt.autoService 34 compileOnly deps.build.jsr305Annotations 35 compileOnly deps.test.jetbrainsAnnotations 36 compileOnly deps.apt.javaxInject 37 38 39 compileOnly deps.build.errorProneCheckApi 40 implementation deps.build.checkerDataflow 41 implementation deps.build.guava 42 43 testImplementation project(":annotations") 44 testImplementation deps.test.junit4 45 testImplementation(deps.build.errorProneTestHelpers) { 46 exclude group: "junit", module: "junit" 47 } 48 testImplementation deps.test.jetbrainsAnnotations 49 testImplementation deps.test.junit5Jupiter 50 testImplementation deps.test.cfQual 51 testImplementation deps.test.cfCompatQual 52 testImplementation deps.build.jspecify 53 testImplementation project(":test-java-lib") 54 testImplementation deps.apt.jakartaInject 55 testImplementation deps.apt.javaxInject 56 testImplementation deps.test.rxjava2 57 testImplementation deps.test.commonsLang 58 testImplementation deps.test.commonsLang3 59 testImplementation project(":test-library-models") 60 testImplementation deps.test.lombok 61 testImplementation deps.test.springBeans 62 testImplementation deps.test.springContext 63 testImplementation deps.test.grpcCore 64 testImplementation project(":test-java-lib-lombok") 65 testImplementation deps.test.mockito 66 testImplementation deps.test.javaxAnnotationApi 67 testImplementation deps.test.assertJ 68 // This is for a test exposing a CFG construction failure in the Checker Framework. We can probably remove it once 69 // the issue is fixed upstream and we update. See https://github.com/typetools/checker-framework/issues/6396. 70 testImplementation 'org.apache.spark:spark-sql_2.12:3.3.2' 71 72 errorProneOldest deps.build.errorProneCheckApiOld 73 errorProneOldest(deps.build.errorProneTestHelpersOld) { 74 exclude group: "junit", module: "junit" 75 } 76} 77 78javadoc { 79 failOnError = false 80} 81 82apply plugin: 'com.vanniktech.maven.publish' 83 84// These --add-exports arguments are required when targeting JDK 11+ since Error Prone and NullAway access a bunch of 85// JDK-internal APIs that are not exposed otherwise. Since we currently target JDK 8, we do not need to pass the 86// arguments, as encapsulation of JDK internals is not enforced on JDK 8. In fact, the arguments cause a compiler error 87// when targeting JDK 8. Leaving commented so we can easily add them back once we target JDK 11. 88// tasks.withType(JavaCompile).configureEach { 89// options.compilerArgs += [ 90// "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", 91// "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", 92// "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", 93// "--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", 94// "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", 95// "--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED", 96// "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", 97// "--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", 98// "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", 99// "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", 100// "--add-exports=jdk.compiler/com.sun.source.tree=ALL-UNNAMED", 101// ] 102// } 103 104// Create a task to test on JDK 8 105// NOTE: even when we drop JDK 8 support, we will still need a test task similar to this one for testing building 106// against a recent JDK and Error Prone version but then running on the oldest supported JDK and Error Prone version, 107// to check for binary compatibility issues. 108def jdk8Test = tasks.register("testJdk8", Test) { 109 javaLauncher = javaToolchains.launcherFor { 110 languageVersion = JavaLanguageVersion.of(8) 111 } 112 113 description = "Runs the test suite on JDK 8" 114 group = LifecycleBasePlugin.VERIFICATION_GROUP 115 116 // Copy inputs from normal Test task. 117 def testTask = tasks.getByName("test") 118 // A bit of a hack: we add the dependencies of the oldest supported Error Prone version to the _beginning_ of the 119 // classpath, so that they are used instead of the latest version. This exercises the scenario of building 120 // NullAway against the latest supported Error Prone version but then running on the oldest supported version. 121 classpath = configurations.errorProneOldest + testTask.classpath 122 123 testClassesDirs = testTask.testClassesDirs 124 jvmArgs "-Xbootclasspath/p:${configurations.errorproneJavac.asPath}" 125 filter { 126 // JDK 8 does not support diamonds on anonymous classes 127 excludeTestsMatching "com.uber.nullaway.NullAwayJSpecifyGenericsTests.overrideDiamondAnonymousClass" 128 // tests cannot run on JDK 8 since Mockito version no longer supports it 129 excludeTestsMatching "com.uber.nullaway.NullAwaySerializationTest.initializationError" 130 excludeTestsMatching "com.uber.nullaway.handlers.contract.ContractUtilsTest.getEmptyAntecedent" 131 } 132} 133 134tasks.named('check').configure { 135 dependsOn(jdk8Test) 136} 137 138// Create a task to build NullAway with NullAway checking enabled 139tasks.register('buildWithNullAway', JavaCompile) { 140 onlyIf { 141 // We only do NullAway checks when compiling against the latest 142 // version of Error Prone (as nullability annotations on the APIs 143 // can change between versions) 144 deps.versions.errorProneApi == deps.versions.errorProneLatest 145 } 146 // Configure compilation to run with Error Prone and NullAway 147 source = sourceSets.main.java 148 classpath = sourceSets.main.compileClasspath 149 destinationDirectory = file("$buildDir/ignoredClasses") 150 options.annotationProcessorPath = files( 151 configurations.errorprone.asCollection(), 152 sourceSets.main.annotationProcessorPath, 153 // This refers to the NullAway jar built from the current source 154 jar.archiveFile.get(), 155 sourceSets.main.compileClasspath) 156 options.errorprone.enabled = true 157 options.errorprone { 158 option("NullAway:AnnotatedPackages", "com.uber,org.checkerframework.nullaway,com.google.common") 159 option("NullAway:CastToNonNullMethod", "com.uber.nullaway.NullabilityUtil.castToNonNull") 160 option("NullAway:CheckOptionalEmptiness") 161 option("NullAway:AcknowledgeRestrictiveAnnotations") 162 option("NullAway:CheckContracts") 163 option("NullAway:JSpecifyMode") 164 } 165 // Make sure the jar has already been built 166 dependsOn 'jar' 167 // Check that the NullAway jar actually exists (without this, 168 // Gradle will run the compilation even if the jar doesn't exist) 169 doFirst { 170 assert jar.archiveFile.get().getAsFile().exists() 171 } 172} 173 174project.tasks.named('check').configure { 175 dependsOn 'buildWithNullAway' 176} 177