RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-09 Thread Iris Clark
Hi, Goetz.

The error messages using "cannot", the preferred word according to the Chicago 
Manual of Style [0], look good to me.

Thanks,
Iris

[0] 
https://www.chicagomanualofstyle.org/qanda/data/faq/topics/Usage/faq0010.html

-Original Message-
From: Lindenmaier, Goetz  
Sent: Thursday, May 9, 2019 1:04 AM
To: Coleen Phillimore ; Schmelter, Ralf 
; Java Core Libs ; 
hotspot-runtime-...@openjdk.java.net; Harold David Seigel 

Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException 
describing what is null.

Hi,

here a webrev which uses 'cannot'. Nothing else changed.
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/10-cannot/

Best regards,
  Goetz.

> -Original Message-
> From: Lindenmaier, Goetz
> Sent: Donnerstag, 9. Mai 2019 08:55
> To: coleen.phillim...@oracle.com; Schmelter, Ralf 
> ; Java Core Libs 
> ; hotspot-runtime- 
> d...@openjdk.java.net; Harold David Seigel 
> Subject: RE: RFR(L): 8218628: Add detailed message to 
> NullPointerException describing what is null.
> 
> Hi,
> 
> > Cannot is apparently preferable in English.
> OK, changed.
> 
> Best regards,
>   Goetz.
> 
> 
> > -Original Message-
> > From: coleen.phillim...@oracle.com 
> > Sent: Mittwoch, 8. Mai 2019 17:32
> > To: Lindenmaier, Goetz ; Schmelter, Ralf 
> > ; Java Core Libs 
> > ; 
> > hotspot-runtime-...@openjdk.java.net; Harold David Seigel 
> > 
> > Subject: Re: RFR(L): 8218628: Add detailed message to 
> > NullPointerException describing what is null.
> >
> >
> >
> > On 5/7/19 9:36 AM, Lindenmaier, Goetz wrote:
> > > Hi,
> > >
> > > Please have a look at this further improved webrev:
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09-
> > incremental/
> > >
> > > Harold, Coleen, thanks for pointing me to those methods.
> > > I'm using them now. This simplifies the helper methods 
> > > considerably.
> > >
> > > Ralf, thanks for looking at the messages!
> > > I now suppress the "static " and
> > > "The return value of '" strings in the array subscript expressions 
> > > and added corresponding test cases.
> > >
> > > About "can not" versus "cannot", what I find in the net "cannot" 
> > > is to be preferred.  Any comments on that?
> > > By native speakers?
> > > See example messages here:
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-
> > NPE/09/output_with_debug_info.txt
> >
> > Cannot is apparently preferable in English.  Native speaker (only
> > language) but somebody had to tell me.
> >
> > Coleen
> > >
> > > Further, I fixed a build issue with the solaris compiler.
> > > All handling of bci is now unsigned.
> > >
> > > Best regards,
> > >Goetz.
> > >
> > >
> > >
> > >
> > >> -Original Message-
> > >> From: Schmelter, Ralf
> > >> Sent: Dienstag, 7. Mai 2019 14:35
> > >> To: Lindenmaier, Goetz ; Java Core 
> > >> Libs
> >  > >> libs-...@openjdk.java.net>; hotspot-runtime-...@openjdk.java.net;
> > Coleen
> > >> Phillimore (coleen.phillim...@oracle.com)
> 
> > >> Subject: RE: RFR(L): 8218628: Add detailed message to
> NullPointerException
> > >> describing what is null.
> > >>
> > >> Hi Goetz,
> > >>
> > >> I've played with the messages a little bit and they generally 
> > >> look good. But
> > I've
> > >> come across two which look strange:
> > >>   - 'o[static Test.INDEX]' is null. Can not invoke method 'int 
> > >> java.lang.Object.hashCode()'
> > >>   - 'o[The return value of 'int java.lang.String.hashCode()]' is 
> > >> null. Can not
> > invoke
> > >> method 'int java.lang.Object.hashCode()'.
> > >>
> > >> Here is the test program to reproduce these:
> > >> public class Test {
> > >>  public static int INDEX = 2;
> > >>
> > >>  public static void main(String[] args) {
> > >>  Object[] o = new Object[10];
> > >>  try {
> > >>   o[INDEX].hashCode();
> > >>  } catch (Exception e) {
> > >>  e.printStackTrace();
> > >>  }
> > >>  try {
> > >>   o["".hashCode()].hashCode();
> > >>  } catch (Exception e) {
> > >>  e.printStackTrace();
> > >>  }
> > >>  }
> > >> }
> > >>
> > >> And 'Can not' should be 'Cannot'?
> > >>
> > >> Best regards,
> > >> Ralf



RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-09 Thread Lindenmaier, Goetz
Hi,

here a webrev which uses 'cannot'. Nothing else changed.
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/10-cannot/

Best regards,
  Goetz.

> -Original Message-
> From: Lindenmaier, Goetz
> Sent: Donnerstag, 9. Mai 2019 08:55
> To: coleen.phillim...@oracle.com; Schmelter, Ralf ;
> Java Core Libs ; hotspot-runtime-
> d...@openjdk.java.net; Harold David Seigel 
> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi,
> 
> > Cannot is apparently preferable in English.
> OK, changed.
> 
> Best regards,
>   Goetz.
> 
> 
> > -Original Message-
> > From: coleen.phillim...@oracle.com 
> > Sent: Mittwoch, 8. Mai 2019 17:32
> > To: Lindenmaier, Goetz ; Schmelter, Ralf
> > ; Java Core Libs ;
> > hotspot-runtime-...@openjdk.java.net; Harold David Seigel
> > 
> > Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> > describing what is null.
> >
> >
> >
> > On 5/7/19 9:36 AM, Lindenmaier, Goetz wrote:
> > > Hi,
> > >
> > > Please have a look at this further improved webrev:
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09-
> > incremental/
> > >
> > > Harold, Coleen, thanks for pointing me to those methods.
> > > I'm using them now. This simplifies the helper methods
> > > considerably.
> > >
> > > Ralf, thanks for looking at the messages!
> > > I now suppress the "static " and
> > > "The return value of '" strings in the array subscript
> > > expressions and added corresponding test cases.
> > >
> > > About "can not" versus "cannot", what I find in the
> > > net "cannot" is to be preferred.  Any comments on that?
> > > By native speakers?
> > > See example messages here:
> > > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-
> > NPE/09/output_with_debug_info.txt
> >
> > Cannot is apparently preferable in English.  Native speaker (only
> > language) but somebody had to tell me.
> >
> > Coleen
> > >
> > > Further, I fixed a build issue with the solaris compiler.
> > > All handling of bci is now unsigned.
> > >
> > > Best regards,
> > >Goetz.
> > >
> > >
> > >
> > >
> > >> -Original Message-
> > >> From: Schmelter, Ralf
> > >> Sent: Dienstag, 7. Mai 2019 14:35
> > >> To: Lindenmaier, Goetz ; Java Core Libs
> >  > >> libs-...@openjdk.java.net>; hotspot-runtime-...@openjdk.java.net;
> > Coleen
> > >> Phillimore (coleen.phillim...@oracle.com)
> 
> > >> Subject: RE: RFR(L): 8218628: Add detailed message to
> NullPointerException
> > >> describing what is null.
> > >>
> > >> Hi Goetz,
> > >>
> > >> I've played with the messages a little bit and they generally look good. 
> > >> But
> > I've
> > >> come across two which look strange:
> > >>   - 'o[static Test.INDEX]' is null. Can not invoke method 'int
> > >> java.lang.Object.hashCode()'
> > >>   - 'o[The return value of 'int java.lang.String.hashCode()]' is null. 
> > >> Can not
> > invoke
> > >> method 'int java.lang.Object.hashCode()'.
> > >>
> > >> Here is the test program to reproduce these:
> > >> public class Test {
> > >>  public static int INDEX = 2;
> > >>
> > >>  public static void main(String[] args) {
> > >>  Object[] o = new Object[10];
> > >>  try {
> > >>   o[INDEX].hashCode();
> > >>  } catch (Exception e) {
> > >>  e.printStackTrace();
> > >>  }
> > >>  try {
> > >>   o["".hashCode()].hashCode();
> > >>  } catch (Exception e) {
> > >>  e.printStackTrace();
> > >>  }
> > >>  }
> > >> }
> > >>
> > >> And 'Can not' should be 'Cannot'?
> > >>
> > >> Best regards,
> > >> Ralf



RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-09 Thread Lindenmaier, Goetz
Hi,

> Cannot is apparently preferable in English.  
OK, changed. 

Best regards,
  Goetz.


> -Original Message-
> From: coleen.phillim...@oracle.com 
> Sent: Mittwoch, 8. Mai 2019 17:32
> To: Lindenmaier, Goetz ; Schmelter, Ralf
> ; Java Core Libs ;
> hotspot-runtime-...@openjdk.java.net; Harold David Seigel
> 
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> 
> 
> On 5/7/19 9:36 AM, Lindenmaier, Goetz wrote:
> > Hi,
> >
> > Please have a look at this further improved webrev:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09-
> incremental/
> >
> > Harold, Coleen, thanks for pointing me to those methods.
> > I'm using them now. This simplifies the helper methods
> > considerably.
> >
> > Ralf, thanks for looking at the messages!
> > I now suppress the "static " and
> > "The return value of '" strings in the array subscript
> > expressions and added corresponding test cases.
> >
> > About "can not" versus "cannot", what I find in the
> > net "cannot" is to be preferred.  Any comments on that?
> > By native speakers?
> > See example messages here:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-
> NPE/09/output_with_debug_info.txt
> 
> Cannot is apparently preferable in English.  Native speaker (only
> language) but somebody had to tell me.
> 
> Coleen
> >
> > Further, I fixed a build issue with the solaris compiler.
> > All handling of bci is now unsigned.
> >
> > Best regards,
> >Goetz.
> >
> >
> >
> >
> >> -----Original Message-----
> >> From: Schmelter, Ralf
> >> Sent: Dienstag, 7. Mai 2019 14:35
> >> To: Lindenmaier, Goetz ; Java Core Libs
>  >> libs-...@openjdk.java.net>; hotspot-runtime-...@openjdk.java.net;
> Coleen
> >> Phillimore (coleen.phillim...@oracle.com) 
> >> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> >> describing what is null.
> >>
> >> Hi Goetz,
> >>
> >> I've played with the messages a little bit and they generally look good. 
> >> But
> I've
> >> come across two which look strange:
> >>   - 'o[static Test.INDEX]' is null. Can not invoke method 'int
> >> java.lang.Object.hashCode()'
> >>   - 'o[The return value of 'int java.lang.String.hashCode()]' is null. Can 
> >> not
> invoke
> >> method 'int java.lang.Object.hashCode()'.
> >>
> >> Here is the test program to reproduce these:
> >> public class Test {
> >>  public static int INDEX = 2;
> >>
> >>  public static void main(String[] args) {
> >>  Object[] o = new Object[10];
> >>  try {
> >>   o[INDEX].hashCode();
> >>  } catch (Exception e) {
> >>  e.printStackTrace();
> >>  }
> >>  try {
> >>   o["".hashCode()].hashCode();
> >>  } catch (Exception e) {
> >>  e.printStackTrace();
> >>  }
> >>  }
> >> }
> >>
> >> And 'Can not' should be 'Cannot'?
> >>
> >> Best regards,
> >> Ralf



Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-08 Thread coleen . phillimore




On 5/7/19 9:36 AM, Lindenmaier, Goetz wrote:

Hi,

Please have a look at this further improved webrev:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09-incremental/

Harold, Coleen, thanks for pointing me to those methods.
I'm using them now. This simplifies the helper methods
considerably.

Ralf, thanks for looking at the messages!
I now suppress the "static " and
"The return value of '" strings in the array subscript
expressions and added corresponding test cases.

About "can not" versus "cannot", what I find in the
net "cannot" is to be preferred.  Any comments on that?
By native speakers?
See example messages here:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/output_with_debug_info.txt


Cannot is apparently preferable in English.  Native speaker (only 
language) but somebody had to tell me.


Coleen


Further, I fixed a build issue with the solaris compiler.
All handling of bci is now unsigned.

Best regards,
   Goetz.





-Original Message-
From: Schmelter, Ralf
Sent: Dienstag, 7. Mai 2019 14:35
To: Lindenmaier, Goetz ; Java Core Libs ; hotspot-runtime-...@openjdk.java.net; Coleen
Phillimore (coleen.phillim...@oracle.com) 
Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
describing what is null.

Hi Goetz,

I've played with the messages a little bit and they generally look good. But 
I've
come across two which look strange:
  - 'o[static Test.INDEX]' is null. Can not invoke method 'int
java.lang.Object.hashCode()'
  - 'o[The return value of 'int java.lang.String.hashCode()]' is null. Can not 
invoke
method 'int java.lang.Object.hashCode()'.

Here is the test program to reproduce these:
public class Test {
 public static int INDEX = 2;

 public static void main(String[] args) {
 Object[] o = new Object[10];
 try {
  o[INDEX].hashCode();
 } catch (Exception e) {
 e.printStackTrace();
 }
 try {
  o["".hashCode()].hashCode();
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
}

And 'Can not' should be 'Cannot'?

Best regards,
Ralf




RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-07 Thread Schmelter, Ralf
Hi Goetz,

I've played with the messages a little bit and they generally look good. But 
I've come across two which look strange:
 - 'o[static Test.INDEX]' is null. Can not invoke method 'int 
java.lang.Object.hashCode()'
 - 'o[The return value of 'int java.lang.String.hashCode()]' is null. Can not 
invoke method 'int java.lang.Object.hashCode()'.

Here is the test program to reproduce these:
public class Test {
public static int INDEX = 2;

public static void main(String[] args) {
Object[] o = new Object[10];
try {
 o[INDEX].hashCode();
} catch (Exception e) {
e.printStackTrace();
}
try {
 o["".hashCode()].hashCode();
} catch (Exception e) {
e.printStackTrace();
}
}
}

And 'Can not' should be 'Cannot'?

Best regards,
Ralf


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-07 Thread Lindenmaier, Goetz
Hi,

Please have a look at this further improved webrev:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09-incremental/

Harold, Coleen, thanks for pointing me to those methods.
I'm using them now. This simplifies the helper methods
considerably.

Ralf, thanks for looking at the messages!
I now suppress the "static " and 
"The return value of '" strings in the array subscript
expressions and added corresponding test cases.

About "can not" versus "cannot", what I find in the 
net "cannot" is to be preferred.  Any comments on that?
By native speakers?
See example messages here: 
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/09/output_with_debug_info.txt

Further, I fixed a build issue with the solaris compiler.
All handling of bci is now unsigned.

Best regards,
  Goetz.




> -Original Message-
> From: Schmelter, Ralf
> Sent: Dienstag, 7. Mai 2019 14:35
> To: Lindenmaier, Goetz ; Java Core Libs  libs-...@openjdk.java.net>; hotspot-runtime-...@openjdk.java.net; Coleen
> Phillimore (coleen.phillim...@oracle.com) 
> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> 
> I've played with the messages a little bit and they generally look good. But 
> I've
> come across two which look strange:
>  - 'o[static Test.INDEX]' is null. Can not invoke method 'int
> java.lang.Object.hashCode()'
>  - 'o[The return value of 'int java.lang.String.hashCode()]' is null. Can not 
> invoke
> method 'int java.lang.Object.hashCode()'.
> 
> Here is the test program to reproduce these:
> public class Test {
> public static int INDEX = 2;
> 
> public static void main(String[] args) {
> Object[] o = new Object[10];
> try {
>  o[INDEX].hashCode();
> } catch (Exception e) {
> e.printStackTrace();
> }
> try {
>  o["".hashCode()].hashCode();
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> }
> 
> And 'Can not' should be 'Cannot'?
> 
> Best regards,
> Ralf


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-05-06 Thread Lindenmaier, Goetz
Hi,

incorporating comments by Coleen, I prepared a new webrev:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/08/ 
incremental webrev:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/08-incremental/

I renamed the following new classes: 
  TrackingStackCreator  -> ExcpetionMessageBuilder
  SimulatedOperandStack -> SimulatedOperandStack
  StackSlotAnalysisData -> StackSlotAnalysisData
and moved their declaration to the .cpp file.

A new wrapper class BytecodeUtils contains the 
method that is called from jvm.cpp. Some code
is moved from jvm.cpp to bytecodeUtils.cpp
so the internal data structures are no more exposed.

StackSlotAnalysisData now has two fields getting
rid of / and %. This also makes debugging more simple.

Lots of comments were added or improved.

I adapted test langtools/jdk/jshell/ToolSimpleTest.java
to the new message.

Coleen, thanks for your help!

Best regards,
  Goetz.



> -Original Message-
> From: Lindenmaier, Goetz
> Sent: Freitag, 12. April 2019 12:33
> To: Mandy Chung ; Roger Riggs
> 
> Cc: Java Core Libs ; hotspot-runtime-
> d...@openjdk.java.net
> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi,
> 
> while waiting for progress on corresponding the JEP, I improved
> the implementation of generating the NPE message.  It now uses
> a single outputStream. This removes several allocations of temporary
> data. I also removed TrackingStackSource. The analysis code originally
> addressed several use cases, for NullPointerExceptions this is
> not needed.  I cleaned up bytecodeUtils from some code not (really) needed.
> 
> I split get_null_pointer_slot() into two methods: get_NPE_null_slot()
> and print_NPE_failed_action(). This simplifies the
> implementation, and streamlines it more with the text in the JEP.
> 
> I print methods using the code added in
> "8221470: Print methods in exception messages in java-like Syntax.",
> so it now prints 'void m(int)' instead of 'm(I)V'.
> 
> I implemented a row of new test cases, and rearranged the test
> to test the message part of print_NPE_failed_action() and
> print_NPE_cause() separated. I made sure all bytecodes
> handled in these methods are covered.
> Further I arranged the tests in methods according to the
> functional properties as discussed in the JEP.
> 
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/07
> 
> Best regards,
>   Goetz.
> 
> 
> 
> 
> 
> > -Original Message-
> > From: Lindenmaier, Goetz
> > Sent: Donnerstag, 14. März 2019 21:56
> > To: 'Mandy Chung' ; 'Roger Riggs'
> > 
> > Cc: 'Java Core Libs' ; 'hotspot-runtime-
> > d...@openjdk.java.net' 
> > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> > describing what is null.
> >
> > Hi,
> >
> > I had promised to work on a better wording of the messages.
> >
> > This I deliver with this webrev:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> > otherMessages/
> >
> > The test in the webrev is modified to just print messages along with the
> > code that raised the messages.
> >
> > Please have a look at these files with test output contained in the webrev:
> > Messages with debug information:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> > otherMessages/output_with_debug_info.txt
> > Messages without debug information:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> > otherMessages/output_no_debug_info.txt
> >
> > Especially look at the first few messages, they point out the usefulness
> > of this change.  They precisely say what was null in a chain of 
> > dereferences.
> >
> > Best regards,
> >   Goetz.
> >
> >
> > > -Original Message-
> > > From: Lindenmaier, Goetz
> > > Sent: Wednesday, February 13, 2019 10:09 AM
> > > To: 'Mandy Chung' ; Roger Riggs
> > > 
> > > Cc: Java Core Libs ; hotspot-runtime-
> > > d...@openjdk.java.net
> > > Subject: RE: RFR(L): 8218628: Add detailed message to
> NullPointerException
> > > describing what is null.
> > >
> > > Hi Mandy,
> > >
> > > Thanks for supporting my intend of adding the message as such!
> > > I'll start implementing this in Java and come back with a webrev
> > > in a while.
> > >
> > > In parallel, I would like to continue discussing the other
> > > topics, e.g., the wording of the message. I will probably come up
> > > with a separate webrev for that.
> > >
> > > Best rega

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-04-12 Thread Jason Mehrens
Hi Goetz,

Looking at the test cases I didn't see any tests for the single argument 
java.util.Objects.requireNonNull.  Using this prototype is that method treated 
like a hidden frame?

Cheers,

Jason

From: core-libs-dev  on behalf of 
Lindenmaier, Goetz 
Sent: Friday, April 12, 2019 5:33 AM
To: Mandy Chung; Roger Riggs
Cc: Java Core Libs; hotspot-runtime-...@openjdk.java.net
Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException 
describing what is null.

Hi,

while waiting for progress on corresponding the JEP, I improved
the implementation of generating the NPE message.  It now uses
a single outputStream. This removes several allocations of temporary
data. I also removed TrackingStackSource. The analysis code originally
addressed several use cases, for NullPointerExceptions this is
not needed.  I cleaned up bytecodeUtils from some code not (really) needed.

I split get_null_pointer_slot() into two methods: get_NPE_null_slot()
and print_NPE_failed_action(). This simplifies the
implementation, and streamlines it more with the text in the JEP.

I print methods using the code added in
"8221470: Print methods in exception messages in java-like Syntax.",
so it now prints 'void m(int)' instead of 'm(I)V'.

I implemented a row of new test cases, and rearranged the test
to test the message part of print_NPE_failed_action() and
print_NPE_cause() separated. I made sure all bytecodes
handled in these methods are covered.
Further I arranged the tests in methods according to the
functional properties as discussed in the JEP.

http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/07

Best regards,
  Goetz.





> -Original Message-
> From: Lindenmaier, Goetz
> Sent: Donnerstag, 14. März 2019 21:56
> To: 'Mandy Chung' ; 'Roger Riggs'
> 
> Cc: 'Java Core Libs' ; 'hotspot-runtime-
> d...@openjdk.java.net' 
> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
>
> Hi,
>
> I had promised to work on a better wording of the messages.
>
> This I deliver with this webrev:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/
>
> The test in the webrev is modified to just print messages along with the
> code that raised the messages.
>
> Please have a look at these files with test output contained in the webrev:
> Messages with debug information:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/output_with_debug_info.txt
> Messages without debug information:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/output_no_debug_info.txt
>
> Especially look at the first few messages, they point out the usefulness
> of this change.  They precisely say what was null in a chain of dereferences.
>
> Best regards,
>   Goetz.
>
>
> > -Original Message-
> > From: Lindenmaier, Goetz
> > Sent: Wednesday, February 13, 2019 10:09 AM
> > To: 'Mandy Chung' ; Roger Riggs
> > 
> > Cc: Java Core Libs ; hotspot-runtime-
> > d...@openjdk.java.net
> > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> > describing what is null.
> >
> > Hi Mandy,
> >
> > Thanks for supporting my intend of adding the message as such!
> > I'll start implementing this in Java and come back with a webrev
> > in a while.
> >
> > In parallel, I would like to continue discussing the other
> > topics, e.g., the wording of the message. I will probably come up
> > with a separate webrev for that.
> >
> > Best regards,
> >   Goetz.
> >
> >
> >
> > > -Original Message-
> > > From: core-libs-dev  On Behalf
> > > Of Mandy Chung
> > > Sent: Tuesday, February 12, 2019 7:32 PM
> > > To: Roger Riggs 
> > > Cc: Java Core Libs ; hotspot-runtime-
> > > d...@openjdk.java.net
> > > Subject: Re: RFR(L): 8218628: Add detailed message to
> > NullPointerException
> > > describing what is null.
> > >
> > > On 2/8/19 11:46 AM, Roger Riggs wrote:
> > > > Hi,
> > > >
> > > > A few higher level issues should be considered, though the details
> > > > of the webrev captured my immediate attention.
> > > >
> > > > Is this the right feature and is this the right level of implementation
> > > > (C++/native)?
> > > > :
> > > > How much of this can be done in Java code with StackWalker and other
> > > > java APIs?
> > > > It would be a shame to add this much native code if there was a more
> > > robust
> > > > way to implement it using AP

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-04-12 Thread Lindenmaier, Goetz
Hi,

while waiting for progress on corresponding the JEP, I improved 
the implementation of generating the NPE message.  It now uses
a single outputStream. This removes several allocations of temporary
data. I also removed TrackingStackSource. The analysis code originally 
addressed several use cases, for NullPointerExceptions this is 
not needed.  I cleaned up bytecodeUtils from some code not (really) needed.

I split get_null_pointer_slot() into two methods: get_NPE_null_slot() 
and print_NPE_failed_action(). This simplifies the
implementation, and streamlines it more with the text in the JEP.

I print methods using the code added in 
"8221470: Print methods in exception messages in java-like Syntax.",
so it now prints 'void m(int)' instead of 'm(I)V'.

I implemented a row of new test cases, and rearranged the test 
to test the message part of print_NPE_failed_action() and 
print_NPE_cause() separated. I made sure all bytecodes 
handled in these methods are covered.  
Further I arranged the tests in methods according to the
functional properties as discussed in the JEP.

http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/07

Best regards,
  Goetz.





> -Original Message-
> From: Lindenmaier, Goetz
> Sent: Donnerstag, 14. März 2019 21:56
> To: 'Mandy Chung' ; 'Roger Riggs'
> 
> Cc: 'Java Core Libs' ; 'hotspot-runtime-
> d...@openjdk.java.net' 
> Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi,
> 
> I had promised to work on a better wording of the messages.
> 
> This I deliver with this webrev:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/
> 
> The test in the webrev is modified to just print messages along with the
> code that raised the messages.
> 
> Please have a look at these files with test output contained in the webrev:
> Messages with debug information:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/output_with_debug_info.txt
> Messages without debug information:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-
> otherMessages/output_no_debug_info.txt
> 
> Especially look at the first few messages, they point out the usefulness
> of this change.  They precisely say what was null in a chain of dereferences.
> 
> Best regards,
>   Goetz.
> 
> 
> > -Original Message-
> > From: Lindenmaier, Goetz
> > Sent: Wednesday, February 13, 2019 10:09 AM
> > To: 'Mandy Chung' ; Roger Riggs
> > 
> > Cc: Java Core Libs ; hotspot-runtime-
> > d...@openjdk.java.net
> > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException
> > describing what is null.
> >
> > Hi Mandy,
> >
> > Thanks for supporting my intend of adding the message as such!
> > I'll start implementing this in Java and come back with a webrev
> > in a while.
> >
> > In parallel, I would like to continue discussing the other
> > topics, e.g., the wording of the message. I will probably come up
> > with a separate webrev for that.
> >
> > Best regards,
> >   Goetz.
> >
> >
> >
> > > -Original Message-
> > > From: core-libs-dev  On Behalf
> > > Of Mandy Chung
> > > Sent: Tuesday, February 12, 2019 7:32 PM
> > > To: Roger Riggs 
> > > Cc: Java Core Libs ; hotspot-runtime-
> > > d...@openjdk.java.net
> > > Subject: Re: RFR(L): 8218628: Add detailed message to
> > NullPointerException
> > > describing what is null.
> > >
> > > On 2/8/19 11:46 AM, Roger Riggs wrote:
> > > > Hi,
> > > >
> > > > A few higher level issues should be considered, though the details
> > > > of the webrev captured my immediate attention.
> > > >
> > > > Is this the right feature and is this the right level of implementation
> > > > (C++/native)?
> > > > :
> > > > How much of this can be done in Java code with StackWalker and other
> > > > java APIs?
> > > > It would be a shame to add this much native code if there was a more
> > > robust
> > > > way to implement it using APIs with more leverage.
> > >
> > > Improving the NPE message for better diagnosability is helpful while
> > > I share the same concern Roger raised.
> > >
> > > Implementing this feature in Java and the library would be a better
> > > choice as this isn't absolutely required to be done in VM in native.
> > >
> > > NPE keeps a backtrace capturing the method id and bci of each stack
> > > frame.  One option to explore is to have StackWalker to accept a
> > > Throwable object that returns a stream of StackFrame which allows
> > > you to get the method and BCI and also code source (I started a
> > > prototype for JDK-8189752 some time ago).  It can use the bytecode
> > > library e.g. ASM to read the bytecode.  For NPE message, you can
> > > implement a specialized StackFrameTraverser just for building
> > > an exception message purpose.
> > >
> > > Mandy


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-04-03 Thread Lindenmaier, Goetz
Hi Maurizio, 

I put your java PoC into a webrev, and added some tests:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/06-java-Maurizio/

Please have a look at NullPointerExceptionTestMini4.java.
It is failing, as the class does not reside in a file. 
Do you have an idea how to fix this?

Further, I extended the implementation to cover all necessary bytecodes.
I had hoped it would print a message on each test case in 
NullPointerExceptionTest.
But it seems to lose track of the byte code index at some point
if the method gets bigger.
I have an idea how to fix this, though, so I'm not concerned about 
that.

I'm currently looking at how to identify hidden frames...

Best regards,
  Goetz.

> -Original Message-
> From: Maurizio Cimadamore 
> Sent: Freitag, 15. März 2019 12:33
> To: Lindenmaier, Goetz ; Mandy Chung
> ; Roger Riggs 
> Cc: Java Core Libs ; hotspot-runtime-
> d...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> please find the attached ASM-based patch. It is just a PoC, as such it
> does not provide as fine-grained messages as the one discussed in the
> RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe.
> 
> When running this:
> 
> Object o = null;
> o.toString();
> 
> you get:
> 
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when calling method 'toString'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)
> 
> While when running this:
> 
> Foo foo = null;
> int y = foo.x;
> 
> You get this:
> 
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when accessing field 'x'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)
> 
> One problem I had is that ASM provides no way to get the instruction
> given a program counter - which means we have to scan all the bytecodes
> and update the sizes as we go along, and, ASM unfortunately doesn’t
> expose opcode sizes either. A more robust solution would be to have a
> big switch which returned the opcode size of any given opcode. Also,
> accessing to StackWalker API on exception creation might not be
> desirable in terms of performances, so this might be one of these area
> where some VM help could be beneficial. Another problem is that we
> cannot distinguish between user-generated exceptions (e.g. `throw new
> NullPointerException`) and genuine NPE issued by the VM.
> 
> But I guess the upshot is that it works to leave all the gory detail of
> bytecode grovelling to a bytecode API - if the logic is applied lazily,
> then the impact on performances should be minimal, and the solution more
> maintainable longer term.
> 
> Cheers
> Maurizio
> 
> On 15/03/2019 07:59, Lindenmaier, Goetz wrote:
> > Yes, it would be nice if you shared that.


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-04-01 Thread Lindenmaier, Goetz
Hi Peter, 

