Skip to content

Removes Commons Lang usage#776

Open
alecharp wants to merge 3 commits intojenkinsci:masterfrom
alecharp:chore/removes-commons-lang-usage
Open

Removes Commons Lang usage#776
alecharp wants to merge 3 commits intojenkinsci:masterfrom
alecharp:chore/removes-commons-lang-usage

Conversation

@alecharp
Copy link
Member

@alecharp alecharp commented Jan 19, 2026

This removes all usage of Commons Lang library.

Testing done

Ran mvn verify locally.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is fixed

@alecharp alecharp requested a review from a team as a code owner January 19, 2026 16:26
Copy link
Member

@jglick jglick left a comment

Choose a reason for hiding this comment

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

Seems to be incorrect in the first two places I checked. Was this produced by some automated rewrite tool?

try {
Properties props = new Properties();
boolean hasCustomEndpoint = StringUtils.isNotBlank(getConfiguration().getResolvedCustomEndpoint());
boolean hasCustomEndpoint = !(getConfiguration().getResolvedCustomEndpoint() != null && getConfiguration().getResolvedCustomEndpoint().isBlank());
Copy link
Member

Choose a reason for hiding this comment

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

Wait, what? This is equivalent to

Suggested change
boolean hasCustomEndpoint = !(getConfiguration().getResolvedCustomEndpoint() != null && getConfiguration().getResolvedCustomEndpoint().isBlank());
boolean hasCustomEndpoint = getConfiguration().getResolvedCustomEndpoint() == null || !getConfiguration().getResolvedCustomEndpoint().isBlank();

A null value was clearly supposed to be no endpoint.

boolean hasCustomEndpoint = !(getConfiguration().getResolvedCustomEndpoint() != null && getConfiguration().getResolvedCustomEndpoint().isBlank());

if(StringUtils.isNotBlank(getRegion())) {
if(!getRegion().isBlank()) {
Copy link
Member

Choose a reason for hiding this comment

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

Also an incorrect translation of the original code, though in this case the original code does not seem to have made any sense; from my reading, it could never have been null or blank.

@alecharp
Copy link
Member Author

Was this produced by some automated rewrite tool?

No it was not. Only used an apparently unfocussed brain.

Properties props = new Properties();
boolean hasCustomEndpoint = StringUtils.isNotBlank(getConfiguration().getResolvedCustomEndpoint());
String resolvedCustomEndpoint = getConfiguration().getResolvedCustomEndpoint();
boolean hasCustomEndpoint = resolvedCustomEndpoint == null || !resolvedCustomEndpoint.isBlank();
Copy link
Member

Choose a reason for hiding this comment

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

This still looks wrong. It has a custom endpoint if the resolved custom endpoint is not null and is not blank. Right?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes usage of Apache commons-lang v2 utilities from the S3 artifact manager plugin, replacing them with JDK equivalents and enabling an explicit build-time ban on commons-lang 2.

Changes:

  • Replace StringUtils blank/abbreviate helpers with JDK String::isBlank + manual truncation logic.
  • Replace RandomStringUtils usage in tests with UUID.
  • Enable ban-commons-lang-2 enforcement via a Maven property.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/test/java/io/jenkins/plugins/artifact_manager_jclouds/s3/S3AbstractTest.java Switches unique test prefix generation from RandomStringUtils to UUID (with truncation).
src/test/java/io/jenkins/plugins/artifact_manager_jclouds/s3/LocalStackIntegrationTest.java Replaces StringUtils.isBlank with a null-safe isBlank check for region selection.
src/main/java/io/jenkins/plugins/artifact_manager_jclouds/s3/S3BlobStoreConfig.java Replaces StringUtils usages in endpoint/validation logic and error message abbreviation.
src/main/java/io/jenkins/plugins/artifact_manager_jclouds/s3/S3BlobStore.java Replaces StringUtils usages in endpoint detection, presigner configuration, and descriptor config check.
pom.xml Adds property to enforce banning commons-lang 2.
Comments suppressed due to low confidence (1)

src/main/java/io/jenkins/plugins/artifact_manager_jclouds/s3/S3BlobStoreConfig.java:265

  • getResolvedCustomEndpoint() currently enters the block when customEndpoint is null because the condition is customEndpoint == null || !customEndpoint.isBlank(). This causes the method to return values like https://null and treats a missing endpoint as configured. The condition should require a non-null, non-blank customEndpoint (and ideally trim it) before constructing the URL.
    public String getResolvedCustomEndpoint() {
        if(customEndpoint == null || !customEndpoint.isBlank()) {
            String protocol;
            if(getUseHttp()) {
                protocol = "http";
            } else {
                protocol = "https";
            }
            return protocol + "://" + customEndpoint;
        }
        return null;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 359 to 373
@@ -368,7 +368,7 @@ public FormValidation doCheckContainer(@QueryParameter String container){

public FormValidation doCheckPrefix(@QueryParameter String prefix){
FormValidation ret;
if (StringUtils.isBlank(prefix)) {
if (prefix.isBlank()) {
ret = FormValidation.ok("Artifacts will be stored in the root folder of the S3 Bucket.");
} else if (prefix.endsWith("/")) {
public FormValidation doCheckCustomSigningRegion(@QueryParameter String customSigningRegion) {
FormValidation ret;
if (StringUtils.isBlank(customSigningRegion) && StringUtils.isNotBlank(customEndpoint)) {
if (customSigningRegion != null && customSigningRegion.isBlank() && (customEndpoint == null || !customEndpoint.isBlank())) {
public FormValidation doCheckCustomEndpoint(@QueryParameter String customEndpoint) {
FormValidation ret = FormValidation.ok();
if (!StringUtils.isBlank(customEndpoint) && !endPointPattern.matcher(customEndpoint).matches()) {
if (!customEndpoint.isBlank() && !endPointPattern.matcher(customEndpoint).matches()) {
Comment on lines 125 to 145
@@ -141,7 +141,7 @@ public BlobStoreContext getContext() throws IOException {
.overrides(props);

if (hasCustomEndpoint) {
builder = builder.endpoint(getConfiguration().getResolvedCustomEndpoint());
builder = builder.endpoint(resolvedCustomEndpoint);
}
Comment on lines 226 to 232
String customRegion = getConfiguration().getCustomSigningRegion();
if(StringUtils.isBlank(customRegion)) {
if(customRegion.isBlank()) {
customRegion = getConfiguration().getRegion().id();
}
if(StringUtils.isNotBlank(customRegion)) {
if(!customRegion.isBlank()) {
presignerBuilder.region(Region.of(customRegion));
}
*/
public boolean isConfigured(){
return StringUtils.isNotBlank(S3BlobStoreConfig.get().getContainer());
return !S3BlobStoreConfig.get().getContainer().isBlank();
public static String generateUniquePrefix() {
return String.format("%s%s-%s/", S3_DIR, ZonedDateTime.now().format(DateTimeFormatter.ISO_INSTANT),
RandomStringUtils.randomAlphabetic(4).toLowerCase());
UUID.randomUUID().toString().substring(0, 4).toLowerCase());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants