Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2024-01-10 Thread Roger Riggs
On Wed, 10 Jan 2024 17:41:41 GMT, Raffaello Giulietti  
wrote:

>> The spec is silent about methods being 'native'; it would generally be 
>> impractical to implement native methods for these purposes, but a native 
>> method can implement the behavior.
>
> @RogerRiggs The checks are agnostic about a method being `native` or not, so 
> I'm not sure I get your point about `native` methods.

Right, there's nothing to change; a method declared as native is not 
mis-declared.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1447785756


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2024-01-10 Thread Raffaello Giulietti
On Wed, 10 Jan 2024 16:58:43 GMT, Roger Riggs  wrote:

>> I'm not sure that a `native` method is not considered effective by 
>> serialization. I have to check.
>
> The spec is silent about methods being 'native'; it would generally be 
> impractical to implement native methods for these purposes, but a native 
> method can implement the behavior.

@RogerRiggs The checks are agnostic about a method being `native` or not, so 
I'm not sure I get your point about `native` methods.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1447721944


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2024-01-10 Thread Roger Riggs
On Tue, 19 Dec 2023 15:58:10 GMT, Raffaello Giulietti  
wrote:

>> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
>> line 185:
>> 
>>> 183: commitEvent(PRIV_METH_NON_STATIC,
>>> 184: m + " must be non-static to be effective");
>>> 185: }
>> 
>> Should there also be a check to see if this `private` method is 
>> (misdeclared) as a `native` method?
>
> I'm not sure that a `native` method is not considered effective by 
> serialization. I have to check.

The spec is silent about methods being 'native'; it would generally be 
impractical to implement native methods for these purposes, but a native method 
can implement the behavior.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1447665831


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-20 Thread Raffaello Giulietti
On Tue, 19 Dec 2023 19:19:35 GMT, Roger Riggs  wrote:

