JDK 22 RDP2 & Deprecate sun.misc.Unsafe Memory-Access Methods…

2024-01-26 Thread David Delabassee
Greetings!

We are starting 2024 with JDK 22 as it has just entered Rampdown Phase 2 [1]. 
And with the initial JDK 22 Release Candidates now less than 2 weeks away (Feb. 
8th) [2], it is time to shift our attention to JDK 23.

After multiple rounds of incubations and preview, the Foreign Function & Memory 
API is becoming standard and permanent in JDK 22. If we put its 'Function' 
angle aside, this API also offers a standard and secure way to access off-heap 
API. And that brings us to the heads-up below 'Deprecate the memory-access 
methods in sun.misc.Unsafe for removal in a future release' as developers still 
using sun.misc.Unsafe for accessing memory are strongly encouraged to start 
preparing their plans to migrate away from those unsafe methods.

[1] https://mail.openjdk.org/pipermail/jdk-dev/2024-January/008675.html
[2] https://openjdk.org/projects/jdk/22/


## Heads-up: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal 
in a Future Release

The effort focused on enforcing the integrity of the Java platform [3] 
continues! The next phase in that long but important initiative will most 
likely target the sun.misc.Unsafe API used for accessing memory. Those methods 
alone represent 79 methods out of the 87 sun.misc.Unsafe methods!

This draft JEP [4] outlines the plan to deprecate for removal the 
sun.misc.Unsafe Memory-Access methods, the reasons, and the standard 
alternatives. As the draft plan suggests, the first step will be to deprecate 
all memory-access methods (on-heap, off-heap, and bimodal) for removal. This 
will cause compile-time deprecation warnings for code that refers to the 
methods, alerting library developers to their forthcoming removal. In addition, 
a new command-line option will allow users to receive runtime warnings when 
those methods are used. This command-line will help users to assess if their 
codebase uses those unsafe API to access memory. It should be mentioned that 
other tools such as JFR and jdeprscan can also be used to detect the use of 
those deprecated APIs.

Library developers are strongly encouraged to migrate from sun.misc.Unsafe to 
the supported replacements, so that applications can migrate smoothly to modern 
JDKs. The initial step will be to conduct investigations to understand if, how, 
and where sun.misc.Unsafe methods are used to access memory.

[3] https://openjdk.org/jeps/8305968
[4] https://openjdk.org/jeps/8323072


## Heads-up: Java Array Element Alignment - Weakening of Some Methods 
Guarantees ?

Some methods make promises about Java array element alignment that are too 
strong. There are some ongoing reflexions to change the implementation (and the 
specification) of `MethodHandles::byteArrayViewVarHandle`, 
`MethodHandles::byteBufferViewVarHandle`, `ByteBuffer::alignedSlice`, and 
`ByteBuffer::alignmentOffset` to weaken the guarantees they make about the 
alignment of Java array elements, in order to bring them in line with the 
guarantees made by an arbitrary JVM implementation.

For more details, make sure to check JDK-8320247 [5] and the related PR [6] but 
in a nutshell, the new behaviour would be :
- The `VarHandle` returned by `MethodHandles::byteArrayViewVarHandle` would 
only support `get` and `set` methods, and all other access methods would throw 
an exception.
- The `VarHandle` returned by `MethodHandles::byteBufferViewHandle` would only 
support the `get` and `set` access methods when a heap buffer is used, and all 
other access methods would throw an exception when used with a heap buffer. 
Direct byte buffers will continue to work the same way.
- The `ByteBuffer::alignmentOffset` and `ByteBuffer::alignedSlice` methods 
would throw an exception if the buffer is a heap buffer, and the given 
`unitSize` is greater than 1.

If you have relevant feedback about this potential change, please make sure to 
bring it to the core-libs-dev mailing list [7], or comment on the PR [6].

[5] https://bugs.openjdk.org/browse/JDK-8320247
[6] https://github.com/openjdk/jdk/pull/16681
[7] https://mail.openjdk.org/pipermail/core-libs-dev/


## JDK 22 Early-Access Builds

JDK 22 Early-Access builds 33 are now available [8], and are provided under the 
GNU General Public License v2, with the Classpath Exception. The Release Notes 
[9] and the javadocs [10] are also available.

### Changes in recent JDK 22 builds that may be of interest:

- JDK-8320597: RSA signature verification fails on signed data that does not 
encode params correctly [Reported by Apache POI]
- JDK-8322214: Return value of XMLInputFactory.getProperty() changed from 
boolean to String in JDK 22 early access builds [Reported by Apache POI]
- JDK-8322725: (tz) Update Timezone Data to 2023d
- JDK-8321480: ISO 4217 Amendment 176 Update
- JDK-8314468: Improve Compiler loops
- JDK-8314295: Enhance verification of verifier
- JDK-8316976: Improve signature handling
- JDK-8317547: Enhance TLS connection support
- JDK-8318971: Better Error Handling for Jar Tool When Process

