Groovy-Eclipse uses this list to "shade" (not remove) stack trace elements:

com.sun
groovy.lang
groovyjarjarasm
java.lang.reflect
jdk.internal
org.apache.groovy
org.codehaus.groovy
sun


I add java.util.stream in my workspace for the internal iteration of collect, 
etc.

Also lambdas tend to create extra frames that I consider internal and try to 
diminish.


You can see the shading results here for a simple script like "[1].forEach { 
print(it) }" with a break inside the closure -- extra frames that are wished to 
be shaded are boxed in orange:
https://user-images.githubusercontent.com/18193802/175365039-4aa9f526-f117-432b-ba5d-3a834175d5e2.png




-----Original Message-----
From: Jochen Theodorou <blackd...@gmx.org> 
Sent: Thursday, June 23, 2022 6:32 AM
To: dev@groovy.apache.org
Subject: [EXT] Re: StackTrace sanitization list

External Email: Use caution with links and attachments.

On 23.06.22 11:41, Paul King wrote:
> I tend to agree with you but it does get a little tricky. If "my own 
> user code" is making use of e.g. Java collection classes, then 
> sometimes I'd really like to see "one level down".

one level down... well, for you in

[...]
> Caught: java.lang.NullPointerException java.lang.NullPointerException
>          at java.util.Hashtable.containsKey(Hashtable.java:336)
>          at java.util.Hashtable$KeySet.contains(Hashtable.java:654)
>          at 
> java.util.Collections$SynchronizedCollection.contains(Collections.java:2023)
>          at java.util.ArrayList.batchRemove(ArrayList.java:726)
>          at java.util.ArrayList.removeAll(ArrayList.java:696)
>          at Script.run(Script.groovy:9)

it is the removeAll, so one level down means for you one level down from the 
caller (skipping indy code) - which is somewhere in the "middle" of the trace 
if not sanitized in this example.

Could we make the sanitizer more intelligent to recognize the caller
(Script.groovy:9) and the method called (ArrayList#removeAll) to then sanitize 
the rest in a more aggressive way?

I think actually that is maybe thought a bit too short... there can be multiple 
such places, that you want to retain. Then we would have to recognize user code 
vs non-user code, which is what the sanitization is kind of about...

How about doing something like this:
* have a "hard sanitizer" list, consisting of packages/classes, that will be 
always removed. like "sun." or GroovyStarter
* have a "soft sanitizer" list, consisting of packages that will be removed 
only under condition
* in a first iteration we remove the frames with the hard sanitizer, in a 
second iteration we remove all frames with the soft sanitizer if the frame two 
frames ago has been removed. Going with the full trace from before the expected 
result would then be:
* two frames ago is true if the frame is the top frame, or the first frame in 
the list as well of course

> java.lang.NullPointerException
>         at java.util.Hashtable.containsKey(Hashtable.java:336)
>         at 
> java.util.Collections$SynchronizedCollection.contains(Collections.java:2023)
>         at java.util.ArrayList.removeAll(ArrayList.java:696)
>         at Script.run(Script.groovy:9)

hard list: org.codehaus.groovy.tools.GroovyStarter, java.lang.reflect., sun., 
org.codehaus.groovy.vmplugin

soft list:
java., groovy.

I would actually also always keep the last frame, which in this case just be 
chance is true, meaning the trace above has only 1 unwanted frame for me.

Maybe somebody else has a better idea

bye Jochen

Reply via email to