Mattias Reichel created GROOVY-11794:
----------------------------------------
Summary: STC - Cannot find matching method
Key: GROOVY-11794
URL: https://issues.apache.org/jira/browse/GROOVY-11794
Project: Groovy
Issue Type: Bug
Components: Static compilation
Affects Versions: 5.0.0
Environment: Linux, Java 17
Reporter: Mattias Reichel
This code fails to compile statically with Groovy 5 but does so successfully
with Groovy 4.
{color:#b20000} {color}
{code:java}
[Static type checking] - Cannot find matching method java.lang.Object#get().
Please check if the declared type is correct and if the method exists.
at line: 54, column: 57
[Static type checking] - Cannot find matching method
java.lang.Object#get(java.lang.String). Please check if the declared type is
correct and if the method exists.
at line: 54, column: 25
{code}
{code:java}
import groovy.transform.CompileStatic
import org.codehaus.groovy.runtime.InvokerHelper
@CompileStatic
class ClosureDecorators {
/**
* Wraps a closure so that during its execution, System.getProperty(key)
* returns a custom value instead of what is actually in the system
properties.
*/
static Closure withSystemProperty(Closure target, String key, Object value)
{
Closure wrapped = { Object... args ->
SysPropScope.withProperty(key, value.toString()) {
InvokerHelper.invokeClosure(target, args)
}
}
// keep original closure semantics
wrapped.rehydrate(target.delegate, target.owner, target.thisObject).tap
{
resolveStrategy = target.resolveStrategy
}
}
@CompileStatic
private static class SysPropScope {
static final ThreadLocal<Map<String,String>>
OVERRIDDEN_SYSTEM_PROPERTIES =
ThreadLocal.withInitial() { [:] as Map<String,String> }
@Lazy // Thread-safe wrapping of system properties
private static Properties propertiesWrappedOnFirstAccess = {
new InterceptingProperties().tap {
putAll(System.getProperties())
System.setProperties(it)
}
}()
static Object withProperty(String key, String value, Closure body) {
propertiesWrappedOnFirstAccess // Access property to trigger
property wrapping
def map = OVERRIDDEN_SYSTEM_PROPERTIES.get()
def prev = map.put(key, value)
try {
return body.call()
} finally {
if (prev == null) map.remove(key) else map[key] = prev
if (map.isEmpty()) OVERRIDDEN_SYSTEM_PROPERTIES.remove()
}
}
@CompileStatic
private static class InterceptingProperties extends Properties {
@Override
String getProperty(String key) {
def v = OVERRIDDEN_SYSTEM_PROPERTIES.get().get(key)
v != null ? v : super.getProperty(key)
}
}
}
}
def c1 = {
System.getProperty('java.version')
}
def c2 = ClosureDecorators.withSystemProperty(c1, 'java.version', 'hello')
println c1()
println c2()
{code}
Adding a cast to line 54 does resolve the problem:
{code:java}
def v = ((ThreadLocal<Map<String,String>>)
OVERRIDDEN_SYSTEM_PROPERTIES).get().get(key){code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)