Skip to content
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

[GR-49816] Throw exception for null pointers passed to RuntimeJNIAccess / RuntimeReflection register methods #6985

Conversation

zakkak
Copy link
Collaborator

@zakkak zakkak commented Jul 12, 2023

Don't allow null values to be passed to the register method of RuntimeJNIAccess and RuntimeReflection. Since these are public APIs GraalVM should either handle null values (by ignoring them in this case) or throw a NullPointerException before creating an asynchronous task to perform the registration in the analysis, which then results in NullPointerExceptions being thrown later when it's no longer possible to understand where the null value originate from.

Closes: quarkusio/quarkus#34698

If accepted, it would also be good to get this backported to 23.1 and 23.0 (and 22.3?).

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Jul 12, 2023
@zakkak zakkak force-pushed the 2023-07-12-forgiving-null-reflectionregistrations branch from d680bbd to 78c9301 Compare July 12, 2023 15:42
@zakkak zakkak requested a review from loicottet July 12, 2023 15:43
@fniephaus
Copy link
Member

Since these are public APIs GraalVM should either handle null values (by ignoring them in this case) or throw a NullPointerException before creating an asynchronous task to perform the registration in the analysis, which then results in NullPointerExceptions being thrown later when it's no longer possible to understand where the null value originated from.

+1 for throwing NPEs, so that users are forced to look into registrations and other API calls that do nothing (e.g., when a class/field/method lookup returned null).

@zakkak zakkak force-pushed the 2023-07-12-forgiving-null-reflectionregistrations branch 2 times, most recently from f8a0c45 to 2b0e34c Compare October 31, 2023 18:46
@zakkak
Copy link
Collaborator Author

zakkak commented Oct 31, 2023

@fniephaus this one slept through the cracks. I have updated it to thrown NullPointerExceptions as discussed. Please have a look.

@zakkak zakkak changed the title Allow null pointer in RuntimeJNIAccess / RuntimeReflection register methods Throw exception for null pointers passed to RuntimeJNIAccess / RuntimeReflection register methods Oct 31, 2023
@zakkak zakkak force-pushed the 2023-07-12-forgiving-null-reflectionregistrations branch from 2b0e34c to 6ba9fb4 Compare November 1, 2023 08:42
@zakkak zakkak force-pushed the 2023-07-12-forgiving-null-reflectionregistrations branch from 6ba9fb4 to 448711d Compare November 1, 2023 09:48
Copy link
Member

@fniephaus fniephaus left a comment

Choose a reason for hiding this comment

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

LGTM

@fniephaus
Copy link
Member

Could you please fix the style gate?

@fniephaus fniephaus changed the title Throw exception for null pointers passed to RuntimeJNIAccess / RuntimeReflection register methods [GR-49816] Throw exception for null pointers passed to RuntimeJNIAccess / RuntimeReflection register methods Nov 1, 2023
@fniephaus fniephaus requested review from vjovanov and removed request for loicottet November 1, 2023 10:13
Don't allow null values to be passed to the `register` method of
`RuntimeJNIAccess` and `RuntimeReflection`. Since these are public APIs
GraalVM should either handle null values (by ignoring them in this case)
or throw a `NullPointerException` before creating an asynchronous task
to perform the registration in the analysis, which then results in
`NullPointerException`s being thrown later when it's no longer possible
to understand where the null value originate from.
@zakkak zakkak force-pushed the 2023-07-12-forgiving-null-reflectionregistrations branch from 448711d to e6c12dd Compare November 1, 2023 11:25
@zakkak
Copy link
Collaborator Author

zakkak commented Nov 1, 2023

Could you please fix the style gate?

Done

@vjovanov
Copy link
Member

vjovanov commented Nov 1, 2023

Thank you greatly for this fix. LGTM.

Not before the register methods, which can miss cases, nor later on in a runnable.
@fniephaus
Copy link
Member

I discussed this internally and changed the PR as follows:

  • Lower the null-check into register(ConfigurationCondition condition, boolean unsafeAllocated, Class<?> clazz). It was missing there.
  • Move null-checks out of runnables and right to the beginning of the register methods.
  • Apply the same strategy to JNIAccessFeature. It seems you, @zakkak, forgot about that.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 2, 2023

I discussed this internally and changed the PR as follows:

Sounds good, are you going to create a different PR or force push on this?

* Lower the null-check into `register(ConfigurationCondition condition, boolean unsafeAllocated, Class<?> clazz)`. It was missing there.

That makes sense, this way it won't cover only the public facing APIs.

* Move null-checks out of runnables and right to the beginning of the register methods.

Doesn't this result in iterating over the arrays twice? Once for the check and another for the runnables?

* Apply the same strategy to `JNIAccessFeature`. It seems you, @zakkak, forgot about that.

Indeed. Thanks for noticing and fixing this.

@fniephaus
Copy link
Member

Doesn't this result in iterating over the arrays twice? Once for the check and another for the runnables?

Yes, but there are no guarantees when the runnables run. What if they run later on in some other thread?

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 2, 2023

Doesn't this result in iterating over the arrays twice? Once for the check and another for the runnables?

Yes, but there are no guarantees when the runnables run. What if they run later on in some other thread?

This is only a concern because we are using Streams instead of iterators (for loop), e.g. here, right?

Given that the arrays being iterated are not expected to be that big, what's the benefit of using streams?

@fniephaus
Copy link
Member

fniephaus commented Nov 2, 2023

Sounds good, are you going to create a different PR or force push on this?

I just pushed my changes manually.

This is only a concern because we are using Streams instead of iterators (for loop), e.g. here, right?
Given that the arrays being iterated are not expected to be that big, what's the benefit of using streams?

I'm not using streams for the null-checks. I didn't touch the other code you references.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 2, 2023

I just pushed my changes manually.

Looks good to me. Thank you Fabio.

Well runnables are inevitable in registerConditionalConfiguration either way. Sorry for the noise.

@fniephaus
Copy link
Member

Well runnables are inevitable in registerConditionalConfiguration either way. Sorry for the noise.

What do you mean? For reachability handlers, some runnables may never run (if something did not get reachable). We should still fail if null values were registered, so that users know. In case the runnables to run later on, there is no way for users to understand which part of their code base registered a null class/method/fields, that's why we should fail as early as possible instead.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 2, 2023

Well runnables are inevitable in registerConditionalConfiguration either way. Sorry for the noise.

What do you mean? For reachability handlers, some runnables may never run (if something did not get reachable). We should still fail if null values were registered, so that users know. In case the runnables to run later on, there is no way for users to understand which part of their code base registered a null class/method/fields, that's why we should fail as early as possible instead.

Yes, I agree. Sorry if it was not clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement. redhat-interest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

After update to 3.2.0.Final native compilation throws an exception
4 participants