Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,17 @@ ext {
gradleRunsOnJava25orHigher = JavaVersion.current() >= JavaVersion.VERSION_25
gradleRunsOnJava26orHigher = JavaVersion.current() >= JavaVersion.VERSION_26
// The JDK for running tests: the jdkTestVersion property or if not set, JavaVersion.current()
if (project.getProperties().containsKey("jdkTestVersion")) {
testJdkVersion = Integer.valueOf(project.getProperties().get("jdkTestVersion"))
jdkTestVersionProperty = providers.gradleProperty("jdkTestVersion").orNull
if (jdkTestVersionProperty != null) {
testJdkVersion = Integer.valueOf(jdkTestVersionProperty)
} else {
testJdkVersion = Integer.valueOf(JavaVersion.current().getMajorVersion())
}
// With "useJdk21Compiler" property, use JDK 21 to compile all code because the release does.
// If you update this line, also update JAVA_HOME in docs/developer/release/release_vars.py.
boolean jdk21Compiler = project.getProperties().getOrDefault("useJdk21Compiler", false)
compilerJdkVersion = jdk21Compiler ? 21 : testJdkVersion
String useJdk21CompilerProperty = providers.gradleProperty("useJdk21Compiler").getOrElse("false")
boolean useJdk21Compiler = Boolean.valueOf(useJdk21CompilerProperty)
compilerJdkVersion = useJdk21Compiler ? 21 : testJdkVersion
compilerRunsOnJava21orHigher = compilerJdkVersion >= 21

// As of 2026-03-11 (Lombok 1.18.44), delombok does not support JDK 26;
Expand Down Expand Up @@ -893,7 +895,7 @@ subprojects {
// The checkNullness task runs on all code, but it only *checks* the following code:
// * All files outside the "framework", "checker", and "annotation-file-utilities" subprojects.
// * In the "framework", "checker", and "annotation-file-utilities" subprojects, files with `@AnnotatedFor("nullness")`.
boolean nullnessAll = project.getProperties().containsKey("nullnessAll")
boolean nullnessAll = providers.gradleProperty("nullnessAll").isPresent()
if (!nullnessAll && (project.name.is("framework") || project.name.is("checker") || project.name.is("annotation-file-utilities"))) {
createCheckTypeTask(project.name, "Nullness",
"org.checkerframework.checker.nullness.NullnessChecker",
Expand Down
8 changes: 4 additions & 4 deletions gradle-mvn-push.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ publishing {
repositories {
maven {
url = (isSnapshot
? project.properties.getOrDefault("SNAPSHOT_REPOSITORY_URL", "https://central.sonatype.com/repository/maven-snapshots/")
: project.properties.getOrDefault("RELEASE_REPOSITORY_URL", "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/")
? providers.gradleProperty("SNAPSHOT_REPOSITORY_URL").getOrElse("https://central.sonatype.com/repository/maven-snapshots/")
: providers.gradleProperty("RELEASE_REPOSITORY_URL").getOrElse("https://ossrh-staging-api.central.sonatype.com/service/local/")
)
credentials {
username = project.properties.get("SONATYPE_NEXUS_USERNAME")
password = project.properties.get("SONATYPE_NEXUS_PASSWORD")
username = providers.gradleProperty("SONATYPE_NEXUS_USERNAME").orNull
password = providers.gradleProperty("SONATYPE_NEXUS_PASSWORD").orNull
}
Comment on lines 13 to 16

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check other places where SONATYPE_NEXUS_USERNAME/PASSWORD or this repo block are referenced
rg -n 'SONATYPE_NEXUS_(USERNAME|PASSWORD)' --type=groovy
rg -n 'publish' gradle-mvn-push.gradle

Repository: typetools/checker-framework

Length of output: 165


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- gradle-mvn-push.gradle outline ---'
ast-grep outline gradle-mvn-push.gradle --view expanded || true

echo
echo '--- gradle-mvn-push.gradle lines 1-120 ---'
nl -ba gradle-mvn-push.gradle | sed -n '1,120p'

echo
echo '--- build.gradle credential/publish snippets ---'
rg -n -C 3 'SONATYPE_NEXUS_(USERNAME|PASSWORD)|maven|publishing|publish' build.gradle gradle-mvn-push.gradle

Repository: typetools/checker-framework

Length of output: 302


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- gradle-related files ---'
git ls-files '*gradle*' | sed -n '1,200p'

echo
echo '--- locate gradle-mvn-push.gradle ---'
fd -a 'gradle-mvn-push.gradle' . || true

echo
echo '--- read candidate files with line numbers ---'
for f in $(git ls-files '*gradle*' | grep -E '(^|/)(gradle-mvn-push\.gradle|build\.gradle)$'); do
  echo "### $f"
  cat -n "$f" | sed -n '1,160p'
  echo
done

Repository: typetools/checker-framework

Length of output: 50383


🌐 Web query:

Gradle maven-publish credentials username password null NullPointerException publish missing credentials

💡 Result:

A NullPointerException (NPE) or "Username must not be null" error during Gradle publishing typically occurs when the maven-publish plugin expects credentials for a repository but receives a null value for the username or password [1][2][3]. This error usually happens because the credentials are being resolved at configuration time, or the variables used to provide them (e.g., via findProperty or System.getenv) are missing or incorrectly configured [4][3][5]. To resolve or avoid this issue, follow these best practices: 1. Ensure properties are correctly named and defined: Verify that the properties you are accessing exist in your gradle.properties file, ~/.gradle/gradle.properties, or as environment variables [6][3]. A common mistake is a mismatch between the property name in the build script and the name provided in the property file [3]. 2. Use secure credential management: Avoid hardcoding credentials in build scripts [6]. Instead, use external properties or environment variables [6][7]: credentials { username = project.findProperty("myRepoUsername")?: System.getenv("MY_REPO_USERNAME") password = project.findProperty("myRepoPassword")?: System.getenv("MY_REPO_PASSWORD") } 3. Debugging with Gradle Scan: If the error persists and is non-obvious, run your build with the --scan flag. This often reveals more detailed stack traces that can pinpoint exactly which part of the credential resolution is failing [1]. 4. Check for incompatible configurations: If you are using features like the Configuration Cache, ensure your credential handling is compatible [4]. In some cases, explicitly defining credentials that are not needed for certain tasks can cause issues; ensure you are only triggering publication tasks when credentials are actually available [6][5]. 5. Report misconfiguration: If you encounter an NPE rather than a helpful error message (like "Username must not be null"), it is often considered a bug in the plugin's error handling [1][2]. Double-check that you are not accidentally setting credentials on a repository type that does not support them (e.g., some authentication methods do not use standard username/password credentials) [2].

Citations:


Guard against null Sonatype credentials

orNull leaves username/password unset when the properties are missing, and maven-publish can fail at publish time with an opaque NPE or “Username must not be null” instead of a clear missing-credentials error. Add an explicit check or fail-fast message for local publish runs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gradle-mvn-push.gradle` around lines 13 - 16, The Maven publish credentials
setup currently uses providers.gradleProperty(...).orNull in the credentials
block, which can leave username and password unset and cause a late, opaque
publish failure. Update the publishing configuration in gradle-mvn-push.gradle
to validate SONATYPE_NEXUS_USERNAME and SONATYPE_NEXUS_PASSWORD before the
credentials block is used, and fail fast with a clear missing-credentials
message for local publish runs. Use the existing publishing/credentials
configuration as the insertion point so the check happens before maven-publish
tries to authenticate.

}
}
Expand Down