You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Alexander Kriegisch (Jira)" <ji...@apache.org> on 2022/01/16 05:58:00 UTC

[jira] [Created] (GROOVY-10450) Cannot call BiPredicate methods on closures or lambdas on JRE 16+

Alexander Kriegisch created GROOVY-10450:
--------------------------------------------

             Summary: Cannot call BiPredicate methods on closures or lambdas on JRE 16+
                 Key: GROOVY-10450
                 URL: https://issues.apache.org/jira/browse/GROOVY-10450
             Project: Groovy
          Issue Type: Bug
    Affects Versions: 3.0.9
            Reporter: Alexander Kriegisch


The issue was first discovered by a Spock user in [Spock-1412|https://github.com/spockframework/spock/issues/1412].

Under Groovy 3.0.9, the following code works on JREs 8-15, but starts failing on 16+, possibly due to [JEP 396 (Strongly Encapsulate JDK Internals by Default)|https://openjdk.java.net/jeps/396]:
{code:groovy}
import java.util.function.BiPredicate

class CombineBiPredicatesAndClosures {
  static void main(String[] args) {
    println "Java version: ${System.properties['java.version']}"

    // Old-school anonymous class instead of closure or lambda
    /*
    BiPredicate<String, Integer> bi = new BiPredicate<String, Integer>() {
      @Override
      boolean test(String domain, Integer score) {
        return domain.equalsIgnoreCase("google.com")
      }
    }
    */

    // Lambda syntax only works in Groovy 3+
    //BiPredicate<String, Integer> bi = (domain, score) -> domain.equalsIgnoreCase("google.com")
    //def bi2 = (domain, score) -> score == 11

    // Closure syntax works in Groovy 2.5, too
    BiPredicate<String, Integer> bi = { domain, score -> domain.equalsIgnoreCase("google.com") }
    def bi2 = { domain, score -> score == 11 }

    def logicalNot = bi.negate()
    assert logicalNot.test("acme.org", 11)
    assert !logicalNot.test("google.com", 11)

    def logicalOr = bi | bi2
    assert logicalOr.test("google.com", 11)
    assert logicalOr.test("google.com", 0)
    assert logicalOr.test("x", 11)
    assert !logicalOr.test("x", 0)

    def logicalAnd = bi & bi2
    assert logicalAnd.test("google.com", 11)
    assert !logicalAnd.test("google.com", 0)
    assert !logicalAnd.test("x", 11)
    assert !logicalAnd.test("x", 0)
  }
}
{code}
Running the program yields something like:
{code}
Unable to find source-code formatter for language: text. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamlJava version: 16
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.codehaus.groovy.vmplugin.v9.Java9.of(Java9.java:160)
	at org.codehaus.groovy.vmplugin.v9.Java9.getInvokeSpecialHandle(Java9.java:179)
	at org.codehaus.groovy.runtime.ConversionHandler.lambda$invoke$0(ConversionHandler.java:97)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
	at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:97)
	at jdk.proxy1/jdk.proxy1.$Proxy9.negate(Unknown Source)
	at java_util_function_BiPredicate$negate.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
	at CombineBiPredicatesAndClosures.main(CombineBiPredicatesAndClosures.groovy:25)
Caused by: java.lang.IllegalAccessException: module jdk.proxy1 does not open jdk.proxy1 to unnamed module @153f5a29
	at java.base/java.lang.invoke.MethodHandles.privateLookupIn(MethodHandles.java:260)
	... 15 more
{code}
When running the same program on Groovy 4.0.0-rc-2, there are no problems on JDK 16+. Using the commented-out anonymous class instead of either a lambda or closure also works around the problem on Groovy 3.

Could you please fix this for the next 3.0.x version? Thank you.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)