Re: Session serialization uses wrapper objects instead of primitives

2020-05-15 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Konstantin,

On 5/15/20 07:36, Konstantin Kolinko wrote:
> чт, 14 мая 2020 г. в 18:48, Christopher Schultz
> :
>>
>> All,
>>
>> I'm interested in the history of the
>> StandardSession.writeObjectData method. I've been looking at it
>> lately because I'm interested in possibly (optionally) encrypting
>> the sessions in the backend session store. But this isn't about
>> encryption at all.
>>
>> The code for StandardSession.doWriteObject(ObjectOutputStream
>> stream) looks like this:
>>
>>
>> // Write the scalar instance variables (except Manager)
>> stream.writeObject(Long.valueOf(creationTime));
>> stream.writeObject(Long.valueOf(lastAccessedTime));
>> stream.writeObject(Integer.valueOf(maxInactiveInterval));
>> stream.writeObject(Boolean.valueOf(isNew));
>> stream.writeObject(Boolean.valueOf(isValid));
>> stream.writeObject(Long.valueOf(thisAccessedTime));
>
> If I understand correctly, with objects you can read them with the
> same 'readObject()' object method and decide what to do with the
> received value.  With primitives you have to decide upfront what
> reading method you are going to call, and calling a wrong one will
> result in a fatal failure where the rest of the data cannot be read
> at all.
>
> For example, StandardSession.doReadObject has the following code:
>
> // The next object read could either be the number of attributes
> (Integer) or the session's // authType followed by a Principal
> object (not an Integer) Object nextObject = stream.readObject(); if
> (!(nextObject instanceof Integer)) {

This is true: changing from objects to primitives means that no
changes can be made in the future such as re-ordering, changing the
data type, etc. without breaking backward-compatibility.

The metadata at the "beginning" of the stream is fairly stable, so I
think it's safe to make this change.

We could always write a version-number to the storage if we wanted. If
we want to get really crazy, we can go full protobuf[1].

- -chris

[1] https://developers.google.com/protocol-buffers/
-BEGIN PGP SIGNATURE-
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl6+pIYACgkQHPApP6U8
pFiRhRAAyCgUGymuV5dlYqVEYPkHtiOUHlmbxrcoeTGU9KfEDnKPZ0frOtdit1X8
POiBEelQooQYwC2AuYxQy0IbdZhCjtZwTX/voi1ieTTH0SQXADVVkD94jkbd2qVQ
Izzn5aWc2KN0/+tDA0iPQtzntP7NhBJ3eCziz7cPxXbPcJCTSLAJr2OZJC7qPvGv
Tit35FLpVyoMD0XE83tnZmEtczTSgKXC2qTHVtOP4/yObl/+JkAG7cUroKINv510
0bAvkqZ1BQnM6ocrKjUcA3GHOw8wPlnwu4B5g2sVXlfbm/Yg0VK9J8r5nUb/KOeZ
iHwPop/FUammNIFJUHGwoVps8pvYHRn4GC2dFotIodrmi62P8B/7NiDW6fXfK/0E
DCJoPdK29Kwy6r9CvMBRy9lbYx/0FcYv3Gb1m9nknAdJgaql55RCVSEUPSZ7J5on
6cnmIFNxKZw0evpBbTMzfuSu+3uGwSnp1VzRN4wCM8d8Ram8pt/3GmK0tt41ADDw
VS8nbzeEmG1G/6MwCj5W1u11I1KLQl6bVcoLHLrREQQyS0X5+1Spg4v1av+kU7N9
uccb2sv6480LiaZvr+oWv5V1QlWKdSZgfekAsv5zWtaBIdw7MLwuY+0vvOYB682u
xpUs2PBLWQHHHrHQRqLtYLBsa3l5imP4w2h1z3F5pwZTQfoJXwk=
=UE1r
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-15 Thread Konstantin Kolinko
чт, 14 мая 2020 г. в 18:48, Christopher Schultz :
>
> All,
>
> I'm interested in the history of the StandardSession.writeObjectData
> method. I've been looking at it lately because I'm interested in
> possibly (optionally) encrypting the sessions in the backend session
> store. But this isn't about encryption at all.
>
> The code for StandardSession.doWriteObject(ObjectOutputStream stream)
> looks like this:
>
>
> // Write the scalar instance variables (except Manager)
> stream.writeObject(Long.valueOf(creationTime));
> stream.writeObject(Long.valueOf(lastAccessedTime));
> stream.writeObject(Integer.valueOf(maxInactiveInterval));
> stream.writeObject(Boolean.valueOf(isNew));
> stream.writeObject(Boolean.valueOf(isValid));
> stream.writeObject(Long.valueOf(thisAccessedTime));

If I understand correctly, with objects you can read them with the
same 'readObject()' object method and decide what to do with the
received value.  With primitives you have to decide upfront what
reading method you are going to call, and calling a wrong one will
result in a fatal failure where the rest of the data cannot be read at
all.

For example, StandardSession.doReadObject has the following code:

// The next object read could either be the number of
attributes (Integer) or the session's
// authType followed by a Principal object (not an Integer)
Object nextObject = stream.readObject();
if (!(nextObject instanceof Integer)) {


Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-15 Thread Martin Grigorov
On Fri, May 15, 2020 at 1:00 AM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA256
>
> Mark,
>
> On 5/14/20 14:21, Mark Thomas wrote:
> > On 14/05/2020 18:41, Christopher Schultz wrote:
> >> Mark,
> >>
> >> On 5/14/20 12:53, Mark Thomas wrote:
> >>> On 14/05/2020 17:46, Mark Thomas wrote:
>  On 14/05/2020 16:48, Christopher Schultz wrote:
> > All,
> >
> > I'm interested in the history of the
> > StandardSession.writeObjectData method. I've been looking
> > at it lately because I'm interested in possibly
> > (optionally) encrypting the sessions in the backend session
> > store. But this isn't about encryption at all.
> >
> > The code for
> > StandardSession.doWriteObject(ObjectOutputStream stream)
> > looks like this:
> >
> >
> > // Write the scalar instance variables (except Manager)
> > stream.writeObject(Long.valueOf(creationTime));
> > stream.writeObject(Long.valueOf(lastAccessedTime));
> > stream.writeObject(Integer.valueOf(maxInactiveInterval));
> > stream.writeObject(Boolean.valueOf(isNew));
> > stream.writeObject(Boolean.valueOf(isValid));
> > stream.writeObject(Long.valueOf(thisAccessedTime));
> >
> >
> > Is there any reason we are writing object wrappers for
> > these primitive members instead of just writing the
> > primitives directly?
> 
>  That code goes all the way back to at least Tomcat 3.1.x
>  (20+ years ago).
> 
> > It turns out that the byte stream is identical whether one
> > uses objects or primitives,
> 
>  That surprises me. Looking at the JRE source code it really
>  surprises me. So much that I am going to go and try it for
>  myself.
> >>
> >>> My testing shows the opposite. There is a significant
> >>> difference between writing primitives and writing objects.
> >>
> >> Hmm. I did a micro-test with just writing a single
> >> Long.valueOf() value and a (primitive) long alone to an
> >> ObjectOutputStream. I didn't test the StandardSession itself.
> >
> > I performed the same micro-test.
> >
> >>> Given backwards compatibility requirements we can't change this
> >>> in 9.0.x and earlier.
> >>
> >> Agreed.
> >>
>  One reason we might want to stick with writing objects is to
>  support sessionAttributeValueClassNameFilter. I'm only going
>  from reading the source so I could easily have missed
>  something but it looks like that will only work if we
>  write/read objects.
> >>
> >>> We only care about this for session attributes. We know our
> >>> internal attributes are safe so we could switch to primitives
> >>> in 10.0.x.
> >>
> >> I'll have to play-around a bit to see what was wrong with my
> >> initial tes t.
>
> So my test was bunk, the data on-the-wire (so to speak) is very
> different, and there is no way at all to make them compatible. :/
>
> Perhaps a rewindable input stream would work, but it's just not really
> that important.
>
> I think it's okay to make a breaking change at 10.0, but only if
> anyone really cares. It saves a couple of bytes which can add up.
>
> In my microtest, I wrote a java.lang.Long value and a (primitive) long
> to two separate files. The object-file was 82 bytes and the
> primitive-file was 14 bytes. It looks like after the 2-byte header and
> 2-byte version identifier, the primitive long is written as "block
> data" with a 1-byte length (8) and then the 8 bytes of the long. The
> object flavor is ... more verbose.
>
> So we get almost 90% savings for a single long value. On the other
> hand, the primitive only values going into sessions are the metadata
> and not the attributes, which will dominate the bulk of the data (or
> should, anyway).
>
> I still think this is worth doing.
>
> Any objections?
>

No objections!


>
> - -chris
> -BEGIN PGP SIGNATURE-
> Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69sXYACgkQHPApP6U8
> pFi6pg/9ExBQhRRlUv4QPUVDJEhJ8pN6KfBIoHgd/UWw2zYxjeifhDrN+biK2lLG
> GHWmJuF+wEAFz9xtYqN46q1QqSKIQcWTAqI05NchNlqFd29JHwj+9QZV00VTd0eK
> My4MTCVY4dSObJrePyw14tEHyRVcFl539bDhtez7fnjOGkq4EGNXvr7ep9L3w5GB
> ckwKAp1OuFYz5/0ZCCDEVdRiSpoXAac06B5v0FUQb3TBn06gdavUJb9q0HM57RjI
> 0FkQHPyZ1ibfWOOLldBrCgA+7SygGiD6LO2nMo5Fgy1A4l5W/uekkhW96FXBKHng
> /ocXJRQSkeDoanpQmu5pC/Ru1S0bNjZCIo9OMS0de6iEMEO3wPtvuLYhINYydk6E
> 3ZNx+EPZEFPoZuB1K0peWNDgFsE3ar5gL+y6cvztNoZtT1WymoDS6uQ4OvGXcXNL
> 61SOSe3CmqHF0dQTlD/Xikakumz4Kefny5QGw/XlchPVNCqUmvgxUwYPb965kwz3
> Vt/3nib0QgKxbR0j54InFIRkG7gPuGyUaL0kwtMbFEdOTw+PqAEyIPSqIRtmkhVG
> Mzf6ikh+TOToYi+OIJXUMloaVL8xafAo6hKTc7lbu2hAUv9bE47X6uVyQmD7Yxqu
> R3LQGo3OYX9+GBdKBhgvbZB9bEkUImMbsgIXKIUScGaMH4RdtBE=
> =AZle
> -END PGP SIGNATURE-
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: 

Re: Session serialization uses wrapper objects instead of primitives

2020-05-15 Thread Rémy Maucherat
On Fri, May 15, 2020 at 12:00 AM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA256
>
> Mark,
>
> On 5/14/20 14:21, Mark Thomas wrote:
> > On 14/05/2020 18:41, Christopher Schultz wrote:
> >> Mark,
> >>
> >> On 5/14/20 12:53, Mark Thomas wrote:
> >>> On 14/05/2020 17:46, Mark Thomas wrote:
>  On 14/05/2020 16:48, Christopher Schultz wrote:
> > All,
> >
> > I'm interested in the history of the
> > StandardSession.writeObjectData method. I've been looking
> > at it lately because I'm interested in possibly
> > (optionally) encrypting the sessions in the backend session
> > store. But this isn't about encryption at all.
> >
> > The code for
> > StandardSession.doWriteObject(ObjectOutputStream stream)
> > looks like this:
> >
> >
> > // Write the scalar instance variables (except Manager)
> > stream.writeObject(Long.valueOf(creationTime));
> > stream.writeObject(Long.valueOf(lastAccessedTime));
> > stream.writeObject(Integer.valueOf(maxInactiveInterval));
> > stream.writeObject(Boolean.valueOf(isNew));
> > stream.writeObject(Boolean.valueOf(isValid));
> > stream.writeObject(Long.valueOf(thisAccessedTime));
> >
> >
> > Is there any reason we are writing object wrappers for
> > these primitive members instead of just writing the
> > primitives directly?
> 
>  That code goes all the way back to at least Tomcat 3.1.x
>  (20+ years ago).
> 
> > It turns out that the byte stream is identical whether one
> > uses objects or primitives,
> 
>  That surprises me. Looking at the JRE source code it really
>  surprises me. So much that I am going to go and try it for
>  myself.
> >>
> >>> My testing shows the opposite. There is a significant
> >>> difference between writing primitives and writing objects.
> >>
> >> Hmm. I did a micro-test with just writing a single
> >> Long.valueOf() value and a (primitive) long alone to an
> >> ObjectOutputStream. I didn't test the StandardSession itself.
> >
> > I performed the same micro-test.
> >
> >>> Given backwards compatibility requirements we can't change this
> >>> in 9.0.x and earlier.
> >>
> >> Agreed.
> >>
>  One reason we might want to stick with writing objects is to
>  support sessionAttributeValueClassNameFilter. I'm only going
>  from reading the source so I could easily have missed
>  something but it looks like that will only work if we
>  write/read objects.
> >>
> >>> We only care about this for session attributes. We know our
> >>> internal attributes are safe so we could switch to primitives
> >>> in 10.0.x.
> >>
> >> I'll have to play-around a bit to see what was wrong with my
> >> initial tes t.
>
> So my test was bunk, the data on-the-wire (so to speak) is very
> different, and there is no way at all to make them compatible. :/
>
> Perhaps a rewindable input stream would work, but it's just not really
> that important.
>
> I think it's okay to make a breaking change at 10.0, but only if
> anyone really cares. It saves a couple of bytes which can add up.
>
> In my microtest, I wrote a java.lang.Long value and a (primitive) long
> to two separate files. The object-file was 82 bytes and the
> primitive-file was 14 bytes. It looks like after the 2-byte header and
> 2-byte version identifier, the primitive long is written as "block
> data" with a 1-byte length (8) and then the 8 bytes of the long. The
> object flavor is ... more verbose.
>
> So we get almost 90% savings for a single long value. On the other
> hand, the primitive only values going into sessions are the metadata
> and not the attributes, which will dominate the bulk of the data (or
> should, anyway).
>
> I still think this is worth doing.
>
> Any objections?
>

Ok.

Rémy

>
> - -chris
> -BEGIN PGP SIGNATURE-
> Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69sXYACgkQHPApP6U8
> pFi6pg/9ExBQhRRlUv4QPUVDJEhJ8pN6KfBIoHgd/UWw2zYxjeifhDrN+biK2lLG
> GHWmJuF+wEAFz9xtYqN46q1QqSKIQcWTAqI05NchNlqFd29JHwj+9QZV00VTd0eK
> My4MTCVY4dSObJrePyw14tEHyRVcFl539bDhtez7fnjOGkq4EGNXvr7ep9L3w5GB
> ckwKAp1OuFYz5/0ZCCDEVdRiSpoXAac06B5v0FUQb3TBn06gdavUJb9q0HM57RjI
> 0FkQHPyZ1ibfWOOLldBrCgA+7SygGiD6LO2nMo5Fgy1A4l5W/uekkhW96FXBKHng
> /ocXJRQSkeDoanpQmu5pC/Ru1S0bNjZCIo9OMS0de6iEMEO3wPtvuLYhINYydk6E
> 3ZNx+EPZEFPoZuB1K0peWNDgFsE3ar5gL+y6cvztNoZtT1WymoDS6uQ4OvGXcXNL
> 61SOSe3CmqHF0dQTlD/Xikakumz4Kefny5QGw/XlchPVNCqUmvgxUwYPb965kwz3
> Vt/3nib0QgKxbR0j54InFIRkG7gPuGyUaL0kwtMbFEdOTw+PqAEyIPSqIRtmkhVG
> Mzf6ikh+TOToYi+OIJXUMloaVL8xafAo6hKTc7lbu2hAUv9bE47X6uVyQmD7Yxqu
> R3LQGo3OYX9+GBdKBhgvbZB9bEkUImMbsgIXKIUScGaMH4RdtBE=
> =AZle
> -END PGP SIGNATURE-
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: 

Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Mark,

On 5/14/20 14:21, Mark Thomas wrote:
> On 14/05/2020 18:41, Christopher Schultz wrote:
>> Mark,
>>
>> On 5/14/20 12:53, Mark Thomas wrote:
>>> On 14/05/2020 17:46, Mark Thomas wrote:
 On 14/05/2020 16:48, Christopher Schultz wrote:
> All,
>
> I'm interested in the history of the
> StandardSession.writeObjectData method. I've been looking
> at it lately because I'm interested in possibly
> (optionally) encrypting the sessions in the backend session
> store. But this isn't about encryption at all.
>
> The code for
> StandardSession.doWriteObject(ObjectOutputStream stream)
> looks like this:
>
>
> // Write the scalar instance variables (except Manager)
> stream.writeObject(Long.valueOf(creationTime));
> stream.writeObject(Long.valueOf(lastAccessedTime));
> stream.writeObject(Integer.valueOf(maxInactiveInterval));
> stream.writeObject(Boolean.valueOf(isNew));
> stream.writeObject(Boolean.valueOf(isValid));
> stream.writeObject(Long.valueOf(thisAccessedTime));
>
>
> Is there any reason we are writing object wrappers for
> these primitive members instead of just writing the
> primitives directly?

 That code goes all the way back to at least Tomcat 3.1.x
 (20+ years ago).

> It turns out that the byte stream is identical whether one
> uses objects or primitives,

 That surprises me. Looking at the JRE source code it really
 surprises me. So much that I am going to go and try it for
 myself.
>>
>>> My testing shows the opposite. There is a significant
>>> difference between writing primitives and writing objects.
>>
>> Hmm. I did a micro-test with just writing a single
>> Long.valueOf() value and a (primitive) long alone to an
>> ObjectOutputStream. I didn't test the StandardSession itself.
>
> I performed the same micro-test.
>
>>> Given backwards compatibility requirements we can't change this
>>> in 9.0.x and earlier.
>>
>> Agreed.
>>
 One reason we might want to stick with writing objects is to
 support sessionAttributeValueClassNameFilter. I'm only going
 from reading the source so I could easily have missed
 something but it looks like that will only work if we
 write/read objects.
>>
>>> We only care about this for session attributes. We know our
>>> internal attributes are safe so we could switch to primitives
>>> in 10.0.x.
>>
>> I'll have to play-around a bit to see what was wrong with my
>> initial tes t.

So my test was bunk, the data on-the-wire (so to speak) is very
different, and there is no way at all to make them compatible. :/

Perhaps a rewindable input stream would work, but it's just not really
that important.

I think it's okay to make a breaking change at 10.0, but only if
anyone really cares. It saves a couple of bytes which can add up.

In my microtest, I wrote a java.lang.Long value and a (primitive) long
to two separate files. The object-file was 82 bytes and the
primitive-file was 14 bytes. It looks like after the 2-byte header and
2-byte version identifier, the primitive long is written as "block
data" with a 1-byte length (8) and then the 8 bytes of the long. The
object flavor is ... more verbose.

So we get almost 90% savings for a single long value. On the other
hand, the primitive only values going into sessions are the metadata
and not the attributes, which will dominate the bulk of the data (or
should, anyway).

I still think this is worth doing.

Any objections?

- -chris
-BEGIN PGP SIGNATURE-
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69sXYACgkQHPApP6U8
pFi6pg/9ExBQhRRlUv4QPUVDJEhJ8pN6KfBIoHgd/UWw2zYxjeifhDrN+biK2lLG
GHWmJuF+wEAFz9xtYqN46q1QqSKIQcWTAqI05NchNlqFd29JHwj+9QZV00VTd0eK
My4MTCVY4dSObJrePyw14tEHyRVcFl539bDhtez7fnjOGkq4EGNXvr7ep9L3w5GB
ckwKAp1OuFYz5/0ZCCDEVdRiSpoXAac06B5v0FUQb3TBn06gdavUJb9q0HM57RjI
0FkQHPyZ1ibfWOOLldBrCgA+7SygGiD6LO2nMo5Fgy1A4l5W/uekkhW96FXBKHng
/ocXJRQSkeDoanpQmu5pC/Ru1S0bNjZCIo9OMS0de6iEMEO3wPtvuLYhINYydk6E
3ZNx+EPZEFPoZuB1K0peWNDgFsE3ar5gL+y6cvztNoZtT1WymoDS6uQ4OvGXcXNL
61SOSe3CmqHF0dQTlD/Xikakumz4Kefny5QGw/XlchPVNCqUmvgxUwYPb965kwz3
Vt/3nib0QgKxbR0j54InFIRkG7gPuGyUaL0kwtMbFEdOTw+PqAEyIPSqIRtmkhVG
Mzf6ikh+TOToYi+OIJXUMloaVL8xafAo6hKTc7lbu2hAUv9bE47X6uVyQmD7Yxqu
R3LQGo3OYX9+GBdKBhgvbZB9bEkUImMbsgIXKIUScGaMH4RdtBE=
=AZle
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Mark,

On 5/14/20 14:21, Mark Thomas wrote:
> On 14/05/2020 18:41, Christopher Schultz wrote:
>> Mark,
>>
>> On 5/14/20 12:53, Mark Thomas wrote:
>>> On 14/05/2020 17:46, Mark Thomas wrote:
 On 14/05/2020 16:48, Christopher Schultz wrote:
> All,
>
> I'm interested in the history of the
> StandardSession.writeObjectData method. I've been looking
> at it lately because I'm interested in possibly
> (optionally) encrypting the sessions in the backend session
> store. But this isn't about encryption at all.
>
> The code for
> StandardSession.doWriteObject(ObjectOutputStream stream)
> looks like this:
>
>
> // Write the scalar instance variables (except Manager)
> stream.writeObject(Long.valueOf(creationTime));
> stream.writeObject(Long.valueOf(lastAccessedTime));
> stream.writeObject(Integer.valueOf(maxInactiveInterval));
> stream.writeObject(Boolean.valueOf(isNew));
> stream.writeObject(Boolean.valueOf(isValid));
> stream.writeObject(Long.valueOf(thisAccessedTime));
>
>
> Is there any reason we are writing object wrappers for
> these primitive members instead of just writing the
> primitives directly?

 That code goes all the way back to at least Tomcat 3.1.x
 (20+ years ago).

> It turns out that the byte stream is identical whether one
> uses objects or primitives,

 That surprises me. Looking at the JRE source code it really
 surprises me. So much that I am going to go and try it for
 myself.
>>
>>> My testing shows the opposite. There is a significant
>>> difference between writing primitives and writing objects.
>>
>> Hmm. I did a micro-test with just writing a single
>> Long.valueOf() value and a (primitive) long alone to an
>> ObjectOutputStream. I didn't test the StandardSession itself.
>
> I performed the same micro-test.
>
>>> Given backwards compatibility requirements we can't change this
>>> in 9.0.x and earlier.
>>
>> Agreed.
>>
 One reason we might want to stick with writing objects is to
 support sessionAttributeValueClassNameFilter. I'm only going
 from reading the source so I could easily have missed
 something but it looks like that will only work if we
 write/read objects.
>>
>>> We only care about this for session attributes. We know our
>>> internal attributes are safe so we could switch to primitives
>>> in 10.0.x.
>>
>> I'll have to play-around a bit to see what was wrong with my
>> initial tes t.
>
> JRE version? I used a newish Java 8. Long value? I used 1000. I
> did something stupid? Source code here:
>
> https://github.com/markt-asf/tomcat-bugs/blob/master/src/java/org/apac
he/tomcat/ObjectStreams.java

My
>
problem appears to be that I copy-pasted and didn't change one of
the calls. *eyeroll*

- -chris
-BEGIN PGP SIGNATURE-
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69rfEACgkQHPApP6U8
pFgO2w/+Mld4Akm77AOAOWRaqVQVi6BOXOUJE5uRGq8XlsTvx2U4GM6PTuT4F/Tp
Ow9g9NdpK89kPxBDDK+wfZF2qDmwO7uXWqKUr6OQ24qJR2aEerTQsn90GvbKp3j3
SmqeKVGMK8TZJlLtsw7YiMguH0z8v38wulwovBFPdVBZsPTKETo0DjrTxR0oZhrD
lZYKo5qwIF+LWd9NtdLSog9s/nMuC9jJoqwjD5azcRbmpAjYU9oIeQX8q3nqcOFh
DFxXVCbzzLe6EQlkSg0Bpc0PU3FoK5qKPaAcMdjtaVP+L28nbTVkTCugDcxcwNou
M2yi88gxtCk7OOknfum3ukNZI1gvRHvEHMQINdQaXmJ32oxy5QpdJ1ICew2Elo45
Hakms9os6i5QIz2XdF8BZ7ihqtuxkb3stzEi66KTtiTp41V6aHHTiAHIpsJfTsHZ
ZTiaS9UPHZVAMnSE6/QvIAz68IkA3/cQvz9Ed+lClp6r4vqWDomkFsqKH1NDMQCX
gCnTj/3zNXb4+FovhzFnEEM+Pbwe0c20y/I+piTe5S6U6Zcl958au4MNToBCr/t0
YXn0OkAlc24EJBOP37b3406SQEfmBDd4FP7z8fY9QTwT3cOBH3dvzaqYhL8mMBhF
ToVs/lbO5KoBJG0xDC3gK/22r19oyNUaiLa1OlUC533IeMpmloc=
=DHdr
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Mark Thomas
On 14/05/2020 18:41, Christopher Schultz wrote:
> Mark,
> 
> On 5/14/20 12:53, Mark Thomas wrote:
>> On 14/05/2020 17:46, Mark Thomas wrote:
>>> On 14/05/2020 16:48, Christopher Schultz wrote:
 All,

 I'm interested in the history of the
 StandardSession.writeObjectData method. I've been looking at it
 lately because I'm interested in possibly (optionally)
 encrypting the sessions in the backend session store. But this
 isn't about encryption at all.

 The code for StandardSession.doWriteObject(ObjectOutputStream
 stream) looks like this:


 // Write the scalar instance variables (except Manager)
 stream.writeObject(Long.valueOf(creationTime));
 stream.writeObject(Long.valueOf(lastAccessedTime));
 stream.writeObject(Integer.valueOf(maxInactiveInterval));
 stream.writeObject(Boolean.valueOf(isNew));
 stream.writeObject(Boolean.valueOf(isValid));
 stream.writeObject(Long.valueOf(thisAccessedTime));


 Is there any reason we are writing object wrappers for these
 primitive members instead of just writing the primitives
 directly?
>>>
>>> That code goes all the way back to at least Tomcat 3.1.x (20+
>>> years ago).
>>>
 It turns out that the byte stream is identical whether one
 uses objects or primitives,
>>>
>>> That surprises me. Looking at the JRE source code it really
>>> surprises me. So much that I am going to go and try it for
>>> myself.
> 
>> My testing shows the opposite. There is a significant difference
>> between writing primitives and writing objects.
> 
> Hmm. I did a micro-test with just writing a single Long.valueOf()
> value and a (primitive) long alone to an ObjectOutputStream. I didn't
> test the StandardSession itself.

I performed the same micro-test.

>> Given backwards compatibility requirements we can't change this in
>> 9.0.x and earlier.
> 
> Agreed.
> 
>>> One reason we might want to stick with writing objects is to
>>> support sessionAttributeValueClassNameFilter. I'm only going from
>>> reading the source so I could easily have missed something but it
>>> looks like that will only work if we write/read objects.
> 
>> We only care about this for session attributes. We know our
>> internal attributes are safe so we could switch to primitives in
>> 10.0.x.
> 
> I'll have to play-around a bit to see what was wrong with my initial tes
> t.

JRE version? I used a newish Java 8. Long value? I used 1000. I did
something stupid? Source code here:

https://github.com/markt-asf/tomcat-bugs/blob/master/src/java/org/apache/tomcat/ObjectStreams.java


Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Mark,

On 5/14/20 12:53, Mark Thomas wrote:
> On 14/05/2020 17:46, Mark Thomas wrote:
>> On 14/05/2020 16:48, Christopher Schultz wrote:
>>> All,
>>>
>>> I'm interested in the history of the
>>> StandardSession.writeObjectData method. I've been looking at it
>>> lately because I'm interested in possibly (optionally)
>>> encrypting the sessions in the backend session store. But this
>>> isn't about encryption at all.
>>>
>>> The code for StandardSession.doWriteObject(ObjectOutputStream
>>> stream) looks like this:
>>>
>>>
>>> // Write the scalar instance variables (except Manager)
>>> stream.writeObject(Long.valueOf(creationTime));
>>> stream.writeObject(Long.valueOf(lastAccessedTime));
>>> stream.writeObject(Integer.valueOf(maxInactiveInterval));
>>> stream.writeObject(Boolean.valueOf(isNew));
>>> stream.writeObject(Boolean.valueOf(isValid));
>>> stream.writeObject(Long.valueOf(thisAccessedTime));
>>>
>>>
>>> Is there any reason we are writing object wrappers for these
>>> primitive members instead of just writing the primitives
>>> directly?
>>
>> That code goes all the way back to at least Tomcat 3.1.x (20+
>> years ago).
>>
>>> It turns out that the byte stream is identical whether one
>>> uses objects or primitives,
>>
>> That surprises me. Looking at the JRE source code it really
>> surprises me. So much that I am going to go and try it for
>> myself.
>
> My testing shows the opposite. There is a significant difference
> between writing primitives and writing objects.

Hmm. I did a micro-test with just writing a single Long.valueOf()
value and a (primitive) long alone to an ObjectOutputStream. I didn't
test the StandardSession itself.

> Given backwards compatibility requirements we can't change this in
> 9.0.x and earlier.

Agreed.

>> One reason we might want to stick with writing objects is to
>> support sessionAttributeValueClassNameFilter. I'm only going from
>> reading the source so I could easily have missed something but it
>> looks like that will only work if we write/read objects.
>
> We only care about this for session attributes. We know our
> internal attributes are safe so we could switch to primitives in
> 10.0.x.

I'll have to play-around a bit to see what was wrong with my initial tes
t.

- -chris
-BEGIN PGP SIGNATURE-
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69guMACgkQHPApP6U8
pFg40BAAowAyGeHKQAWyj4OjZVwuZJnZpNaBsK0Rthw2rmCPFVVzBb37IDV7svxk
HjmYyvKSM3NxRke/ftSysfg7hnGAaK0gFuyk8XSqUp5ZXkJUzHoS/44Ite1Fsqux
8iwc+djveuybUEacxz9PGLH9+vmXVI9EhvYUHKXyWS5w5KKXBVghPcrnL9gjBbTs
F7a92V6xiRUdnhDBpixOEBnwihfAisd1CS9XQjIAhVB2T0mkSsinZBFqzy5HZX4a
ohMhX1aAFKyHEV9rHeNlV9mTzj1Wg+rgXEVW4hWnGzmt+iS3KdLxdRZRw+6v78O6
M4cYPclPYek//toB7mf+FFyrPtyfVMjG9lvqP3serXQ8Ujh7HvUNQX91/kgpC9mQ
xWJQqpsR7CwkmleU/XFFcyz9Dp+N/SlZSomPneeLRj4+Epx+AX8WgXVZMZdJNXVf
MN5IIix7K9ff+drbCgwFsC2Yf1M76Mf6VQSXKdNmxZ5AfXJy9Kzk8z2rukj63wMA
wHs3CEjHjN7PevbgUbvQnA6Ze92ZRlzQqhrZl400/lriYzGeePQmqeVg5/mlAWLW
2YJQRsmaA8Q7QI63vZXkBYGBA1/lh6NDFF3mVqHCxAy3nUfSx3VNgwVZSk3aItqw
eDgNxRJkhR43MLj1GDQTAVjHF+XrMw87xDp58cI0pxhgavGzlsI=
=2xPi
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Mark Thomas
On 14/05/2020 17:46, Mark Thomas wrote:
> On 14/05/2020 16:48, Christopher Schultz wrote:
>> All,
>>
>> I'm interested in the history of the StandardSession.writeObjectData
>> method. I've been looking at it lately because I'm interested in
>> possibly (optionally) encrypting the sessions in the backend session
>> store. But this isn't about encryption at all.
>>
>> The code for StandardSession.doWriteObject(ObjectOutputStream stream)
>> looks like this:
>>
>>
>> // Write the scalar instance variables (except Manager)
>> stream.writeObject(Long.valueOf(creationTime));
>> stream.writeObject(Long.valueOf(lastAccessedTime));
>> stream.writeObject(Integer.valueOf(maxInactiveInterval));
>> stream.writeObject(Boolean.valueOf(isNew));
>> stream.writeObject(Boolean.valueOf(isValid));
>> stream.writeObject(Long.valueOf(thisAccessedTime));
>>
>>
>> Is there any reason we are writing object wrappers for these primitive
>> members instead of just writing the primitives directly?
> 
> That code goes all the way back to at least Tomcat 3.1.x (20+ years ago).
> 
>> It turns out that the byte stream is identical whether one uses
>> objects or primitives,
> 
> That surprises me. Looking at the JRE source code it really surprises
> me. So much that I am going to go and try it for myself.

My testing shows the opposite. There is a significant difference between
writing primitives and writing objects.

Given backwards compatibility requirements we can't change this in 9.0.x
and earlier.

> One reason we might want to stick with writing objects is to support
> sessionAttributeValueClassNameFilter. I'm only going from reading the
> source so I could easily have missed something but it looks like that
> will only work if we write/read objects.

We only care about this for session attributes. We know our internal
attributes are safe so we could switch to primitives in 10.0.x.

Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Mark Thomas
On 14/05/2020 16:48, Christopher Schultz wrote:
> All,
> 
> I'm interested in the history of the StandardSession.writeObjectData
> method. I've been looking at it lately because I'm interested in
> possibly (optionally) encrypting the sessions in the backend session
> store. But this isn't about encryption at all.
> 
> The code for StandardSession.doWriteObject(ObjectOutputStream stream)
> looks like this:
> 
> 
> // Write the scalar instance variables (except Manager)
> stream.writeObject(Long.valueOf(creationTime));
> stream.writeObject(Long.valueOf(lastAccessedTime));
> stream.writeObject(Integer.valueOf(maxInactiveInterval));
> stream.writeObject(Boolean.valueOf(isNew));
> stream.writeObject(Boolean.valueOf(isValid));
> stream.writeObject(Long.valueOf(thisAccessedTime));
> 
> 
> Is there any reason we are writing object wrappers for these primitive
> members instead of just writing the primitives directly?

That code goes all the way back to at least Tomcat 3.1.x (20+ years ago).

> It turns out that the byte stream is identical whether one uses
> objects or primitives,

That surprises me. Looking at the JRE source code it really surprises
me. So much that I am going to go and try it for myself.

One reason we might want to stick with writing objects is to support
sessionAttributeValueClassNameFilter. I'm only going from reading the
source so I could easily have missed something but it looks like that
will only work if we write/read objects.

Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Session serialization uses wrapper objects instead of primitives

2020-05-14 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

All,

I'm interested in the history of the StandardSession.writeObjectData
method. I've been looking at it lately because I'm interested in
possibly (optionally) encrypting the sessions in the backend session
store. But this isn't about encryption at all.

The code for StandardSession.doWriteObject(ObjectOutputStream stream)
looks like this:


// Write the scalar instance variables (except Manager)
stream.writeObject(Long.valueOf(creationTime));
stream.writeObject(Long.valueOf(lastAccessedTime));
stream.writeObject(Integer.valueOf(maxInactiveInterval));
stream.writeObject(Boolean.valueOf(isNew));
stream.writeObject(Boolean.valueOf(isValid));
stream.writeObject(Long.valueOf(thisAccessedTime));


Is there any reason we are writing object wrappers for these primitive
members instead of just writing the primitives directly?

It turns out that the byte stream is identical whether one uses
objects or primitives, but the code is a little more complicated,
generates objects when none are necessary, etc. Here is the
doReadObject code:

creationTime = ((Long) stream.readObject()).longValue();
lastAccessedTime = ((Long) stream.readObject()).longValue();
maxInactiveInterval = ((Integer) stream.readObject()).intValue()
;
isNew = ((Boolean) stream.readObject()).booleanValue();
isValid = ((Boolean) stream.readObject()).booleanValue();
thisAccessedTime = ((Long) stream.readObject()).longValue();

If using primitives, it would be:

creationTime = stream.readLong();
lastAccessedTime = stream.readLong();
maxInactiveInterval = stream.readInt();
isNew = stream.readBoolean();
isValid = stream.readBoolean();
thisAccessedTime = stream.readLong();

I don't believe there is any benefit to using objects over primitives
in this case. If the stream doesn't contain the right object types in
the right order, the operation will fail so they are providing any
e.g. type-safety that you might get by casting to (Number) and then
pulling long value (to convert an int -> long, possibly).

I think the code is easier to read and will generate less temporary
garbage if the wrapper objects are removed.

I think the change will also remain interoperable between versions
since the byte-stream is unchanged.

Any objections to making this change?

- -chris
-BEGIN PGP SIGNATURE-
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl69aFEACgkQHPApP6U8
pFiiGA/+OTShGMP1QvzP9rINT8hyrjhoiXTxCN6cfazQZ3Q8UUXAFA6514tLLkli
3FBfu6CWyAe1S8WvzgkeWg0UospfKjSi3pod/uVjF9Bo4JYyPAe39FV8k74Suotk
HpQNbrrFMp7MeQowXdtns/ua8F+uo77JXTHrdc3eZIhBpfiyyyPQLaC73r/djMwf
v/0iDF/SBAL98fTQsnTqeFVGJGBUkHS1Yvuhr1DQ+I6gpSRn+wUGlvUmrxaNF6J6
opYfBpU53L/2skjN7yC/DC5pnYbgRRzKdoNKzgrNbEbK9dyqEztr4N82+8VdIccj
BJJA+7LqYDkVvrrTSCBL8hTlWr10P609rwX7t+/LHl0SzBVdsdiZurpBD/SRZXbQ
nNU2n2DauAVUDUsKoLR/MvzpGVW3cNJNOqMX8mscA9RkLJwfWTnrohD7YFXtj6iv
D03ekPpOBGSF1TX6JAjgDuciSPD2/Z9NV6wR1yKcfjm/rKkoAnv/orP/ccTsuXnq
fggNFZQAmfp93QJFf2G3wntmR/3fCWjETVWT5CxyTxSdn/Zmj08P2lKiyRUriLd1
4kGnNxLSFgo/UWIgoFaPeITbkupmI9rGQq+LZM1UlnhoHxWj3vVOdCN/Zu+3OpLQ
rFD5YTunZmHDBIcbtHbOmHeAGq7VU1BpvJ7V50jz9LW6OoX6GfQ=
=vEuO
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org