Skip to content

[SPARK-52880][CORE] Improve toString by JEP-280 instead of ToStringBuilder - #51572

Closed
dongjoon-hyun wants to merge 2 commits into
apache:masterfrom
dongjoon-hyun:SPARK-52880
Closed

[SPARK-52880][CORE] Improve toString by JEP-280 instead of ToStringBuilder#51572
dongjoon-hyun wants to merge 2 commits into
apache:masterfrom
dongjoon-hyun:SPARK-52880

Conversation

@dongjoon-hyun

@dongjoon-hyundongjoon-hyun commented Jul 19, 2025

Copy link
Copy Markdown
Member

What changes were proposed in this pull request?

This PR aims to improve toString by JEP-280 instead of ToStringBuilder. In addition, Scalastyle and Checkstyle rules are added to prevent a future regression.

Why are the changes needed?

Since Java 9, String Concatenation has been handled better by default.

IDDESCRIPTION
JEP-280Indify String Concatenation

For example, this PR improves OpenBlocks like the following. Both Java source code and byte code are simplified a lot by utilizing JEP-280 properly.

CODE CHANGE

- returnnewToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
- .append("appId", appId)
- .append("execId", execId)
- .append("blockIds", Arrays.toString(blockIds))
- .toString();
+ return"OpenBlocks[appId=" + appId + ",execId=" + execId + ",blockIds=" +
+ Arrays.toString(blockIds) + "]";

BEFORE

 public java.lang.String toString();
Code:
0: new #39 // class org/apache/commons/lang3/builder/ToStringBuilder
3: dup
4: aload_0
5: getstatic #41 // Field org/apache/commons/lang3/builder/ToStringStyle.SHORT_PREFIX_STYLE:Lorg/apache/commons/lang3/builder/ToStringStyle;
8: invokespecial #47 // Method org/apache/commons/lang3/builder/ToStringBuilder."<init>":(Ljava/lang/Object;Lorg/apache/commons/lang3/builder/ToStringStyle;)V
11: ldc #50 // String appId
13: aload_0
14: getfield #7 // Field appId:Ljava/lang/String;
17: invokevirtual #51 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;Ljava/lang/Object;)Lorg/apache/commons/lang3/builder/ToStringBuilder;
20: ldc #55 // String execId
22: aload_0
23: getfield #13 // Field execId:Ljava/lang/String;
26: invokevirtual #51 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;Ljava/lang/Object;)Lorg/apache/commons/lang3/builder/ToStringBuilder;
29: ldc #56 // String blockIds
31: aload_0
32: getfield #16 // Field blockIds:[Ljava/lang/String;
35: invokestatic #57 // Method java/util/Arrays.toString:([Ljava/lang/Object;)Ljava/lang/String;
38: invokevirtual #51 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;Ljava/lang/Object;)Lorg/apache/commons/lang3/builder/ToStringBuilder;
41: invokevirtual #61 // Method org/apache/commons/lang3/builder/ToStringBuilder.toString:()Ljava/lang/String;
44: areturn

AFTER

 public java.lang.String toString();
Code:
0: aload_0
1: getfield #7 // Field appId:Ljava/lang/String;
4: aload_0
5: getfield #13 // Field execId:Ljava/lang/String;
8: aload_0
9: getfield #16 // Field blockIds:[Ljava/lang/String;
12: invokestatic #39 // Method java/util/Arrays.toString:([Ljava/lang/Object;)Ljava/lang/String;
15: invokedynamic #43, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
20: areturn

Does this PR introduce any user-facing change?

No. This is an toString implementation improvement.

How was this patch tested?

Pass the CIs.

Was this patch authored or co-authored using generative AI tooling?

No.

@dongjoon-hyundongjoon-hyun changed the title [SPARK-52880][CORE] Improve toString by JEP-280 instead of ToStringBuilder[SPARK-52880][CORE] Improve toString by JEP-280 instead of ToStringBuilderJul 19, 2025
@dongjoon-hyun

Copy link
Copy Markdown
MemberAuthor

Comment threaddev/checkstyle.xml
<property name="format" value="new URL\("/>
<property name="message" value="Use URI.toURL or URL.of instead of URL constructors." />
</module>
<module name="RegexpSinglelineJava">

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.

We should ban the use of org.apache.commons.lang.builder.ToStringBuilder simultaneously, even though it is not currently being used, because the commons-lang/2.6//commons-lang-2.6.jar is still a dependency of Spark.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Thank you for review, @LuciferYang . We already banned lang2 package completely.

