[ 
https://issues.apache.org/jira/browse/DERBY-6881?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15219560#comment-15219560
 ] 

Knut Anders Hatlen commented on DERBY-6881:
-------------------------------------------

Hi Bryan. Thanks for reviewing the patches.

Regarding the following line:
{code}
PrivilegedAction<ClassLoader> pa = () -> new URLClassLoader(new URL[0]);
{code}
Everything up to the equals sign is as before. That is, we're declaring a 
variable pa of type PrivilegedAction<ClassLoader> and assigning a value to it.

What comes after the equals sign, is a so-called lambda expression. A lambda 
expression can be used where an instance of an interface with a single abstract 
method is expected. PrivilegedAction is such an interface (it has one method: 
run()).

The lambda expression specifies how that method is implemented. It consists of 
an argument list, an arrow (->) and then the function body. In this case, the 
argument list is empty, so it's just a pair of parentheses (). Also, since the 
method body consists of a single statement, we can use the shorthand syntax 
where the method body has no curly braces around it and the "return" keyword is 
left out. We could have chosen not to use the shorthand syntax and written this 
instead:
{code}
PrivilegedAction<ClassLoader> pa = () -> {
    return new URLClassLoader(new URL[0]);
});
{code}

One would often inline the lambda expression, rather than creating a helper 
variable like I did in the patch. However, the obvious code
{code}
AccessController.doPrivileged(() -> new URLClassLoader(new URL[0]));
{code}
does not get accepted by the compiler. The reason is that there are two 
variants of AccessController.doPrivileged(); one that takes a PrivilegedAction, 
and one that takes a PrivilegedExceptionAction. The compiler cannot tell which 
one we want to call without a little help. One way is to create a helper 
variable of the desired type, like I did. Another way is to add a cast to give 
the compiler more context:
{code}
AccessController.doPrivileged((PrivilegedAction) () -> new URLClassLoader(new 
URL[0]));
{code}
If lambda expressions had been supported when the AccessController class was 
added, I'm sure this clash and the resulting inconvenience would have been 
avoided.

Lambda expressions can in many cases be used as a replacement for anonymous 
inner classes. The most obvious advantage is that lambda expressions have much 
less boilerplate than anonymous inner classes. It also slightly reduces the 
footprint of the jar files. If you inspect the contents of derbyTesting.jar, 
you'll see that the file 
{{org/apache/derbyTesting/junit/ClassLoaderTestSetup$3.class}} has disappeared, 
and no new class has been added to it.

This suggests that lambda expressions are not simply translated to a 
corresponding anonymous inner class by the compiler. In fact, the JVM can 
optimize this for us and produce code that performs better than the 
corresponding anonymous inner class. For example, in this case, it can probably 
see that the lambda expression is stateless, and produce a single instance that 
is reused every time this code is executed. In contrast, the corresponding 
anonymous class would have been instantiated every time, unless we added even 
more boilerplate to cache a singleton instance manually. Not that we care much 
about performance in the test code, but it's nice that the JVM can do this for 
us automatically so that we don't have to do anything special in the places 
where we do care about performance.

I haven't used these new features much myself, so everything above is probably 
better and more correctly explained by the Java tutorial on lambda expressions: 
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

> Test failures with JDK 9-ea b111
> --------------------------------
>
>                 Key: DERBY-6881
>                 URL: https://issues.apache.org/jira/browse/DERBY-6881
>             Project: Derby
>          Issue Type: Bug
>          Components: Test
>    Affects Versions: 10.13.0.0
>            Reporter: Knut Anders Hatlen
>         Attachments: d6881-classloader.diff, d6881-sed.diff
>
>
> With JDK 9-ea b111 there are a number of test failures.
> Tests that use ClassLoaderTestSetup fail because the context class loader no 
> longer is a URLClassLoader, which causes a ClassCastException in the class 
> loader magic performed by the test setup:
> {noformat}
> java.lang.ClassCastException: jdk.internal.loader.ClassLoaders$AppClassLoader 
> (in module: java.base) cannot be cast to java.net.URLClassLoader (in module: 
> java.base)
>       at 
> org.apache.derbyTesting.junit.ClassLoaderTestSetup$1.run(ClassLoaderTestSetup.java:53)
>       at 
> org.apache.derbyTesting.junit.ClassLoaderTestSetup$1.run(ClassLoaderTestSetup.java:50)
>       at java.security.AccessController.doPrivileged(java.base@9-ea/Native 
> Method)
>       at 
> org.apache.derbyTesting.junit.ClassLoaderTestSetup.makeClassLoader(ClassLoaderTestSetup.java:49)
>       at 
> org.apache.derbyTesting.junit.ClassLoaderTestSetup.setUp(ClassLoaderTestSetup.java:64)
>       at junit.extensions.TestSetup$1.protect(TestSetup.java:20)
>       at junit.extensions.TestSetup.run(TestSetup.java:25)
>       at 
> org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:58)
> {noformat}
> CollationTest, CollationTest2, LocalizedAttributeScriptTest and 
> LocalizedDisplayScriptTest have failures, for example:
> {noformat}
> junit.framework.AssertionFailedError: Column value mismatch @ column 'ID', 
> row 1:
>     Expected: >4<
>     Found:    >6<
>     ID,NAME
>     -- ----
>    [6, aacorn]
>    [4, Acorn]
>    [2, Ącorn]
>    [0, Smith]
>    [5, Śmith]
>    [1, Zebra]
>    [3, Żebra]
>       at 
> org.apache.derbyTesting.junit.BaseTestCase.newAssertionFailedError(BaseTestCase.java:1177)
>       at org.apache.derbyTesting.junit.JDBC.addRsToReport(JDBC.java:1998)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertRowInResultSet(JDBC.java:1497)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertRowInResultSet(JDBC.java:1395)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSetMinion(JDBC.java:1257)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSet(JDBC.java:1168)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSet(JDBC.java:1125)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSet(JDBC.java:1083)
>       at 
> org.apache.derbyTesting.functionTests.tests.lang.CollationTest.checkLangBasedQuery(CollationTest.java:2055)
>       at 
> org.apache.derbyTesting.functionTests.tests.lang.CollationTest.testNorwayCollation(CollationTest.java:482)
>       at 
> org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:120)
>       at 
> org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:443)
>       at 
> org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:460)
>       at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
>       at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
>       at junit.extensions.TestSetup.run(TestSetup.java:25)
>       at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
>       at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
>       at junit.extensions.TestSetup.run(TestSetup.java:25)
>       at 
> org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:58)
>       at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
>       at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
>       at junit.extensions.TestSetup.run(TestSetup.java:25)
> Caused by: junit.framework.AssertionFailedError: Column value mismatch @ 
> column 'ID', row 1:
>     Expected: >4<
>     Found:    >6<
>       at 
> org.apache.derbyTesting.junit.JDBC.assertRowInResultSet(JDBC.java:1492)
> {noformat}
> And the stack trace deletion patterns in the Sed class seem to be missing out 
> on some stack frames now, causing failures like this one in dblook_test and 
> dblook_test_territory:
> {noformat}
> ********* Diff file derbyall/derbytools/dblook_test.diff
> *** Start: dblook_test jdk9-ea derbyall:derbytools 2016-03-29 14:16:38 ***
> 6511a6512
> >     at java.io.FileInputStream.open0(java.base@9-ea/Native Method)
> Test Failed.
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to