> -Original Message-
> From: Peter Levart 
> Sent: Freitag, 29. März 2019 16:44
> To: Lindenmaier, Goetz ; 'Mandy Chung'
> 
> Cc: core-libs-dev@openjdk.java.net; maurizio.cimadam...@oracle.com;
> hotspot-runtime-...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> 
> 
> On 3/29/19 4:36 PM, Peter Levart wrote:
> >
> >
> > On 3/29/19 8:49 AM, Lindenmaier, Goetz wrote:
> >> So I want to withdraw my claim that NPEs are thrown frequently.
> >> Probably I was biased by my compiler construction background,
> >> remembering NPE checks are all over the place in the code.
> >>
> >> But I think I can still keep the claim that the message is
> >> printed rarely.
> >>
> >> I'll adapt the JEP saying something like this:
> >> "While exceptions are supposed to be thrown rarely, i.e., only
> >> In exceptional situations, most are swallowed without ever
> >> looking at the message. Thus, overhead in getMessage() will
> >> not fall into account."
> >
> > Is this really a realistic assumption? That NPE exceptions are mostly
> > swallowed in most programs despite the fact that swallowing exceptions
> > (and throwing them to control the flow) is an anti-pattern? Is
> > majority of code really so badly written? I would expect that most
> > programs contain an exception handler of some kind that at least logs
> > all unexpected exceptions.
> >
> > I think JDK should assume that NPEs are not frequent in most well
> > written programs. Because in well written programs all unexpected
> > exceptions are at least logged somewhere and this alone guarantees
> > that programs are eventually "fixed" to not throw them frequently...
> >
> > Regards, Peter
> 
> So I would say that there are two kinds of programs (which kind is in
> majority doesn't matter):
> 
> a - programs that throw and catch exceptions for exceptional situations
> only (i.e. non frequently) - they also print the exceptions' messages
> b - programs that throw and swallow exceptions frequently, but they
> mostly don't print their messages
> 
> In either case .getMessage() is not called frequently for kind (a) and
> hopefully also for kind (b).
> 
> Regards, Peter
Hi,

I agree with this, and my numbers show
that the message is not printed frequently in any case.

Best regards,
  Goetz.



Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-29 Thread Peter Levart




On 3/29/19 4:36 PM, Peter Levart wrote:



On 3/29/19 8:49 AM, Lindenmaier, Goetz wrote:

So I want to withdraw my claim that NPEs are thrown frequently.
Probably I was biased by my compiler construction background,
remembering NPE checks are all over the place in the code.

But I think I can still keep the claim that the message is
printed rarely.

I'll adapt the JEP saying something like this:
"While exceptions are supposed to be thrown rarely, i.e., only
In exceptional situations, most are swallowed without ever
looking at the message. Thus, overhead in getMessage() will
not fall into account."


Is this really a realistic assumption? That NPE exceptions are mostly 
swallowed in most programs despite the fact that swallowing exceptions 
(and throwing them to control the flow) is an anti-pattern? Is 
majority of code really so badly written? I would expect that most 
programs contain an exception handler of some kind that at least logs 
all unexpected exceptions.


I think JDK should assume that NPEs are not frequent in most well 
written programs. Because in well written programs all unexpected 
exceptions are at least logged somewhere and this alone guarantees 
that programs are eventually "fixed" to not throw them frequently...


Regards, Peter


So I would say that there are two kinds of programs (which kind is in 
majority doesn't matter):


a - programs that throw and catch exceptions for exceptional situations 
only (i.e. non frequently) - they also print the exceptions' messages
b - programs that throw and swallow exceptions frequently, but they 
mostly don't print their messages


In either case .getMessage() is not called frequently for kind (a) and 
hopefully also for kind (b).


Regards, Peter



Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-29 Thread Peter Levart




On 3/29/19 8:49 AM, Lindenmaier, Goetz wrote:

So I want to withdraw my claim that NPEs are thrown frequently.
Probably I was biased by my compiler construction background,
remembering NPE checks are all over the place in the code.

But I think I can still keep the claim that the message is
printed rarely.

I'll adapt the JEP saying something like this:
"While exceptions are supposed to be thrown rarely, i.e., only
In exceptional situations, most are swallowed without ever
looking at the message. Thus, overhead in getMessage() will
not fall into account."


Is this really a realistic assumption? That NPE exceptions are mostly 
swallowed in most programs despite the fact that swallowing exceptions 
(and throwing them to control the flow) is an anti-pattern? Is majority 
of code really so badly written? I would expect that most programs 
contain an exception handler of some kind that at least logs all 
unexpected exceptions.


I think JDK should assume that NPEs are not frequent in most well 
written programs. Because in well written programs all unexpected 
exceptions are at least logged somewhere and this alone guarantees that 
programs are eventually "fixed" to not throw them frequently...


Regards, Peter



Best regards,
   Goetz.




RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-29 Thread Lindenmaier, Goetz
Hi Mandy,

I could access the JBS now, so part 2 of my reply.

Yesterday, I added tables to the JEP describing what is printed
for which bytecode.   If this is too verbose for the JEP, it might
be nice in the bug implementing it.

> > This is a design decision not to make the printout too complex.
> This is fine.   The JEP should call this out.
I added this to the table entry for invokes.

> > The algorithm looks at a lot of bytecodes to print the method. I can not 
> > enumerate all combinations of bytecodes, it's millions. I will add a 
> > per-bytecode table to 
> > the "Message content" section describing what is printed for which bytecode.
> This is not what I am suggesting to do.
> The JEP can describe the known cases or pattern (if enumerating these cases 
> is not possible) 
> to help the readers understand the proposed feature and what is not covered.
I added the tables to describe this before I got your mail, see above. 

Best regards,
  Goetz.




RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-29 Thread Lindenmaier, Goetz
Hi Mandy,

The JBS is offline, so I'll just reply on this item for now:

> > > Since the JEP quotes that NullPointerExceptions are thrown frequently
> > > and swallowed, it would help if you can generate some numbers.
> > > This JEP will help the discussion on the proposed feature and design and 
> > > avoid
> > > any confusion/assumption of the implementation.
> > I'll generate some numbers.  Is running jvm2008 fine?
> A benchmark may not be a good representative.  I'd be interested in a real 
> application
> to support the claim.  

I ran the following applications:
  Jbb2005: 15 NPE raised
  Jvm2008: 5 NPE raised, only in 'check' benchmark
  SAP application: 16138 NPE raised.
None of these called NPE.getMessage().

This SAP application is known to us for bad NPE behavior 
and runs a few hours. It's from our GC stress tests.
I think 16000 is still a small number given the runtime of
the test.

So I want to withdraw my claim that NPEs are thrown frequently.
Probably I was biased by my compiler construction background,
remembering NPE checks are all over the place in the code.

But I think I can still keep the claim that the message is
printed rarely.

I'll adapt the JEP saying something like this:
"While exceptions are supposed to be thrown rarely, i.e., only
In exceptional situations, most are swallowed without ever
looking at the message. Thus, overhead in getMessage() will
not fall into account."

Best regards,
  Goetz.




Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-28 Thread Mandy Chung




On 3/27/19 7:18 AM, Lindenmaier, Goetz wrote:

, is this example very clear to them that it won't be supported?


You probably meant that for
   n().getNull().m()
it is not printed that getNull() was called on the result of n()?


Yes, I caught my error after I sent my example.

This is a design decision not to make the printout too complex.
  


This is fine.   The JEP should call this out.



The algorithm looks at a lot of bytecodes to print the method. I can not
enumerate all combinations of bytecodes, it's millions. I will add a 
per-bytecode table to
the "Message content" section describing what is printed for which bytecode.


This is not what I am suggesting to do.

The JEP can describe the known cases or pattern (if enumerating these 
cases is not possible) to help the readers understand the proposed 
feature and what is not covered.

This paragraph lists a possible problem -- multiple variants of methods
with the same name and class name -- and how this is solved.
I added a section "Cases not covered by this JEP" and mention it there, too.


Sounds good.

Since the JEP quotes that NullPointerExceptions are thrown frequently
and swallowed, it would help if you can generate some numbers.
This JEP will help the discussion on the proposed feature and design and avoid
any
confusion/assumption of the implementation.

I'll generate some numbers.  Is running jvm2008 fine?


A benchmark may not be a good representative.  I'd be interested in a 
real application

to support the claim.

OTOH, we are in agreement that this change should not incur any 
significant overhead to the construction cost of throwable.  I asked the 
data because of the claim of many NPE thrown get swallowed.



Mandy


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-27 Thread Lindenmaier, Goetz
Hi Mandy,

>and also the cases when it requires to look at its caller 
> frame.
> 
>   Never.  Only the method that was executed when the exception is
>   thrown is needed. I only mention the backtrace because it happens to
>   store the top method and the corresponding bytecode position in the
>   top method.
> 
> 
> That explains why I don't see an example of:
>  getNull().m();
> 
>  public void m() {};
> 
>  static NPE getNull() {
>  return null;
>  }
> 
> For a compiler expert or one who study the data flow analysis paper
Yes, I think compiler people should understand this.

> , is this example very clear to them that it won't be supported?
The example for your code is supported, see[1], examples 11-14. (I should 
enumerate them)
For your code, it will print
"The return value of 'MyClass.getNULL()LNPE;' is null. Can not invoke method 
'MyOtherClass.m()V'".

getNull().m() are not nested calls, but subsequent ones. Therefore you will not 
find
them on the call stack.
The byte code index of the invoke bytecode invoking m() is known from the 
backtrace or
StackWalker/StackFrame.  Looking at the bytecode the part "Can not invoke 
method 'MyOtherClass.m()V"
is printed.
With the result of the data flow analysis it is possible to find the bytecode 
that produced
the reference on which m() is invoked.  This is another invoke bytecode in the 
method.
Looking at this other bytecode, " The return value of 'MyClass.getNULL()LNPE;' 
is null." 
is printed.

You probably meant that for 
  n().getNull().m()
it is not printed that getNull() was called on the result of n()?
This is a design decision not to make the printout too complex.
 
> This is related to my comment w.r.t. the data flow analysis comes from.  I was
> looking for some level of information be spelled out in the JEP that can
> sufficiently give a non-compiler expert an idea but of course no point to
> replicate the paper here.
"The simulated stack" ... contains ..."information about which bytecode pushed 
the value to the stack."
That's all.

> It's good to know that this proposal needs the top frame only.   Please make 
> it
> clear in the JEP.   
I tried to point out more precisely why and when I need the top frame. I 
pushed this down a bit in the text in "basic algorithm".

> The JEP can take out `StackWalker` but instead talks about
> `StackFrame` since doing it in Java means that it only needs to get back a 
> `StackFrame`
> instance representing the top frame stored in `Throwable::backtrace`
Yes. I tried to make the text more precise.

> This will avoid the confusion on calling StackWalker in the NPE constructor 
> and
> constructing many StackFrame and many ResolvedMethodName.  That was
> part of the code review discussion.
Yes, only the top StackFrame is needed.

>   "Computing either part of these messages can fail due to
> insufficient
>   information."
>   What are the cases that it fails to obtain the information? It'd
> be useful
>   to list some examples if not all.
> 
>   (a ? b : c).d
>   You can not know whether the ?-expression yielded b or c, thus
>   you don't know why the access .d failed.  There is a corresponding
> example
>   in [1].
> 
> 
> Please describe in the JEP the known cases that this proposal doesn't cover.
> Conditional expression is one and 

The algorithm looks at a lot of bytecodes to print the method. I can not 
enumerate all combinations of bytecodes, it's millions. I will add a 
per-bytecode table to 
the "Message content" section describing what is printed for which bytecode.

>null receiver if it's the return value from a caller frame (I think this would 
>help the readers).
... this is supported, see above.

>   The "Different bytecode variants of a method" section
> 
>   This section raises the case when a method representing an
> execution stack
>   frame throwing NPE becomes obsolete, it does not have the
> information
>   to compute the message lazily.  So this falls into the
> "insufficient
>   information" category and no improved NPE message can be
> generated.
> 
>   Yes, note this also only addresses the method in which the exception
> was raised.
> 
> This should also go to the list of known cases that this proposal does not 
> cover.

This paragraph lists a possible problem -- multiple variants of methods
with the same name and class name -- and how this is solved. 
I added a section "Cases not covered by this JEP" and mention it there, too.

> Since the JEP quotes that NullPointerExceptions are thrown frequently
> and swallowed, it would help if you can generate some numbers.
> This JEP will help the discussion on the proposed feature and design and avoid
> any
> confusion/assumption of the implementation.
I'll generate some numbers.  Is running jvm2008 fine?

> I think this is related to this JEP.The question 

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-26 Thread Mandy Chung




On 3/26/19 4:57 AM, Lindenmaier, Goetz wrote:

  and also the cases when it requires to look at its caller frame.

Never.  Only the method that was executed when the exception is
thrown is needed. I only mention the backtrace because it happens to
store the top method and the corresponding bytecode position in the
top method.


That explains why I don't see an example of:
 getNull().m();

 public void m() {};

 static NPE getNull() {
 return null;
 }

For a compiler expert or one who study the data flow analysis paper, is 
this example very clear to them that it won't be supported?


This is related to my comment w.r.t. the data flow analysis comes from.  
I was looking for some level of information be spelled out in the JEP 
that can sufficiently give a non-compiler expert an idea but of course 
no point to replicate the paper here.


It's good to know that this proposal needs the top frame only. Please 
make it clear in
the JEP.    The JEP can take out `StackWalker` but instead talks about 
`StackFrame`
since doing it in Java means that it only needs to get back a 
`StackFrame` instance

representing the top frame stored in `Throwable::backtrace`

This will avoid the confusion on calling StackWalker in the NPE 
constructor and

constructing many StackFrame and many ResolvedMethodName.  That was part
of the code review discussion.
  

"Computing either part of these messages can fail due to insufficient
information."
What are the cases that it fails to obtain the information? It'd be useful
to list some examples if not all.

(a ? b : c).d
You can not know whether the ?-expression yielded b or c, thus
you don't know why the access .d failed.  There is a corresponding example
in [1].


Please describe in the JEP the known cases that this proposal doesn't 
cover.   Conditional expression is one and null receiver if it's the 
return value from a caller frame (I think this would help the readers).

The "Different bytecode variants of a method" section

This section raises the case when a method representing an execution stack
frame throwing NPE becomes obsolete, it does not have the information
to compute the message lazily.  So this falls into the "insufficient
information" category and no improved NPE message can be generated.

Yes, note this also only addresses the method in which the exception was raised.


This should also go to the list of known cases that this proposal does 
not cover.

The "computation overhead" section

I agree with the requirement to have minimal performance overhead to
the NPE construction cost.

"NullPointerExceptions are thrown frequently."
"Fortunately, most Exceptions are discarded without looking at the message."

This is interesting.  Do you have any statistic on the number of NPE thrown
and swallowed on certain application/environment that you have gathered?

No, I can try to generate some numbers, though.  But this assumption was made by
several others that commented on the previous review thread. For Throwable
in general, it is also the assumption why the intermediate backtrace data
structure is implemented instead of generating the stackFrames right away.


Since the JEP quotes that NullPointerExceptions are thrown frequently
and swallowed, it would help if you can generate some numbers.

This JEP will help the discussion on the proposed feature and design and 
avoid any

confusion/assumption of the implementation.


"If the message is printed based on the backtrace, it must be omitted
  if the top frame was dropped from the backtrace."

If NPE includes the hidden frames, `Throwable::getStackTrace` and
`Throwable::toString` and the VM printing of NPE stack trace needs to
filter the hidden frames.  I think it's appropriate for this JEP to
cover rather than in a separate JBS issue.

Hmm, I don't completely understand what you want to say, please
excuse, I'm a foreign speaker :). I'll give a comprehensive answer:
To my understanding this is a consequence of the existing JVM/class file
implementation that calls methods that should be hidden to the user.
The implementation drops these frames when the backtrace datastructure
is computed. If this happens, the information needed to compute the
message is lost, and it can not be printed.


Yes I am familiar with that.

The fact that this happened must be remembered in the VM
so that printing the message can be suppressed. Else a message for
a completely wrong bytecode is printed.


Yup.

I think the JEP should mention that this is happening.  How this is
implemented and then pushed to the repo is not subject to a JEP,
is it?


I think this is related to this JEP.    The question would be:
- should it include all hidden frames?
- should it include the top frame if it's a hidden frame since this 
feature only requires the top frame?


This JEP requires the hidden frame to be recorded in the backtrace. This 
has

impact to the printing of stack trace that needs to know about hidden frames
and decide if it 

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-26 Thread Lindenmaier, Goetz
Hi Mandy, 

thanks for reading the JEP and giving detailed feedback!

> In the "Basic algorithm to compute the message" section:
> 
> "This dataflow analysis walks the bytecodes forward simulating the execution
> stack."
> 
> Please elaborate it.  Given a stack trace, it starts with the most recently
> executed method and bytecode index, I assume it simulates the method from
> the beginning of the method until it hits the instruction with the matching 
> BCI.
> Please describe it
A data flow analysis is a fixpoint iteration on the code. It is a  
basic concept of compiler construction and used in lots of places in 
the hotspot code. I don't think I should further give an explanation
of this. Maybe I could point to Wikipedia? 
https://en.wikipedia.org/wiki/Data-flow_analysis

>  and also the cases when it requires to look at its caller frame.
Never.  Only the method that was executed when the exception is 
thrown is needed. I only mention the backtrace because it happens to 
store the top method and the corresponding bytecode position in the 
top method.

I tried to make this more clear by changing the formulation of the first
two paragraphs.
 
> "Computing either part of these messages can fail due to insufficient
> information."
> What are the cases that it fails to obtain the information? It'd be useful
> to list some examples if not all.
(a ? b : c).d
You can not know whether the ?-expression yielded b or c, thus
you don't know why the access .d failed.  There is a corresponding example 
in [1]. 

> 
> The "Different bytecode variants of a method" section
> 
> This section raises the case when a method representing an execution stack
> frame throwing NPE becomes obsolete, it does not have the information
> to compute the message lazily.  So this falls into the "insufficient
> information" category and no improved NPE message can be generated.
Yes, note this also only addresses the method in which the exception was raised.

> The "computation overhead" section
> 
> I agree with the requirement to have minimal performance overhead to
> the NPE construction cost.
> 
> "NullPointerExceptions are thrown frequently."
> "Fortunately, most Exceptions are discarded without looking at the message."
> 
> This is interesting.  Do you have any statistic on the number of NPE thrown
> and swallowed on certain application/environment that you have gathered?
No, I can try to generate some numbers, though.  But this assumption was made 
by 
several others that commented on the previous review thread. For Throwable
in general, it is also the assumption why the intermediate backtrace data
structure is implemented instead of generating the stackFrames right away.

> "If the message is printed based on the backtrace, it must be omitted
>  if the top frame was dropped from the backtrace."
> 
> If NPE includes the hidden frames, `Throwable::getStackTrace` and
> `Throwable::toString` and the VM printing of NPE stack trace needs to
> filter the hidden frames.  I think it's appropriate for this JEP to
> cover rather than in a separate JBS issue.
Hmm, I don't completely understand what you want to say, please
excuse, I'm a foreign speaker :). I'll give a comprehensive answer:
To my understanding this is a consequence of the existing JVM/class file
implementation that calls methods that should be hidden to the user.
The implementation drops these frames when the backtrace datastructure
is computed. If this happens, the information needed to compute the 
message is lost, and it can not be printed.
The fact that this happened must be remembered in the VM
so that printing the message can be suppressed. Else a message for
a completely wrong bytecode is printed.
I think the JEP should mention that this is happening.  How this is 
implemented and then pushed to the repo is not subject to a JEP,
is it?
I made a webrev of its own for this problem, so that the code
can be looked at isolated of other, orthogonal issues.
http://cr.openjdk.java.net/~goetz/wr19/8221077-hidden_to_frame/

> The "Message persistance" section
> 
> I read this section like an implementation details
 Yes, I had the feeling that I was talking too much about implementation 
details, 
but mostly in the "Basic algorithm" section. 
This section discusses characteristics of NPE that differ from other exceptions
and that were proposed in the course of the review of my 
original webrev. They are visible to the Java implementor. 
So I think this is just the basic information needed in a JEP.

> I think this section
> intends to call out that the message of NPE if constructed by user code
> i.e. via public constructor, should not be altered including no-arg
> constructor or pass a null message to 1-arg constructor.  The enhanced
> NPE message is proposed only when NPE is thrown due to null dereference
> when executing bytecode.
Yes.
 
> I don't understand what you tried to say about "npe.getMessage() ==
> npe.getMessage()".
> Throwable::getMessage does not guarantee to return 

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-25 Thread Mandy Chung

Hi Goetz,

On 3/15/19 3:55 AM, Lindenmaier, Goetz wrote:

I followed your advice and created a JEP:
https://bugs.openjdk.java.net/browse/JDK-8220715


This is a good start.   I include my comments as a reader who does not
read TrackingStackCreator and other C++ code.

In the "Basic algorithm to compute the message" section:

"This dataflow analysis walks the bytecodes forward simulating the 
execution stack."


Please elaborate it.  Given a stack trace, it starts with the most recently
executed method and bytecode index, I assume it simulates the method from
the beginning of the method until it hits the instruction with the 
matching BCI.
Please describe it and also the cases when it requires to look at its 
caller frame.


"Computing either part of these messages can fail due to insufficient 
information."


What are the cases that it fails to obtain the information? It'd be useful
to list some examples if not all.

The "Different bytecode variants of a method" section

This section raises the case when a method representing an execution stack
frame throwing NPE becomes obsolete, it does not have the information
to compute the message lazily.  So this falls into the "insufficient
information" category and no improved NPE message can be generated.

The "computation overhead" section

I agree with the requirement to have minimal performance overhead to
the NPE construction cost.

"NullPointerExceptions are thrown frequently."
"Fortunately, most Exceptions are discarded without looking at the message."

This is interesting.  Do you have any statistic on the number of NPE thrown
and swallowed on certain application/environment that you have gathered?

"If the message is printed based on the backtrace, it must be omitted
 if the top frame was dropped from the backtrace."

If NPE includes the hidden frames, `Throwable::getStackTrace` and
`Throwable::toString` and the VM printing of NPE stack trace needs to
filter the hidden frames.  I think it's appropriate for this JEP to
cover rather than in a separate JBS issue.

The "Message persistance" section

I read this section like an implementation details.  I think this section
intends to call out that the message of NPE if constructed by user code
i.e. via public constructor, should not be altered including no-arg
constructor or pass a null message to 1-arg constructor.  The enhanced
NPE message is proposed only when NPE is thrown due to null dereference
when executing bytecode.

I don't understand what you tried to say about "npe.getMessage() == 
npe.getMessage()".

Throwable::getMessage does not guarantee to return same String object for
each invocation.

When deserializing the class bytes may be of a different version, so 
StackTraceElements
are serialized with its string form.  Serializing NPE with a computed 
message

seems to be the only viable solution.

The "Message content" section

I think this section can break down into clear scenarios
1. debug information is present
2. debug information is absent
3. the matching version of bytecode is not available

I agree that the message should be easy for Java developers including the
beginners to understand the error.

You bring up a good question about the exception message format e.g. 
whether with
quotation (none vs single quote vs double quote).  It's good to have a 
guideline

on that while this is out of scope of this JEP.  IAE was updated to include
module name, loader name and improve the error message for the developers
to understand the exception which is a good improvement.

"Alternatives" section

"The current proposal is to implement this in the Java runtime in C++ 
accessing

 directly the available datastructures in the metaspace."

"Also, ASM and StackWalker do not support the full functionality needed.
StackWalker must be called in the NullPointerException constructor."

This is not true as you wrote in the subsequent sentence.  If we choose
the implementation to Java, StackWalker will need to be extended to
read Throwable's backtrace.  Such specialized form can provide the
ability to fetch the bytecode in Method* if appropriate.  This is
the implementation details.  As discussed in the email thread, another
implementation choice could be a hybrid of native in the VM and Java
to accomplish this task (for example fetching the bytecode of the
current version could be done in the VM if we agree supporting
the redefinition case).

For logic that is not strictly needed to be done in the VM, doing it
in Java and library is a good option to consider (putting aside the
amount of new code you have to write).   Looks like you can't evaluate
the alternatives since existing library code requires work in order to
prototype this in Java.  So I'd say more investigation needs to be done
to decide on alternative implementation approaches.

"Testing" section

"The basic implementation is in use in SAP's internal Java virtual 
machine since 2006."


This is good information.  This assumes if the same 

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-20 Thread Mandy Chung




On 3/20/19 1:54 AM, Lindenmaier, Goetz wrote:

Should I move the JEP to status 'submitted'?


Per the Process states section  [1]

Draft --- In circulation by the author for initial review and 
consensus-building


I certainly don't want to be the bottleneck.   Others can help do the 
initial review.


Mandy
[1] http://openjdk.java.net/jeps/1#Process-states


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-20 Thread Lindenmaier, Goetz
Hi Mandy,

> Sorry I have been busy on other time-critical things.  I will
> get to it hopefully next week.
No problem, I have been improving the text slightly
anyways.
I also pushed my change and a follow up needed to the sandbox 
repos so it can be played with.

Should I move the JEP to status 'submitted'?

Best regards,
  Goetz




> 
> Mandy
> 
> On 3/15/19 3:55 AM, Lindenmaier, Goetz wrote:
> > Hi everybody, Mark,
> >
> > I followed your advice and created a JEP:
> > https://bugs.openjdk.java.net/browse/JDK-8220715
> >
> > Please point me to things I need to improve formally, this is my first
> > JEP. Also feel free to fix the administrative information in the
> > Jira issue if it is wrong.
> >
> > And, naturally, you're welcome to discuss the topic!
> >
> > Best regards,
> >Goetz.
> >
> >> -Original Message-
> >> From: mark.reinh...@oracle.com 
> >> Sent: Donnerstag, 14. März 2019 22:38
> >> To: maurizio.cimadam...@oracle.com; Lindenmaier, Goetz
> >> 
> >> Cc: mandy.ch...@oracle.com; roger.ri...@oracle.com; core-libs-
> >> d...@openjdk.java.net; hotspot-runtime-...@openjdk.java.net
> >> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> >> describing what is null.
> >>
> >> 2019/3/14 8:00:20 -0700, maurizio.cimadam...@oracle.com:
> >>> I second what Mandy says.
> >>>
> >>> First let me start by saying that this enhancement will be a great
> >>> addition to our platform; back in the days when I was teaching some Java
> >>> classes at the university, I was very aware of how hard it is to
> >>> diagnose a NPE for someone novel to Java programming.
> >>
> >> Agreed!
> >>
> >>> ...
> >>>
> >>> I also think that the design space for such an enhancement is non
> >>> trivial, and would best be explored (and captured!) in a medium that is
> >>> something other than a patch. ...
> >>
> >> Agreed, also.
> >>
> >> Goetz -- if, per Mandy’s suggestion, you’re going to write something
> >> up using the JEP template, might I suggest that you then submit it as
> >> an actual JEP?  Giving visibility to, and recording, such design-space
> >> explorations is one of the primary goals of the JEP process.
> >>
> >> - Mark


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-19 Thread Mandy Chung

Hi Goetz,

Sorry I have been busy on other time-critical things.  I will
get to it hopefully next week.

Mandy

On 3/15/19 3:55 AM, Lindenmaier, Goetz wrote:

Hi everybody, Mark,

I followed your advice and created a JEP:
https://bugs.openjdk.java.net/browse/JDK-8220715

Please point me to things I need to improve formally, this is my first
JEP. Also feel free to fix the administrative information in the
Jira issue if it is wrong.

And, naturally, you're welcome to discuss the topic!

Best regards,
   Goetz.


-Original Message-
From: mark.reinh...@oracle.com 
Sent: Donnerstag, 14. März 2019 22:38
To: maurizio.cimadam...@oracle.com; Lindenmaier, Goetz

Cc: mandy.ch...@oracle.com; roger.ri...@oracle.com; core-libs-
d...@openjdk.java.net; hotspot-runtime-...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
describing what is null.

2019/3/14 8:00:20 -0700, maurizio.cimadam...@oracle.com:

I second what Mandy says.

First let me start by saying that this enhancement will be a great
addition to our platform; back in the days when I was teaching some Java
classes at the university, I was very aware of how hard it is to
diagnose a NPE for someone novel to Java programming.


Agreed!


...

I also think that the design space for such an enhancement is non
trivial, and would best be explored (and captured!) in a medium that is
something other than a patch. ...


Agreed, also.

Goetz -- if, per Mandy’s suggestion, you’re going to write something
up using the JEP template, might I suggest that you then submit it as
an actual JEP?  Giving visibility to, and recording, such design-space
explorations is one of the primary goals of the JEP process.

- Mark


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-18 Thread Lindenmaier, Goetz
Hi Mandy,

> ... This brings up one
> issue that when constructing the enhanced NPE message, a method
> might become obsolete due to redefintion, it should handle
> gracefully.
The C++ solution has access to the proper version of redefined codes,
so this is no problem.  It is attached to the backtrace.
And yes, in the Java variant we could just skip the message if we don't 
have the proper variant of the bytecode at hand. But we need 
a way to find out that this is the case.  It's unclear to me how this 
should work ... it also depends on the way we retrieve the bytecodes
to analyze.

Best regards,
  Goetz.



> Mandy
> 
> On 3/15/19 10:34 AM, Maurizio Cimadamore wrote:
> > You touch an important point here - who is this feature for? Is it for
> > the casual developer in need of some hand holding? Or is it for
> > diagnosing complex instrumented stacks? I think the two use cases are
> > not necessarily similar and might be served by different sets of
> > enhancements. In the latter case it might be ok, for instance, to say
> > "and, btw, the NPE came from local[1]". But for users in the former
> > bucket (and most users, really), this level of detail will simply be
> > unacceptable (since now they have to understand the JVMS to parse the
> > message :-)).
> >
> > I suggest we separate the use cases, at least for the purpose of the
> > design discussion.
> >
> > Maurizio
> >
> > On 15/03/2019 13:11, Lindenmaier, Goetz wrote:
> >> Hi Maurizio,
> >>
> >> thanks for sharing your patch!  This is about what I thought about
> >> so far, just that it's working already :)
> >>
> >> It prints the information of the failing bytecode.  Adding the dataflow
> >> analysis, the other information could be printed as well.
> >>
> >> The major problem I see is here:
> >> +    File f = new File(location.getFile(),
> >> +    clazz.getCanonicalName().replaceAll("\\.", "/") +
> >> ".class");
> >> +    ClassReader cr = new ClassReader(new FileInputStream(f));
> >> +    ClassNode classNode = new ClassNode();
> >> +    cr.accept(classNode, 0);
> >>
> >> As I understand, this reads the Bytecode from the classfile.
> >> The bytecode in the classfile must not match that executed
> >> by the VM, i.e, the pc you get from the stackWalker will not
> >> reference the bytecode that caused the NPE.
> >>
> >> Other issues have been discussed in the mail thread before.
> >> Good that you point this out, I'll add it to the JEP.
> >>
> >> Best regards,
> >>    Goetz
> >>
> >> ... Sorry, I missed the "reply all" on my first reply.
> >>
> >>
> >>
> >>
> >>> -Original Message-
> >>> From: Maurizio Cimadamore 
> >>> Sent: Freitag, 15. März 2019 12:33
> >>> To: Lindenmaier, Goetz ; Mandy Chung
> >>> ; Roger Riggs 
> >>> Cc: Java Core Libs ; hotspot-runtime-
> >>> d...@openjdk.java.net
> >>> Subject: Re: RFR(L): 8218628: Add detailed message to
> >>> NullPointerException
> >>> describing what is null.
> >>>
> >>> Hi Goetz,
> >>> please find the attached ASM-based patch. It is just a PoC, as such it
> >>> does not provide as fine-grained messages as the one discussed in the
> >>> RFE/JEP, but can be enhanced to cover custom debugging attribute, I
> >>> believe.
> >>>
> >>> When running this:
> >>>
> >>> Object o = null;
> >>> o.toString();
> >>>
> >>> you get:
> >>>
> >>> Exception in thread "main" java.lang.NullPointerException: attempt to
> >>> dereference 'null' when calling method 'toString'
> >>>       at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)
> >>>
> >>> While when running this:
> >>>
> >>> Foo foo = null;
> >>> int y = foo.x;
> >>>
> >>> You get this:
> >>>
> >>> Exception in thread "main" java.lang.NullPointerException: attempt to
> >>> dereference 'null' when accessing field 'x'
> >>>       at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)
> >>>
> >>> One problem I had is that ASM provides no way to get the instruction
> >>> given a program counter - which means we have to scan all the bytecodes
> >>> an

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-18 Thread Lindenmaier, Goetz
Hi,

