Skip to content

Conversation

stevenschlansker
Copy link
Contributor

@stevenschlansker stevenschlansker commented Apr 11, 2025

Fixes #3390

Before opening a 'pull request'

  • Search existing issues and pull requests to see if the issue was already discussed.
  • Check our discussions to see if the issue was already discussed.
  • Check for specific project we support to raise the issue on, under spotbugs
  • Do not open intellij plugin issues here, open them at intellij-plugin

Make sure these boxes are checked before submitting your PR -- thank you!

  • Added an entry into CHANGELOG.md if you have changed SpotBugs code

@@ -57,6 +57,9 @@ private MultiThreadedCodeIdentifierUtils() {

public static boolean isPartOfMultiThreadedCode(ClassContext classContext) {
JavaClass javaClass = classContext.getJavaClass();
if (notThreadSafe(javaClass.getAnnotationEntries())) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be better to introduce a new method here: now the name of the method does not match with what it does

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @gtoison , I am not sure I understand your request here. From my understanding, "multi-threaded code" here refers to code that is in use from multiple threads and should be checked.
The @NotThreadSafe annotation is an explicit declaration from the user - "this code is not intended to be used from multiple threads". Therefore, any code marked @NotThreadSafe is definitionally not "part of multi-threaded code", as the user has told us it is not.

Do you have a better method name to propose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@JuditKnoll previously indicated this would be a good place for the logic to live - perhaps they have a suggestion of the best way to resolve this

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently isPartOfMultiThreadedCode() means "that class does things that imply intent to use multiple threads".
On the other hand, @NotThreadSafe means "this won't work when used from multiple threads".

I think something like isNotThreadSafe() or isExplicitelyNotThreadSafe() would convey that meaning.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently this function is only used in the SharedVariableAtomicityDetector to decide whether the class should be visited and the bugs reported. To my best knowledge, there are no ongoing work (open PRs in SpotBugs) depending on this function.
From the detector's POV, it's true, it would prevent Fps, however there could be another usecase, where this annotation check is not necessary. (It's true that it could be easily refactored, if it's necessary, if the code depending on it is inside SpotBugs.)
Introducing a new method with the @NotThreadSafe annotation check and other functionalities of the function leaves open this option (of course with calling the new method from the SharedVariableAtomicityDetector).
Maybe isThreadSafeMultiThreadedClass or shouldBeThreadSafeMultiThreadedClass names could reflect this check as well?

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
Copy link
Collaborator

Choose a reason for hiding this comment

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

As far as I can see, the original NotThreadSafe annotation (see javadoc of the jakarta version or a copy of the javax annotation) has some different annotations: @Documented, @Target(TYPE) and @Retention(Class).

If there is no particular reason to change the fake annotations, it's best to keep them the same as the original ones IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I updated this

@@ -57,6 +57,9 @@ private MultiThreadedCodeIdentifierUtils() {

public static boolean isPartOfMultiThreadedCode(ClassContext classContext) {
JavaClass javaClass = classContext.getJavaClass();
if (notThreadSafe(javaClass.getAnnotationEntries())) {
return false;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently this function is only used in the SharedVariableAtomicityDetector to decide whether the class should be visited and the bugs reported. To my best knowledge, there are no ongoing work (open PRs in SpotBugs) depending on this function.
From the detector's POV, it's true, it would prevent Fps, however there could be another usecase, where this annotation check is not necessary. (It's true that it could be easily refactored, if it's necessary, if the code depending on it is inside SpotBugs.)
Introducing a new method with the @NotThreadSafe annotation check and other functionalities of the function leaves open this option (of course with calling the new method from the SharedVariableAtomicityDetector).
Maybe isThreadSafeMultiThreadedClass or shouldBeThreadSafeMultiThreadedClass names could reflect this check as well?

@gtoison
Copy link
Contributor

gtoison commented Apr 18, 2025

I've pushed a commit to illustrate what I meant, IMO the isPartOfMultiThreadedCode() logic is complicated enough already and we should avoid adding a somewhat contradictory case in there.
IMO it is slightly better to break things down a bit, let me know if you think there's a better way

@stevenschlansker
Copy link
Contributor Author

Sounds good to me. Let me know if I should rebase / squash the commit or anything.

@@ -151,4 +151,18 @@ public static boolean isLocked(Method currentMethod, CFG currentCFG, LockDataflo
}
return false;
}

/**
* @return <code>true</code> if the class is explicitely annotated with <code>NotThreadSafe</code> to document that it is not thread sage

Choose a reason for hiding this comment

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

typo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Copy link
Contributor

@gtoison gtoison left a comment

Choose a reason for hiding this comment

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

Thank you very much for the contribution!

@@ -57,6 +57,9 @@ private MultiThreadedCodeIdentifierUtils() {

public static boolean isPartOfMultiThreadedCode(ClassContext classContext) {
JavaClass javaClass = classContext.getJavaClass();
if (notThreadSafe(javaClass.getAnnotationEntries())) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently isPartOfMultiThreadedCode() means "that class does things that imply intent to use multiple threads".
On the other hand, @NotThreadSafe means "this won't work when used from multiple threads".

I think something like isNotThreadSafe() or isExplicitelyNotThreadSafe() would convey that meaning.

@JuditKnoll JuditKnoll merged commit b584409 into spotbugs:master Apr 23, 2025
15 checks passed
@JuditKnoll JuditKnoll added this to the Spotbugs 4.9.4 milestone Apr 23, 2025
@hazendaz hazendaz self-assigned this Apr 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mark classes / code as not threadsafe
6 participants