-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
GH-37286: [Java] Start adding nullability/nullness annotations #37723
Conversation
Thanks for opening a pull request! If this is not a minor PR. Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project. Then could you also rename the pull request title in the following format?
or
In the case of PARQUET issues on JIRA the title also supports:
See also: |
|
Hello @lidavidm, could you please provide me with an initial review of how I intend to integrate Nullness evaluation into Java modules (please consider only: arrow-memory-core initially)? I have these 02 doubts:
Could you please help me with these two doubts so that I know how to proceed? Thank you in advance |
For (1), what are some examples of the warnings? Ideally, we'd only enable it one module at a time. For (2), can we enable it only in a separate profile, and have that be run in CI? That way it does not affect the 'normal' builds. |
java/pom.xml
Outdated
@@ -44,8 +44,11 @@ | |||
<forkCount>2</forkCount> | |||
<checkstyle.failOnViolation>true</checkstyle.failOnViolation> | |||
<errorprone.javac.version>9+181-r4173-1</errorprone.javac.version> | |||
<error_prone_core.version>2.16</error_prone_core.version> | |||
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version> | |||
<pinjdk8.errorprone.core.version>2.10.0</pinjdk8.errorprone.core.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More reason to drop JDK8 ASAP.
java/pom.xml
Outdated
with other annotation processors. | ||
See https://github.com/jbosstools/m2e-apt/issues/62 for details | ||
--> | ||
<id>error-prone-checkerframework-jdk8</id> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, we don't bother enabling this for JDK8. In fact, I'd be OK with dropping error-prone for JDK8 as well, and only enabling these checks only on the latest LTS.
@@ -1033,7 +1034,7 @@ public void getBytes(long index, OutputStream out, int length) throws IOExceptio | |||
// copy length bytes of data from this ArrowBuf starting at | |||
// address addr(index) into the tmp byte array starting at index 0 | |||
byte[] tmp = new byte[length]; | |||
MemoryUtil.UNSAFE.copyMemory(null, addr(index), tmp, MemoryUtil.BYTE_ARRAY_BASE_OFFSET, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: is it possible to make the UNSAFE
constant private
to avoid other problems like this? (We can do that in a separate ticket.)
@@ -154,7 +157,7 @@ private static String createErrorMsg(final BufferAllocator allocator, final long | |||
} | |||
} | |||
|
|||
public static boolean isDebug() { | |||
public static @Nullable boolean isDebug() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems wrong: this is a primitive and should never be null.
@@ -42,7 +43,7 @@ abstract class BaseAllocator extends Accountant implements BufferAllocator { | |||
|
|||
public static final String DEBUG_ALLOCATOR = "arrow.memory.debug.allocator"; | |||
public static final int DEBUG_LOG_LENGTH = 6; | |||
public static final boolean DEBUG; | |||
public static final @Nullable boolean DEBUG; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also seems wrong.
@@ -64,15 +65,16 @@ abstract class BaseAllocator extends Accountant implements BufferAllocator { | |||
// Package exposed for sharing between AllocatorManger and BaseAllocator objects | |||
private final String name; | |||
private final RootAllocator root; | |||
private final Object DEBUG_LOCK = DEBUG ? new Object() : null; | |||
|
|||
private final @Nullable Object DEBUG_LOCK = DEBUG ? new Object() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, there is no harm in always initializing this.
@@ -183,6 +186,7 @@ public ArrowBuf getEmpty() { | |||
* we have a new ledger | |||
* associated with this allocator. | |||
*/ | |||
@SuppressWarnings({"nullness:locking.nullable", "nullness:argument"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the warnings here?
@@ -81,7 +82,8 @@ public ArrowBufPointer(ArrowBuf buf, long offset, long length) { | |||
* @param length the length off set of the memory region pointed to. | |||
* @param hasher the hasher used to calculate the hash code. | |||
*/ | |||
public ArrowBufPointer(ArrowBuf buf, long offset, long length, ArrowBufHasher hasher) { | |||
@SuppressWarnings("initialization.fields.uninitialized") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we initialize fields instead of suppressing the warnings?
@@ -33,7 +35,7 @@ | |||
public class MemoryUtil { | |||
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MemoryUtil.class); | |||
|
|||
private static final Constructor<?> DIRECT_BUFFER_CONSTRUCTOR; | |||
private static final @Nullable Constructor<?> DIRECT_BUFFER_CONSTRUCTOR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Checker Framework have anything for static initializers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see anything at first glance besides this https://checkerframework.org/api/org/checkerframework/checker/initialization/InitializationChecker.html
(1) You could see warning messages here, search for (2) Ok, let me add that inside a custom profile only for CI |
(1) let's only run the checker on memory-core to start with |
For https://github.com/apache/arrow/tree/main/java/format/src/main/java/org/apache/arrow/flatbuf let's add a package-info.java with a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening up this PR @davisusanibar!
I see there are a lot of Suppressed warnings. Are they truly all needed? (I haven't looked into all of them). I would like to see zero suppressed warnings if possible. Otherwise, the checker doesn't feel as useful.
java/pom.xml
Outdated
@@ -46,6 +46,7 @@ | |||
<errorprone.javac.version>9+181-r4173-1</errorprone.javac.version> | |||
<error_prone_core.version>2.16</error_prone_core.version> | |||
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version> | |||
<checker.framework.version>3.38.0</checker.framework.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v3.39.0 just released a few days ago, which adds additional support for Java 21 compilation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we try v3.39.0? It might be worth rebasing so that the Java 21 CI job can run to see if its required.
@@ -29,6 +29,7 @@ public class StackTrace { | |||
/** | |||
* Constructor. Captures the current stack trace. | |||
*/ | |||
@SuppressWarnings("nullness:assignment") //incompatible types in assignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you expand on why this is suppressed? nullness:assignment
warning makes me think we can just check the length of the stack trace to make sure we are assigning valid entries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you expand on why this is suppressed?
nullness:assignment
warning makes me think we can just check the length of the stack trace to make sure we are assigning valid entries.
It is not necessary, I will update it.
@@ -286,7 +288,7 @@ public void setLimit(long newLimit) { | |||
* | |||
* @return Currently allocate memory in bytes. | |||
*/ | |||
public long getAllocatedMemory() { | |||
public long getAllocatedMemory(Accountant this) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is this needed? It's not used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is this needed? It's not used.
Not needed, I am going to delete that
Hi @danepitkin yes this is possible to suppress some warnings such as Let me add that logic explicitly. |
if (parent == null) { | ||
throw new IllegalArgumentException(String.valueOf("Accountant(parent) must not be null")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you use String.valueOf?
if (parent == null) { | |
throw new IllegalArgumentException(String.valueOf("Accountant(parent) must not be null")); | |
} | |
Preconditions.checkArgument(parent != null, "parent must not be null"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mention at #37723 (comment) (1st option) if I added Preconditions.xxx then that finished also with errors, then, is needed to add inline throw validation.
Finished OK:
final BufferLedger oldLedger = map.remove(allocator);
if (oldLedger == null) {
throw new IllegalArgumentException(String.valueOf("BufferLedger(oldLedger) must not be null"));
}
BufferAllocator oldAllocator = oldLedger.getAllocator();
Finished with errors:
final BufferLedger oldLedger = map.remove(allocator);
Preconditions.checkArgument(oldLedger != null, "BufferLedger(oldLedger) must not be null");
BufferAllocator oldAllocator = oldLedger.getAllocator();
Error message:
error: [dereference.of.nullable] dereference of possibly-null reference oldLedger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to annotate the Preconditions methods so that Checker Framework recognizes them...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
@@ -48,8 +49,9 @@ public abstract class AllocationManager { | |||
// This is mostly a semantic constraint on the API user: if the reference count reaches 0 in the owningLedger, then | |||
// there are not supposed to be any references through other allocators. In practice, this doesn't do anything | |||
// as the implementation just forces ownership to be transferred to one of the other extant references. | |||
private volatile BufferLedger owningLedger; | |||
private volatile @Nullable BufferLedger owningLedger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davisusanibar can you review this?
java/memory/memory-core/src/main/java/org/apache/arrow/memory/AllocationManager.java
Outdated
Show resolved
Hide resolved
java/memory/memory-core/src/main/java/org/apache/arrow/memory/BufferLedger.java
Outdated
Show resolved
Hide resolved
private final RoundingPolicy roundingPolicy; | ||
private final AllocationManager.Factory allocationManagerFactory; | ||
private final AllocationManager.@NonNull Factory allocationManagerFactory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davisusanibar can you follow up here? File an issue?
* @param eval The assertion to be evaluated at compile time | ||
*/ | ||
@AssertMethod | ||
public static void assertMethod(boolean eval) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any change.
java/memory/memory-core/src/main/java/org/apache/arrow/memory/BaseAllocator.java
Outdated
Show resolved
Hide resolved
java/memory/memory-core/src/main/java/org/apache/arrow/memory/BaseAllocator.java
Outdated
Show resolved
Hide resolved
java/memory/memory-core/src/main/java/org/apache/arrow/memory/BaseAllocator.java
Outdated
Show resolved
Hide resolved
@github-actions crossbow submit java |
Revision: f92f376 Submitted crossbow builds: ursacomputing/crossbow @ actions-b35c84940e |
After merging your PR, Conbench analyzed the 5 benchmarking runs that have been run so far on merge-commit ccc79e9. There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 3 possible false positives for unstable benchmarks that are known to sometimes produce them. |
…pache#37723) ### Rationale for this change Closes: apache#37286 ### What changes are included in this PR? Initial support for: - Use the Checker Framework to enhances Java’s type system to make it more powerful and useful. Planning to start with [Nullness Checker](https://checkerframework.org/manual/#nullness-checker) ### Are these changes tested? These are the activities involved on this PR: - [x] Configure the Checker Framework - [x] Treat checker errors as warnings initially - [x] Applying Nullness Checker annotation as needed: @ NonNull / @ Nullable - [x] Check if building timer increases after this checker is added - [x] Fixes for code review ### Are there any user-facing changes? Yes * Closes: apache#37286 Lead-authored-by: david dali susanibar arce <davi.sarces@gmail.com> Co-authored-by: David Susanibar Arce <dsusanibar@Voltron.local> Co-authored-by: David Susanibar Arce <davi.sarces@gmail.com> Signed-off-by: David Li <li.davidm96@gmail.com>
…pache#37723) ### Rationale for this change Closes: apache#37286 ### What changes are included in this PR? Initial support for: - Use the Checker Framework to enhances Java’s type system to make it more powerful and useful. Planning to start with [Nullness Checker](https://checkerframework.org/manual/#nullness-checker) ### Are these changes tested? These are the activities involved on this PR: - [x] Configure the Checker Framework - [x] Treat checker errors as warnings initially - [x] Applying Nullness Checker annotation as needed: @ NonNull / @ Nullable - [x] Check if building timer increases after this checker is added - [x] Fixes for code review ### Are there any user-facing changes? Yes * Closes: apache#37286 Lead-authored-by: david dali susanibar arce <davi.sarces@gmail.com> Co-authored-by: David Susanibar Arce <dsusanibar@Voltron.local> Co-authored-by: David Susanibar Arce <davi.sarces@gmail.com> Signed-off-by: David Li <li.davidm96@gmail.com>
…pache#37723) ### Rationale for this change Closes: apache#37286 ### What changes are included in this PR? Initial support for: - Use the Checker Framework to enhances Java’s type system to make it more powerful and useful. Planning to start with [Nullness Checker](https://checkerframework.org/manual/#nullness-checker) ### Are these changes tested? These are the activities involved on this PR: - [x] Configure the Checker Framework - [x] Treat checker errors as warnings initially - [x] Applying Nullness Checker annotation as needed: @ NonNull / @ Nullable - [x] Check if building timer increases after this checker is added - [x] Fixes for code review ### Are there any user-facing changes? Yes * Closes: apache#37286 Lead-authored-by: david dali susanibar arce <davi.sarces@gmail.com> Co-authored-by: David Susanibar Arce <dsusanibar@Voltron.local> Co-authored-by: David Susanibar Arce <davi.sarces@gmail.com> Signed-off-by: David Li <li.davidm96@gmail.com>
Rationale for this change
Closes: #37286
What changes are included in this PR?
Initial support for:
Are these changes tested?
These are the activities involved on this PR:
Are there any user-facing changes?
Yes