> You touch an important point here - who is this feature for? Is it for
> the casual developer in need of some hand holding? Or is it for
> diagnosing complex instrumented stacks? I think the two use cases are
> not necessarily similar and might be served by different sets of
> enhancements.
Do you propose to have two different messages, to be selected by some 
flag or the like?
To my knowledge exceptions have only one message, and it should
be as helpful as possible I think.

>  In the latter case it might be ok, for instance, to say
> "and, btw, the NPE came from local[1]". But for users in the former
> bucket (and most users, really), this level of detail will simply be
> unacceptable 

>(since now they have to understand the JVMS to parse the
> message :-)).
Can you please elaborate why they have to understand the JVMS?

And why would information you don't need be unacceptable?
You can just ignore it ... 

Best regards,
  Goetz.
 
> I suggest we separate the use cases, at least for the purpose of the
> design discussion.
> 
> Maurizio
> 
> On 15/03/2019 13:11, Lindenmaier, Goetz wrote:
> > Hi Maurizio,
> >
> > thanks for sharing your patch!  This is about what I thought about
> > so far, just that it's working already :)
> >
> > It prints the information of the failing bytecode.  Adding the dataflow
> > analysis, the other information could be printed as well.
> >
> > The major problem I see is here:
> > +File f = new File(location.getFile(),
> > +clazz.getCanonicalName().replaceAll("\\.", "/") + 
> > ".class");
> > +ClassReader cr = new ClassReader(new FileInputStream(f));
> > +ClassNode classNode = new ClassNode();
> > +cr.accept(classNode, 0);
> >
> > As I understand, this reads the Bytecode from the classfile.
> > The bytecode in the classfile must not match that executed
> > by the VM, i.e, the pc you get from the stackWalker will not
> > reference the bytecode that caused the NPE.
> >
> > Other issues have been discussed in the mail thread before.
> > Good that you point this out, I'll add it to the JEP.
> >
> > Best regards,
> >Goetz
> >
> > ... Sorry, I missed the "reply all" on my first reply.
> >
> >
> >
> >
> >> -Original Message-----
> >> From: Maurizio Cimadamore 
> >> Sent: Freitag, 15. März 2019 12:33
> >> To: Lindenmaier, Goetz ; Mandy Chung
> >> ; Roger Riggs 
> >> Cc: Java Core Libs ; hotspot-runtime-
> >> d...@openjdk.java.net
> >> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> >> describing what is null.
> >>
> >> Hi Goetz,
> >> please find the attached ASM-based patch. It is just a PoC, as such it
> >> does not provide as fine-grained messages as the one discussed in the
> >> RFE/JEP, but can be enhanced to cover custom debugging attribute, I
> believe.
> >>
> >> When running this:
> >>
> >> Object o = null;
> >> o.toString();
> >>
> >> you get:
> >>
> >> Exception in thread "main" java.lang.NullPointerException: attempt to
> >> dereference 'null' when calling method 'toString'
> >>       at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)
> >>
> >> While when running this:
> >>
> >> Foo foo = null;
> >> int y = foo.x;
> >>
> >> You get this:
> >>
> >> Exception in thread "main" java.lang.NullPointerException: attempt to
> >> dereference 'null' when accessing field 'x'
> >>       at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)
> >>
> >> One problem I had is that ASM provides no way to get the instruction
> >> given a program counter - which means we have to scan all the bytecodes
> >> and update the sizes as we go along, and, ASM unfortunately doesn’t
> >> expose opcode sizes either. A more robust solution would be to have a
> >> big switch which returned the opcode size of any given opcode. Also,
> >> accessing to StackWalker API on exception creation might not be
> >> desirable in terms of performances, so this might be one of these area
> >> where some VM help could be beneficial. Another problem is that we
> >> cannot distinguish between user-generated exceptions (e.g. `throw new
> >> NullPointerException`) and genuine NPE issued by the VM.
> >>
> >> But I guess the upshot is that it works to leave all the gory detail of
> >> bytecode grovelling to a bytecode API - if the logic is applied lazily,
> >> then the impact on performances should be minimal, and the solution more
> >> maintainable longer term.
> >>
> >> Cheers
> >> Maurizio
> >>
> >> On 15/03/2019 07:59, Lindenmaier, Goetz wrote:
> >>> Yes, it would be nice if you shared that.


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Mandy Chung

That's a good suggestion.  The JDK out-of-the-box case and the
complex environment case with instrumentation agents transforming
the bytecodes are two different use cases.  This brings up one
issue that when constructing the enhanced NPE message, a method
might become obsolete due to redefintion, it should handle
gracefully.

Mandy

On 3/15/19 10:34 AM, Maurizio Cimadamore wrote:
You touch an important point here - who is this feature for? Is it for 
the casual developer in need of some hand holding? Or is it for 
diagnosing complex instrumented stacks? I think the two use cases are 
not necessarily similar and might be served by different sets of 
enhancements. In the latter case it might be ok, for instance, to say 
"and, btw, the NPE came from local[1]". But for users in the former 
bucket (and most users, really), this level of detail will simply be 
unacceptable (since now they have to understand the JVMS to parse the 
message :-)).


I suggest we separate the use cases, at least for the purpose of the 
design discussion.


Maurizio

On 15/03/2019 13:11, Lindenmaier, Goetz wrote:

Hi Maurizio,

thanks for sharing your patch!  This is about what I thought about
so far, just that it's working already :)

It prints the information of the failing bytecode.  Adding the dataflow
analysis, the other information could be printed as well.

The major problem I see is here:
+    File f = new File(location.getFile(),
+    clazz.getCanonicalName().replaceAll("\\.", "/") + 
".class");

+    ClassReader cr = new ClassReader(new FileInputStream(f));
+    ClassNode classNode = new ClassNode();
+    cr.accept(classNode, 0);

As I understand, this reads the Bytecode from the classfile.
The bytecode in the classfile must not match that executed
by the VM, i.e, the pc you get from the stackWalker will not
reference the bytecode that caused the NPE.

Other issues have been discussed in the mail thread before.
Good that you point this out, I'll add it to the JEP.

Best regards,
   Goetz

... Sorry, I missed the "reply all" on my first reply.





-Original Message-
From: Maurizio Cimadamore 
Sent: Freitag, 15. März 2019 12:33
To: Lindenmaier, Goetz ; Mandy Chung
; Roger Riggs 
Cc: Java Core Libs ; hotspot-runtime-
d...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to 
NullPointerException

describing what is null.

Hi Goetz,
please find the attached ASM-based patch. It is just a PoC, as such it
does not provide as fine-grained messages as the one discussed in the
RFE/JEP, but can be enhanced to cover custom debugging attribute, I 
believe.


When running this:

Object o = null;
o.toString();

you get:

Exception in thread "main" java.lang.NullPointerException: attempt to
dereference 'null' when calling method 'toString'
      at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)

While when running this:

Foo foo = null;
int y = foo.x;

You get this:

Exception in thread "main" java.lang.NullPointerException: attempt to
dereference 'null' when accessing field 'x'
      at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)

One problem I had is that ASM provides no way to get the instruction
given a program counter - which means we have to scan all the bytecodes
and update the sizes as we go along, and, ASM unfortunately doesn’t
expose opcode sizes either. A more robust solution would be to have a
big switch which returned the opcode size of any given opcode. Also,
accessing to StackWalker API on exception creation might not be
desirable in terms of performances, so this might be one of these area
where some VM help could be beneficial. Another problem is that we
cannot distinguish between user-generated exceptions (e.g. `throw new
NullPointerException`) and genuine NPE issued by the VM.

But I guess the upshot is that it works to leave all the gory detail of
bytecode grovelling to a bytecode API - if the logic is applied lazily,
then the impact on performances should be minimal, and the solution more
maintainable longer term.

Cheers
Maurizio

On 15/03/2019 07:59, Lindenmaier, Goetz wrote:

Yes, it would be nice if you shared that.


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Maurizio Cimadamore
You touch an important point here - who is this feature for? Is it for 
the casual developer in need of some hand holding? Or is it for 
diagnosing complex instrumented stacks? I think the two use cases are 
not necessarily similar and might be served by different sets of 
enhancements. In the latter case it might be ok, for instance, to say 
"and, btw, the NPE came from local[1]". But for users in the former 
bucket (and most users, really), this level of detail will simply be 
unacceptable (since now they have to understand the JVMS to parse the 
message :-)).


I suggest we separate the use cases, at least for the purpose of the 
design discussion.


Maurizio

On 15/03/2019 13:11, Lindenmaier, Goetz wrote:

Hi Maurizio,

thanks for sharing your patch!  This is about what I thought about
so far, just that it's working already :)

It prints the information of the failing bytecode.  Adding the dataflow
analysis, the other information could be printed as well.

The major problem I see is here:
+File f = new File(location.getFile(),
+clazz.getCanonicalName().replaceAll("\\.", "/") + 
".class");
+ClassReader cr = new ClassReader(new FileInputStream(f));
+ClassNode classNode = new ClassNode();
+cr.accept(classNode, 0);

As I understand, this reads the Bytecode from the classfile.
The bytecode in the classfile must not match that executed
by the VM, i.e, the pc you get from the stackWalker will not
reference the bytecode that caused the NPE.

Other issues have been discussed in the mail thread before.
Good that you point this out, I'll add it to the JEP.

Best regards,
   Goetz

... Sorry, I missed the "reply all" on my first reply.





-Original Message-
From: Maurizio Cimadamore 
Sent: Freitag, 15. März 2019 12:33
To: Lindenmaier, Goetz ; Mandy Chung
; Roger Riggs 
Cc: Java Core Libs ; hotspot-runtime-
d...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
describing what is null.

Hi Goetz,
please find the attached ASM-based patch. It is just a PoC, as such it
does not provide as fine-grained messages as the one discussed in the
RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe.

When running this:

Object o = null;
o.toString();

you get:

Exception in thread "main" java.lang.NullPointerException: attempt to
dereference 'null' when calling method 'toString'
      at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)

While when running this:

Foo foo = null;
int y = foo.x;

You get this:

Exception in thread "main" java.lang.NullPointerException: attempt to
dereference 'null' when accessing field 'x'
      at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)

One problem I had is that ASM provides no way to get the instruction
given a program counter - which means we have to scan all the bytecodes
and update the sizes as we go along, and, ASM unfortunately doesn’t
expose opcode sizes either. A more robust solution would be to have a
big switch which returned the opcode size of any given opcode. Also,
accessing to StackWalker API on exception creation might not be
desirable in terms of performances, so this might be one of these area
where some VM help could be beneficial. Another problem is that we
cannot distinguish between user-generated exceptions (e.g. `throw new
NullPointerException`) and genuine NPE issued by the VM.

But I guess the upshot is that it works to leave all the gory detail of
bytecode grovelling to a bytecode API - if the logic is applied lazily,
then the impact on performances should be minimal, and the solution more
maintainable longer term.

Cheers
Maurizio

On 15/03/2019 07:59, Lindenmaier, Goetz wrote:

Yes, it would be nice if you shared that.


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Lindenmaier, Goetz
Hi Maurizio,

thanks for sharing your patch!  This is about what I thought about
so far, just that it's working already :)

It prints the information of the failing bytecode.  Adding the dataflow
analysis, the other information could be printed as well.

The major problem I see is here:
+File f = new File(location.getFile(),
+clazz.getCanonicalName().replaceAll("\\.", "/") + 
".class");
+ClassReader cr = new ClassReader(new FileInputStream(f));
+ClassNode classNode = new ClassNode();
+cr.accept(classNode, 0);

As I understand, this reads the Bytecode from the classfile.
The bytecode in the classfile must not match that executed
by the VM, i.e, the pc you get from the stackWalker will not
reference the bytecode that caused the NPE.

Other issues have been discussed in the mail thread before.
Good that you point this out, I'll add it to the JEP.

Best regards,
  Goetz

... Sorry, I missed the "reply all" on my first reply.




> -Original Message-
> From: Maurizio Cimadamore 
> Sent: Freitag, 15. März 2019 12:33
> To: Lindenmaier, Goetz ; Mandy Chung
> ; Roger Riggs 
> Cc: Java Core Libs ; hotspot-runtime-
> d...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> please find the attached ASM-based patch. It is just a PoC, as such it
> does not provide as fine-grained messages as the one discussed in the
> RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe.
> 
> When running this:
> 
> Object o = null;
> o.toString();
> 
> you get:
> 
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when calling method 'toString'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)
> 
> While when running this:
> 
> Foo foo = null;
> int y = foo.x;
> 
> You get this:
> 
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when accessing field 'x'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)
> 
> One problem I had is that ASM provides no way to get the instruction
> given a program counter - which means we have to scan all the bytecodes
> and update the sizes as we go along, and, ASM unfortunately doesn’t
> expose opcode sizes either. A more robust solution would be to have a
> big switch which returned the opcode size of any given opcode. Also,
> accessing to StackWalker API on exception creation might not be
> desirable in terms of performances, so this might be one of these area
> where some VM help could be beneficial. Another problem is that we
> cannot distinguish between user-generated exceptions (e.g. `throw new
> NullPointerException`) and genuine NPE issued by the VM.
> 
> But I guess the upshot is that it works to leave all the gory detail of
> bytecode grovelling to a bytecode API - if the logic is applied lazily,
> then the impact on performances should be minimal, and the solution more
> maintainable longer term.
> 
> Cheers
> Maurizio
> 
> On 15/03/2019 07:59, Lindenmaier, Goetz wrote:
> > Yes, it would be nice if you shared that.


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Maurizio Cimadamore

Hi Goetz,
please find the attached ASM-based patch. It is just a PoC, as such it 
does not provide as fine-grained messages as the one discussed in the 
RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe.


When running this:

Object o = null;
o.toString();

you get:

Exception in thread "main" java.lang.NullPointerException: attempt to 
dereference 'null' when calling method 'toString'

    at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)

While when running this:

Foo foo = null;
int y = foo.x;

You get this:

Exception in thread "main" java.lang.NullPointerException: attempt to 
dereference 'null' when accessing field 'x'

    at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)

One problem I had is that ASM provides no way to get the instruction 
given a program counter - which means we have to scan all the bytecodes 
and update the sizes as we go along, and, ASM unfortunately doesn’t 
expose opcode sizes either. A more robust solution would be to have a 
big switch which returned the opcode size of any given opcode. Also, 
accessing to StackWalker API on exception creation might not be 
desirable in terms of performances, so this might be one of these area 
where some VM help could be beneficial. Another problem is that we 
cannot distinguish between user-generated exceptions (e.g. `throw new 
NullPointerException`) and genuine NPE issued by the VM.


But I guess the upshot is that it works to leave all the gory detail of 
bytecode grovelling to a bytecode API - if the logic is applied lazily, 
then the impact on performances should be minimal, and the solution more 
maintainable longer term.


Cheers
Maurizio

On 15/03/2019 07:59, Lindenmaier, Goetz wrote:

Yes, it would be nice if you shared that.
diff -r 03461dde9ace src/java.base/share/classes/java/lang/NullPointerException.java
--- a/src/java.base/share/classes/java/lang/NullPointerException.java	Wed Mar 06 22:09:34 2019 +0100
+++ b/src/java.base/share/classes/java/lang/NullPointerException.java	Fri Mar 08 01:51:22 2019 +
@@ -25,6 +25,24 @@
 
 package java.lang;
 
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.commons.CodeSizeEvaluator;
+import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode;
+import jdk.internal.org.objectweb.asm.tree.ClassNode;
+import jdk.internal.org.objectweb.asm.tree.MethodNode;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.invoke.MethodType;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.util.Iterator;
+import java.util.stream.Stream;
+
 /**
  * Thrown when an application attempts to use {@code null} in a
  * case where an object is required. These include:
@@ -53,11 +71,17 @@
 class NullPointerException extends RuntimeException {
 private static final long serialVersionUID = 5162710183389028792L;
 
+transient Class clazz;
+transient String methodName;
+transient MethodType methodType;
+transient int pc;
+
 /**
  * Constructs a {@code NullPointerException} with no detail message.
  */
 public NullPointerException() {
 super();
+init();
 }
 
 /**
@@ -68,5 +92,85 @@
  */
 public NullPointerException(String s) {
 super(s);
+init();
+}
+
+void init() {
+StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+walker.walk(s -> {
+StackWalker.StackFrame frame = s.filter(fr -> fr.getDeclaringClass() != NullPointerException.class)
+.findFirst().get();
+clazz = frame.getDeclaringClass();
+pc = frame.getByteCodeIndex();
+methodName = frame.getMethodName();
+methodType = frame.getMethodType();
+return null;
+});
+}
+
+@Override
+public String getMessage() {
+ProtectionDomain domain = clazz.getProtectionDomain();
+CodeSource codeSource = domain.getCodeSource();
+if (domain.getCodeSource() == null) {
+return super.getMessage();
+}
+URL location = codeSource.getLocation();
+if (location == null) {
+return super.getMessage();
+}
+try {
+File f = new File(location.getFile(),
+clazz.getCanonicalName().replaceAll("\\.", "/") + ".class");
+ClassReader cr = new ClassReader(new FileInputStream(f));
+ClassNode classNode = new ClassNode();
+cr.accept(classNode, 0);
+MethodNode meth = classNode.methods.stream()
+.filter(mn -> mn.name.equals(methodName) &&
+mn.desc.equals(methodType.descriptorString()))
+.findFirst().get();
+InsnVisitor insnVisitor = 

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Lindenmaier, Goetz
Hi everybody, Mark,

I followed your advice and created a JEP:
https://bugs.openjdk.java.net/browse/JDK-8220715

Please point me to things I need to improve formally, this is my first
JEP. Also feel free to fix the administrative information in the 
Jira issue if it is wrong.

And, naturally, you're welcome to discuss the topic!

Best regards,
  Goetz.

> -Original Message-
> From: mark.reinh...@oracle.com 
> Sent: Donnerstag, 14. März 2019 22:38
> To: maurizio.cimadam...@oracle.com; Lindenmaier, Goetz
> 
> Cc: mandy.ch...@oracle.com; roger.ri...@oracle.com; core-libs-
> d...@openjdk.java.net; hotspot-runtime-...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> 2019/3/14 8:00:20 -0700, maurizio.cimadam...@oracle.com:
> > I second what Mandy says.
> >
> > First let me start by saying that this enhancement will be a great
> > addition to our platform; back in the days when I was teaching some Java
> > classes at the university, I was very aware of how hard it is to
> > diagnose a NPE for someone novel to Java programming.
> 
> Agreed!
> 
> > ...
> >
> > I also think that the design space for such an enhancement is non
> > trivial, and would best be explored (and captured!) in a medium that is
> > something other than a patch. ...
> 
> Agreed, also.
> 
> Goetz -- if, per Mandy’s suggestion, you’re going to write something
> up using the JEP template, might I suggest that you then submit it as
> an actual JEP?  Giving visibility to, and recording, such design-space
> explorations is one of the primary goals of the JEP process.
> 
> - Mark


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-15 Thread Lindenmaier, Goetz
Hi Maurizio,

> 
> I second what Mandy says.
> 
> First let me start by saying that this enhancement will be a great
> addition to our platform; back in the days when I was teaching some Java
> classes at the university, I was very aware of how hard it is to
> diagnose a NPE for someone novel to Java programming. A trained eye of
> course can quickly scan the line where an exception occurs, and quickly
> isolate the couple of problematic spots which could have caused an
> exception. But it takes time to get to that point, and having some
> helpful messages to help you to get to that point is, IMHO a valuable
> goal in itself.
Thanks!

> I also think that the design space for such an enhancement is non
> trivial, and would best be explored (and captured!) in a medium that is
> something other than a patch. What kind of improvements should we add to
> the NPE exception? What happens if the NPE already has an user-provided
> details message? Should the enhancement make use of optional debugging
> classfile attributes (you touch this in your nice RFE). And again, what
> are the performance considerations we deem important for this work to be
> declared successful? And, maintenance-wise, what is the right way to
> implement the enhancement? Should we implement that as a pure VM
> feature, should we implement it on top of the existing VM, using some
> classfile manipulation (**) ? Or a combination of those?
I'm working on a text... 

> As you can see, there are so many question this enhancement raises that
> I think going straight for a code review can be a premature move; people
> will be coming at the review table with different answers to the above
> set of questions (and maybe additional questions too :-)), and that
> could make the review process hard and frustrating for all the parties
> involved. So I warmly suggest we take a step back from the code, and
> formulate a proposal for enhancing NPE messages in Java; in this sense,
> a JEP seems to me the most natural way to move forward.
Well, I had the code around, so I started this enhancement just showing our 
code.
I guess a prototype is always a good starting point.

> (**) I have a quick and dirty prototype of that built using ASM which
> I'm happy to share, in case you are interested taking a look when
> evaluating alternatives.
Yes, it would be nice if you shared that.

Best regards,
  Goetz.


> 
> Cheers
> Maurizio
> 
> 
> On 14/03/2019 00:42, Mandy Chung wrote:
> > Hi Goetz,
> >
> > Roger, Coleen, Maurizio and I talked about this proposed feature.
> > We all think that improving NPE message is a useful enhancement for
> > the platform and helps developers to tell what causes NPE.
> >
> > This is not a small enhancement.  Diving into a large code review
> > would not be the best way to move this forward as you can see the
> > discussion so far.
> >
> > It would help if you can start with writing down the problem and
> > the proposal like what improvements are proposed and under what
> > circumstances may be acceptable that NPE message won't be improved.
> > This would get the discussion on the proposal feature and then
> > the discussion of the best way to to implement it in the VM, library,
> > or combination.  You can consider using the JEP template that gives
> > you a good structure to follow for the write up.
> >
> > What do you think?
> >
> > Mandy


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-14 Thread mark . reinhold
2019/3/14 8:00:20 -0700, maurizio.cimadam...@oracle.com:
> I second what Mandy says.
> 
> First let me start by saying that this enhancement will be a great 
> addition to our platform; back in the days when I was teaching some Java 
> classes at the university, I was very aware of how hard it is to 
> diagnose a NPE for someone novel to Java programming.

Agreed!

> ...
> 
> I also think that the design space for such an enhancement is non 
> trivial, and would best be explored (and captured!) in a medium that is 
> something other than a patch. ...

Agreed, also.

Goetz -- if, per Mandy’s suggestion, you’re going to write something
up using the JEP template, might I suggest that you then submit it as
an actual JEP?  Giving visibility to, and recording, such design-space
explorations is one of the primary goals of the JEP process.

- Mark


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-14 Thread Lindenmaier, Goetz
Hi Coleen, 

thanks for looking at my change..

> For the record, I think the C++ implementation is more straightforward
> than trying to use the Stackwalker and ASM because there's other code
> just like it right here. You have all the information you need directly
> in the Throwable.backtrace field. Walking it makes sense to me.  Also
> the StackWalker has a cost because it creates ResolvedMethodNames that
> must be interned in the native code in case of redefinition.
Yes, I also think that a Java implementation has more costs at 
runtime.  But as this is only encountered if the message is actually
accessed, it's not that much of a concern.

> I didn't make it through the code for bytecodeUtils but I think it
> should be in the interpreter directory where all the other bytecode
> iterating methods are.  
I moved it to the interpreter directory.
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05-otherMessages/

> It does seem expensive when printing an NPE
> message.  I wonder if there's some easily helpful variable names that
> you could pick out and not have to do all this work for every sort of
> bytecode. 
I'll describe the algorithm in some detail in the paper requested. 
This might answer this point. 

> Also the file uses non hotspot names also like
> 'createInvalidSource' that should be fixed.
I still need to fix these. I’ll leave this to a final review.  The 
code still might be discarded in favour of another implementation.

> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-
> NPE/02/src/hotspot/share/classfile/javaClasses.cpp.udiff.html
> 
> There's a 'version' in the backtrace.  If the method->version() doesn't
> match the one in the backtrace, this should return false, because the
> method was redefined and the bci probably won't match. There's a bunch
> of code in javaClasses that does the similar thing.
Starting with the back trace, I will always get the right bytecodes.
The backtrace keeps the method alive as I understand.

The problem I mentioned in other mails is to get that accessible in Java code 
... 
for the C-implementation I have all the proper information 
just per design of the metaspace/backtrace etc. at hand.

Best regards,
  Goetz.



> 
> This isn't a full review.
> 
> Thanks,
> Coleen
> 
> >
> > Thanks!
> >Goetz
> >
> >> Also, it was not strictly correct when I said all that is retained is
> >> the method bytecodes. Exception tables, line number tables and local var
> >> name & type tables are also retained.
> >>
> >> regards,
> >>
> >>
> >> Andrew Dinn
> >> ---
> >> Senior Principal Software Engineer
> >> Red Hat UK Ltd
> >> Registered in England and Wales under Company Registration No.
> 03798903
> >> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander



Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-14 Thread Maurizio Cimadamore

I second what Mandy says.

First let me start by saying that this enhancement will be a great 
addition to our platform; back in the days when I was teaching some Java 
classes at the university, I was very aware of how hard it is to 
diagnose a NPE for someone novel to Java programming. A trained eye of 
course can quickly scan the line where an exception occurs, and quickly 
isolate the couple of problematic spots which could have caused an 
exception. But it takes time to get to that point, and having some 
helpful messages to help you to get to that point is, IMHO a valuable 
goal in itself.


I also think that the design space for such an enhancement is non 
trivial, and would best be explored (and captured!) in a medium that is 
something other than a patch. What kind of improvements should we add to 
the NPE exception? What happens if the NPE already has an user-provided 
details message? Should the enhancement make use of optional debugging 
classfile attributes (you touch this in your nice RFE). And again, what 
are the performance considerations we deem important for this work to be 
declared successful? And, maintenance-wise, what is the right way to 
implement the enhancement? Should we implement that as a pure VM 
feature, should we implement it on top of the existing VM, using some 
classfile manipulation (**) ? Or a combination of those?


As you can see, there are so many question this enhancement raises that 
I think going straight for a code review can be a premature move; people 
will be coming at the review table with different answers to the above 
set of questions (and maybe additional questions too :-)), and that 
could make the review process hard and frustrating for all the parties 
involved. So I warmly suggest we take a step back from the code, and 
formulate a proposal for enhancing NPE messages in Java; in this sense, 
a JEP seems to me the most natural way to move forward.


(**) I have a quick and dirty prototype of that built using ASM which 
I'm happy to share, in case you are interested taking a look when 
evaluating alternatives.


Cheers
Maurizio


On 14/03/2019 00:42, Mandy Chung wrote:

Hi Goetz,

Roger, Coleen, Maurizio and I talked about this proposed feature.
We all think that improving NPE message is a useful enhancement for
the platform and helps developers to tell what causes NPE.

This is not a small enhancement.  Diving into a large code review
would not be the best way to move this forward as you can see the
discussion so far.

It would help if you can start with writing down the problem and
the proposal like what improvements are proposed and under what
circumstances may be acceptable that NPE message won't be improved.
This would get the discussion on the proposal feature and then
the discussion of the best way to to implement it in the VM, library,
or combination.  You can consider using the JEP template that gives
you a good structure to follow for the write up.

What do you think?

Mandy


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-14 Thread Lindenmaier, Goetz
Hi, 

> Roger, Coleen, Maurizio and I talked about this proposed feature.
> We all think that improving NPE message is a useful enhancement for
> the platform and helps developers to tell what causes NPE.
Thanks for this positive feedback :)!

> This is not a small enhancement.  Diving into a large code review
> would not be the best way to move this forward as you can see the
> discussion so far.
> 
> It would help if you can start with writing down the problem and
> the proposal like what improvements are proposed and under what
> circumstances may be acceptable that NPE message won't be improved.
> This would get the discussion on the proposal feature and then
> the discussion of the best way to to implement it in the VM, library,
> or combination.  You can consider using the JEP template that gives
> you a good structure to follow for the write up.

Yes, I can write down the overall design of this.  This probably is a good
idea.
I already started editing, but please give me a day or two.

The past days I have been working on the C-code. I incorporated 
Coleens comments, but mostly changed the messages to print 
different text as it was proposed in several reviews. 
I'm about to publish a webrev with this new coding. This could 
be a new, better basis for discussing the wording of the message.

Best regards,
  Goetz.


 


> 
> What do you think?
> 
> Mandy


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-13 Thread Mandy Chung

Hi Goetz,

Roger, Coleen, Maurizio and I talked about this proposed feature.
We all think that improving NPE message is a useful enhancement for
the platform and helps developers to tell what causes NPE.

This is not a small enhancement.  Diving into a large code review
would not be the best way to move this forward as you can see the
discussion so far.

It would help if you can start with writing down the problem and
the proposal like what improvements are proposed and under what
circumstances may be acceptable that NPE message won't be improved.
This would get the discussion on the proposal feature and then
the discussion of the best way to to implement it in the VM, library,
or combination.  You can consider using the JEP template that gives
you a good structure to follow for the write up.

What do you think?

Mandy


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-13 Thread Jason Mehrens
Hi Goetz,

For NullPointerException, I don't think you want writeReplace() to call a 
public method that can be overridden.  You probably should create a private 
helper method that both getMessage and writeReplace() call into.

Jason


From: core-libs-dev  on behalf of 
Lindenmaier, Goetz 
Sent: Tuesday, March 12, 2019 10:04 AM
To: Peter Levart; Roger Riggs; Java Core Libs
Cc: hotspot-runtime-...@openjdk.java.net
Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException 
describing what is null.

Hi Peter,

>56 private static final String MESSAGE_PLACEHOLDER =
> "NPE_MESSAGE_PLACEHOLDER";
> Here, the initializer of that constant should create a private instance
> of String:
...
>  private static final String MESSAGE_PLACEHOLDER = new String();
Ok, I understand.

>81 public String getMessage() {
>82 String message = super.getMessage();
>83 if (message == MESSAGE_PLACEHOLDER) {
>84 message = getExtendedNPEMessage();
>85 setMessage(message);
>86 }
>87 return super.getMessage();
>88 }
>
> Why not simply returning 'message' local variable here?
As I removed the synchronization, this would reduce the chance to
get different objects in case of a race.  Highly unlikely though.

I changed the webrev with this solution to include these your remarks:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/03-PeterLevart/
(updated in-place).

Nevertheless, I think I will follow Roger's demand to not modify the 
defaultMessage
field.

Best regards,
  Goetz.


>
>
> Regards, Peter
>
> On 2/14/19 5:35 PM, Lindenmaier, Goetz wrote:
> > Hi Roger,
> >
> >> Maybe 10 years ago, when native was the only solution.
> >> Now there are tools to analyze bytecode in java.
> > I'm working on a Java implementation.
> >
> >>> Peter Levart proposed to initialize the message with a sentinel instead.
> >>> I'll implement this as a proposal.
> >> That's an extra overhead too, any assignment is.
> > Yes, any code requires some run time. But I think this really is negligible
> > in comparison to generating the backtrace, which happens on every
> > exception.  But I'm fine with the 'always recompute, no serialization'
> > solution. If it turns out to be limited, it still can be changed easily.
> >
> >>> I guess we can go without.
> >>> It would be possible to construct a case where two threads
> >>> do getMessage() on the same NPE Object but the string is not
> >>> the same.
> >> Really!, if the bci is the same, the bytecode is the same, what could be
> different
> >> that would change the data used to create the exception?
> > e.getMessage().equals(e.getMessage()) will hold, but
> > e.getMessage() != e.getMessage().
> >
> > I just implemented the two variants of computing the message, they
> > basically differ in NullPointerException.java:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/03-
> PeterLevart/
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/04-
> RogerRiggs/
> >
> > I also cleaned up the parameters passed as proposed.
> >
> >>> We uses this code since 2006, it needed only few changes.  I would like to
> >>> contribute a follow up for hidden frames of lambdas.
> >> Valhalla and evolution of the byte code needs to be considered.
> >> Just because its worked for years does not mean it's the best approach
> >> today.  Dropping it in now means maintaining it in its current form
> >> or needing to re-write it later.
> > Well, yes, that is true. For any change.  For any project.  We have heard
> > this argument for many of our changes. I don't really think it's a good
> > argument. As I understand Valhalla is not targeted for jdk13, and
> > holding up changes for some future projects not really is the process
> > of OpenJDK, is it?
> >
> >>>> The change to the jtreg/vmTestbase/jit/t/t104/t104.gold file raises a
> >>>> question
> >>>> about how useful the information is,  developers should not need to know
> >>>> about "slot 1".
> >>> Developers should work with class files with debug information and then
> >>> they would get the name printed. If exceptions are thrown in production
> >>> code, any information is helpful.  Should I just write "a local"?
> >> Go back to who you think is going to benefit from it, it seems targeted
> >> at a fairly novice developer, so exposing low level details may be more
> &

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-03-12 Thread Lindenmaier, Goetz
ere it was running to see what is wrong ...
> >
> > E.g., com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
> > is failing in a headless environment with an NPE on this line:
> >      SwingUtilities.invokeAndWait(() -> frame.dispose());
> > With this change it said "while trying to invoke the method
> javax.swing.JFrame.dispose(()V) of a null object loaded from static field
> AltFocusIssueTest.frame" and I figured it's the fact we run headless that
> > makes the test fail without even looking at the code.
> >
> > Best regards,
> >Goetz
> >
> >
> >
> >
> >
> >
> >
> >
> > From: Roger Riggs 
> > Sent: Dienstag, 12. Februar 2019 17:03
> > To: Lindenmaier, Goetz ; Java Core Libs  libs-...@openjdk.java.net>
> > Cc: hotspot-runtime-...@openjdk.java.net
> > Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> >
> > Hi,
> > On 02/12/2019 08:14 AM, Lindenmaier, Goetz wrote:
> > Hi Roger,
> >
> > thanks for looking at my change!
> >
> > A few higher level issues should be considered, though the details of
> > the webrev captured my immediate attention.
> >
> > Is this the right feature
> > Yes!!
> > Maybe, that's what debuggers are for.
> >
> >
> >
> >   and is this the right level of implementation (C++/native)?
> > See below.
> > Maybe 10 years ago, when native was the only solution.
> > Now there are tools to analyze bytecode in java.
> >
> >
> >
> >   From a security perspective, adding field names to exceptions exposes
> > information to callers that they could not otherwise get and that breaks
> > encapsulation.
> > That needs to be evaluated.
> > I can not comment on that. How can I trigger an evaluation of this?
> > Who needs to evaluate this?
> >
> > I think there are ways to make this easier to implement and be easier to
> > maintain and perform better.
> >
> > NullPointerException:
> > 28: unused import of Field
> > Removed
> >
> > 64: The lazyComputeMessage boolean should be inverted so it does not
> > require
> >      initialization, false is the default, anything else adds overhead.
> >      And it may not be needed.
> > Peter Levart proposed to initialize the message with a sentinel instead.
> > I'll implement this as a proposal.
> > That's an extra overhead too, any assignment is.
> >
> >
> >
> > 91: Why do you think synchonization is necessary?  It is a performance hit.
> >      It is highly unlikely to be called from multiple threads and the
> > value will
> >      be the same whether it is computed once or multiple times by
> > different threads.
> > I guess we can go without.
> > It would be possible to construct a case where two threads
> > do getMessage() on the same NPE Object but the string is not
> > the same.
> > Really!, if the bci is the same, the bytecode is the same, what could be
> different
> > that would change the data used to create the exception?
> >
> >
> >
> > 99: extendedMessage will never be null (so says the javadoc of
> > getExtendedNPEMessage)
> >     Bug: If it does return null, then null is returned from getMessage
> >     regardless of the value of super.getMessage().
> > Fixed.
> >
> > 121: Simplify getExtendedNPEMessage by making it only responsible for
> > the detail
> >     and not concatenation with an existing message.  Put that in
> > getMessage().
> > Fixed. You are right, I only call this when the message is NULL.
> >
> >     Its not strictly necessary to change the updated message with
> > setMessage().
> >     Avoiding that will avoid complexity and a performance hit.
> >     The message will be computed each time it is needed, and that happens
> > infrequently.
> >     (Even in the serialization case, it will be re-computed from the
> > attached stack frames).
> > No, you can not recompute it from the stacktrace because that
> > does not contain the BCI. Also, after deserialization, the bytecode
> > might look different or not available at all. It depends on the actual
> > bytecode that has been running when the exception was thrown.
> > Right, I realized this too when thinking about it over the weekend.
> >
> > If a suitable low impact mechanism can't be found, then just
> > go back to not exposing the extended message and use only the original.
> > Its a bad idea to twist and contort the local design and accessibility

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-21 Thread Lindenmaier, Goetz
Hi Andrew, 

> Ok. However, if you have the appropriate method bytecodes and the BCI at
> which the exception occurred then I'm not sure why you would need ASM.
I implemented it in C++ at first. I was asked to investigate an implementation 
in Java by the reviewers.
 
Thanks!
  Goetz

> Also, it was not strictly correct when I said all that is retained is
> the method bytecodes. Exception tables, line number tables and local var
> name & type tables are also retained.
> 
> regards,
> 
> 
> Andrew Dinn
> ---
> Senior Principal Software Engineer
> Red Hat UK Ltd
> Registered in England and Wales under Company Registration No. 03798903
> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-21 Thread Andrew Dinn
On 21/02/2019 12:57, Lindenmaier, Goetz wrote:
> thanks for giving this advice!  It confirms the problems I see.

You are welcome.

> For the context:
> The idea was to implement this in Java using StackWalker and 
> ASM. If I had the right bytecodes, and the right starting point, 
> ASM would be helpful to implement the analysis I think.

Ok. However, if you have the appropriate method bytecodes and the BCI at
which the exception occurred then I'm not sure why you would need ASM.

Also, it was not strictly correct when I said all that is retained is
the method bytecodes. Exception tables, line number tables and local var
name & type tables are also retained.

regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-21 Thread Lindenmaier, Goetz
Hi Andrew, 

thanks for giving this advice!  It confirms the problems I see.

For the context:
I proposed better NPE exception messages: 
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/

The original implementation is C++ and walks the metaspace 
given the method* and BCI where the exception occurred.
So it uses only data already sitting in memory.
See JVM_GetExtendedNPEMessage() in jvm.cpp.

The idea was to implement this in Java using StackWalker and 
ASM. If I had the right bytecodes, and the right starting point, 
ASM would be helpful to implement the analysis I think.

I'll look some more into the reconstituter code...

Thanks,
  Goetz.


> -Original Message-
> From: Andrew Dinn 
> Sent: Mittwoch, 20. Februar 2019 18:29
> To: Lindenmaier, Goetz 
> Cc: core-libs-dev ; hotspot-runtime-
> d...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> 
> Forgive me for jumping in here and, possibly, misunderstanding what you
> want -- I may have misunderstood what you are trying to do as I have not
> been following this thread carefully.
> 
> On 20/02/2019 16:36, Lindenmaier, Goetz wrote:
> > 1. As I understand, it would be simple to extend ASM to deliver the initial
> > BCIs when the stream is parsed.  They could be stored separately and
> > discarded once something gets modified (similar to InsnList.cache).
> 
> Non-method bytecodes are normally dropped by the JVM during parsing.
> Only method bytecode is retained in the metadata model. One exception is
> when a registered ClassFileTransformer changes the loaded bytecode at
> load time. The original bytecode for the class is saved when that happens.
> 
> Note that retaining method bytecode does not imply retaining the
> original classpool in bytecode format. Indices into the classpool are
> interpreted as indices into a metadata version of the classpool. Amongst
> other things, that allows sharing of symbols that occur in more than one
> class files. This avoids a /vast/ amount of storage costs.
> 
> > 2. Is there any possibility to access the live datastructures/bytecode in 
> > the
> VM?
> > I was pointed to former JvmtiClassFileReconstitutor ... something like that?
> JvmtiClassFileReconstitutor exists precisely to recreate the full class
> bytecode from the metadata when needed. I believe it is only ever needed
> to allow a ClassFileTransformer to retransform a loaded class that was
> not transformed at load time. Using it seems like overkill to me (also
> see below). If you want to locate a specific bytecode instruction in a
> method you should be able to do so by pulling the method bytecodes out
> of the metadata.
> 
> Also, if you want your message to reflect the bytecode that is actually
> in use when the exception occurs then you really need to do it by
> pulling the bytecodes out of the method metadata. The bytecode returned
> by JvmtiClassFileReconstitutor will not include any bytecode changes
> that were installed by a ClassFileTransformer.
> 
> However, this is a potential can of worms because old and new versions
> of a method and associated bytecode can exist at the same time. You need
> to be sure which version of the method and, hence, bytecode the
> exception was generated from. If you are trying to do this from Java by
> calling into the JVM then I think you are going to have problems.
> 
> regards,
> 
> 
> Andrew Dinn
> ---
> Senior Principal Software Engineer
> Red Hat UK Ltd
> Registered in England and Wales under Company Registration No. 03798903
> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-20 Thread Andrew Dinn
Hi Goetz,

Forgive me for jumping in here and, possibly, misunderstanding what you
want -- I may have misunderstood what you are trying to do as I have not
been following this thread carefully.

On 20/02/2019 16:36, Lindenmaier, Goetz wrote:
> 1. As I understand, it would be simple to extend ASM to deliver the initial 
> BCIs when the stream is parsed.  They could be stored separately and
> discarded once something gets modified (similar to InsnList.cache).

Non-method bytecodes are normally dropped by the JVM during parsing.
Only method bytecode is retained in the metadata model. One exception is
when a registered ClassFileTransformer changes the loaded bytecode at
load time. The original bytecode for the class is saved when that happens.

Note that retaining method bytecode does not imply retaining the
original classpool in bytecode format. Indices into the classpool are
interpreted as indices into a metadata version of the classpool. Amongst
other things, that allows sharing of symbols that occur in more than one
class files. This avoids a /vast/ amount of storage costs.

> 2. Is there any possibility to access the live datastructures/bytecode in the 
> VM?
> I was pointed to former JvmtiClassFileReconstitutor ... something like that?
JvmtiClassFileReconstitutor exists precisely to recreate the full class
bytecode from the metadata when needed. I believe it is only ever needed
to allow a ClassFileTransformer to retransform a loaded class that was
not transformed at load time. Using it seems like overkill to me (also
see below). If you want to locate a specific bytecode instruction in a
method you should be able to do so by pulling the method bytecodes out
of the metadata.

Also, if you want your message to reflect the bytecode that is actually
in use when the exception occurs then you really need to do it by
pulling the bytecodes out of the method metadata. The bytecode returned
by JvmtiClassFileReconstitutor will not include any bytecode changes
that were installed by a ClassFileTransformer.

However, this is a potential can of worms because old and new versions
of a method and associated bytecode can exist at the same time. You need
to be sure which version of the method and, hence, bytecode the
exception was generated from. If you are trying to do this from Java by
calling into the JVM then I think you are going to have problems.

regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-20 Thread Lindenmaier, Goetz
Hi Remi,

> yes, it's a feature of ASM, offer the right abstraction to do bytecode
> generation/transformation i.e. a stream of opcodes that are more abstract
> than the real bytecode, so there is no way to get a direct access to the
> bytecode at a specific BCI.
For the generation of the NPE message I intend the abstraction would be 
helpful. But I need to identify the bytecode that raised the NPE to start
with, and I need to operate on the exact bytecode that was executed when 
the NPE occurred.

Thus, two questions:

1. As I understand, it would be simple to extend ASM to deliver the initial 
BCIs when the stream is parsed.  They could be stored separately and
discarded once something gets modified (similar to InsnList.cache).

2. Is there any possibility to access the live datastructures/bytecode in the 
VM?
I was pointed to former JvmtiClassFileReconstitutor ... something like that?

Thanks and best regards,
  Goetz.




Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-20 Thread Remi Forax
with my ASM hat,

- Mail original -
> De: "Lindenmaier, Goetz" 
> À: "Peter Levart" , "Roger Riggs" 
> , "core-libs-dev"
> 
> Cc: hotspot-runtime-...@openjdk.java.net
> Envoyé: Mardi 19 Février 2019 17:08:07
> Objet: RE: RFR(L): 8218628: Add detailed message to NullPointerException 
> describing what is null.

> Hi,
> 
> I have been looking at how to implement this in Java using
> StackWalker and ASM.
> Either I oversee something or there is a row of deficiencies with
> these tools to solve my issue.
> 
> StackWalker allows me to collect class name, method name, method
> description and BCI. Given the current implementation, this must
> happen in the NPE constructor which is very inefficient, but
> works. Mandy, should I really change Throwable/StackWalker to
> overcome this? Alternatively, I could JNI-call into the VM
> and get the info when I need it.
> 
> ASM allows me to access the class and the bytecode of the method.
> 
> Unfortunately, ASM has no notion of BCI. It also does not
> externally expose the bytecodes of the methods. It simplifies
> the bytecodes, which is useful to manipulate them, but does
> not allow me to recompute the BCI of instructions, say, iterating
> the InsnList.

yes, it's a feature of ASM, offer the right abstraction to do bytecode 
generation/transformation i.e. a stream of opcodes that are more abstract than 
the real bytecode, so there is no way to get a direct access to the bytecode at 
a specific BCI.

> 
> Further, as I understand, the bytecode I can access in ASM
> is the bytecode as it resides in the class file, not the
> bytecode used by hotspot (bitwise). Hotspot rewrites bytecodes when
> it loads them. And the BCI returned by StackWalker corresponds
> to the bytecode used by hotspot, not that in the class file.
> 
> If a method has been rewritten, there even might be several
> instances of the same method/bytecode, the old still needed for
> running executions and the new, rewritten one. The BCI
> is only correct for one of these.
> 
> So I don't see how I should find the ASM representation of
> the bytecode that caused the NPE.  Do you have any advice?
> 
> Best regards,
>  Goetz.
> 

Rémi

> 
>> -Original Message-----
>> From: Peter Levart 
>> Sent: Freitag, 15. Februar 2019 18:38
>> To: Lindenmaier, Goetz ; Roger Riggs
>> ; Java Core Libs 
>> Cc: hotspot-runtime-...@openjdk.java.net
>> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
>> describing what is null.
>> 
>> Hi Goetz,
>> 
>> Just a couple of things if you go that route (of placeholder String):
>> 
>> 
>>    56 private static final String MESSAGE_PLACEHOLDER =
>> "NPE_MESSAGE_PLACEHOLDER";
>> 
>> Here, the initializer of that constant should create a private instance
>> of String:
>> 
>>      private static final String MESSAGE_PLACEHOLDER = new
>> String("NPE_MESSAGE_PLACEHOLDER");
>> 
>> or even (since the content of the placeholder string doesn't matter -
>> the identity does):
>> 
>>      private static final String MESSAGE_PLACEHOLDER = new String();
>> 
>> ...or else anybody calling new
>> NullPointerException("NPE_MESSAGE_PLACEHOLDER") will also be the subject
>> of replacement since the string literals are interned constants. I.e.:
>> 
>> "NPE_MESSAGE_PLACEHOLDER" == "NPE_MESSAGE_PLACEHOLDER"
>> 
>> 
>>    81 public String getMessage() {
>>    82 String message = super.getMessage();
>>    83 if (message == MESSAGE_PLACEHOLDER) {
>>    84 message = getExtendedNPEMessage();
>>    85 setMessage(message);
>>    86 }
>>    87 return super.getMessage();
>>    88 }
>> 
>> Why not simply returning 'message' local variable here?
>> 
>> 
>> Regards, Peter
>> 
>> On 2/14/19 5:35 PM, Lindenmaier, Goetz wrote:
>> > Hi Roger,
>> >
>> >> Maybe 10 years ago, when native was the only solution.
>> >> Now there are tools to analyze bytecode in java.
>> > I'm working on a Java implementation.
>> >
>> >>> Peter Levart proposed to initialize the message with a sentinel instead.
>> >>> I'll implement this as a proposal.
>> >> That's an extra overhead too, any assignment is.
>> > Yes, any code requires some run time. But I think this really is negligible
>> > in comparison to generating the backtrace, which happens on every
>> > exception.  But I'm fine w

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-19 Thread Mandy Chung




On 2/19/19 8:08 AM, Lindenmaier, Goetz wrote:

Hi,

I have been looking at how to implement this in Java using
StackWalker and ASM.
Either I oversee something or there is a row of deficiencies with
these tools to solve my issue.

StackWalker allows me to collect class name, method name, method
description and BCI. Given the current implementation, this must
happen in the NPE constructor which is very inefficient, but
works. Mandy, should I really change Throwable/StackWalker to
overcome this? Alternatively, I could JNI-call into the VM
and get the info when I need it.



One idea is to make a call to VM to fill StackFrameInfo array
for the backtrace stored in NPE (that is in VM native representation)
and then iterate StackFrameInfo and extract the code/local variable etc
from the classfile per class/method and BCI for each frame.

I don't think you have to modify Throwable/StackWalker API to do so
but keep it implementation details.


ASM allows me to access the class and the bytecode of the method.

Unfortunately, ASM has no notion of BCI. It also does not
externally expose the bytecodes of the methods. It simplifies
the bytecodes, which is useful to manipulate them, but does
not allow me to recompute the BCI of instructions, say, iterating
the InsnList.

Further, as I understand, the bytecode I can access in ASM
is the bytecode as it resides in the class file, not the
bytecode used by hotspot (bitwise). Hotspot rewrites bytecodes when
it loads them. And the BCI returned by StackWalker corresponds
to the bytecode used by hotspot, not that in the class file.


When the class file is redefined, it's reasonable to report the line
number is not available.  If you want to keep the previous versions
of class byte, an instrumentation agent can do this work.


If a method has been rewritten, there even might be several
instances of the same method/bytecode, the old still needed for
running executions and the new, rewritten one. The BCI
is only correct for one of these.


The old method would be GC'ed when it becomes unreachable, right?
I expect you won't be able to reliably report the info when the method
has been redefined.


So I don't see how I should find the ASM representation of
the bytecode that caused the NPE.  Do you have any advice?


Have you looked at the Code attribute?

Mandy


Best regards,
   Goetz.



-Original Message-
From: Peter Levart 
Sent: Freitag, 15. Februar 2019 18:38
To: Lindenmaier, Goetz ; Roger Riggs
; Java Core Libs 
Cc: hotspot-runtime-...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
describing what is null.

Hi Goetz,

Just a couple of things if you go that route (of placeholder String):


    56 private static final String MESSAGE_PLACEHOLDER =
"NPE_MESSAGE_PLACEHOLDER";

Here, the initializer of that constant should create a private instance
of String:

      private static final String MESSAGE_PLACEHOLDER = new
String("NPE_MESSAGE_PLACEHOLDER");

or even (since the content of the placeholder string doesn't matter -
the identity does):

      private static final String MESSAGE_PLACEHOLDER = new String();

...or else anybody calling new
NullPointerException("NPE_MESSAGE_PLACEHOLDER") will also be the subject
of replacement since the string literals are interned constants. I.e.:

"NPE_MESSAGE_PLACEHOLDER" == "NPE_MESSAGE_PLACEHOLDER"


    81 public String getMessage() {
    82 String message = super.getMessage();
    83 if (message == MESSAGE_PLACEHOLDER) {
    84 message = getExtendedNPEMessage();
    85 setMessage(message);
    86 }
    87 return super.getMessage();
    88 }

Why not simply returning 'message' local variable here?


Regards, Peter

On 2/14/19 5:35 PM, Lindenmaier, Goetz wrote:

Hi Roger,


Maybe 10 years ago, when native was the only solution.
Now there are tools to analyze bytecode in java.

I'm working on a Java implementation.


Peter Levart proposed to initialize the message with a sentinel instead.
I'll implement this as a proposal.

That's an extra overhead too, any assignment is.

Yes, any code requires some run time. But I think this really is negligible
in comparison to generating the backtrace, which happens on every
exception.  But I'm fine with the 'always recompute, no serialization'
solution. If it turns out to be limited, it still can be changed easily.


I guess we can go without.
It would be possible to construct a case where two threads
do getMessage() on the same NPE Object but the string is not
the same.

Really!, if the bci is the same, the bytecode is the same, what could be

different

that would change the data used to create the exception?

e.getMessage().equals(e.getMessage()) will hold, but
e.getMessage() != e.getMessage().

I just implemented the two variants of computing the message, they
basically differ in NullPointerException.java:
http://cr

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-19 Thread Lindenmaier, Goetz
Hi, 

I have been looking at how to implement this in Java using
StackWalker and ASM.
Either I oversee something or there is a row of deficiencies with 
these tools to solve my issue.

StackWalker allows me to collect class name, method name, method
description and BCI. Given the current implementation, this must
happen in the NPE constructor which is very inefficient, but
works. Mandy, should I really change Throwable/StackWalker to
overcome this? Alternatively, I could JNI-call into the VM
and get the info when I need it.

ASM allows me to access the class and the bytecode of the method.

Unfortunately, ASM has no notion of BCI. It also does not 
externally expose the bytecodes of the methods. It simplifies
the bytecodes, which is useful to manipulate them, but does
not allow me to recompute the BCI of instructions, say, iterating
the InsnList.

Further, as I understand, the bytecode I can access in ASM
is the bytecode as it resides in the class file, not the 
bytecode used by hotspot (bitwise). Hotspot rewrites bytecodes when
it loads them. And the BCI returned by StackWalker corresponds
to the bytecode used by hotspot, not that in the class file.

If a method has been rewritten, there even might be several
instances of the same method/bytecode, the old still needed for 
running executions and the new, rewritten one. The BCI
is only correct for one of these.

So I don't see how I should find the ASM representation of 
the bytecode that caused the NPE.  Do you have any advice?

Best regards,
  Goetz.


> -Original Message-
> From: Peter Levart 
> Sent: Freitag, 15. Februar 2019 18:38
> To: Lindenmaier, Goetz ; Roger Riggs
> ; Java Core Libs 
> Cc: hotspot-runtime-...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> 
> Just a couple of things if you go that route (of placeholder String):
> 
> 
>    56 private static final String MESSAGE_PLACEHOLDER =
> "NPE_MESSAGE_PLACEHOLDER";
> 
> Here, the initializer of that constant should create a private instance
> of String:
> 
>      private static final String MESSAGE_PLACEHOLDER = new
> String("NPE_MESSAGE_PLACEHOLDER");
> 
> or even (since the content of the placeholder string doesn't matter -
> the identity does):
> 
>      private static final String MESSAGE_PLACEHOLDER = new String();
> 
> ...or else anybody calling new
> NullPointerException("NPE_MESSAGE_PLACEHOLDER") will also be the subject
> of replacement since the string literals are interned constants. I.e.:
> 
> "NPE_MESSAGE_PLACEHOLDER" == "NPE_MESSAGE_PLACEHOLDER"
> 
> 
>    81 public String getMessage() {
>    82 String message = super.getMessage();
>    83 if (message == MESSAGE_PLACEHOLDER) {
>    84 message = getExtendedNPEMessage();
>    85 setMessage(message);
>    86 }
>    87 return super.getMessage();
>    88 }
> 
> Why not simply returning 'message' local variable here?
> 
> 
> Regards, Peter
> 
> On 2/14/19 5:35 PM, Lindenmaier, Goetz wrote:
> > Hi Roger,
> >
> >> Maybe 10 years ago, when native was the only solution.
> >> Now there are tools to analyze bytecode in java.
> > I'm working on a Java implementation.
> >
> >>> Peter Levart proposed to initialize the message with a sentinel instead.
> >>> I'll implement this as a proposal.
> >> That's an extra overhead too, any assignment is.
> > Yes, any code requires some run time. But I think this really is negligible
> > in comparison to generating the backtrace, which happens on every
> > exception.  But I'm fine with the 'always recompute, no serialization'
> > solution. If it turns out to be limited, it still can be changed easily.
> >
> >>> I guess we can go without.
> >>> It would be possible to construct a case where two threads
> >>> do getMessage() on the same NPE Object but the string is not
> >>> the same.
> >> Really!, if the bci is the same, the bytecode is the same, what could be
> different
> >> that would change the data used to create the exception?
> > e.getMessage().equals(e.getMessage()) will hold, but
> > e.getMessage() != e.getMessage().
> >
> > I just implemented the two variants of computing the message, they
> > basically differ in NullPointerException.java:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/03-
> PeterLevart/
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/04-
> RogerRiggs/
> >
> > I also cleaned up the parameters passed as proposed.
> >
> >>> We uses this co

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-15 Thread Peter Levart

Hi Goetz,

Just a couple of things if you go that route (of placeholder String):


  56 private static final String MESSAGE_PLACEHOLDER = 
"NPE_MESSAGE_PLACEHOLDER";


Here, the initializer of that constant should create a private instance 
of String:


    private static final String MESSAGE_PLACEHOLDER = new 
String("NPE_MESSAGE_PLACEHOLDER");


or even (since the content of the placeholder string doesn't matter - 
the identity does):


    private static final String MESSAGE_PLACEHOLDER = new String();

...or else anybody calling new 
NullPointerException("NPE_MESSAGE_PLACEHOLDER") will also be the subject 
of replacement since the string literals are interned constants. I.e.:


"NPE_MESSAGE_PLACEHOLDER" == "NPE_MESSAGE_PLACEHOLDER"


  81 public String getMessage() {
  82 String message = super.getMessage();
  83 if (message == MESSAGE_PLACEHOLDER) {
  84 message = getExtendedNPEMessage();
  85 setMessage(message);
  86 }
  87 return super.getMessage();
  88 }

Why not simply returning 'message' local variable here?


Regards, Peter

On 2/14/19 5:35 PM, Lindenmaier, Goetz wrote:

Hi Roger,


Maybe 10 years ago, when native was the only solution.
Now there are tools to analyze bytecode in java.

I'm working on a Java implementation.


Peter Levart proposed to initialize the message with a sentinel instead.
I'll implement this as a proposal.

That's an extra overhead too, any assignment is.

Yes, any code requires some run time. But I think this really is negligible
in comparison to generating the backtrace, which happens on every
exception.  But I'm fine with the 'always recompute, no serialization'
solution. If it turns out to be limited, it still can be changed easily.


I guess we can go without.
It would be possible to construct a case where two threads
do getMessage() on the same NPE Object but the string is not
the same.

Really!, if the bci is the same, the bytecode is the same, what could be 
different
that would change the data used to create the exception?

e.getMessage().equals(e.getMessage()) will hold, but
e.getMessage() != e.getMessage().

I just implemented the two variants of computing the message, they
basically differ in NullPointerException.java:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/03-PeterLevart/
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/04-RogerRiggs/

I also cleaned up the parameters passed as proposed.


We uses this code since 2006, it needed only few changes.  I would like to
contribute a follow up for hidden frames of lambdas.

Valhalla and evolution of the byte code needs to be considered.
Just because its worked for years does not mean it's the best approach
today.  Dropping it in now means maintaining it in its current form
or needing to re-write it later.

Well, yes, that is true. For any change.  For any project.  We have heard
this argument for many of our changes. I don't really think it's a good
argument. As I understand Valhalla is not targeted for jdk13, and
holding up changes for some future projects not really is the process
of OpenJDK, is it?


The change to the jtreg/vmTestbase/jit/t/t104/t104.gold file raises a
question
about how useful the information is,  developers should not need to know
about "slot 1".

Developers should work with class files with debug information and then
they would get the name printed. If exceptions are thrown in production
code, any information is helpful.  Should I just write "a local"?

Go back to who you think is going to benefit from it, it seems targeted
at a fairly novice developer, so exposing low level details may be more
confusing that just giving a line number and NPE.

Especially on our improved NPE messages we always got good feedback
from the developers within SAP. And there are quite some experienced
people.  Any message requires some background to be helpful.  And I
like to get any information I can have in first place. Attaching the
debugger often is a big overhead. E.g., I look at about 50 failing jtreg
tests every day, I don't want to get each into the debugger every time
in the setup where it was running to see what is wrong ...

E.g., com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
is failing in a headless environment with an NPE on this line:
 SwingUtilities.invokeAndWait(() -> frame.dispose());
With this change it said "while trying to invoke the method 
javax.swing.JFrame.dispose(()V) of a null object loaded from static field 
AltFocusIssueTest.frame" and I figured it's the fact we run headless that
makes the test fail without even looking at the code.

Best regards,
   Goetz








From: Roger Riggs 
Sent: Dienstag, 12. Februar 2019 17:03
To: Lindenmaier, Goetz ; Java Core Libs 

Cc: hotspot-runtime-...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException 
describing wha

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-14 Thread Lindenmaier, Goetz
Hi Roger,

> Maybe 10 years ago, when native was the only solution.
> Now there are tools to analyze bytecode in java.
I'm working on a Java implementation. 

> > Peter Levart proposed to initialize the message with a sentinel instead.
> > I'll implement this as a proposal.
> That's an extra overhead too, any assignment is.
Yes, any code requires some run time. But I think this really is negligible
in comparison to generating the backtrace, which happens on every
exception.  But I'm fine with the 'always recompute, no serialization' 
solution. If it turns out to be limited, it still can be changed easily.

> > I guess we can go without. 
> > It would be possible to construct a case where two threads
> > do getMessage() on the same NPE Object but the string is not 
> > the same.
> Really!, if the bci is the same, the bytecode is the same, what could be 
> different
> that would change the data used to create the exception?
e.getMessage().equals(e.getMessage()) will hold, but
e.getMessage() != e.getMessage().

I just implemented the two variants of computing the message, they 
basically differ in NullPointerException.java:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/03-PeterLevart/
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/04-RogerRiggs/

I also cleaned up the parameters passed as proposed.

> > We uses this code since 2006, it needed only few changes.  I would like to 
> > contribute a follow up for hidden frames of lambdas.
> Valhalla and evolution of the byte code needs to be considered.
> Just because its worked for years does not mean it's the best approach
> today.  Dropping it in now means maintaining it in its current form
> or needing to re-write it later.
Well, yes, that is true. For any change.  For any project.  We have heard
this argument for many of our changes. I don't really think it's a good
argument. As I understand Valhalla is not targeted for jdk13, and 
holding up changes for some future projects not really is the process
of OpenJDK, is it? 

> > > The change to the jtreg/vmTestbase/jit/t/t104/t104.gold file raises a
> > > question
> > > about how useful the information is,  developers should not need to know
> > > about "slot 1". 
> > Developers should work with class files with debug information and then
> > they would get the name printed. If exceptions are thrown in production
> > code, any information is helpful.  Should I just write "a local"?
> Go back to who you think is going to benefit from it, it seems targeted
> at a fairly novice developer, so exposing low level details may be more
> confusing that just giving a line number and NPE.
Especially on our improved NPE messages we always got good feedback
from the developers within SAP. And there are quite some experienced
people.  Any message requires some background to be helpful.  And I
like to get any information I can have in first place. Attaching the 
debugger often is a big overhead. E.g., I look at about 50 failing jtreg
tests every day, I don't want to get each into the debugger every time
in the setup where it was running to see what is wrong ... 

E.g., com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
is failing in a headless environment with an NPE on this line:
SwingUtilities.invokeAndWait(() -> frame.dispose());
With this change it said "while trying to invoke the method 
javax.swing.JFrame.dispose(()V) of a null object loaded from static field 
AltFocusIssueTest.frame" and I figured it's the fact we run headless that 
makes the test fail without even looking at the code.  

Best regards,
  Goetz








From: Roger Riggs  
Sent: Dienstag, 12. Februar 2019 17:03
To: Lindenmaier, Goetz ; Java Core Libs 

Cc: hotspot-runtime-...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException 
describing what is null.

Hi,
On 02/12/2019 08:14 AM, Lindenmaier, Goetz wrote:
Hi Roger, 

thanks for looking at my change!

A few higher level issues should be considered, though the details of
the webrev captured my immediate attention.

Is this the right feature
Yes!!
Maybe, that's what debuggers are for.



 and is this the right level of implementation (C++/native)?
See below.
Maybe 10 years ago, when native was the only solution.
Now there are tools to analyze bytecode in java.



 From a security perspective, adding field names to exceptions exposes
information to callers that they could not otherwise get and that breaks
encapsulation.
That needs to be evaluated.
I can not comment on that. How can I trigger an evaluation of this?
Who needs to evaluate this?

I think there are ways to make this easier to implement and be easier to
maintain and perform better.

NullPointerException:
28: unused import of Field
Removed

64: The lazyComputeMessage boolean should be inverted so it does no

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-13 Thread Mandy Chung

I have to say that the example NPE messages this patch has
are like stuffing as much relevant information in the message
but they are not developer-friendly as Roger and David has
commented.  Exposing bytecode-level details is very confusing
to Joe's developer while, from your perspective, anything
would be useful because this is helpful for production support
purpose.  It's a tradeoff.  That's why I think the default message
should include an informative and developer-friendly message whereas
the field support needs the customization ability for better
serviceability at production environment.

Prototyping this in Java will allow us to explore other possibility
for example enabling a plugin to format a custom exception message
rather than hardcoding this in the default message.   This RFE
and JDK-8211152 may better be addressed by providing the ability
to customize the exception message format (that's the idea in
my mind but I have not had time to pursue further).

Mandy

On 2/13/19 1:09 AM, Lindenmaier, Goetz wrote:

Hi Mandy,

Thanks for supporting my intend of adding the message as such!
I'll start implementing this in Java and come back with a webrev
in a while.

In parallel, I would like to continue discussing the other
topics, e.g., the wording of the message. I will probably come up
with a separate webrev for that.

Best regards,
   Goetz.




-Original Message-
From: core-libs-dev  On Behalf
Of Mandy Chung
Sent: Tuesday, February 12, 2019 7:32 PM
To: Roger Riggs 
Cc: Java Core Libs ; hotspot-runtime-
d...@openjdk.java.net
Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
describing what is null.

On 2/8/19 11:46 AM, Roger Riggs wrote:

Hi,

A few higher level issues should be considered, though the details
of the webrev captured my immediate attention.

Is this the right feature and is this the right level of implementation
(C++/native)?
:
How much of this can be done in Java code with StackWalker and other
java APIs?
It would be a shame to add this much native code if there was a more

robust

way to implement it using APIs with more leverage.


Improving the NPE message for better diagnosability is helpful while
I share the same concern Roger raised.

Implementing this feature in Java and the library would be a better
choice as this isn't absolutely required to be done in VM in native.

NPE keeps a backtrace capturing the method id and bci of each stack
frame.  One option to explore is to have StackWalker to accept a
Throwable object that returns a stream of StackFrame which allows
you to get the method and BCI and also code source (I started a
prototype for JDK-8189752 some time ago).  It can use the bytecode
library e.g. ASM to read the bytecode.  For NPE message, you can
implement a specialized StackFrameTraverser just for building
an exception message purpose.

Mandy


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-13 Thread Lindenmaier, Goetz
Hi Bernd, 

I think this is a feasible idea, while I'm not sure whether 
this is really critical information. 
The stack trace already contains the names of Classes,
Inner classes etc.. Field names should be not that more
sensible information I guess, if at all.

> but maybe as  a default?
You mean to enable it per default?  Yes.

Best regards,
  Goetz.


> -Original Message-
> From: core-libs-dev  On Behalf
> Of Bernd Eckenfels
> Sent: Tuesday, February 12, 2019 8:45 PM
> To: Java Core Libs 
> Cc: hotspot-runtime-...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> For security reasons I would add it to `jdk.includeInExceptions`, but maybe as
> a default?
> 
> Gruss
> Bernd
> --
> http://bernd.eckenfels.net
> 
> 
> Von: core-libs-dev  im Auftrag
> von Roger Riggs 
> Gesendet: Dienstag, Februar 12, 2019 8:07 PM
> An: Lindenmaier, Goetz; Java Core Libs
> Cc: hotspot-runtime-...@openjdk.java.net
> Betreff: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi,
> 
> On 02/12/2019 08:14 AM, Lindenmaier, Goetz wrote:
> > Hi Roger,
> >
> > thanks for looking at my change!
> >
> >> A few higher level issues should be considered, though the details of
> >> the webrev captured my immediate attention.
> >>
> >> Is this the right feature
> > Yes!!
> Maybe, that's what debuggers are for.
> >
> >> and is this the right level of implementation (C++/native)?
> > See below.
> Maybe 10 years ago, when native was the only solution.
> Now there are tools to analyze bytecode in java.
> >
> >> From a security perspective, adding field names to exceptions exposes
> >> information to callers that they could not otherwise get and that breaks
> >> encapsulation.
> >> That needs to be evaluated.
> > I can not comment on that. How can I trigger an evaluation of this?
> > Who needs to evaluate this?
> >
> >> I think there are ways to make this easier to implement and be easier to
> >> maintain and perform better.
> >>
> >> NullPointerException:
> >> 28: unused import of Field
> > Removed
> >
> >> 64: The lazyComputeMessage boolean should be inverted so it does not
> >> require
> >>initialization, false is the default, anything else adds overhead.
> >>And it may not be needed.
> > Peter Levart proposed to initialize the message with a sentinel instead.
> > I'll implement this as a proposal.
> That's an extra overhead too, any assignment is.
> >
> >> 91: Why do you think synchonization is necessary?  It is a performance hit.
> >>It is highly unlikely to be called from multiple threads and the
> >> value will
> >>be the same whether it is computed once or multiple times by
> >> different threads.
> > I guess we can go without.
> > It would be possible to construct a case where two threads
> > do getMessage() on the same NPE Object but the string is not
> > the same.
> Really!, if the bci is the same, the bytecode is the same, what could be
> different
> that would change the data used to create the exception?
> >
> >> 99: extendedMessage will never be null (so says the javadoc of
> >> getExtendedNPEMessage)
> >>   Bug: If it does return null, then null is returned from getMessage
> >>   regardless of the value of super.getMessage().
> > Fixed.
> >
> >> 121: Simplify getExtendedNPEMessage by making it only responsible for
> >> the detail
> >>   and not concatenation with an existing message.  Put that in
> >> getMessage().
> > Fixed. You are right, I only call this when the message is NULL.
> >
> >>   Its not strictly necessary to change the updated message with
> >> setMessage().
> >>   Avoiding that will avoid complexity and a performance hit.
> >>   The message will be computed each time it is needed, and that happens
> >> infrequently.
> >>   (Even in the serialization case, it will be re-computed from the
> >> attached stack frames).
> > No, you can not recompute it from the stacktrace because that
> > does not contain the BCI. Also, after deserialization, the bytecode
> > might look different or not available at all. It depends on the actual
> > bytecode that has been running when the exception was thrown.
> Right, I realized this too when thinking about it over the weekend.
> 
> If a suitable low impact mechanism can't b

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-13 Thread Lindenmaier, Goetz
Hi Mandy, 

Thanks for supporting my intend of adding the message as such!
I'll start implementing this in Java and come back with a webrev
in a while. 

In parallel, I would like to continue discussing the other 
topics, e.g., the wording of the message. I will probably come up 
with a separate webrev for that.

Best regards,
  Goetz.



> -Original Message-
> From: core-libs-dev  On Behalf
> Of Mandy Chung
> Sent: Tuesday, February 12, 2019 7:32 PM
> To: Roger Riggs 
> Cc: Java Core Libs ; hotspot-runtime-
> d...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> On 2/8/19 11:46 AM, Roger Riggs wrote:
> > Hi,
> >
> > A few higher level issues should be considered, though the details
> > of the webrev captured my immediate attention.
> >
> > Is this the right feature and is this the right level of implementation
> > (C++/native)?
> > :
> > How much of this can be done in Java code with StackWalker and other
> > java APIs?
> > It would be a shame to add this much native code if there was a more
> robust
> > way to implement it using APIs with more leverage.
> 
> Improving the NPE message for better diagnosability is helpful while
> I share the same concern Roger raised.
> 
> Implementing this feature in Java and the library would be a better
> choice as this isn't absolutely required to be done in VM in native.
> 
> NPE keeps a backtrace capturing the method id and bci of each stack
> frame.  One option to explore is to have StackWalker to accept a
> Throwable object that returns a stream of StackFrame which allows
> you to get the method and BCI and also code source (I started a
> prototype for JDK-8189752 some time ago).  It can use the bytecode
> library e.g. ASM to read the bytecode.  For NPE message, you can
> implement a specialized StackFrameTraverser just for building
> an exception message purpose.
> 
> Mandy


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Bernd Eckenfels
For security reasons I would add it to `jdk.includeInExceptions`, but maybe as 
a default?

Gruss
Bernd
--
http://bernd.eckenfels.net


Von: core-libs-dev  im Auftrag von 
Roger Riggs 
Gesendet: Dienstag, Februar 12, 2019 8:07 PM
An: Lindenmaier, Goetz; Java Core Libs
Cc: hotspot-runtime-...@openjdk.java.net
Betreff: Re: RFR(L): 8218628: Add detailed message to NullPointerException 
describing what is null.

Hi,

On 02/12/2019 08:14 AM, Lindenmaier, Goetz wrote:
> Hi Roger,
>
> thanks for looking at my change!
>
>> A few higher level issues should be considered, though the details of
>> the webrev captured my immediate attention.
>>
>> Is this the right feature
> Yes!!
Maybe, that's what debuggers are for.
>
>> and is this the right level of implementation (C++/native)?
> See below.
Maybe 10 years ago, when native was the only solution.
Now there are tools to analyze bytecode in java.
>
>> From a security perspective, adding field names to exceptions exposes
>> information to callers that they could not otherwise get and that breaks
>> encapsulation.
>> That needs to be evaluated.
> I can not comment on that. How can I trigger an evaluation of this?
> Who needs to evaluate this?
>
>> I think there are ways to make this easier to implement and be easier to
>> maintain and perform better.
>>
>> NullPointerException:
>> 28: unused import of Field
> Removed
>
>> 64: The lazyComputeMessage boolean should be inverted so it does not
>> require
>>initialization, false is the default, anything else adds overhead.
>>And it may not be needed.
> Peter Levart proposed to initialize the message with a sentinel instead.
> I'll implement this as a proposal.
That's an extra overhead too, any assignment is.
>
>> 91: Why do you think synchonization is necessary?  It is a performance hit.
>>It is highly unlikely to be called from multiple threads and the
>> value will
>>be the same whether it is computed once or multiple times by
>> different threads.
> I guess we can go without.
> It would be possible to construct a case where two threads
> do getMessage() on the same NPE Object but the string is not
> the same.
Really!, if the bci is the same, the bytecode is the same, what could be
different
that would change the data used to create the exception?
>
>> 99: extendedMessage will never be null (so says the javadoc of
>> getExtendedNPEMessage)
>>   Bug: If it does return null, then null is returned from getMessage
>>   regardless of the value of super.getMessage().
> Fixed.
>
>> 121: Simplify getExtendedNPEMessage by making it only responsible for
>> the detail
>>   and not concatenation with an existing message.  Put that in
>> getMessage().
> Fixed. You are right, I only call this when the message is NULL.
>
>>   Its not strictly necessary to change the updated message with
>> setMessage().
>>   Avoiding that will avoid complexity and a performance hit.
>>   The message will be computed each time it is needed, and that happens
>> infrequently.
>>   (Even in the serialization case, it will be re-computed from the
>> attached stack frames).
> No, you can not recompute it from the stacktrace because that
> does not contain the BCI. Also, after deserialization, the bytecode
> might look different or not available at all. It depends on the actual
> bytecode that has been running when the exception was thrown.
Right, I realized this too when thinking about it over the weekend.

If a suitable low impact mechanism can't be found, then just
go back to not exposing the extended message and use only the original.
Its a bad idea to twist and contort the local design and accessibility
just for serialization. What remote or delayed client needs to know this?

>
>>   And it avoids adding setMessage() to Throwable, that's significant
>> change since
>>   the current implementation only allows the message to be initialized
>> not updated.
>>   Immutable is an important characteristic to maintain.
> Yes, I don't like I have to set this. But it follows the same pattern
> as with the stack trace which is only computed on demand. Thus,
> Throwable is not immutable anyways. Before, I implemented this by a
> JNI call hiding this in the Java code.
> I proposed implementing setting the field by reflection, Christoph
> proposed a shared secret. David favored the package private setter.
> Please advice what is best.
All of them are bad. Private needs to mean private.

And making it mutable, also means that synchronization or volatile
is needed to ensure a consistent value for getMessage().
That turns into a performance issue for all throw

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Mandy Chung

On 2/8/19 11:46 AM, Roger Riggs wrote:

Hi,

A few higher level issues should be considered, though the details
of the webrev captured my immediate attention.

Is this the right feature and is this the right level of implementation 
(C++/native)?

:
How much of this can be done in Java code with StackWalker and other 
java APIs?

It would be a shame to add this much native code if there was a more robust
way to implement it using APIs with more leverage.


Improving the NPE message for better diagnosability is helpful while
I share the same concern Roger raised.

Implementing this feature in Java and the library would be a better
choice as this isn't absolutely required to be done in VM in native.

NPE keeps a backtrace capturing the method id and bci of each stack
frame.  One option to explore is to have StackWalker to accept a
Throwable object that returns a stream of StackFrame which allows
you to get the method and BCI and also code source (I started a
prototype for JDK-8189752 some time ago).  It can use the bytecode
library e.g. ASM to read the bytecode.  For NPE message, you can
implement a specialized StackFrameTraverser just for building
an exception message purpose.

Mandy


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Roger Riggs

Hi,

On 02/12/2019 08:14 AM, Lindenmaier, Goetz wrote:

Hi Roger,

thanks for looking at my change!


A few higher level issues should be considered, though the details of
the webrev captured my immediate attention.

Is this the right feature

Yes!!

Maybe, that's what debuggers are for.



  and is this the right level of implementation (C++/native)?

See below.

Maybe 10 years ago, when native was the only solution.
Now there are tools to analyze bytecode in java.



  From a security perspective, adding field names to exceptions exposes
information to callers that they could not otherwise get and that breaks
encapsulation.
That needs to be evaluated.

I can not comment on that. How can I trigger an evaluation of this?
Who needs to evaluate this?


I think there are ways to make this easier to implement and be easier to
maintain and perform better.

NullPointerException:
28: unused import of Field

Removed


64: The lazyComputeMessage boolean should be inverted so it does not
require
     initialization, false is the default, anything else adds overhead.
     And it may not be needed.

Peter Levart proposed to initialize the message with a sentinel instead.
I'll implement this as a proposal.

That's an extra overhead too, any assignment is.



91: Why do you think synchonization is necessary?  It is a performance hit.
     It is highly unlikely to be called from multiple threads and the
value will
     be the same whether it is computed once or multiple times by
different threads.

I guess we can go without.
It would be possible to construct a case where two threads
do getMessage() on the same NPE Object but the string is not
the same.
Really!, if the bci is the same, the bytecode is the same, what could be 
different

that would change the data used to create the exception?



99: extendedMessage will never be null (so says the javadoc of
getExtendedNPEMessage)
    Bug: If it does return null, then null is returned from getMessage
    regardless of the value of super.getMessage().

Fixed.


121: Simplify getExtendedNPEMessage by making it only responsible for
the detail
    and not concatenation with an existing message.  Put that in
getMessage().

Fixed. You are right, I only call this when the message is NULL.
  

    Its not strictly necessary to change the updated message with
setMessage().
    Avoiding that will avoid complexity and a performance hit.
    The message will be computed each time it is needed, and that happens
infrequently.
    (Even in the serialization case, it will be re-computed from the
attached stack frames).

No, you can not recompute it from the stacktrace because that
does not contain the BCI. Also, after deserialization, the bytecode
might look different or not available at all. It depends on the actual
bytecode that has been running when the exception was thrown.

Right, I realized this too when thinking about it over the weekend.

If a suitable low impact mechanism can't be found, then just
go back to not exposing the extended message and use only the original.
Its a bad idea to twist and contort the local design and accessibility
just for serialization. What remote or delayed client needs to know this?




    And it avoids adding setMessage() to Throwable, that's significant
change since
    the current implementation only allows the message to be initialized
not updated.
    Immutable is an important characteristic to maintain.

Yes, I don't like I have to set this. But it follows the same pattern
as with the stack trace which is only computed on demand. Thus,
Throwable is not immutable anyways.  Before, I implemented this by a
JNI call hiding this in the Java code.
I proposed implementing setting the field by reflection, Christoph
proposed a shared secret.  David favored the package private setter.
Please advice what is best.

All of them are bad. Private needs to mean private.

And making it mutable, also means that synchronization or volatile
is needed to ensure a consistent value for getMessage().
That turns into a performance issue for all throwables.
None of the above.
  

  That makes the writeReplace() unnecessary too.

No. I need this, see above.

See above, but is not essential to the core feature.



Additional command line arguments are an unnecessary complexity,
documentation, and maintenance overhead.  If the feature is as valuable as
you suggest, it should be enabled all the time.

Removed.


I'm assuming there are no tests broken by the modification of the message.
It is likely that somewhere an application or test looks at the message
itself.
Has that been verified?

Our nightly testing runs the headless jdk and hostspot jtreg tests, jck tests 
and some
other applications. They are all unaffected by this change after adapting the
message in jtreg/vmTestbase/jit/t/t104/t104.gold.
(win-x86_64, linux: ppc64, ppc64le, s390, x86_64, aarch, aix, solaris-sparc, 
mac)
Also, I modified quite some messages before which didn't cause any follow-up
breakages to my 

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Lindenmaier, Goetz
Hi Daniel, 

> public int getByteCodeIndex(); [1]
thanks for this info. I missed that.

> But I am not sure how you would use that in this case.
> I mean - IIUC the stack would have to be walked when the exception
> is raised - not when getMessage() is called. It's possible that
Well, I will have to call StackWalker in the constructor and remember 
the data I need.

> It's possible that
> the BCI is encoded in the backtrace data though. I have not
> checked.
Yes it is. That is what I'm using currently, in the C++ implementation.
See get_method_and_bci in javaClasses.cpp.

Best regards,
  Goetz.

> -Original Message-
> From: Daniel Fuchs 
> Sent: Dienstag, 12. Februar 2019 14:55
> To: Lindenmaier, Goetz ; Roger Riggs
> ; Java Core Libs 
> Cc: hotspot-runtime-...@openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> 
> On 12/02/2019 14:14, Lindenmaier, Goetz wrote:
> > StackWalker operates on the Java stack tracke, which does not contain the
> BCI
> > to my knowledge.
> 
> For what it's worth, StackWalker::StackFrame has the BCI: returned by
> 
> public int getByteCodeIndex(); [1]
> 
> But I am not sure how you would use that in this case.
> I mean - IIUC the stack would have to be walked when the exception
> is raised - not when getMessage() is called. It's possible that
> the BCI is encoded in the backtrace data though. I have not
> checked.
> 
> best regards,
> 
> -- daniel
> 
> [1]
> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Stac
> kWalker.StackFrame.html#getByteCodeIndex()


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Daniel Fuchs

Hi Goetz,

On 12/02/2019 14:14, Lindenmaier, Goetz wrote:

StackWalker operates on the Java stack tracke, which does not contain the BCI
to my knowledge. 


For what it's worth, StackWalker::StackFrame has the BCI: returned by

   public int getByteCodeIndex(); [1]

But I am not sure how you would use that in this case.
I mean - IIUC the stack would have to be walked when the exception
is raised - not when getMessage() is called. It's possible that
the BCI is encoded in the backtrace data though. I have not
checked.

best regards,

-- daniel

[1] 
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StackWalker.StackFrame.html#getByteCodeIndex()


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-12 Thread Lindenmaier, Goetz
Hi Roger, 

thanks for looking at my change!

> A few higher level issues should be considered, though the details of
> the webrev captured my immediate attention.
> 
> Is this the right feature
Yes!!

>  and is this the right level of implementation (C++/native)?
See below.

>  From a security perspective, adding field names to exceptions exposes
> information to callers that they could not otherwise get and that breaks
> encapsulation.
> That needs to be evaluated.
I can not comment on that. How can I trigger an evaluation of this?
Who needs to evaluate this?

> I think there are ways to make this easier to implement and be easier to
> maintain and perform better.
>
> NullPointerException:
> 28: unused import of Field
Removed

> 64: The lazyComputeMessage boolean should be inverted so it does not
> require
>     initialization, false is the default, anything else adds overhead.
>     And it may not be needed.
Peter Levart proposed to initialize the message with a sentinel instead.
I'll implement this as a proposal.

> 91: Why do you think synchonization is necessary?  It is a performance hit.
>     It is highly unlikely to be called from multiple threads and the
> value will
>     be the same whether it is computed once or multiple times by
> different threads.
I guess we can go without. 
It would be possible to construct a case where two threads
do getMessage() on the same NPE Object but the string is not 
the same.

> 99: extendedMessage will never be null (so says the javadoc of
> getExtendedNPEMessage)
>    Bug: If it does return null, then null is returned from getMessage
>    regardless of the value of super.getMessage().
Fixed.  

> 121: Simplify getExtendedNPEMessage by making it only responsible for
> the detail
>    and not concatenation with an existing message.  Put that in
> getMessage().
Fixed. You are right, I only call this when the message is NULL.
 
>    Its not strictly necessary to change the updated message with
> setMessage().
>    Avoiding that will avoid complexity and a performance hit.
>    The message will be computed each time it is needed, and that happens
> infrequently.
>    (Even in the serialization case, it will be re-computed from the
> attached stack frames).
No, you can not recompute it from the stacktrace because that
does not contain the BCI. Also, after deserialization, the bytecode
might look different or not available at all. It depends on the actual 
bytecode that has been running when the exception was thrown.

>    And it avoids adding setMessage() to Throwable, that's significant
> change since
>    the current implementation only allows the message to be initialized
> not updated.
>    Immutable is an important characteristic to maintain.
Yes, I don't like I have to set this. But it follows the same pattern
as with the stack trace which is only computed on demand. Thus, 
Throwable is not immutable anyways.  Before, I implemented this by a 
JNI call hiding this in the Java code.  
I proposed implementing setting the field by reflection, Christoph
proposed a shared secret.  David favored the package private setter.
Please advice what is best.
 
>  That makes the writeReplace() unnecessary too.
No. I need this, see above.

> Additional command line arguments are an unnecessary complexity,
> documentation, and maintenance overhead.  If the feature is as valuable as
> you suggest, it should be enabled all the time.
Removed.  

> I'm assuming there are no tests broken by the modification of the message.
> It is likely that somewhere an application or test looks at the message
> itself.
> Has that been verified?
Our nightly testing runs the headless jdk and hostspot jtreg tests, jck tests 
and some
other applications. They are all unaffected by this change after adapting the 
message in jtreg/vmTestbase/jit/t/t104/t104.gold.
(win-x86_64, linux: ppc64, ppc64le, s390, x86_64, aarch, aix, solaris-sparc, 
mac)
Also, I modified quite some messages before which didn't cause any follow-up
breakages to my knowledge.
 
> I can't speak for the hotspot code, but that seems to add a lot of code
> to support
> only this convenience feature.  That's a maintenance overhead and burden.
We uses this code since 2006, it needed only few changes.  I would like to 
contribute a follow up for hidden frames of lambdas.

> The change to the jtreg/vmTestbase/jit/t/t104/t104.gold file raises a
> question
> about how useful the information is,  developers should not need to know
> about "slot 1". 
Developers should work with class files with debug information and then
they would get the name printed. If exceptions are thrown in production
code, any information is helpful.  Should I just write "a local"?

> The test output of NullPointerExceptionTest shows
> "java.lang.Object.hashCode(()I)".
> Why is the argument type for Integer shown as "()I";  that's not the
> conventional
> representation of a primitive int.
I already discussed this with David Holmes:

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Roger Riggs

Hi,

A few higher level issues should be considered, though the details of 
the webrev

captured my immediate attention.

Is this the right feature and is this the right level of implementation 
(C++/native)?


From a security perspective, adding field names to exceptions exposes
information to callers that they could not otherwise get and that breaks 
encapsulation.

That needs to be evaluated.


I think there are ways to make this easier to implement and be easier to 
maintain

and perform better.

NullPointerException:

28: unused import of Field

64: The lazyComputeMessage boolean should be inverted so it does not require
   initialization, false is the default, anything else adds overhead.
   And it may not be needed.

91: Why do you think synchonization is necessary?  It is a performance hit.
   It is highly unlikely to be called from multiple threads and the 
value will
   be the same whether it is computed once or multiple times by 
different threads.


99: extendedMessage will never be null (so says the javadoc of 
getExtendedNPEMessage)

  Bug: If it does return null, then null is returned from getMessage
  regardless of the value of super.getMessage().

121: Simplify getExtendedNPEMessage by making it only responsible for 
the detail
  and not concatenation with an existing message.  Put that in 
getMessage().


  Its not strictly necessary to change the updated message with 
setMessage().

  Avoiding that will avoid complexity and a performance hit.
  The message will be computed each time it is needed, and that happens 
infrequently.
  (Even in the serialization case, it will be re-computed from the 
attached stack frames).


  And it avoids adding setMessage() to Throwable, that's significant 
change since
  the current implementation only allows the message to be initialized 
not updated.

  Immutable is an important characteristic to maintain.

  That makes the writeReplace() unnecessary too.

Additional command line arguments are an unnecessary complexity,
documentation, and maintenance overhead.  If the feature is as valuable as
you suggest, it should be enabled all the time.

I'm assuming there are no tests broken by the modification of the message.
It is likely that somewhere an application or test looks at the message 
itself.

Has that been verified?

I can't speak for the hotspot code, but that seems to add a lot of code 
to support

only this convenience feature.  That's a maintenance overhead and burden.

The change to the jtreg/vmTestbase/jit/t/t104/t104.gold file raises a 
question

about how useful the information is,  developers should not need to know
about "slot 1".

The test output of NullPointerExceptionTest shows 
"java.lang.Object.hashCode(()I)".
Why is the argument type for Integer shown as "()I";  that's not the 
conventional

representation of a primitive int.

Generally, the explanations are too verbose.
Method names and field names would be easier to recognize if they were
quoted, as is done with 'this'.  Argument numbers should be digits,
not English words (first, second, etc) to make them easier to pick out.
And has it limits that do not read easily, e.g. "nr. 9".
I would not describe 'this' as a local variable.

Tests, especially new tests should compile without warnings.
NullPointerExceptionTest.java:125 newInstance has been deprecated.

The messages can be easier to understand, e.g.
'field a1 is null, trying to invoke a1.hashCode...' instead of:

"while trying to invoke the method java.lang.Object.hashCode(()I) on a 
null reference loaded from local variable 'a1'"


It will easier to understand if it looks more like the code.
BTW, what does this look like for fully optimized code?
Does it bear any resemblance to the source code at all?
Or does it have to be deoptimized to come up with a sensible source 
reference.


How much of this can be done in Java code with StackWalker and other 
java APIs?

It would be a shame to add this much native code if there was a more robust
way to implement it using APIs with more leverage.

Regards, Roger


On 02/08/2019 09:13 AM, Langer, Christoph wrote:

Hi Goetz,


ok, so here a new webrev just adding a setter for the field:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/02

... and incorporating the other comments.

Looks better 

I have a few additions to 
src/java.base/share/classes/java/lang/NullPointerException.java:

28 import java.lang.reflect.Field;
29
-> can be removed now.

91 synchronized (this) {
-> I think this is not needed here. The transient modifier for 
lazyComputeMessage already implies the lock on the Object, I think.

108 return extendedMessage;
-> I guess it would be more correct if you returned super.getMessage() here.

Thanks
Christoph




Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Roger Riggs

Hi Goetz,


On 02/08/2019 06:51 AM, Lindenmaier, Goetz wrote:
... 

though I think trying to produce signatures within the message is going
to be very awkward in the general case. The key part is the "method
NPE.b() ... returned from NPE.a()"

Actually, I have left out code that changes the signatures to the
Java source code wording. I already left that out in my former
exception message contributions.  For example see the messages in
jtreg/runtime/exceptionMsgs/IllegalAccessError/IllegalAccessErrorTest.java,
they have the same bad format:
"class test.Runner4 tried to access private method 
test.IllegalAccessErrorTest.iae4_m()V"

I would like to fix them altogether in a follow-up, is that acceptable to
you?
  


Please no partial solutions, it all needs to be complete.

I'll take a look at it today.

Thanks, Roger




Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Peter Levart
...just one thing if you go that route. Make sure to initialize the
NPE_MESSAGE_PENDING to a new String("something") or else you may be
sharing this constant reference with somebody else via string
interning...

2019-02-08 16:01 GMT+01.00, Peter Levart :
> Hi Goetz,
>
> In NPE:
>
>  97 String extendedMessage =
> getExtendedNPEMessage(super.getMessage());
>
> ...do you expect super.getMessage() to return anything else than null?
> Wouldn't that only occur when there was a data race between two
> threads observing that lazyComputeMessage is strill true in the
> synchronized block before that and then one thread proceeding to
> compute and set the message while the other reading the set message
> via data race? Or are you planing to replace default message in some
> cases with computed one?
>
> I would just pass null there or even get rid of this parameter if that
> is not the case.
>
> If you do that, there is an alternative to having a boolean field in
> NPE. You could create a private static final String constant, call it
> NPE_MESSAGE_PENDING for example and pass it to super constructor in
> NPE no-arg constructor. Then instead of testing for
> lazyComputeMessage, you could test for super.getMessage() ==
> NPE_MESSAGE_PENDING...
>
> Not that this buys much space as NPEs are not numbered. Just a thought...
>
>
> Regards, Peter
>
> 2019-02-08 14:39 GMT+01.00, Lindenmaier, Goetz :
>> Hi,
>>
>> ok, so here a new webrev just adding a setter for the field:
>> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/02
>>
>> ... and incorporating the other comments.
>>
>> Best regards,
>>   Goetz.
>>
>>
>>
>>
>>
>>> -----Original Message-----
>>> From: David Holmes 
>>> Sent: Freitag, 8. Februar 2019 13:31
>>> To: Lindenmaier, Goetz ; hotspot-runtime-
>>> d...@openjdk.java.net; Java Core Libs 
>>> Subject: Re: RFR(L): 8218628: Add detailed message to
>>> NullPointerException
>>> describing what is null.
>>>
>>> Hi Goetz,
>>>
>>> Just one follow up for now:
>>>
>>> >   * Add package visible "void setMessage (String msg)" to Throwable.
>>>
>>> Yes, just use package accessibility to deal with this, no need to jump
>>> through hoops (or the VM :) ).
>>>
>>> Thanks,
>>> David
>>>
>>> On 8/02/2019 9:51 pm, Lindenmaier, Goetz wrote:
>>> > Hi David,
>>> >
>>> >> Hi Volker,
>>> > ... I assume Volker could have contributed this as well, but actually
>>> > I must mention Ralf Schmelter as the original author of this :)
>>> >
>>> >> You know I'm not going to be a big fan of this :), but as long as we
>>> >> don't pay for it if we don't want it, then that's okay. (I'm still
>>> >> trying to gauge that)
>>> >>
>>> >> I have a little test for this that I ran through your patch:
>>> >>
>>> >> public class NPE {
>>> >> static class B {
>>> >>   C b() { return null; }
>>> >> }
>>> >> static class C {
>>> >>   int c(Object o, String s) {  return 0; }
>>> >> }
>>> >>
>>> >> public static void main(String[] args) {
>>> >>   int x  = a().b().c(d(), e().toString());
>>> >> }
>>> >>
>>> >> static B a() { return null; }
>>> >> static Object d() { return null; }
>>> >> static Object e() { return null; }
>>> >>
>>> >> }
>>> >>
>>> >> and the result was a bit confusing for me:
>>> >>
>>> >> java.lang.NullPointerException: while trying to invoke the method
>>> >> NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)
>>> >>
>>> >> The placement and format of the return type descriptors obfuscates
>>> >> things to me - especially the Lxxx; format. Can we make that more
>>> >> Java
>>> >> programmer friendly eg:
>>> >>
>>> >> "while trying to invoke the method 'NPE$C NPE$B.b()' ..."
>>> >>
>>> >> though I think trying to produce signatures within the message is
>>> >> going
>>> >> to be very awkward in the general case. The key part is the "method
>>> >> NPE.b() ... returned from NPE.a()"
>>>

Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Peter Levart
Hi Goetz,

In NPE:

 97 String extendedMessage = getExtendedNPEMessage(super.getMessage());

...do you expect super.getMessage() to return anything else than null?
Wouldn't that only occur when there was a data race between two
threads observing that lazyComputeMessage is strill true in the
synchronized block before that and then one thread proceeding to
compute and set the message while the other reading the set message
via data race? Or are you planing to replace default message in some
cases with computed one?

I would just pass null there or even get rid of this parameter if that
is not the case.

If you do that, there is an alternative to having a boolean field in
NPE. You could create a private static final String constant, call it
NPE_MESSAGE_PENDING for example and pass it to super constructor in
NPE no-arg constructor. Then instead of testing for
lazyComputeMessage, you could test for super.getMessage() ==
NPE_MESSAGE_PENDING...

Not that this buys much space as NPEs are not numbered. Just a thought...


Regards, Peter

2019-02-08 14:39 GMT+01.00, Lindenmaier, Goetz :
> Hi,
>
> ok, so here a new webrev just adding a setter for the field:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/02
>
> ... and incorporating the other comments.
>
> Best regards,
>   Goetz.
>
>
>
>
>
>> -Original Message-
>> From: David Holmes 
>> Sent: Freitag, 8. Februar 2019 13:31
>> To: Lindenmaier, Goetz ; hotspot-runtime-
>> d...@openjdk.java.net; Java Core Libs 
>> Subject: Re: RFR(L): 8218628: Add detailed message to
>> NullPointerException
>> describing what is null.
>>
>> Hi Goetz,
>>
>> Just one follow up for now:
>>
>> >   * Add package visible "void setMessage (String msg)" to Throwable.
>>
>> Yes, just use package accessibility to deal with this, no need to jump
>> through hoops (or the VM :) ).
>>
>> Thanks,
>> David
>>
>> On 8/02/2019 9:51 pm, Lindenmaier, Goetz wrote:
>> > Hi David,
>> >
>> >> Hi Volker,
>> > ... I assume Volker could have contributed this as well, but actually
>> > I must mention Ralf Schmelter as the original author of this :)
>> >
>> >> You know I'm not going to be a big fan of this :), but as long as we
>> >> don't pay for it if we don't want it, then that's okay. (I'm still
>> >> trying to gauge that)
>> >>
>> >> I have a little test for this that I ran through your patch:
>> >>
>> >> public class NPE {
>> >> static class B {
>> >>   C b() { return null; }
>> >> }
>> >> static class C {
>> >>   int c(Object o, String s) {  return 0; }
>> >> }
>> >>
>> >> public static void main(String[] args) {
>> >>   int x  = a().b().c(d(), e().toString());
>> >> }
>> >>
>> >> static B a() { return null; }
>> >> static Object d() { return null; }
>> >> static Object e() { return null; }
>> >>
>> >> }
>> >>
>> >> and the result was a bit confusing for me:
>> >>
>> >> java.lang.NullPointerException: while trying to invoke the method
>> >> NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)
>> >>
>> >> The placement and format of the return type descriptors obfuscates
>> >> things to me - especially the Lxxx; format. Can we make that more Java
>> >> programmer friendly eg:
>> >>
>> >> "while trying to invoke the method 'NPE$C NPE$B.b()' ..."
>> >>
>> >> though I think trying to produce signatures within the message is
>> >> going
>> >> to be very awkward in the general case. The key part is the "method
>> >> NPE.b() ... returned from NPE.a()"
>> > Actually, I have left out code that changes the signatures to the
>> > Java source code wording. I already left that out in my former
>> > exception message contributions.  For example see the messages in
>> > jtreg/runtime/exceptionMsgs/IllegalAccessError/IllegalAccessErrorTest.java,
>> > they have the same bad format:
>> > "class test.Runner4 tried to access private method
>> test.IllegalAccessErrorTest.iae4_m()V"
>> >
>> > I would like to fix them altogether in a follow-up, is that acceptable
>> > to
>> > you?
>> >
>> >> Also "of a null object" would read better as "on a null reference".
>> >

RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Langer, Christoph
Hi Goetz,

> 91 synchronized (this) {
> -> I think this is not needed here. The transient modifier for
> lazyComputeMessage already implies the lock on the Object, I think.

please ignore this comment, I'm wrong here. I confused transient with 
volatile...

/Christoph



RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Langer, Christoph
Hi Goetz,

> ok, so here a new webrev just adding a setter for the field:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/02
> 
> ... and incorporating the other comments.

Looks better 

I have a few additions to 
src/java.base/share/classes/java/lang/NullPointerException.java:

28 import java.lang.reflect.Field;
29
-> can be removed now.

91 synchronized (this) {
-> I think this is not needed here. The transient modifier for 
lazyComputeMessage already implies the lock on the Object, I think.

108 return extendedMessage;
-> I guess it would be more correct if you returned super.getMessage() here.

Thanks
Christoph


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Lindenmaier, Goetz
Hi,

ok, so here a new webrev just adding a setter for the field:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/02

... and incorporating the other comments.

Best regards,
  Goetz.





> -Original Message-
> From: David Holmes 
> Sent: Freitag, 8. Februar 2019 13:31
> To: Lindenmaier, Goetz ; hotspot-runtime-
> d...@openjdk.java.net; Java Core Libs 
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> 
> Hi Goetz,
> 
> Just one follow up for now:
> 
> >   * Add package visible "void setMessage (String msg)" to Throwable.
> 
> Yes, just use package accessibility to deal with this, no need to jump
> through hoops (or the VM :) ).
> 
> Thanks,
> David
> 
> On 8/02/2019 9:51 pm, Lindenmaier, Goetz wrote:
> > Hi David,
> >
> >> Hi Volker,
> > ... I assume Volker could have contributed this as well, but actually
> > I must mention Ralf Schmelter as the original author of this :)
> >
> >> You know I'm not going to be a big fan of this :), but as long as we
> >> don't pay for it if we don't want it, then that's okay. (I'm still
> >> trying to gauge that)
> >>
> >> I have a little test for this that I ran through your patch:
> >>
> >> public class NPE {
> >> static class B {
> >>   C b() { return null; }
> >> }
> >> static class C {
> >>   int c(Object o, String s) {  return 0; }
> >> }
> >>
> >> public static void main(String[] args) {
> >>   int x  = a().b().c(d(), e().toString());
> >> }
> >>
> >> static B a() { return null; }
> >> static Object d() { return null; }
> >> static Object e() { return null; }
> >>
> >> }
> >>
> >> and the result was a bit confusing for me:
> >>
> >> java.lang.NullPointerException: while trying to invoke the method
> >> NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)
> >>
> >> The placement and format of the return type descriptors obfuscates
> >> things to me - especially the Lxxx; format. Can we make that more Java
> >> programmer friendly eg:
> >>
> >> "while trying to invoke the method 'NPE$C NPE$B.b()' ..."
> >>
> >> though I think trying to produce signatures within the message is going
> >> to be very awkward in the general case. The key part is the "method
> >> NPE.b() ... returned from NPE.a()"
> > Actually, I have left out code that changes the signatures to the
> > Java source code wording. I already left that out in my former
> > exception message contributions.  For example see the messages in
> > jtreg/runtime/exceptionMsgs/IllegalAccessError/IllegalAccessErrorTest.java,
> > they have the same bad format:
> > "class test.Runner4 tried to access private method
> test.IllegalAccessErrorTest.iae4_m()V"
> >
> > I would like to fix them altogether in a follow-up, is that acceptable to
> > you?
> >
> >> Also "of a null object" would read better as "on a null reference".
> > Makes sense, fixed.
> >
> > But I'm not that sure about changing these:
> > "while trying to read the field '%s' of a null object"
> > --> "while trying to read the field '%s' from a null reference"
> > "while trying to write the field %s of a null object"
> > --> "while trying to write the field %s  of a null reference"
> >
> >> First you will need to file a CSR request for the new product flags.
> > I'm not sure whether I need the product flags altogether. I would
> > prefer removing them.
> >
> >> Second, I don't understand why you need to call into the VM with
> >> JVM_SetDefaultMessage, to set a field in the Java object? Why isn't that
> >> done in Java?
> > Obviously, the problem is that the field is private.
> > As Christoph points out, there are several ways to implement this.
> > Please give advice:
> >* reflection
> >* shared secret
> >* Add package visible "void setMessage (String msg)" to Throwable.
> >
> > Best regards,
> >Goetz
> >
> >
> >>
> >> Thanks,
> >> David
> >>
> >> On 8/02/2019 2:43 am, Lindenmaier, Goetz wrote:
> >>> Hi,
> >>>
> >>> since Java 5, our internal VM reports verbose null pointer exception
> >>> messages. I would like to contribute this feature to OpenJDK.
> >>>
> >>> With this change, messages as
> >>>  "java.lang.NullPointerException: while trying to load from a null int
> array
> >> loaded from local variable 'ia1'"
> >>> are printed.  For more examples see the JBS bug or the test included.
> >>> https://bugs.openjdk.java.net/browse/JDK-8218628
> >>>
> >>> The messages are generated by parsing the bytecodes. For not to have any
> >> overhead when the
> >>> NPE is allocated, the message is only generated when it is accessed by
> >> getMessage() or
> >>> serialization. For this I added a field to NPE to indicate that the 
> >>> message
> still
> >> needs to be
> >>> computed lazily.
> >>>
> >>> Please review:
> >>> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
> >>> I'm happy to incorporate your comments.
> >>>
> >>> Best regards,
> >>> Goetz
> >>>
> >>>


Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread David Holmes

Hi Goetz,

Just one follow up for now:

  * Add package visible "void setMessage (String msg)" to Throwable. 


Yes, just use package accessibility to deal with this, no need to jump 
through hoops (or the VM :) ).


Thanks,
David

On 8/02/2019 9:51 pm, Lindenmaier, Goetz wrote:

Hi David,


Hi Volker,

... I assume Volker could have contributed this as well, but actually
I must mention Ralf Schmelter as the original author of this :)
  

You know I'm not going to be a big fan of this :), but as long as we
don't pay for it if we don't want it, then that's okay. (I'm still
trying to gauge that)

I have a little test for this that I ran through your patch:

public class NPE {
static class B {
  C b() { return null; }
}
static class C {
  int c(Object o, String s) {  return 0; }
}

public static void main(String[] args) {
  int x  = a().b().c(d(), e().toString());
}

static B a() { return null; }
static Object d() { return null; }
static Object e() { return null; }

}

and the result was a bit confusing for me:

java.lang.NullPointerException: while trying to invoke the method
NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)

The placement and format of the return type descriptors obfuscates
things to me - especially the Lxxx; format. Can we make that more Java
programmer friendly eg:

"while trying to invoke the method 'NPE$C NPE$B.b()' ..."

though I think trying to produce signatures within the message is going
to be very awkward in the general case. The key part is the "method
NPE.b() ... returned from NPE.a()"

Actually, I have left out code that changes the signatures to the
Java source code wording. I already left that out in my former
exception message contributions.  For example see the messages in
jtreg/runtime/exceptionMsgs/IllegalAccessError/IllegalAccessErrorTest.java,
they have the same bad format:
"class test.Runner4 tried to access private method 
test.IllegalAccessErrorTest.iae4_m()V"

I would like to fix them altogether in a follow-up, is that acceptable to
you?
  

Also "of a null object" would read better as "on a null reference".

Makes sense, fixed.

But I'm not that sure about changing these:
"while trying to read the field '%s' of a null object"
--> "while trying to read the field '%s' from a null reference"
"while trying to write the field %s of a null object"
--> "while trying to write the field %s  of a null reference"


First you will need to file a CSR request for the new product flags.

I'm not sure whether I need the product flags altogether. I would
prefer removing them.
  

Second, I don't understand why you need to call into the VM with
JVM_SetDefaultMessage, to set a field in the Java object? Why isn't that
done in Java?

Obviously, the problem is that the field is private.
As Christoph points out, there are several ways to implement this.
Please give advice:
   * reflection
   * shared secret
   * Add package visible "void setMessage (String msg)" to Throwable.

Best regards,
   Goetz




Thanks,
David

On 8/02/2019 2:43 am, Lindenmaier, Goetz wrote:

Hi,

since Java 5, our internal VM reports verbose null pointer exception
messages. I would like to contribute this feature to OpenJDK.

With this change, messages as
 "java.lang.NullPointerException: while trying to load from a null int array

loaded from local variable 'ia1'"

are printed.  For more examples see the JBS bug or the test included.
https://bugs.openjdk.java.net/browse/JDK-8218628

The messages are generated by parsing the bytecodes. For not to have any

overhead when the

NPE is allocated, the message is only generated when it is accessed by

getMessage() or

serialization. For this I added a field to NPE to indicate that the message 
still

needs to be

computed lazily.

Please review:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
I'm happy to incorporate your comments.

Best regards,
Goetz




RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Lindenmaier, Goetz
Hi David, 

> Hi Volker,
... I assume Volker could have contributed this as well, but actually 
I must mention Ralf Schmelter as the original author of this :)
 
> You know I'm not going to be a big fan of this :), but as long as we
> don't pay for it if we don't want it, then that's okay. (I'm still
> trying to gauge that)
> 
> I have a little test for this that I ran through your patch:
> 
> public class NPE {
>static class B {
>  C b() { return null; }
>}
>static class C {
>  int c(Object o, String s) {  return 0; }
>}
> 
>public static void main(String[] args) {
>  int x  = a().b().c(d(), e().toString());
>}
> 
>static B a() { return null; }
>static Object d() { return null; }
>static Object e() { return null; }
> 
> }
> 
> and the result was a bit confusing for me:
> 
> java.lang.NullPointerException: while trying to invoke the method
> NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)
> 
> The placement and format of the return type descriptors obfuscates
> things to me - especially the Lxxx; format. Can we make that more Java
> programmer friendly eg:
> 
> "while trying to invoke the method 'NPE$C NPE$B.b()' ..."
> 
> though I think trying to produce signatures within the message is going
> to be very awkward in the general case. The key part is the "method
> NPE.b() ... returned from NPE.a()"
Actually, I have left out code that changes the signatures to the 
Java source code wording. I already left that out in my former 
exception message contributions.  For example see the messages in 
jtreg/runtime/exceptionMsgs/IllegalAccessError/IllegalAccessErrorTest.java, 
they have the same bad format:
"class test.Runner4 tried to access private method 
test.IllegalAccessErrorTest.iae4_m()V"

I would like to fix them altogether in a follow-up, is that acceptable to 
you?
 
> Also "of a null object" would read better as "on a null reference".
Makes sense, fixed.

But I'm not that sure about changing these:
"while trying to read the field '%s' of a null object"
--> "while trying to read the field '%s' from a null reference"
"while trying to write the field %s of a null object"
--> "while trying to write the field %s  of a null reference"

> First you will need to file a CSR request for the new product flags.
I'm not sure whether I need the product flags altogether. I would 
prefer removing them.
 
> Second, I don't understand why you need to call into the VM with
> JVM_SetDefaultMessage, to set a field in the Java object? Why isn't that
> done in Java?
Obviously, the problem is that the field is private.
As Christoph points out, there are several ways to implement this. 
Please give advice:
  * reflection
  * shared secret
  * Add package visible "void setMessage (String msg)" to Throwable. 

Best regards,
  Goetz


> 
> Thanks,
> David
> 
> On 8/02/2019 2:43 am, Lindenmaier, Goetz wrote:
> > Hi,
> >
> > since Java 5, our internal VM reports verbose null pointer exception
> > messages. I would like to contribute this feature to OpenJDK.
> >
> > With this change, messages as
> > "java.lang.NullPointerException: while trying to load from a null int 
> > array
> loaded from local variable 'ia1'"
> > are printed.  For more examples see the JBS bug or the test included.
> > https://bugs.openjdk.java.net/browse/JDK-8218628
> >
> > The messages are generated by parsing the bytecodes. For not to have any
> overhead when the
> > NPE is allocated, the message is only generated when it is accessed by
> getMessage() or
> > serialization. For this I added a field to NPE to indicate that the message 
> > still
> needs to be
> > computed lazily.
> >
> > Please review:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
> > I'm happy to incorporate your comments.
> >
> > Best regards,
> >Goetz
> >
> >


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Lindenmaier, Goetz
Hi Christoph, 

thanks for looking at this.

> src/java.base/share/classes/java/lang/NullPointerException.java:
> line 56:
> remove a space before the comment
fixed.

> line 62: private transient boolean lazyComputeDefaultMessage;
> I think the name for this variable is not well chosen. I'd prefer
> lazyComputeMessage, because it's not a default message, it's rather "the"
> message of the exception.
OK, removed 'default'

> Then, I think you should initialize the field right away in this line to 
> true, no
> need to do it in the constructor. (Or can't that be done for transient 
> fields?? )
No, it must be initialized to false because there is a second constructor that 
uses a custom message (that was also the reason for the 'default' in the field 
name, it 
only applies to the constructor without custom message)

> 122 private native void setDefaultMessage(String extendedMessage);
> Here, I agree with David, that you should do it in Java. Just use a shared 
> secret,
> then you don't even need reflection...
> It also should not be "setDefaultMessage" but rather "setMessage".
Obviously, the problem is that the field is private. I see various ways to 
implement this.  Please give advice:
  * reflection
  * shared secret
  * Add package visible "void setMessage (String msg)" to throwable. 

Best regards,
  Goetz.


> 
> Best regards
> Christoph
> 
> 
> > -Original Message-
> > From: hotspot-runtime-dev  > boun...@openjdk.java.net> On Behalf Of Lindenmaier, Goetz
> > Sent: Donnerstag, 7. Februar 2019 17:43
> > To: hotspot-runtime-...@openjdk.java.net; Java Core Libs  > d...@openjdk.java.net>
> > Subject: [CAUTION] RFR(L): 8218628: Add detailed message to
> > NullPointerException describing what is null.
> >
> > Hi,
> >
> > since Java 5, our internal VM reports verbose null pointer exception
> > messages. I would like to contribute this feature to OpenJDK.
> >
> > With this change, messages as
> >"java.lang.NullPointerException: while trying to load from a null int 
> > array
> > loaded from local variable 'ia1'"
> > are printed.  For more examples see the JBS bug or the test included.
> > https://bugs.openjdk.java.net/browse/JDK-8218628
> >
> > The messages are generated by parsing the bytecodes. For not to have any
> > overhead when the
> > NPE is allocated, the message is only generated when it is accessed by
> > getMessage() or
> > serialization. For this I added a field to NPE to indicate that the message 
> > still
> > needs to be
> > computed lazily.
> >
> > Please review:
> > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
> > I'm happy to incorporate your comments.
> >
> > Best regards,
> >   Goetz
> >



RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Langer, Christoph
> 122 private native void setDefaultMessage(String extendedMessage);
> Here, I agree with David, that you should do it in Java. Just use a shared
> secret, then you don't even need reflection...

Addition: you should not even need to use a shared secret as Throwable and NPE 
are in the same package. Just add some package private setter to Throwable's 
detailMessage.


RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-08 Thread Langer, Christoph
Hi Goetz,

thanks for bringing this into OpenJDK finally. I know of people that'll be 
quite happy about this feature.

I had a quick glance through the code. Here are a few findings:

src/java.base/share/classes/java/lang/NullPointerException.java:
line 56:
remove a space before the comment

line 62: private transient boolean lazyComputeDefaultMessage;
I think the name for this variable is not well chosen. I'd prefer 
lazyComputeMessage, because it's not a default message, it's rather "the" 
message of the exception.
Then, I think you should initialize the field right away in this line to true, 
no need to do it in the constructor. (Or can't that be done for transient 
fields?? )

122 private native void setDefaultMessage(String extendedMessage);
Here, I agree with David, that you should do it in Java. Just use a shared 
secret, then you don't even need reflection...
It also should not be "setDefaultMessage" but rather "setMessage".

Best regards
Christoph

 
> -Original Message-
> From: hotspot-runtime-dev  boun...@openjdk.java.net> On Behalf Of Lindenmaier, Goetz
> Sent: Donnerstag, 7. Februar 2019 17:43
> To: hotspot-runtime-...@openjdk.java.net; Java Core Libs  d...@openjdk.java.net>
> Subject: [CAUTION] RFR(L): 8218628: Add detailed message to
> NullPointerException describing what is null.
> 
> Hi,
> 
> since Java 5, our internal VM reports verbose null pointer exception
> messages. I would like to contribute this feature to OpenJDK.
> 
> With this change, messages as
>"java.lang.NullPointerException: while trying to load from a null int array
> loaded from local variable 'ia1'"
> are printed.  For more examples see the JBS bug or the test included.
> https://bugs.openjdk.java.net/browse/JDK-8218628
> 
> The messages are generated by parsing the bytecodes. For not to have any
> overhead when the
> NPE is allocated, the message is only generated when it is accessed by
> getMessage() or
> serialization. For this I added a field to NPE to indicate that the message 
> still
> needs to be
> computed lazily.
> 
> Please review:
> http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
> I'm happy to incorporate your comments.
> 
> Best regards,
>   Goetz
> 



Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-07 Thread David Holmes

In 8/02/2019 10:05 am, David Holmes wrote:

Hi Volker,


Aaarggh!! Sorry Volker and Goetz. No idea where that came from.

David
-

You know I'm not going to be a big fan of this :), but as long as we 
don't pay for it if we don't want it, then that's okay. (I'm still 
trying to gauge that)


I have a little test for this that I ran through your patch:

public class NPE {
   static class B {
     C b() { return null; }
   }
   static class C {
     int c(Object o, String s) {  return 0; }
   }

   public static void main(String[] args) {
     int x  = a().b().c(d(), e().toString());
   }

   static B a() { return null; }
   static Object d() { return null; }
   static Object e() { return null; }

}

and the result was a bit confusing for me:

java.lang.NullPointerException: while trying to invoke the method 
NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)


The placement and format of the return type descriptors obfuscates 
things to me - especially the Lxxx; format. Can we make that more Java 
programmer friendly eg:


"while trying to invoke the method 'NPE$C NPE$B.b()' ..."

though I think trying to produce signatures within the message is going 
to be very awkward in the general case. The key part is the "method 
NPE.b() ... returned from NPE.a()"


Also "of a null object" would read better as "on a null reference".


A couple of initial comments

First you will need to file a CSR request for the new product flags.

Second, I don't understand why you need to call into the VM with 
JVM_SetDefaultMessage, to set a field in the Java object? Why isn't that 
done in Java?


Thanks,
David

On 8/02/2019 2:43 am, Lindenmaier, Goetz wrote:

Hi,

since Java 5, our internal VM reports verbose null pointer exception
messages. I would like to contribute this feature to OpenJDK.

With this change, messages as
    "java.lang.NullPointerException: while trying to load from a null 
int array loaded from local variable 'ia1'"

are printed.  For more examples see the JBS bug or the test included.
https://bugs.openjdk.java.net/browse/JDK-8218628

The messages are generated by parsing the bytecodes. For not to have 
any overhead when the
NPE is allocated, the message is only generated when it is accessed by 
getMessage() or
serialization. For this I added a field to NPE to indicate that the 
message still needs to be

computed lazily.

Please review:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
I'm happy to incorporate your comments.

Best regards,
   Goetz




Re: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

2019-02-07 Thread David Holmes

Hi Volker,

You know I'm not going to be a big fan of this :), but as long as we 
don't pay for it if we don't want it, then that's okay. (I'm still 
trying to gauge that)


I have a little test for this that I ran through your patch:

public class NPE {
  static class B {
C b() { return null; }
  }
  static class C {
int c(Object o, String s) {  return 0; }
  }

  public static void main(String[] args) {
int x  = a().b().c(d(), e().toString());
  }

  static B a() { return null; }
  static Object d() { return null; }
  static Object e() { return null; }

}

and the result was a bit confusing for me:

java.lang.NullPointerException: while trying to invoke the method 
NPE$B.b(()LNPE$C;) of a null object returned from NPE.a(()LNPE$B;)


The placement and format of the return type descriptors obfuscates 
things to me - especially the Lxxx; format. Can we make that more Java 
programmer friendly eg:


"while trying to invoke the method 'NPE$C NPE$B.b()' ..."

though I think trying to produce signatures within the message is going 
to be very awkward in the general case. The key part is the "method 
NPE.b() ... returned from NPE.a()"


Also "of a null object" would read better as "on a null reference".


A couple of initial comments

First you will need to file a CSR request for the new product flags.

Second, I don't understand why you need to call into the VM with 
JVM_SetDefaultMessage, to set a field in the Java object? Why isn't that 
done in Java?


Thanks,
David

On 8/02/2019 2:43 am, Lindenmaier, Goetz wrote:

Hi,

since Java 5, our internal VM reports verbose null pointer exception
messages. I would like to contribute this feature to OpenJDK.

With this change, messages as
"java.lang.NullPointerException: while trying to load from a null int array 
loaded from local variable 'ia1'"
are printed.  For more examples see the JBS bug or the test included.
https://bugs.openjdk.java.net/browse/JDK-8218628

The messages are generated by parsing the bytecodes. For not to have any 
overhead when the
NPE is allocated, the message is only generated when it is accessed by 
getMessage() or
serialization. For this I added a field to NPE to indicate that the message 
still needs to be
computed lazily.

Please review:
http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/01/
I'm happy to incorporate your comments.

Best regards,
   Goetz