Skip to content

Add rule to prevent calls to Objects.requireNonNull() #41611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed

Add rule to prevent calls to Objects.requireNonNull() #41611

wants to merge 4 commits into from

Conversation

ivamly
Copy link
Contributor

@ivamly ivamly commented Jul 25, 2024

Add Check for Objects.requireNonNull Usage and Corresponding Tests

This pull request for issue ticket #41603 introduces a new architecture check for ensuring that Objects.requireNonNull is not used directly. Instead, the Assert.notNull method from Spring Framework should be used. Additionally, this update includes new test cases and necessary files to validate this architecture rule.

Changes:

New Architecture Check:

Added a method to the ArchitectureCheck class to verify that Objects.requireNonNull is not used within the codebase.

Test Cases:

Implemented tests to validate the new architecture check:
RequireNonNullUsage: Tests that the direct use of Objects.requireNonNull in the code results in a failure.
AssertNotNullUsage: Tests that using Assert.notNull is allowed and does not cause a failure.

File Updates:

Created the necessary files and classes for testing:
RequireNonNullUsage: Contains a method using Objects.requireNonNull to trigger the architecture check.
AssertNotNullUsage: Contains a method using Assert.notNull to verify that it does not violate the rule.

These changes help enforce best practices for null-checking within the project and ensure that the code adheres to the preferred use of Spring utilities.

@pivotal-cla
Copy link

@ivamly Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-cla
Copy link

@ivamly Thank you for signing the Contributor License Agreement!

@ivamly
Copy link
Contributor Author

ivamly commented Jul 25, 2024

I've reviewed the contribution guidelines and considered adding Javadoc comments to ArchitectureCheck.java and ArchitectureCheckTests.java. However, I wasn't sure if it was necessary to include Javadoc for these classes, so I have refrained from adding them for now. If it's required, please let me know, and I will update the code accordingly.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 25, 2024
@wilkinsona wilkinsona added type: task A general task and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 25, 2024
@wilkinsona wilkinsona added this to the 3.2.x milestone Jul 25, 2024
@ivamly
Copy link
Contributor Author

ivamly commented Jul 25, 2024

@wilkinsona I noticed from the build report that the build is failing due to missing newline characters at the end of my files. What should I do to resolve this issue? Do I need to make another commit, update the pull request, or take any other action?

Apologies if this seems like a basic question—I'm still new to this process. Thank you for your help!

@wilkinsona
Copy link
Member

wilkinsona commented Jul 25, 2024

Either we can take care of it as part of merging the changes, or you can push another commit to your main branch and it will then automatically update this PR.

@ivamly
Copy link
Contributor Author

ivamly commented Jul 25, 2024

I'll make a commit tonight.

@wilkinsona wilkinsona self-assigned this Jul 25, 2024
@wilkinsona
Copy link
Member

It looks like there's a bug in ArchUnit that's causing it to report many false positives. It trips up on code that uses a method reference such as this:

public void someCodeThatUsesAMethodReference() {
	List.of("1", "2", "3").forEach(System.out::println);
}

We'll have to see if there's a workaround or if there's a fix available.

@ivamly
Copy link
Contributor Author

ivamly commented Jul 25, 2024

Thank you for the update. That's interesting. Is there anything I can do? I’m happy to assist if needed.

@wilkinsona
Copy link
Member

It isn't a bug in ArchUnit, but an unfortunate side effort of the bytecode that's produced by a method reference. The example above looks like this:

  public void someCodeThatUsesAMethodReference();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: ldc           #15                 // String 1
         2: ldc           #17                 // String 2
         4: ldc           #19                 // String 3
         6: invokestatic  #21                 // InterfaceMethod java/util/List.of:(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
         9: getstatic     #27                 // Field java/lang/System.out:Ljava/io/PrintStream;
        12: dup
        13: invokestatic  #33                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
        16: pop
        17: invokedynamic #39,  0             // InvokeDynamic #0:accept:(Ljava/io/PrintStream;)Ljava/util/function/Consumer;
        22: invokeinterface #43,  2           // InterfaceMethod java/util/List.forEach:(Ljava/util/function/Consumer;)V
        27: return
      LineNumberTable:
        line 30: 0
        line 31: 27
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      28     0  this   Lorg/springframework/boot/build/architecture/objects/noRequireNonNull/AssertNotNullUsage;

Note 13 where it's calling java.lang.Objects.requireNonNull(Object).

Is there anything I can do? I’m happy to assist if needed.

Thanks for the offer.

Could you please update the PR so that it doesn't prohibit Objects.requireNonNull(Object)? We can still prohibit Objects.requireNonNull(Object, String) with Assert.notNull(Object, String) being the recommend replacement. We should also prohibit Objects.requireNonNull(Object, Supplier) with Assert.notNull(Object, Supplier) being the recommend replacement. These two will probably have to be separate rules as the because reason will be different.

@ivamly
Copy link
Contributor Author

ivamly commented Jul 25, 2024

Thanks for the clarification! This is really interesting. I’ll update the PR within an hour.

@wilkinsona
Copy link
Member

Thanks very much, @ivamly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task A general task
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants