Skip to content

Review JSpecify nullness on type user array elements and lists #4035

Open

Description

@filiphr

Review how something like:

@NullMarked
class JSpecifyArrays {

  public String @Nullable[] getNullableArrayOfNonNullStrings() { }

  public @Nullable String[] getNonNullArrayOfNullableStrings() { }

  public String[] getNonNullArrayOfNonNullStrings() { }
}

works. This is from #4033 (comment)

Activity

  1. added this to the 1.7.x milestone on Apr 13, 2026
  2. Karkoon commented on May 3, 2026

    @Karkoon

    Hi, I've used the latest commit 79aee1a
    I believe what I've experienced is related to this issue (like, a variant of it). I've spotted it when working on my homelab setup.

    I've modified the SourceBean and TargetBean classes used in the JSpecifyNullMarkedTest to include an additional field

    private List<String> nonNullListValue;
    

    I've added the JSpecify annotation @NonNull to the getters.

    But I see that the generated code contains:

    List<String> list = source.getNonNullListValue();
    if ( list != null ) {
         nonNullListValue = new ArrayList<String>( list );
    }
    

    I believe the JSpecify support for normal fields meant that if there was the NonNull annotation, then such additional nullability checks were removed. So it means it should be also removed in this case.

    There's also a similar case when the mapping method takes in a Collection/Container - it also seems that the @NullMarked check isn't included and by default the mapper can return null.

        @Override
        public List<CategoryResponseDto> toResponseDtos(List<Category> categories) {
            if ( categories == null ) {
                return null;
            }
    
            List<CategoryResponseDto> list = new ArrayList<CategoryResponseDto>( categories.size() );
            for ( Category category : categories ) {
                list.add( toResponseDto( category ) );
            }
    
            return list;
        }
    

    These two are an issue for me, because my ErrorProne NullAway check sees these two as errors.

    error: [NullAway] returning @Nullable expression from method with @NonNull return type
    

    By removing these if checks, the check passes.

    I believe this is something that forces people to exclude the Mapstruct generated classes from being checked with ErrorProne.
    Not really 100% if this is something that is in scope of Mapstruct though, just providing feedback.

    Thanks for the work on this tool!

  3. filiphr commented on May 15, 2026

    @filiphr
    MemberAuthor

    Thanks for reporting this @Karkoon, I've created #4056 for this. THe issue here is more for things like List<@NotNull String>

  4. exijn commented on Aug 20, 2026

    @exijn

    Hi, I'd like to investigate this issue if it is still available.

    I'll add focused processor tests covering nullable arrays, nullable array elements, nested arrays, and generic collection elements under @NullMarked. I'll compare the resolved nullability with the generated null checks and generated mappings, then fix the smallest part of the type-use nullability handling that loses the array or element position.

    Please let me know if this should be limited to arrays first or include List<@Nullable T> and nested generic containers in the same PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions