[jira] [Created] (GROOVY-10142) Infinite loop when clearing tye Parameterized Type Cache

2021-06-16 Thread Leon A (Jira)
Leon A created GROOVY-10142:
---

 Summary: Infinite loop when clearing tye Parameterized Type Cache
 Key: GROOVY-10142
 URL: https://issues.apache.org/jira/browse/GROOVY-10142
 Project: Groovy
  Issue Type: Bug
  Components: Static compilation, Static Type Checker
Affects Versions: 3.0.8
Reporter: Leon A


I have application that essential makes concurrent calls to a method similar to 
the one below
{code:java}
Script compileConcurrently(String source) {
  Script = (Script) groovyClassLoader.parseClass(source).newInstance();
  GenericsUtils.clearParameterizedTypeCache();
  StaticTypeCheckingSupport.clearExtensionMethodCache();
  return script;
}{code}
I am running into an issue where one thread gets stuck in an infinite loop in 
theĀ GenericsUtils::clearParameterizedTypeCache method while other threads are 
waiting in GroovyClassLoader::parseClass

I see PARAMETERIZED_TYPE_CACHE is backed by an access-ordered LinkedHashMap 
guarded with ReadWriteLock. I think the root cause is concurrent 
LinkedHashMap::get calls modifies the order of the map entries and creates a 
loop.

See 
[LinkedHashMap|https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html]
 api docs
{noformat}
Note that this implementation is not synchronized. If multiple threads access a 
linked hash map concurrently, and at least one of the threads modifies the map 
structurally, it must be synchronized externally. This is typically 
accomplished by synchronizing on some object that naturally encapsulates the 
map. If no such object exists, the map should be "wrapped" using the 
Collections.synchronizedMap method. This is best done at creation time, to 
prevent accidental unsynchronized access to the map:

   Map m = Collections.synchronizedMap(new LinkedHashMap(...));

A structural modification is any operation that adds or deletes one or more 
mappings or, in the case of access-ordered linked hash maps, affects iteration 
order. In insertion-ordered linked hash maps, merely changing the value 
associated with a key that is already contained in the map is not a structural 
modification. In access-ordered linked hash maps, merely querying the map with 
get is a structural modification. ) 
{noformat}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Created] (GROOVY-10141) NPE in InnerClassVisitor for non-static inner class CCE within two AICs

2021-06-16 Thread Eric Milles (Jira)
Eric Milles created GROOVY-10141:


 Summary: NPE in InnerClassVisitor for non-static inner class CCE 
within two AICs
 Key: GROOVY-10141
 URL: https://issues.apache.org/jira/browse/GROOVY-10141
 Project: Groovy
  Issue Type: Bug
Reporter: Eric Milles
Assignee: Eric Milles


Consider the following:
{code:groovy}
class Outer {
class Inner {
}
def obj = new Object() {
String toString() {
new Object() {
String toString() {
new Inner()
}
}
}
}
}
{code}

https://github.com/groovy/groovy-eclipse/issues/1268

{code}
java.lang.NullPointerException
at 
org.codehaus.groovy.classgen.InnerClassVisitor.insertThis0ToSuperCall(InnerClassVisitor.java:306)
at 
org.codehaus.groovy.classgen.InnerClassVisitor.passThisReference(InnerClassVisitor.java:286)
at 
org.codehaus.groovy.classgen.InnerClassVisitor.visitConstructorCallExpression(InnerClassVisitor.java:147)
at 
org.codehaus.groovy.ast.expr.ConstructorCallExpression.visit(ConstructorCallExpression.java:45)
at 
org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:117)
at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:200)
at 
org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:41)
at 
org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:86)
at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:164)
at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:70)
at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:138)
at 
org.codehaus.groovy.classgen.InnerClassVisitor.visitConstructorOrMethod(InnerClassVisitor.java:116)
at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:106)
at org.codehaus.groovy.ast.ClassNode.visitMethods(ClassNode.java:1110)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1103)
at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:52)
at 
org.codehaus.groovy.classgen.InnerClassVisitor.visitClass(InnerClassVisitor.java:86)
at 
org.codehaus.groovy.control.CompilationUnit.lambda$addPhaseOperations$4(CompilationUnit.java:213)
at 
org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:928)
{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Commented] (GROOVY-8660) Unexpected MethodSelectionException with implicit null argument

2021-06-16 Thread Paul King (Jira)


[ 
https://issues.apache.org/jira/browse/GROOVY-8660?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17364329#comment-17364329
 ] 

Paul King commented on GROOVY-8660:
---

[~blackdrag], you don't recall any more specifics do you? Otherwise I can try 
to refresh my memory by trawling through the mailing lists or commit history.

> Unexpected MethodSelectionException with implicit null argument
> ---
>
> Key: GROOVY-8660
> URL: https://issues.apache.org/jira/browse/GROOVY-8660
> Project: Groovy
>  Issue Type: Bug
>Affects Versions: 3.0.0-alpha-2, 2.4.15, 2.5.0
>Reporter: Daniil Ovchinnikov
>Priority: Major
>
> {code:groovy}
> class OnlySingle {
> def foo(a) { "single param: $a" }
> }
> println new OnlySingle().foo()
> // as expected: 'single param: null'
> class OnlyVararg {
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new OnlyVararg().foo()
> // as expected: 'MME: No signature of method: OnlyVararg.foo() is applicable 
> for argument types: () values: []'
> class Both {
> def foo(a) { "single param: $a" }
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new Both().foo()
> // unexpected:
> // MethodSelectionException: Could not find which method foo() to invoke from 
> this list:
> //  public java.lang.Object Both#foo(java.lang.Object)
> //  public transient java.lang.Object Both#foo(java.lang.Object, 
> [Ljava.lang.Object;)
> {code}
> If the exception is expected then {{OnlyVararg}} case should work too.
> If the exception is unexpected then {{Both#foo(Object)}} should be selected.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Commented] (GROOVY-8660) Unexpected MethodSelectionException with implicit null argument

2021-06-16 Thread Eric Milles (Jira)


[ 
https://issues.apache.org/jira/browse/GROOVY-8660?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17364325#comment-17364325
 ] 

Eric Milles commented on GROOVY-8660:
-

I only found out about this a couple weeks ago.  As best as I can gather, the 
method selection (in MetaClassImpl) will translate "foo()" to "foo(null)" if 
there is only one method "foo" for the receiver type and the method has one 
non-primitive parameter.  This extends to category methods, so a static 
category method will apply to "foo()" if is has one self parameter and one 
additional non-primitive parameter.

In your "Both" case, the one method criterion is not met.  I'm not sure why 
this exists and I think I have seen some discussion of removing it in MOP 2.0.  
But I think that effort is largely stalled.

> Unexpected MethodSelectionException with implicit null argument
> ---
>
> Key: GROOVY-8660
> URL: https://issues.apache.org/jira/browse/GROOVY-8660
> Project: Groovy
>  Issue Type: Bug
>Affects Versions: 3.0.0-alpha-2, 2.4.15, 2.5.0
>Reporter: Daniil Ovchinnikov
>Priority: Major
>
> {code:groovy}
> class OnlySingle {
> def foo(a) { "single param: $a" }
> }
> println new OnlySingle().foo()
> // as expected: 'single param: null'
> class OnlyVararg {
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new OnlyVararg().foo()
> // as expected: 'MME: No signature of method: OnlyVararg.foo() is applicable 
> for argument types: () values: []'
> class Both {
> def foo(a) { "single param: $a" }
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new Both().foo()
> // unexpected:
> // MethodSelectionException: Could not find which method foo() to invoke from 
> this list:
> //  public java.lang.Object Both#foo(java.lang.Object)
> //  public transient java.lang.Object Both#foo(java.lang.Object, 
> [Ljava.lang.Object;)
> {code}
> If the exception is expected then {{OnlyVararg}} case should work too.
> If the exception is unexpected then {{Both#foo(Object)}} should be selected.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Comment Edited] (GROOVY-8660) Unexpected MethodSelectionException with implicit null argument

2021-06-16 Thread Daniil Ovchinnikov (Jira)


[ 
https://issues.apache.org/jira/browse/GROOVY-8660?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17364269#comment-17364269
 ] 

Daniil Ovchinnikov edited comment on GROOVY-8660 at 6/16/21, 12:07 PM:
---

This should be documented somewhere. Last time I've checked, there was 
something like: "if a method can be called with a single null argument, then 
the argument can be omitted", there was no mention that the method must not 
have overloads or varargs. 

If {{new OnlyVararg().foo()}} fails
=> {{Both#foo(Object, [LObject; )}} must be inapplicable
=>  method selection in {{new Both().foo()}} should try only 
{{Both#foo(Object)}} against {{null}} argument 
=> {{Both#foo(Object)}} should be selected.

Now let's reverse the above.

If {{Both#foo(Object)}} is not selected
=> method selection in {{new Both().foo()}} actually sees both methods as 
applicable before trying them with null argument
=> {{Both#foo(Object, [LObject; )}} was applicable
=> {{new OnlyVararg().foo()}} must not fail.

I'm having trouble understanding `org.codehaus.groovy.*` code. Can you describe 
me the algorithm in human words, please?


was (Author: daniilo):
This should be documented somewhere. Last time I've checked, there was 
something like: "if a method can be called with a single null argument, then 
the argument can be omitted", there was no mention that the method must not 
have overloads or varargs. 

If {{new OnlyVararg().foo()}} fails
=> {{Both#foo(Object, [LObject;)}} must be inapplicable
=>  method selection in {{new Both().foo()}} should try only 
{{Both#foo(Object)}} against {{null}} argument 
=> {{Both#foo(Object)}} should be selected.

Now let's reverse the above.

If {{Both#foo(Object)}} is not selected
=> method selection in {{new Both().foo()}} actually sees both methods as 
applicable before trying them with null argument
=> {{Both#foo(Object, [LObject;)}} was applicable
=> {{new OnlyVararg().foo()}} must not fail.

I'm having trouble understanding `org.codehaus.groovy.*` code. Can you describe 
me the algorithm in human words, please?

> Unexpected MethodSelectionException with implicit null argument
> ---
>
> Key: GROOVY-8660
> URL: https://issues.apache.org/jira/browse/GROOVY-8660
> Project: Groovy
>  Issue Type: Bug
>Affects Versions: 3.0.0-alpha-2, 2.4.15, 2.5.0
>Reporter: Daniil Ovchinnikov
>Priority: Major
>
> {code:groovy}
> class OnlySingle {
> def foo(a) { "single param: $a" }
> }
> println new OnlySingle().foo()
> // as expected: 'single param: null'
> class OnlyVararg {
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new OnlyVararg().foo()
> // as expected: 'MME: No signature of method: OnlyVararg.foo() is applicable 
> for argument types: () values: []'
> class Both {
> def foo(a) { "single param: $a" }
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new Both().foo()
> // unexpected:
> // MethodSelectionException: Could not find which method foo() to invoke from 
> this list:
> //  public java.lang.Object Both#foo(java.lang.Object)
> //  public transient java.lang.Object Both#foo(java.lang.Object, 
> [Ljava.lang.Object;)
> {code}
> If the exception is expected then {{OnlyVararg}} case should work too.
> If the exception is unexpected then {{Both#foo(Object)}} should be selected.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Commented] (GROOVY-8660) Unexpected MethodSelectionException with implicit null argument

2021-06-16 Thread Daniil Ovchinnikov (Jira)


[ 
https://issues.apache.org/jira/browse/GROOVY-8660?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17364269#comment-17364269
 ] 

Daniil Ovchinnikov commented on GROOVY-8660:


This should be documented somewhere. Last time I've checked, there was 
something like: "if a method can be called with a single null argument, then 
the argument can be omitted", there was no mention that the method must not 
have overloads or varargs. 

If {{new OnlyVararg().foo()}} fails
=> {{Both#foo(Object, [LObject;)}} must be inapplicable
=>  method selection in {{new Both().foo()}} should try only 
{{Both#foo(Object)}} against {{null}} argument 
=> {{Both#foo(Object)}} should be selected.

Now let's reverse the above.

If {{Both#foo(Object)}} is not selected
=> method selection in {{new Both().foo()}} actually sees both methods as 
applicable before trying them with null argument
=> {{Both#foo(Object, [LObject;)}} was applicable
=> {{new OnlyVararg().foo()}} must not fail.

I'm having trouble understanding `org.codehaus.groovy.*` code. Can you describe 
me the algorithm in human words, please?

> Unexpected MethodSelectionException with implicit null argument
> ---
>
> Key: GROOVY-8660
> URL: https://issues.apache.org/jira/browse/GROOVY-8660
> Project: Groovy
>  Issue Type: Bug
>Affects Versions: 3.0.0-alpha-2, 2.4.15, 2.5.0
>Reporter: Daniil Ovchinnikov
>Priority: Major
>
> {code:groovy}
> class OnlySingle {
> def foo(a) { "single param: $a" }
> }
> println new OnlySingle().foo()
> // as expected: 'single param: null'
> class OnlyVararg {
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new OnlyVararg().foo()
> // as expected: 'MME: No signature of method: OnlyVararg.foo() is applicable 
> for argument types: () values: []'
> class Both {
> def foo(a) { "single param: $a" }
> def foo(a, ... b) { "vararg param: $a, $b" }
> }
> println new Both().foo()
> // unexpected:
> // MethodSelectionException: Could not find which method foo() to invoke from 
> this list:
> //  public java.lang.Object Both#foo(java.lang.Object)
> //  public transient java.lang.Object Both#foo(java.lang.Object, 
> [Ljava.lang.Object;)
> {code}
> If the exception is expected then {{OnlyVararg}} case should work too.
> If the exception is unexpected then {{Both#foo(Object)}} should be selected.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)