Re: [Log4j] If and how to document potential OOME

2024-01-26 Thread Apache
That is kind of my point. Anyone who logs an object that behaves this way is 
asking for trouble. It really sounds like an esoteric edge case to me. I don’t 
view this as a Log4J problem as the error wouldn’t even have Log4J in the stack 
trace.

Ralph

> On Jan 25, 2024, at 9:52 PM, Gary Gregory  wrote:
> 
> I have no control over this. I think this is a general problem with third
> party objects and toString(). There is no toString(fromHereToThere) or
> toStringReader() so I can't see a general way to deal with it. Even if I
> created a wrapper for the Object and called toString(), truncated and
> cached the result and have the wrapper return the shorter string in its
> toString(), I still would have toString()'d the original...
> 
> Gary
> 
>> On Thu, Jan 25, 2024, 11:33 PM Ralph Goers 
>> wrote:
>> 
>> OK. The only good way to handle that is to parse the YAML/JSON file while
>> streaming it and extract just the fields you want to include in the logs.
>> 
>> Ralph
>> 
>>> On Jan 25, 2024, at 6:40 PM, Gary Gregory 
>> wrote:
>>> 
>>> Well, it's worse than that because the object is an object created by
>>> parsing a YAML (or JSON) file, then the toString() of that object
>>> renders a String in some other format.
>>> 
>>> Gary
>>> 
>>> On Thu, Jan 25, 2024 at 7:45 PM Ralph Goers 
>> wrote:
 
 Volkan & Matt,
 
 Neither of those is going to help. The issue is that when the toString
>> method is called it reads a whole file in and stores it as a String. This
>> could cause the OOM error. Truncating it in a layout simply limits how much
>> of the String is printed. Even Gary’s proposal of calling substring() is
>> still going to operate on the whole String. He would really need a method
>> that accepts the max number of characters to read from the file.
 
 Ralph
 
> On Jan 25, 2024, at 2:49 PM, Volkan Yazıcı  wrote:
> 
> *[Just responding to Matt. I don't have an answer for Gary.]*
> 
> `JsonTemplateLayout` has `maxStringLength`, and related with it,
> `truncatedStringSuffix`.
> 
> On Thu, Jan 25, 2024 at 9:45 PM Matt Sicker  wrote:
> 
>> You can use the %maxLength{…}{N} pattern converter with PatternLayout
>> at
>> least. Unfortunately, I don’t think any other layouts support a
>> similar
>> option.
>> 
>>> On Jan 25, 2024, at 10:55, Gary D. Gregory 
>> wrote:
>>> 
>>> Hi All,
>>> 
>>> I'd like to ask how to if we can devise advice around an issue I ran
>> into this week.
>>> 
>>> One of our test suites processes about 40K files of test fixtures.
>> These
>> inputs are parsed, processed, and asserted. This randomly fails on a
>> call
>> to Logger#debug(), randomly in that it happens usually once per build,
>> somewhere in a logging call. But it usually fails with a call that
>> looks
>> like this:
>>> 
>>> logger.debug("This is fun" + myFunObject);
>>> 
>>> To simplify things, let's say that it turns out that after an
>> underlying
>> third party jar file version upgrade the call to
>> myFunObject#toString() no
>> longer returns Object#toString() but rather (again to simplify) the
>> contents of the file that was parsed to create myFunObject. This
>> toString()
>> can be megabytes. The solution is obvious:
>>> 
>>> logger.debug("This is fun", myFunObject::toString)
>>> 
>>> And our CI builds no longer randomly fail since our default logging
>> does
>> not log at the debug level.
>>> 
>>> A better solution could be:
>>> 
>>> logger.debug("This is fun", () -> myFunObject.toString().substring(0,
>> 100))
>>> 
>>> where I still want _some_ information better than making my own
>> toString() with System#identityHashCode(Object) or somesuch. Sure,
>> .toString() is still called but it does not make it down into
>> logging. In
>> my case the OOME happened in myFunObject::toString so the substring()
>> example would not have worked.
>>> 
>>> My question is: Should we document some general advice on this
>> pattern
>> and what should the advice be? Would it make sense to have some
>> features
>> where we truncate/reject Strings above a threshold. And yes, calling
>> myFunObject.toString() can still still get me in trouble.
>>> 
>>> Gary
>>> 
>> 
>> 
 
>> 
>> 



Re: [Log4j] If and how to document potential OOME

2024-01-26 Thread Gary Gregory
Oh, I don't want to suggest this is a Lo4j issue at all. I am wondering if
there is a pattern we should document aside from "know your third party
objects" which is not helpful for us to say. It sounds like there is
nothing for us to do.

Gary

On Fri, Jan 26, 2024, 7:16 AM Apache  wrote:

> That is kind of my point. Anyone who logs an object that behaves this way
> is asking for trouble. It really sounds like an esoteric edge case to me. I
> don’t view this as a Log4J problem as the error wouldn’t even have Log4J in
> the stack trace.
>
> Ralph
>
> > On Jan 25, 2024, at 9:52 PM, Gary Gregory 
> wrote:
> >
> > I have no control over this. I think this is a general problem with
> third
> > party objects and toString(). There is no toString(fromHereToThere) or
> > toStringReader() so I can't see a general way to deal with it. Even if I
> > created a wrapper for the Object and called toString(), truncated and
> > cached the result and have the wrapper return the shorter string in its
> > toString(), I still would have toString()'d the original...
> >
> > Gary
> >
> >> On Thu, Jan 25, 2024, 11:33 PM Ralph Goers 
> >> wrote:
> >>
> >> OK. The only good way to handle that is to parse the YAML/JSON file
> while
> >> streaming it and extract just the fields you want to include in the
> logs.
> >>
> >> Ralph
> >>
> >>> On Jan 25, 2024, at 6:40 PM, Gary Gregory 
> >> wrote:
> >>>
> >>> Well, it's worse than that because the object is an object created by
> >>> parsing a YAML (or JSON) file, then the toString() of that object
> >>> renders a String in some other format.
> >>>
> >>> Gary
> >>>
> >>> On Thu, Jan 25, 2024 at 7:45 PM Ralph Goers <
> ralph.go...@dslextreme.com>
> >> wrote:
> 
>  Volkan & Matt,
> 
>  Neither of those is going to help. The issue is that when the toString
> >> method is called it reads a whole file in and stores it as a String.
> This
> >> could cause the OOM error. Truncating it in a layout simply limits how
> much
> >> of the String is printed. Even Gary’s proposal of calling substring() is
> >> still going to operate on the whole String. He would really need a
> method
> >> that accepts the max number of characters to read from the file.
> 
>  Ralph
> 
> > On Jan 25, 2024, at 2:49 PM, Volkan Yazıcı  wrote:
> >
> > *[Just responding to Matt. I don't have an answer for Gary.]*
> >
> > `JsonTemplateLayout` has `maxStringLength`, and related with it,
> > `truncatedStringSuffix`.
> >
> > On Thu, Jan 25, 2024 at 9:45 PM Matt Sicker 
> wrote:
> >
> >> You can use the %maxLength{…}{N} pattern converter with
> PatternLayout
> >> at
> >> least. Unfortunately, I don’t think any other layouts support a
> >> similar
> >> option.
> >>
> >>> On Jan 25, 2024, at 10:55, Gary D. Gregory 
> >> wrote:
> >>>
> >>> Hi All,
> >>>
> >>> I'd like to ask how to if we can devise advice around an issue I
> ran
> >> into this week.
> >>>
> >>> One of our test suites processes about 40K files of test fixtures.
> >> These
> >> inputs are parsed, processed, and asserted. This randomly fails on a
> >> call
> >> to Logger#debug(), randomly in that it happens usually once per
> build,
> >> somewhere in a logging call. But it usually fails with a call that
> >> looks
> >> like this:
> >>>
> >>> logger.debug("This is fun" + myFunObject);
> >>>
> >>> To simplify things, let's say that it turns out that after an
> >> underlying
> >> third party jar file version upgrade the call to
> >> myFunObject#toString() no
> >> longer returns Object#toString() but rather (again to simplify) the
> >> contents of the file that was parsed to create myFunObject. This
> >> toString()
> >> can be megabytes. The solution is obvious:
> >>>
> >>> logger.debug("This is fun", myFunObject::toString)
> >>>
> >>> And our CI builds no longer randomly fail since our default logging
> >> does
> >> not log at the debug level.
> >>>
> >>> A better solution could be:
> >>>
> >>> logger.debug("This is fun", () ->
> myFunObject.toString().substring(0,
> >> 100))
> >>>
> >>> where I still want _some_ information better than making my own
> >> toString() with System#identityHashCode(Object) or somesuch. Sure,
> >> .toString() is still called but it does not make it down into
> >> logging. In
> >> my case the OOME happened in myFunObject::toString so the
> substring()
> >> example would not have worked.
> >>>
> >>> My question is: Should we document some general advice on this
> >> pattern
> >> and what should the advice be? Would it make sense to have some
> >> features
> >> where we truncate/reject Strings above a threshold. And yes, calling
> >> myFunObject.toString() can still still get me in trouble.
> >>>
> >>> Gary
> >>>
> >>
> >>
> 
> >>
> >>
>
>


Re: [Log4j] If and how to document potential OOME

2024-01-26 Thread Matt Sicker
Perhaps mention of StringBuilderFormattable? It helps work around the “load the 
string all at once” problem.

> On Jan 26, 2024, at 06:36, Gary Gregory  wrote:
> 
> Oh, I don't want to suggest this is a Lo4j issue at all. I am wondering if
> there is a pattern we should document aside from "know your third party
> objects" which is not helpful for us to say. It sounds like there is
> nothing for us to do.
> 
> Gary
> 
> On Fri, Jan 26, 2024, 7:16 AM Apache  wrote:
> 
>> That is kind of my point. Anyone who logs an object that behaves this way
>> is asking for trouble. It really sounds like an esoteric edge case to me. I
>> don’t view this as a Log4J problem as the error wouldn’t even have Log4J in
>> the stack trace.
>> 
>> Ralph
>> 
>>> On Jan 25, 2024, at 9:52 PM, Gary Gregory 
>> wrote:
>>> 
>>> I have no control over this. I think this is a general problem with
>> third
>>> party objects and toString(). There is no toString(fromHereToThere) or
>>> toStringReader() so I can't see a general way to deal with it. Even if I
>>> created a wrapper for the Object and called toString(), truncated and
>>> cached the result and have the wrapper return the shorter string in its
>>> toString(), I still would have toString()'d the original...
>>> 
>>> Gary
>>> 
 On Thu, Jan 25, 2024, 11:33 PM Ralph Goers 
 wrote:
 
 OK. The only good way to handle that is to parse the YAML/JSON file
>> while
 streaming it and extract just the fields you want to include in the
>> logs.
 
 Ralph
 
> On Jan 25, 2024, at 6:40 PM, Gary Gregory 
 wrote:
> 
> Well, it's worse than that because the object is an object created by
> parsing a YAML (or JSON) file, then the toString() of that object
> renders a String in some other format.
> 
> Gary
> 
> On Thu, Jan 25, 2024 at 7:45 PM Ralph Goers <
>> ralph.go...@dslextreme.com>
 wrote:
>> 
>> Volkan & Matt,
>> 
>> Neither of those is going to help. The issue is that when the toString
 method is called it reads a whole file in and stores it as a String.
>> This
 could cause the OOM error. Truncating it in a layout simply limits how
>> much
 of the String is printed. Even Gary’s proposal of calling substring() is
 still going to operate on the whole String. He would really need a
>> method
 that accepts the max number of characters to read from the file.
>> 
>> Ralph
>> 
>>> On Jan 25, 2024, at 2:49 PM, Volkan Yazıcı  wrote:
>>> 
>>> *[Just responding to Matt. I don't have an answer for Gary.]*
>>> 
>>> `JsonTemplateLayout` has `maxStringLength`, and related with it,
>>> `truncatedStringSuffix`.
>>> 
>>> On Thu, Jan 25, 2024 at 9:45 PM Matt Sicker 
>> wrote:
>>> 
 You can use the %maxLength{…}{N} pattern converter with
>> PatternLayout
 at
 least. Unfortunately, I don’t think any other layouts support a
 similar
 option.
 
> On Jan 25, 2024, at 10:55, Gary D. Gregory 
 wrote:
> 
> Hi All,
> 
> I'd like to ask how to if we can devise advice around an issue I
>> ran
 into this week.
> 
> One of our test suites processes about 40K files of test fixtures.
 These
 inputs are parsed, processed, and asserted. This randomly fails on a
 call
 to Logger#debug(), randomly in that it happens usually once per
>> build,
 somewhere in a logging call. But it usually fails with a call that
 looks
 like this:
> 
> logger.debug("This is fun" + myFunObject);
> 
> To simplify things, let's say that it turns out that after an
 underlying
 third party jar file version upgrade the call to
 myFunObject#toString() no
 longer returns Object#toString() but rather (again to simplify) the
 contents of the file that was parsed to create myFunObject. This
 toString()
 can be megabytes. The solution is obvious:
> 
> logger.debug("This is fun", myFunObject::toString)
> 
> And our CI builds no longer randomly fail since our default logging
 does
 not log at the debug level.
> 
> A better solution could be:
> 
> logger.debug("This is fun", () ->
>> myFunObject.toString().substring(0,
 100))
> 
> where I still want _some_ information better than making my own
 toString() with System#identityHashCode(Object) or somesuch. Sure,
 .toString() is still called but it does not make it down into
 logging. In
 my case the OOME happened in myFunObject::toString so the
>> substring()
 example would not have worked.
> 
> My question is: Should we document some general advice on this
 pattern
 and what should the advice be? Would it make sense to have some
 features
 where we truncate/rej