> And those arguments are currently presumed nullable?

I would rather say that the current state of the code is "undetermined
nullness".

Just one random example: PolarisCatalogHelpers [1]. This class has no
nullability annotations, yet all of the parameters without exception
are implicitly non-null. The code throws NPE if any of them is null.

Alex

[1]: 
https://github.com/apache/polaris/blob/17f28a92144e2ec00fb8151ac17a41796ebdf901/polaris-core/src/main/java/org/apache/polaris/core/catalog/PolarisCatalogHelpers.java#L34

On Mon, Jun 2, 2025 at 5:49 PM Eric Maynard <eric.w.mayn...@gmail.com> wrote:
>
> I think frequency is a hugely important goal, behind perhaps only accuracy
> (if I see an annotation or a lack of one, can I trust it?).
>
> The largest group of parameters we currently have is certainly
> non-annotated arguments, no? And those arguments are currently presumed
> nullable?
>
> --EM
>
> On Mon, Jun 2, 2025 at 8:42 AM Alex Dutra <alex.du...@dremio.com.invalid>
> wrote:
>
> > Hi all,
> >
> > > So now, the onus is on me, as the developer to write [...]
> >
> > But this remark is valid both ways, right? If the default is non-null
> > and my method can return null, the onus is on me to annotate it with
> > @Nullable; but if the default is nullable and my method cannot return
> > null, then the onus is again on me to annotate it with @Nonnull.
> >
> > What really matters for me is: how **frequently** would I need to
> > annotate things with @Nullable if we assume non-null by default,
> > versus how frequently would I need to annotate things with @Nonnull if
> > we assume nullable by default?
> >
> > From a quick glance, it seems to me we have more non-null arguments
> > than nullable ones.
> >
> > Thanks,
> > Alex
> >
> > On Wed, May 28, 2025 at 2:10 AM Dmitri Bourlatchkov <di...@apache.org>
> > wrote:
> > >
> > > The thing is that IntelliJ, for example, does not infer @Nullable very
> > well.
> > >
> > > For example:
> > >
> > >   Map<String, String> m = new HashMap<>();
> > >   private @Nullable String value() {
> > >     return m.get("key");
> > >   }
> > >
> > >   private void test() {
> > >     String value = value();
> > >     if (value.length() > 3) {
> > >       m.put("key", value);
> > >     };
> > >   }
> > >
> > > This code gives a warning on `value.length()`. However, if you remove
> > > @Nullable the warning disappears.
> > >
> > > So the onus is on the developer to put @Nullable where relevant. Then
> > IDEs
> > > will help.
> > >
> > > If we accept that, assuming @Nonnull by default is the next logical step.
> > >
> > > Cheers,
> > > Dmitri.
> > >
> > > On Tue, May 27, 2025 at 7:50 PM Michael Collado <collado.m...@gmail.com>
> > > wrote:
> > >
> > > > The concern, for me, is whether the onus is on the developer or on the
> > > > tools. For example, if I write a method:
> > > >
> > > > public String getTheValue() { return map.get("value");}
> > > >
> > > > with no annotation, the assumption is the return value of getTheValue
> > is
> > > > always non-null even though java.util.Map does not make any such
> > guarantee.
> > > > So now, the onus is on me, as the developer to write
> > > >
> > > > public @Nullable String getTheValue() { return map.get("value");}
> > > >
> > > > I can do this, but the reality is that I'm lazy and I'm probably going
> > to
> > > > forget and there's a high likelihood that nobody is going to call me
> > out on
> > > > it during code review because it's one small function in a 5,000 line
> > PR :)
> > > > For me, I'd much rather have the static analysis tool assume that
> > anything
> > > > not annotated might possibly be null so that when I write the
> > following, I
> > > > get a bug during the build:
> > > >
> > > > String foo = getTheValue();
> > > > return foo.length();
> > > >
> > > > Now the tool is actually doing its job of reminding me that I'm using a
> > > > value without having checked for nullability and if I want to avoid
> > that
> > > > warning (maybe because I'm using a special java.util.Map), I need to
> > update
> > > > my annotations. Given that the Iceberg codebase doesn't use these
> > > > annotations, I think we'll be dealing with nullable values far more
> > often
> > > > than non-nullable ones.
> > > >
> > > > Mike
> > > >
> > > > On Tue, May 27, 2025 at 2:25 PM Eric Maynard <eric.w.mayn...@gmail.com
> > >
> > > > wrote:
> > > >
> > > > > Right, but I think Michael is correct that when something comes from
> > > > > outside of Polaris, we have to assume it’s nullable even if it’s not
> > > > > annotated as such.
> > > > >
> > > > > Also as we are using CDI, it may not be clear whether an
> > implementation
> > > > of
> > > > > an interface is coming from “Polaris code” and therefore what
> > assumptions
> > > > > can be made about the nullability of its members.
> > > > >
> > > > > Given these considerations, I think developers are forced to do
> > their own
> > > > > due diligence for nullability when working with non-annotated
> > members. If
> > > > > we would go with option 1, this means developers are encouraged to
> > do the
> > > > > opposite and forego a nullability check on non-annotated members.
> > That
> > > > > seems dangerous.
> > > > >
> > > > > Another argument against option 1 is that for better or for worse
> > most
> > > > > variables in Polaris are in fact nullable. If we have the choice
> > between
> > > > > annotating 90% of variables and annotating 10%, I prefer the latter.
> > > > >
> > > > > On Tue, May 27, 2025 at 2:12 PM Dmitri Bourlatchkov
> > > > > <dmitri.bourlatch...@dremio.com.invalid> wrote:
> > > > >
> > > > > > Yes, the idea is to simplify things by using only one of @Nullable
> > > > > > and @Nonnull in Polaris code.
> > > > > >
> > > > > > However, I lean toward using @Nullable when necessary and assume
> > > > @Nonnull
> > > > > > by
> > > > > > default. Again this is only for Polaris code.
> > > > > >
> > > > > > Cheers,
> > > > > > Dmitri.
> > > > > >
> > > > > > On Tue, May 27, 2025 at 5:07 PM Eric Maynard <
> > eric.w.mayn...@gmail.com
> > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > If we've checked something is non-null or received a non-null
> > value
> > > > > from
> > > > > > a
> > > > > > > library, we can continue annotating it as @Nonnull within
> > Polaris. We
> > > > > can
> > > > > > > also use Optional to get similar functionality to typescript's ?
> > and
> > > > > > handle
> > > > > > > missing values that way.
> > > > > > >
> > > > > > > In all other cases, developers must assume any given reference
> > can be
> > > > > > null
> > > > > > > and do their own checks. It seems to me that there is no need for
> > > > > > @Nullable
> > > > > > > in that case. That is, if we label everything that cannot be
> > null as
> > > > > > > @Nonnull and everything that can be null as @Nullable, then every
> > > > > > reference
> > > > > > > should be annotated as one or the other. We can simplify things
> > by
> > > > just
> > > > > > > removing the @Nullable annotations.
> > > > > > >
> > > > > > > --EM
> > > > > > >
> > > > > > > On Tue, May 27, 2025 at 1:56 PM Dmitri Bourlatchkov <
> > > > di...@apache.org>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Your example is quite valid, Mike. In my proposal (several
> > emails
> > > > > ago)
> > > > > > > I'd
> > > > > > > > classify this as "inputs into Polaris code".
> > > > > > > >
> > > > > > > > However, I guess the topic of this thread is slightly
> > different.
> > > > The
> > > > > > > > question we're trying to reach consensus on, is about what we
> > > > should
> > > > > > > > annotate as @Nullable in Polaris code.
> > > > > > > >
> > > > > > > > I'd say if a value is received from external code, which is not
> > > > > > > annotated,
> > > > > > > > and returned from a Polaris method without validation, and the
> > > > > returned
> > > > > > > > value can reasonably be null, then the Polaris method should be
> > > > > > annotated
> > > > > > > > as @Nullable. However, if Polaris code checks the value to be
> > > > > non-null,
> > > > > > > the
> > > > > > > > return value need not be annotated in Polaris.
> > > > > > > >
> > > > > > > > Does this sound reasonable?
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > > Dmitri.
> > > > > > > >
> > > > > > > > On Tue, May 27, 2025 at 4:34 PM Michael Collado <
> > > > > > collado.m...@gmail.com>
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > I generally assume the other way around. Many (most)
> > libraries
> > > > > don't
> > > > > > > > > annotate the return values of their methods, so I assume
> > > > everything
> > > > > > is
> > > > > > > > > nullable unless specifically told otherwise. I would prefer
> > > > > > everything
> > > > > > > be
> > > > > > > > > non-nullable unless specifically stated (the ? is the one
> > thing I
> > > > > > would
> > > > > > > > > steal from typescript if I could), but given that library
> > code
> > > > > can't
> > > > > > be
> > > > > > > > > modified to be explicit when null return values are
> > possible, I
> > > > > don't
> > > > > > > > think
> > > > > > > > > we can make that assumption.
> > > > > > > > >
> > > > > > > > > Mike
> > > > > > > > >
> > > > > > > > > On Thu, May 22, 2025 at 10:57 AM Dmitri Bourlatchkov <
> > > > > > di...@apache.org
> > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > My preference is for option 1 below.
> > > > > > > > > >
> > > > > > > > > > On Thu, May 22, 2025 at 1:53 PM Alex Dutra
> > > > > > > > <alex.du...@dremio.com.invalid
> > > > > > > > > >
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Hi,
> > > > > > > > > > >
> > > > > > > > > > > My proposal was centered around compile-time checks and
> > > > targets
> > > > > > > > mostly
> > > > > > > > > > > developers and contributors. I am not questioning the
> > > > > usefulness
> > > > > > of
> > > > > > > > > > > runtime checks when these make sense.
> > > > > > > > > > >
> > > > > > > > > > > Maybe an example is better than a thousand words. Let's
> > > > > imagine a
> > > > > > > > > > > simple getOrDefault() method. Which version do you
> > prefer?
> > > > > > > > > > >
> > > > > > > > > > > 1. Annotate only nullable items:
> > > > > > > > > > > public String getOrDefault(@Nullable String s, String
> > def) {
> > > > > > > return s
> > > > > > > > > > > == null ? def : Objects.requireNonNull(def); }
> > > > > > > > > > >
> > > > > > > > > > > 2. Annotate only non-null items:
> > > > > > > > > > > @Nonnull public String getOrDefault(String s, @Nonnull
> > String
> > > > > > def)
> > > > > > > {
> > > > > > > > > > > return s == null ? def : Objects.requireNonNull(def); }
> > > > > > > > > > >
> > > > > > > > > > > 3. Annotate everything:
> > > > > > > > > > > @Nonnull public String getOrDefault(@Nullable String s,
> > > > > @Nonnull
> > > > > > > > > > > String def) { return s == null ? def :
> > > > > > > Objects.requireNonNull(def); }
> > > > > > > > > > >
> > > > > > > > > > > Many places in Polaris are using option 3, which is too
> > > > verbose
> > > > > > and
> > > > > > > > > > > leads to visual fatigue. What I was suggesting to the
> > > > community
> > > > > > is
> > > > > > > to
> > > > > > > > > > > adopt option 1, that reduces the visual clutter and also
> > > > > assumes
> > > > > > > > > > > non-null by default.
> > > > > > > > > > >
> > > > > > > > > > > (You will notice that I added a runtime check to all
> > three
> > > > > > > versions.)
> > > > > > > > > > >
> > > > > > > > > > > Hope that helps to clarify the discussion.
> > > > > > > > > > >
> > > > > > > > > > > Alex
> > > > > > > > > > >
> > > > > > > > > > > On Wed, May 21, 2025 at 8:54 PM Yufei Gu <
> > > > flyrain...@gmail.com
> > > > > >
> > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > In my opinion, assuming everything is nullable by
> > default
> > > > > > isn't
> > > > > > > > the
> > > > > > > > > > > > > best approach for writing robust code. I believe a
> > bias
> > > > > > towards
> > > > > > > > > > > > > non-nullness leads to more reliable systems.
> > > > > > > > > > > >
> > > > > > > > > > > > I agreed with the intention, but am concerned that
> > assuming
> > > > > > > > > everything
> > > > > > > > > > is
> > > > > > > > > > > > non-nullness may discourage null-checking, which is
> > > > > problematic
> > > > > > > as
> > > > > > > > > > > runtime
> > > > > > > > > > > > null-checking isn't a thing.
> > > > > > > > > > > >
> > > > > > > > > > > > Yufei
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > On Wed, May 21, 2025 at 9:52 AM Alex Dutra
> > > > > > > > > > <alex.du...@dremio.com.invalid
> > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > Hi Eric,
> > > > > > > > > > > > >
> > > > > > > > > > > > > You're right that annotations don't change the
> > bytecode
> > > > at
> > > > > > > > runtime.
> > > > > > > > > > > > > Their real value comes during compilation, as many
> > static
> > > > > > > > analysis
> > > > > > > > > > > > > tools use them to flag potential issues. They can
> > even
> > > > > cause
> > > > > > > > build
> > > > > > > > > > > > > failures depending on how you configure them. My IDE
> > > > > > (IntelliJ)
> > > > > > > > > > > > > frequently warns me when I forget to handle a
> > potential
> > > > > NPE;
> > > > > > if
> > > > > > > > > > you're
> > > > > > > > > > > > > not seeing similar feedback, it might be worth
> > checking
> > > > > your
> > > > > > > IDE
> > > > > > > > > > > > > settings.
> > > > > > > > > > > > >
> > > > > > > > > > > > > While the annotations are primarily for compile-time
> > > > > checks,
> > > > > > > that
> > > > > > > > > > > > > doesn't mean we can't also incorporate runtime
> > checks. We
> > > > > > > should
> > > > > > > > > aim
> > > > > > > > > > > > > to include these whenever this makes sense, for
> > example
> > > > by
> > > > > > > using
> > > > > > > > > > > > > Guava's Preconditions. This is especially useful if
> > we
> > > > > can't
> > > > > > > > > > guarantee
> > > > > > > > > > > > > that a method parameter, for instance, will never be
> > > > null,
> > > > > > > > because
> > > > > > > > > > > > > it's being provided by some external system.
> > > > > > > > > > > > >
> > > > > > > > > > > > > In my opinion, assuming everything is nullable by
> > default
> > > > > > isn't
> > > > > > > > the
> > > > > > > > > > > > > best approach for writing robust code. I believe a
> > bias
> > > > > > towards
> > > > > > > > > > > > > non-nullness leads to more reliable systems.
> > > > > > > > > > > > >
> > > > > > > > > > > > > I am also a big fan of Optional and think we should
> > > > strive
> > > > > to
> > > > > > > use
> > > > > > > > > it
> > > > > > > > > > > > > as much as possible. That said, it's not always
> > possible,
> > > > > > > > > especially
> > > > > > > > > > > > > if you are implementing a third-party interface that
> > > > > doesn't
> > > > > > > use
> > > > > > > > > it.
> > > > > > > > > > > > > Using Optional in class fields and method parameters
> > is
> > > > > also
> > > > > > > > > > > > > controversial: Optional was designed primarily as a
> > > > signal
> > > > > > from
> > > > > > > > the
> > > > > > > > > > > > > callee to the caller, to signify: "no result". In
> > other
> > > > > > words,
> > > > > > > > its
> > > > > > > > > > > > > main purpose is to clarify method return types. This
> > post
> > > > > on
> > > > > > > > Stack
> > > > > > > > > > > > > Overflow by Brian Goetz is worth reading: [1].
> > > > > > > > > > > > >
> > > > > > > > > > > > > Thanks,
> > > > > > > > > > > > >
> > > > > > > > > > > > > Alex
> > > > > > > > > > > > >
> > > > > > > > > > > > > [1]:
> > > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type/26328555#26328555
> > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Wed, May 21, 2025 at 4:37 PM Eric Maynard <
> > > > > > > > > > eric.w.mayn...@gmail.com
> > > > > > > > > > > >
> > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Thanks for bringing this up as I’ve been confused
> > by
> > > > > this a
> > > > > > > few
> > > > > > > > > > > times.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Before Polaris I hadn’t really encountered these
> > > > > > annotations
> > > > > > > > and
> > > > > > > > > I
> > > > > > > > > > > was
> > > > > > > > > > > > > > surprised to learn they don’t “do anything” — that
> > is,
> > > > > > there
> > > > > > > is
> > > > > > > > > no
> > > > > > > > > > > > > > additional safety you get at runtime when a null
> > value
> > > > is
> > > > > > > > passed
> > > > > > > > > > > into a
> > > > > > > > > > > > > > parameter marked non-null. Similarly nothing
> > enforces
> > > > > that
> > > > > > > you
> > > > > > > > > > handle
> > > > > > > > > > > > > null
> > > > > > > > > > > > > > values when something is annotated as nullable.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > For that reason, I tend to assume everything is
> > > > nullable
> > > > > > > > > regardless
> > > > > > > > > > > of
> > > > > > > > > > > > > > annotation and I would be in favor of standardizing
> > > > > around
> > > > > > > that
> > > > > > > > > > > > > assumption.
> > > > > > > > > > > > > > Iff something is annotated as Non-null a developer
> > > > should
> > > > > > > feel
> > > > > > > > > safe
> > > > > > > > > > > > > > skipping a check for null, but otherwise they
> > should
> > > > > handle
> > > > > > > > null.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I am a big fan of Optional and of trying to reduce
> > the
> > > > > > usage
> > > > > > > of
> > > > > > > > > > null
> > > > > > > > > > > as
> > > > > > > > > > > > > > much as possible though.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Wed, May 21, 2025 at 3:02 PM Alex Dutra
> > > > > > > > > > > <alex.du...@dremio.com.invalid
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Hi all,
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > A while ago, we had a discussion regarding which
> > > > > nullness
> > > > > > > > > > > annotations
> > > > > > > > > > > > > > > to use and whether we should consider favoring
> > > > non-null
> > > > > > by
> > > > > > > > > > > default. I
> > > > > > > > > > > > > > > would like to revive that discussion.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > We are currently using the `jakarta.annotation`
> > > > package
> > > > > > > > > > > consistently,
> > > > > > > > > > > > > > > but the defaults are not clear: should we
> > consider
> > > > > > > everything
> > > > > > > > > as
> > > > > > > > > > > > > > > non-null by default and only annotate the
> > nullable
> > > > > > things,
> > > > > > > or
> > > > > > > > > the
> > > > > > > > > > > > > > > other way around? Some classes are cluttered with
> > > > both
> > > > > > > > > > annotations,
> > > > > > > > > > > > > > > which seems unnecessary and confusing.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I would personally be in favor of considering
> > > > > everything
> > > > > > as
> > > > > > > > > > > non-null by
> > > > > > > > > > > > > > > default.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Please let me know your thoughts.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Alex
> > > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> >

Reply via email to