<checkcustomId="commonslang2"level="error"class="org.scalastyle.file.RegexChecker"enabled="true">
<parameters><parametername="regex">org\.apache\.commons\.lang\.</parameter></parameters>
<customMessage>Use Commons Lang 3 classes (package org.apache.commons.lang3.*) instead
of Commons Lang 2 (package org.apache.commons.lang.*)</customMessage>
</check>

Comment threadscalastyle-config.xml
<customMessage>Use org.apache.spark.util.Pair instead</customMessage>
</check>

<check customId="commonslang3tuple" level="error" class="org.scalastyle.file.RegexChecker" enabled="true">

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.

ditto

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

ditto.

Comment on lines +339 to +340
return "TransportClient[remoteAddress=" + channel.remoteAddress() + "clientId=" + clientId +
"isActive=" + isActive() + "]";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
return"TransportClient[remoteAddress=" + channel.remoteAddress() + "clientId=" + clientId +
"isActive=" + isActive() + "]";
return"TransportClient[remoteAddress=" + channel.remoteAddress() + ",clientId=" + clientId +
",isActive=" + isActive() + "]";

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Thanks!

.toString();
return "FetchShuffleBlockChunks[appId=" + appId + ",execId=" + execId +
",shuffleId=" + shuffleId + ",shuffleMergeId=" + shuffleMergeId +
",reduceIds=" + Arrays.toString(reduceIds) + ",chunkIds=" + Arrays.toString(chunkIds) + "]";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why changing chunkIds from Arrays.deepToString to Arrays.toString?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Oh, thank you. I'll fix it.

Comment on lines +65 to +67
return "FetchShuffleBlocks[appId=" + appId + ",execId=" + execId + ",shuffleId=" + shuffleId +
",mapIds=" + Arrays.toString(mapIds) + ",reduceIds=" + Arrays.deepToString(reduceIds) +
",batchFetchEnabled=" + batchFetchEnabled + "]";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This adds more fields than before?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

It came from toStringHelper() method at line 65. Technically, this PR removed toStringHelper usage.

publicToStringBuildertoStringHelper() {
returnnewToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("appId", appId)
.append("execId", execId)
.append("shuffleId", shuffleId);
}

}