>> Raffaello Giulietti has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Better name for a label, corrected name of removed field.
>
> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 108:
> 
>> 106: SUID_NAME + " should be declared of type long");
>> 107: }
>> 108: if (!isStatic(f)) {
> 
> The two calls to isStatic could be reordered closer together to be a single 
> if (isstatic()) { ... } else {... }.

I guess you are looking to an older commit?

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1432581987


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-20 Thread Daniel Fuchs
On Tue, 19 Dec 2023 16:00:09 GMT, Raffaello Giulietti  
wrote:

>> src/java.base/share/classes/jdk/internal/event/SerializationMisdeclarationEvent.java
>>  line 94:
>> 
>>> 92: 
>>> 93: /*
>>> 94:  * These constants are not final on purpose.
>> 
>> Just curious - what's the purpose? I don't see them being changed/updated 
>> anywhere (not even in tests).
>
> Declaring a `public static int` field `final` means that the value is then 
> stored in the client class. If a value is changed, then the client needs to 
> be recompiled as well, but this is not enforced by the language, so it might 
> lead to inconsistencies.
> 
> The clean solution would be to use an enum class, but that's not supported by 
> JFR.

Not having them final is a quite smelly. I would suggest to make them final 
with a comment that new values can be added but that existing values must not 
be changed.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1432400888


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Roger Riggs
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 108:

> 106: SUID_NAME + " should be declared of type long");
> 107: }
> 108: if (!isStatic(f)) {

The two calls to isStatic could be reordered closer together to be a single if 
(isstatic()) { ... } else {... }.

src/java.base/share/classes/jdk/internal/event/SerializationMisdeclarationEvent.java
 line 126:

> 124: public static int ACC_METH_PARAM_TYPES= 404;
> 125: public static int ACC_METH_NON_ACCESSIBLE = 405;
> 126: 

I'd rather see few (fewer, just one) kinds of events, with so many different 
kinds of events there needs to be a convenient method to look for any kind of 
serialization mis-declaration.
Perhaps a single event with flags for the different kinds of errors.
The event classes could be responsible for turning the flags back into useful 
messages on display.

test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 157:

> 155: }
> 156: 
> 157: private static class A implements Serializable {

The test classes should document the good or badness of the class either in the 
class/field/method names or in comments.  What's wrong with this XXX.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431846034
PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431850091
PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431856800


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Erik Gahlin
On Tue, 19 Dec 2023 16:28:03 GMT, Raffaello Giulietti  
wrote:

> However, the cache can be emptied under high memory pressure, so the 
> `ObjectStreamClass` instance might be recreated later, thus re-invoking the 
> serialization checker once again.

I think it would be good to state in the description when checks occur, 
something like: Only the first time a class is serialized are the 
misdeclaration checks carried out, but may happen happen more frequently under 
high memory pressure. (Try to avoid using the word "event")

-

PR Comment: https://git.openjdk.org/jdk/pull/17129#issuecomment-1863216232


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Erik Gahlin
On Tue, 19 Dec 2023 16:00:59 GMT, Raffaello Giulietti  
wrote:

>> test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 50:
>> 
>>> 48:  * @requires vm.hasJFR
>>> 49:  * @library /test/lib
>>> 50:  * @run junit/othervm 
>>> jdk.jfr.event.io.TestSerializationMisdeclarationEvent
>> 
>> Is the use of "othervm" needed here because of the use of 
>> `jdk.jfr.consumer.RecordingStream`? Does `RecordingStream` do JVM wide state 
>> changes? I did a quick look at that class but couldn't come to a conclusion.
>
> Not sure, I have to check.

All the other events run in othervm. While it may be possible in some case to 
not do that, it's much easier to analyse issues, if we are sure the JVM is 
fresh. For example, JFR may not generate bytecode if an event is disabled. The 
JFR tests have been hardened to be able to run in parallel, so they run pretty 
fast.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431727571


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Raffaello Giulietti
On Tue, 19 Dec 2023 15:56:39 GMT, Raffaello Giulietti  
wrote:

> > Is it per class for each classloader that loads it? Or is it per class per 
> > JVM? It's more out of curiosity than anything else because I don't think it 
> > makes a big difference (I don't expect too many classloaders that would 
> > lead to the case of extremely large streams of events).
> 
> The checks are done on the `Class` instance, that is, per each defined (as 
> per JVMS) and _used_ serializable class, on first usage in serialization. If 
> enabled at all, they are invoked by the private `ObjectStreamClass` 
> constructor.

Well, in fact `ObjectStreamClass` maintains a cache of `Class` -> 
`ObjectStreamClass` to avoid creating a new instance of `ObjectStreamClass` 
each time a `Class` is looked up. It memoizes the association the first time.

However, the cache can be emptied under high memory pressure, so the 
`ObjectStreamClass` instance might be recreated later, thus re-invoking the 
serialization checker once again.

-

PR Comment: https://git.openjdk.org/jdk/pull/17129#issuecomment-1863090984


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Raffaello Giulietti
On Tue, 19 Dec 2023 14:39:47 GMT, Jaikiran Pai  wrote:

> Is it per class for each classloader that loads it? Or is it per class per 
> JVM? It's more out of curiosity than anything else because I don't think it 
> makes a big difference (I don't expect too many classloaders that would lead 
> to the case of extremely large streams of events).

The checks are done on the `Class` instance, that is, per each defined (as 
per JVMS) and _used_ serializable class, on first usage in serialization. If 
enabled at all, they are invoked by the private `ObjectStreamClass` constructor.

> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 94:
> 
>> 92: if (!isPrivate(f)) {
>> 93: commitEvent(SUID_PRIVATE,
>> 94: SUID_NAME + " should be declared private");
> 
> Rest of the event messages use "... to be effective", should this one too use 
> a similar text?

The field needs not be declared `private` to be effective, although it is 
recommended to do so. In this sense, "should" is just a recommendation, while 
"must" is really needed to make something effective.

> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 108:
> 
>> 106: SUID_NAME + " should be declared of type long");
>> 107: }
>> 108: if (!isStatic(f)) {
> 
> Nit - perhaps save the return value from the previous call to `isStatic(f)` a 
> few lines above and reuse it here?

Assuming that most serializable classes are declared correctly, I don't think 
that caching the value of `isStatic()` makes a measurable difference.
If at all, then I'd prefer to cache the modifiers and "inline" the masking 
logic of the individual is*() methods.

> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 112:
> 
>> 110: }
>> 111: f.setAccessible(true);
>> 112: if (getLong(f) == null) {
> 
> Is this check and the `setAccessible()` needed if a few lines above, the call 
> to `f.getType()` returns `Long.TYPE` (i.e. primitive type)? Perhaps we can 
> conditionally do these additional checks and calls, only if `f.getType()` 
> isn't a primitive?

Right, will be addressed in the next commit.

> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 185:
> 
>> 183: commitEvent(PRIV_METH_NON_STATIC,
>> 184: m + " must be non-static to be effective");
>> 185: }
> 
> Should there also be a check to see if this `private` method is (misdeclared) 
> as a `native` method?

I'm not sure that a `native` method is not considered effective by 
serialization. I have to check.

> src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
> line 276:
> 
>> 274: }
>> 275: 
>> 276: private static Object getObject(Field f) {
> 
> Should we call this method `getStaticFieldValue(...)`, because that's what 
> the implementation is.

Since the only parameter is `Field`, it has to be a static field almost for 
sure.
Further, there's a `getLong()` method down below that operates on a static 
field as well and that one would also need a renaming.
If I can come up with better names they will be in the next commit.

> src/java.base/share/classes/jdk/internal/event/SerializationMisdeclarationEvent.java
>  line 94:
> 
>> 92: 
>> 93: /*
>> 94:  * These constants are not final on purpose.
> 
> Just curious - what's the purpose? I don't see them being changed/updated 
> anywhere (not even in tests).

Declaring a `public static int` field `final` means that the value is then 
stored in the client class. If a value is changed, then the client needs to be 
recompiled as well, but this is not enforced by the language, so it might lead 
to inconsistencies.

The clean solution would be to use an enum class, but that's not supported by 
JFR.

> test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 50:
> 
>> 48:  * @requires vm.hasJFR
>> 49:  * @library /test/lib
>> 50:  * @run junit/othervm 
>> jdk.jfr.event.io.TestSerializationMisdeclarationEvent
> 
> Is the use of "othervm" needed here because of the use of 
> `jdk.jfr.consumer.RecordingStream`? Does `RecordingStream` do JVM wide state 
> changes? I did a quick look at that class but couldn't come to a conclusion.

Not sure, I have to check.

> test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 112:
> 
>> 110: @MethodSource
>> 111: public void testGoodClass(Class cls) {
>> 112: assertEquals(0, getEventsFor(cls).size());
> 
> Can this and other assertions in this test be updated to include the class 
> name which failed? You can still use `assertEquals(...)`, it takes an 
> optional message as a third parameter which you could use to include the 
> failing class name. It becomes a bit more easier to debug (unexpected) 
> failures when the assertion includes these additional details.

Thanks for the suggestion, will ta

Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 50:

> 48:  * @requires vm.hasJFR
> 49:  * @library /test/lib
> 50:  * @run junit/othervm 
> jdk.jfr.event.io.TestSerializationMisdeclarationEvent

Is the use of "othervm" needed here because of the use of 
`jdk.jfr.consumer.RecordingStream`? Does `RecordingStream` do JVM wide state 
changes? I did a quick look at that class but couldn't come to a conclusion.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431578942


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 144:

> 142: }
> 143: 
> 144: static {

It's a bit odd for a test case to be doing this in a static block. Could this 
instead be done in a `org.junit.jupiter.api.BeforeAll` method:


import org.junit.jupiter.api.BeforeAll;
...
@BeforeAll
static void recordEvents() {
   // that static block's code here
}

Any (unexpected) failures in that method will then be reported in a better way 
by the testing framework instead of an `ExceptionInInitializer` that would be 
reported from a failure in static block and the test class itself failing to 
load.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431571145


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java line 112:

> 110: @MethodSource
> 111: public void testGoodClass(Class cls) {
> 112: assertEquals(0, getEventsFor(cls).size());

Can this and other assertions in this test be updated to include the class name 
which failed? You can still use `assertEquals(...)`, it takes an optional 
message as a third parameter which you could use to include the failing class 
name. It becomes a bit more easier to debug (unexpected) failures when the 
assertion includes these additional details.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431563775


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

src/java.base/share/classes/jdk/internal/event/SerializationMisdeclarationEvent.java
 line 94:

> 92: 
> 93: /*
> 94:  * These constants are not final on purpose.

Just curious - what's the purpose? I don't see them being changed/updated 
anywhere (not even in tests).

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431551183


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 276:

> 274: }
> 275: 
> 276: private static Object getObject(Field f) {

Should we call this method `getStaticFieldValue(...)`, because that's what the 
implementation is.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431535049


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 185:

> 183: commitEvent(PRIV_METH_NON_STATIC,
> 184: m + " must be non-static to be effective");
> 185: }

Should there also be a check to see if this `private` method is (misdeclared) 
as a `native` method?

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431524703


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 94:

> 92: if (!isPrivate(f)) {
> 93: commitEvent(SUID_PRIVATE,
> 94: SUID_NAME + " should be declared private");

Rest of the event messages use "... to be effective", should this one too use a 
similar text?

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 108:

> 106: SUID_NAME + " should be declared of type long");
> 107: }
> 108: if (!isStatic(f)) {

Nit - perhaps save the return value from the previous call to `isStatic(f)` a 
few lines above and reuse it here?

src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java 
line 112:

> 110: }
> 111: f.setAccessible(true);
> 112: if (getLong(f) == null) {

Is this check and the `setAccessible()` needed if a few lines above, the call 
to `f.getType()` returns `Long.TYPE` (i.e. primitive type)? Perhaps we can 
conditionally do these additional checks and calls, only if `f.getType()` isn't 
a primitive?

-

PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431512491
PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431506705
PR Review Comment: https://git.openjdk.org/jdk/pull/17129#discussion_r1431511005


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Jaikiran Pai
On Tue, 19 Dec 2023 12:21:05 GMT, Raffaello Giulietti  
wrote:

>> Adds serialization misdeclaration events to JFR.
>
> Raffaello Giulietti has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Better name for a label, corrected name of removed field.

Hello Raffaello, 

> On the other hand, the checks and the events generation are done for 
> serializable classes that actually actively participate in serialization, 
> lazily, and just once per class

Is it per class for each classloader that loads it? Or is it per class per JVM? 
It's more out of curiosity than anything else because I don't think it makes a 
big difference (I don't expect too many classloaders that would lead to the 
case of extremely large streams of events).

-

PR Comment: https://git.openjdk.org/jdk/pull/17129#issuecomment-1862882260


Re: RFR: 8275338: Add JFR events for notable serialization situations [v4]

2023-12-19 Thread Raffaello Giulietti
> Adds serialization misdeclaration events to JFR.

Raffaello Giulietti has updated the pull request incrementally with one 
additional commit since the last revision:

  Better name for a label, corrected name of removed field.

-

Changes:
  - all: https://git.openjdk.org/jdk/pull/17129/files
  - new: https://git.openjdk.org/jdk/pull/17129/files/8534d7af..51507e4e

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=17129&range=03
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=17129&range=02-03

  Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod
  Patch: https://git.openjdk.org/jdk/pull/17129.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/17129/head:pull/17129

PR: https://git.openjdk.org/jdk/pull/17129