Fix: don't force native access if disabled (#15815)#15843
Fix: don't force native access if disabled (#15815)#15843cortlepp wants to merge 3 commits intoapache:mainfrom
Conversation
|
@uschindler @jpountz friendly ping because you are the main authors of this file 😄 . |
uschindler
left a comment
There was a problem hiding this comment.
Hi,
thanks for the PR. In general this looks good. We use a holder pattern at different places, too - although it is strange that we really need this here, if we have the moudle check.
Can you explain why it may fail and lead to clinit problem and later ClassDefNotFoundExceptions?
There is a small change needed: Private fields should be final and therefor the one in the enum. If this is automatic (don't remember how this is in enums), I'd prefer to be explicit.
Uwe
lucene/core/src/java/org/apache/lucene/store/PosixNativeAccess.java
Outdated
Show resolved
Hide resolved
|
In general this can only be applied to main branch (11.0), backporting to Lucene 10 is possible, but needs a bit more adaptions: We need to add class I forgot to add this earlier (I had it on my "brain-only-TODO-list" but forgot about it). Can you add this to the 10.x changes list in this PR already. I will take care of the backport and add modifications to the "preview" compilation in Java 21. I will open a PR for that after we merged this. |
|
P.S.: Nice Singleton style - I like it! |
|
I still don't think that the current code fails when native access is disabled. Have you tested this? Actually it is intended to log warning, with your change the warning is no longer printed. In general I don't see a problem with current code. If you want to get rid of the warning, suppress it in your logging config. The current code is fine, but I don't understand why it fails. I have tested current code with disabled native access and it correctly logs a warning, so the clinit stuff is fine. |
|
Basically the current code should only be changed to have a possible So maybe move that down into the try-catch. Then it is safe for clinit. I don't see a reason for refactoring this otherwise. Logging the warning IF native access is disabled is actually wanted. |
It doesn't fail, that's not what I meant. If an exception is thrown for the 2nd/3rd catch block it will fail though and then you have the described class loading issues. My main argument is that the current implementation is brittle because it can lead to wider class loading issues for a feature that is strictly speaking optional, even on posix platforms. Besides I think that it is unwise to do the setup things we need to in
I kind of disagree with that, but it seems to be the general stance in Lucene so I've made my peace with it. My problem with the current implementation is that I can't suppress the warning because it always attempts the native access, which triggers a JVM warning (which I can't suppress) and then a log (which I can suppress). If I want to avoid the JVM warning I would have to add a JVM flag, which is hard in my deployment scenario where I don't have direct access to the JVM, we only provide the jar.
|
|
Hi, Actually the current code is a bit broken due to this change by @jpountz: cortlepp@3003731 The first two lines of the static initializer must be inside the try...catch. The code is NOT briddle, sorry. The exception handling was done carefully and accoridng to the native access spec. We don't generally want to do anything like "catch (RuntimeException _)", because it would swallow an important exception. If the static initializer breaks, its a bug in the JVM and should fail. So IMHO, the change by @jpountz should be fixed to move the first two lines of the static initializer to the try/catch block. This is indeed a bug and may fail the startup - the UnsupportedOperationException is handled there. I can open a PR and merge this to fix this bug, but all the other code changes here are unneeded and theres no risk in the current code because all native access runtime Exceptions are handled according to the Panama Foreign spec. |
|
Actually: Your enum could also be accidentally loaded. The enum constants are also initialized on class loading so the same problems occur. So theres no reason to actually make a holder. |
|
See #15844 for the only fix needed here. I will also add a comment in source code to explain why the catch blocks are required. I will close this issue as there is no problem requiring a refactoring. The code is not briddle and used in similar way at other static initializers. |
|
I tested all combinations in #15844. I look into adding integration test that spawns a JVM without native access. as a separate PR. |
Sorry, but it really isn't because in the vectorization case I can silence the logger, in this case here my JVM will print the following:
Yeah, you're right, my mistake. But IMO that means we should still change the current implementation, just not to an enum singleton holder but instead a double locking pattern (or something else that does not have the class loading issue). |
That's the same for Vectorization, the only difference is that it only happens when you enable Vectorization. To get rid of the warning pass the correct command line parameter. This PR does not fix the issue. The easiest is to disallow or allow native access (see test config on other PR). It is not Lucene's problem how you configure your JVM.
Why. There is no issue during class loading. If you are afraid you need to do this for every clinit anywhere in Lucene. It is impossible that the code fails after the other PR is merged. If an exception is thrown, your JVM is broken anyways. Lucene is very strict on exceptions, e.g. we never ever catch Throwable and swallow or don't report. The patterns seen here is at many places, e.g. Panama vector init, Lucene 10 Mmap, Expressions module,... - we have many static initializers that may fail if your JVM is broken. The exception handling is always strict. We never ever intend to catch or swallow Throwable. It's always rethrowed if unknown, also in static initializers. Sorry, Uwe |
|
In the other PR I will add some code to prevent the warning message on JVM startup. |
|
Hi, The check for So actually the check you do in this PR breaks native access unless opted in, which is not what we want. |
|
Hi, |
The current implementation of
PosixNativeAccessalways tries to use native access, even if this is disallowed by the JVM. This can lead to warnings on JDK24+ and will eventually be the default setting in future JVM versions. Additionally the current singleton implementation inPosixNativeAccessis problematic because it does the native setup during class initialization (<clinit>). This makes the timing of that setup unpredictable (because the JVM may load classes at any time, not just before first use) and can cause the entire application to fail if an exception is thrown (and not caught) during this setup (even if the application would work fine without native access).This PR:
PosixNativeAccessto use an enum pattern