// checkstyle.off: RegexpSinglelineJava
public ToStringBuilder toStringHelper() {

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.

This should probably not be a public api, since deleting it doesn't cause a mima check failure.

@dongjoon-hyundongjoon-hyunJul 20, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Ya, I hope to remove this eventually later because this method is not used from now.

However, this PR aims to focus on toString method improvement only in order to avoid any discussion about this method toStringHelper.

/**
* Base class for fetch shuffle blocks and chunks.
*
* @since 3.2.0
*/
publicabstractclassAbstractFetchShuffleBlocksextendsBlockTransferMessage {
publicfinalStringappId;
publicfinalStringexecId;
publicfinalintshuffleId;
protectedAbstractFetchShuffleBlocks(
StringappId,
StringexecId,
intshuffleId) {
this.appId = appId;
this.execId = execId;
this.shuffleId = shuffleId;
}
publicToStringBuildertoStringHelper() {

@dongjoon-hyun

Copy link
Copy Markdown
MemberAuthor

Thank you, @LuciferYang and @viirya . I addressed your comments and replied.

@peter-tothpeter-toth left a comment

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.

LGTM, just a nit that maybe we could use .getClass().getSimpleName()s instead of duplicating the class names.

@dongjoon-hyun

Copy link
Copy Markdown
MemberAuthor

Thank you, @peter-toth and @cloud-fan .

@dongjoon-hyun

Copy link
Copy Markdown
MemberAuthor

To @peter-toth , you are right that it's a generally good approach. Actually, I intentionally avoid that generalized pattern here due to the nature of three additional operations; two additional invokevirtuals and one additional string argument at makeConcatWithConstants at the end. For this PR, let's keep toString as simple/faster as possible for now because this is Spark internals. We may want to generalize it later.

 0: aload_0
1: invokevirtual #39 // Method java/lang/Object.getClass:()Ljava/lang/Class;
4: invokevirtual #43 // Method java/lang/Class.getSimpleName:()Ljava/lang/String;

@dongjoon-hyun

Copy link
Copy Markdown
MemberAuthor

Merged to master for Apache Spark 4.1.0.

Thank you, @LuciferYang , @viirya , @peter-toth , @cloud-fan , @MaxGekk !

@dongjoon-hyun
dongjoon-hyun deleted the SPARK-52880 branch July 21, 2025 15:46
turboFei pushed a commit to apache/celeborn that referenced this pull request Jul 23, 2025
### What changes were proposed in this pull request?
Improve `toString` by JEP-280 instead of `ToStringBuilder`.
### Why are the changes needed?
Since Java 9, String Concatenation has been handled better by default.
ID | DESCRIPTION
-- | --
JEP-280 | [Indify String Concatenation](https://openjdk.org/jeps/280)
Backport apache/spark#51572.
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
CI.
Closes#3380 from SteNicholas/CELEBORN-2077.
Authored-by: SteNicholas <programgeek@163.com>
Signed-off-by: Wang, Fei <fwang12@ebay.com>
turboFei pushed a commit to apache/celeborn that referenced this pull request Jul 23, 2025
Improve `toString` by JEP-280 instead of `ToStringBuilder`.
Since Java 9, String Concatenation has been handled better by default.
ID | DESCRIPTION
-- | --
JEP-280 | [Indify String Concatenation](https://openjdk.org/jeps/280)
Backport apache/spark#51572.
No.
CI.
Closes#3380 from SteNicholas/CELEBORN-2077.
Authored-by: SteNicholas <programgeek@163.com>
Signed-off-by: Wang, Fei <fwang12@ebay.com>
(cherry picked from commit 66856f2)
Signed-off-by: Wang, Fei <fwang12@ebay.com>
dongjoon-hyun added a commit to apache/spark-kubernetes-operator that referenced this pull request Oct 7, 2025
…tead of `ToStringBuilder`
### What changes were proposed in this pull request?
This PR aims to improve `SentinelResourceState.toString` by JEP-280 instead of `ToStringBuilder`.
### Why are the changes needed?
This is aligned with Apache Spark main repository improvement.
- apache/spark#51572
Since Java 9, `String Concatenation` has been handled better by default.
| ID | DESCRIPTION |
| - | - |
| JEP-280 | [Indify String Concatenation](https://openjdk.org/jeps/280) |
For example, `SentinelResourceState.toString` is changed like the following by this PR.
**BEFORE**
```
public java.lang.String toString();
Code:
0: new #43 // class org/apache/commons/lang3/builder/ToStringBuilder
3: dup
4: aload_0
5: invokespecial #45 // Method org/apache/commons/lang3/builder/ToStringBuilder."<init>":(Ljava/lang/Object;)V
8: ldc #48 // String resource
10: aload_0
11: getfield #17 // Field resource:Lorg/apache/spark/k8s/operator/BaseResource;
14: invokevirtual #49 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;Ljava/lang/Object;)Lorg/apache/commons/lang3/builder/ToStringBuilder;
17: ldc #53 // String previousGeneration
19: aload_0
20: getfield #39 // Field previousGeneration:J
23: invokevirtual #54 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;J)Lorg/apache/commons/lang3/builder/ToStringBuilder;
26: ldc #57 // String isHealthy
28: aload_0
29: getfield #13 // Field isHealthy:Z
32: invokevirtual #58 // Method org/apache/commons/lang3/builder/ToStringBuilder.append:(Ljava/lang/String;Z)Lorg/apache/commons/lang3/builder/ToStringBuilder;
35: invokevirtual #61 // Method org/apache/commons/lang3/builder/ToStringBuilder.toString:()Ljava/lang/String;
38: areturn
```
**AFTER**
```
public java.lang.String toString();
Code:
0: aload_0
1: getfield #17 // Field resource:Lorg/apache/spark/k8s/operator/BaseResource;
4: invokestatic #43 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
7: aload_0
8: getfield #39 // Field previousGeneration:J
11: aload_0
12: getfield #13 // Field isHealthy:Z
15: invokedynamic #49, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;JZ)Ljava/lang/String;
20: areturn
```
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Pass the CIs.
### Was this patch authored or co-authored using generative AI tooling?
No.
Closes#369 from dongjoon-hyun/SPARK-53818.
Authored-by: Dongjoon Hyun <dongjoon@apache.org>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
LuciferYang added a commit that referenced this pull request Dec 6, 2025
…actFetchShuffleBlocks.java`
### What changes were proposed in this pull request?
This pr aims to remove the unused method `toStringHelper` from `AbstractFetchShuffleBlocks.java` because it is no longer used after #51572.
### Why are the changes needed?
Code cleanup.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
- Pass Github Actions
### Was this patch authored or co-authored using generative AI tooling?
No
Closes#53341 from LuciferYang/remove-toStringHelper.
Authored-by: yangjie01 <yangjie01@baidu.com>
Signed-off-by: yangjie01 <yangjie01@baidu.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@dongjoon-hyun@viirya@LuciferYang@MaxGekk@cloud-fan@peter-toth