You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2017/07/18 01:48:53 UTC

[1/6] groovy git commit: GROOVY-8251: Implement withCloseable on AutoCloseable (closes #572)

Repository: groovy
Updated Branches:
  refs/heads/master 6a8232a5b -> 4fae56bb8


GROOVY-8251: Implement withCloseable on AutoCloseable (closes #572)

Relocate withAutoCloseable from NIO subproject to core. Since
AutoCloseable is not strictly an NIO related class and release
2.5.0 will target Java 7, the method should be available as part
of core.

Relocated withCloseable tests to core since that method has
already been moved to core and is deprecated in the NIO module.


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9d8e4335
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9d8e4335
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9d8e4335

Branch: refs/heads/master
Commit: 9d8e433533b8d5d8e84d768db5190291ddc6b598
Parents: 6a8232a
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 09:16:12 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:45:11 2017 -0700

----------------------------------------------------------------------
 .../runtime/DefaultGroovyMethodsSupport.java    |  15 ++-
 .../groovy/runtime/IOGroovyMethods.java         |  24 ++++
 .../groovy/runtime/IOGroovyMethodsTest.groovy   | 126 +++++++++++++++++++
 .../groovy/runtime/NioGroovyMethods.java        |  44 -------
 .../groovy/runtime/NioGroovyMethodsTest.groovy  |  69 ----------
 5 files changed, 162 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/9d8e4335/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
index a81f292..dc370d8 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
@@ -86,10 +86,19 @@ public class DefaultGroovyMethodsSupport {
      * @param c the thing to close
      */
     public static void closeWithWarning(Closeable c) {
-        if (c != null) {
+        closeWithWarning((AutoCloseable) c);
+    }
+
+    /**
+     * Close the AutoCloseable. Logging a warning if any problems occur.
+     *
+     * @param closeable the thing to close
+     */
+    public static void closeWithWarning(AutoCloseable closeable) {
+        if (closeable != null) {
             try {
-                c.close();
-            } catch (IOException e) {
+                closeable.close();
+            } catch (Exception e) {
                 LOG.warning("Caught exception during close(): " + e);
             }
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/9d8e4335/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
index e7c26fd..57ea844 100644
--- a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
@@ -1610,6 +1610,30 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
         }
     }
 
+    /**
+     * Allows this AutoCloseable to be used within the closure, ensuring that it
+     * is closed once the closure has been executed and before this method returns.
+     *
+     * @param self the AutoCloseable
+     * @param action the closure taking the AutoCloseable as parameter
+     * @return the value returned by the closure
+     * @throws Exception if an Exception occurs.
+     * @since 2.5.0
+     */
+    public static <T, U extends AutoCloseable> T withAutoCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
+        try {
+            T result = action.call(self);
+
+            U temp = self;
+            self = null;
+            temp.close();
+
+            return result;
+        } finally {
+            DefaultGroovyMethodsSupport.closeWithWarning(self);
+        }
+    }
+
     static void writeUTF16BomIfRequired(final Writer writer, final String charset) throws IOException {
         writeUTF16BomIfRequired(writer, Charset.forName(charset));
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/9d8e4335/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
new file mode 100644
index 0000000..b66936c
--- /dev/null
+++ b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
@@ -0,0 +1,126 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.runtime
+
+class IOGroovyMethodsTest extends GroovyTestCase {
+
+    void testWithAutoCloseable() {
+        def closeable = new DummyAutoCloseable()
+        def closeableParam = null
+        def result = closeable.withAutoCloseable {
+            closeableParam = it
+            123
+        }
+        assert closeableParam == closeable
+        assert result == 123
+        assert closeable.closed
+    }
+
+    void testWithAutoCloseableDoesNotSuppressException() {
+        def closeable = new DummyAutoCloseable(new Exception('close exception'))
+        def message = shouldFail(UnsupportedOperationException) {
+            closeable.withAutoCloseable {
+                throw new UnsupportedOperationException('not a close exception')
+            }
+        }
+        assert closeable.closed
+        assert message == 'not a close exception'
+    }
+
+    void testWithAutoCloseableAndException() {
+        def closeable = new DummyAutoCloseable(new Exception('close exception'))
+        def result = null
+        def message = shouldFail(Exception) {
+            closeable.withAutoCloseable {
+                result = 123
+            }
+        }
+        assert result == 123
+        assert message == 'close exception'
+    }
+
+    void testWithCloseable() {
+        def closeable = new DummyCloseable()
+        def closeableParam = null
+        def result = closeable.withCloseable {
+            closeableParam = it
+            123
+        }
+        assert closeableParam == closeable
+        assert result == 123
+        assert closeable.closed
+    }
+
+    void testWithCloseableDoesNotSuppressException() {
+        def closeable = new DummyCloseable(new IOException('close ioexception'))
+        def message = shouldFail(UnsupportedOperationException) {
+            closeable.withCloseable {
+                throw new UnsupportedOperationException('not a close ioexception')
+            }
+        }
+        assert closeable.closed
+        assert message == 'not a close ioexception'
+    }
+
+    void testWithCloseableAndException() {
+        def closeable = new DummyCloseable(new IOException('close ioexception'))
+        def result = null
+        def message = shouldFail(IOException) {
+            closeable.withCloseable {
+                result = 123
+            }
+        }
+        assert result == 123
+        assert message == 'close ioexception'
+    }
+
+    // --------------------------------------------------------------------
+    // Helper Classes
+
+    static class DummyAutoCloseable implements AutoCloseable {
+        Exception throwOnClose
+        boolean closed
+        DummyAutoCloseable(Exception throwOnClose=null) {
+            this.throwOnClose = throwOnClose
+        }
+        @Override
+        void close() throws Exception {
+            closed = true
+            if (throwOnClose) {
+                throw throwOnClose
+            }
+        }
+    }
+
+    static class DummyCloseable implements Closeable {
+        Exception throwOnClose
+        boolean closed
+        DummyCloseable(Exception throwOnClose=null) {
+            this.throwOnClose = throwOnClose
+        }
+        @Override
+        void close() throws IOException {
+            closed = true
+            if (throwOnClose) {
+                throw throwOnClose
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/9d8e4335/subprojects/groovy-nio/src/main/java/org/codehaus/groovy/runtime/NioGroovyMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-nio/src/main/java/org/codehaus/groovy/runtime/NioGroovyMethods.java b/subprojects/groovy-nio/src/main/java/org/codehaus/groovy/runtime/NioGroovyMethods.java
index 6ac4837..385bcaa 100644
--- a/subprojects/groovy-nio/src/main/java/org/codehaus/groovy/runtime/NioGroovyMethods.java
+++ b/subprojects/groovy-nio/src/main/java/org/codehaus/groovy/runtime/NioGroovyMethods.java
@@ -50,7 +50,6 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.logging.Logger;
 import java.util.regex.Pattern;
 
 import groovy.io.FileType;
@@ -60,7 +59,6 @@ import groovy.lang.Closure;
 import groovy.lang.MetaClass;
 import groovy.lang.Writable;
 import groovy.transform.stc.ClosureParams;
-import groovy.transform.stc.FirstParam;
 import groovy.transform.stc.FromString;
 import groovy.transform.stc.PickFirstResolver;
 import groovy.transform.stc.SimpleType;
@@ -113,8 +111,6 @@ import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
 
 public class NioGroovyMethods extends DefaultGroovyMethodsSupport {
 
-    private static final Logger LOG = Logger.getLogger(NioGroovyMethods.class.getName());
-
     /**
      * Provide the standard Groovy <code>size()</code> method for <code>Path</code>.
      *
@@ -1949,44 +1945,4 @@ public class NioGroovyMethods extends DefaultGroovyMethodsSupport {
         return IOGroovyMethods.withCloseable(self, action);
     }
 
-    /**
-     * Allows this autocloseable to be used within the closure, ensuring that it
-     * is closed once the closure has been executed and before this method returns.
-     *
-     * @param self the AutoCloseable
-     * @param action the closure taking the AutoCloseable as parameter
-     * @return the value returned by the closure
-     * @throws Exception if an Exception occurs.
-     * @since 2.5.0
-     */
-    public static <T, U extends AutoCloseable> T withAutoCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
-        try {
-            T result = action.call(self);
-
-            AutoCloseable temp = self;
-            self = null;
-            temp.close();
-
-            return result;
-        } finally {
-            closeWithWarning(self);
-        }
-    }
-
-    /**
-     * Close the AutoCloseable. Logging a warning if any problems occur.
-     *
-     * @param c the thing to close
-     */
-    public static void closeWithWarning(AutoCloseable c) {
-        if (c != null) {
-            try {
-                c.close();
-            } catch (Exception e) {
-                LOG.warning("Caught exception during close(): " + e);
-            }
-        }
-    }
-
-
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/9d8e4335/subprojects/groovy-nio/src/test/groovy/org/codehaus/groovy/runtime/NioGroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-nio/src/test/groovy/org/codehaus/groovy/runtime/NioGroovyMethodsTest.groovy b/subprojects/groovy-nio/src/test/groovy/org/codehaus/groovy/runtime/NioGroovyMethodsTest.groovy
index 86bc596..01fc88e 100644
--- a/subprojects/groovy-nio/src/test/groovy/org/codehaus/groovy/runtime/NioGroovyMethodsTest.groovy
+++ b/subprojects/groovy-nio/src/test/groovy/org/codehaus/groovy/runtime/NioGroovyMethodsTest.groovy
@@ -543,73 +543,4 @@ class NioGroovyMethodsTest extends Specification {
         assert NioGroovyMethods.getBytes(path) == [-2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 119, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33] as byte[]
     }
 
-    def testWithCloseable() {
-        setup:
-        def closeable = new DummyCloseable()
-
-        when:
-        def closeableParam = null
-        def result = closeable.withCloseable {
-            closeableParam = it
-            123
-        }
-
-        then:
-        closeableParam == closeable
-        result == 123
-        closeable.closed
-    }
-
-    def testWithAutoCloseable() {
-        setup:
-            def closeable = new DummyAutoCloseable()
-
-        when:
-            def closeableParam = null
-            def result = closeable.withAutoCloseable {
-                closeableParam = it
-                123
-            }
-
-        then:
-            closeableParam == closeable
-            result == 123
-            closeable.closed
-    }
-
-    def testWithCloseableAndException() {
-        setup:
-        def closeable = new ExceptionDummyCloseable()
-
-        when:
-        closeable.close()
-
-        then:
-        thrown IOException
-    }
-}
-
-class DummyCloseable implements Closeable {
-    boolean closed = false
-
-    @Override
-    void close() throws IOException {
-        closed = true
-    }
-}
-
-class DummyAutoCloseable implements AutoCloseable {
-    boolean closed = false
-
-    @Override
-    void close() throws IOException {
-        closed = true
-    }
-}
-
-class ExceptionDummyCloseable implements Closeable {
-    @Override
-    void close() throws IOException {
-        throw new IOException('boom badaboom')
-    }
 }


[6/6] groovy git commit: GroovyRunnerRegistry iterator benchmarks

Posted by jw...@apache.org.
GroovyRunnerRegistry iterator benchmarks


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/4fae56bb
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/4fae56bb
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/4fae56bb

Branch: refs/heads/master
Commit: 4fae56bb84f63c8b3015cfc3004200e00d9b5c7d
Parents: 8ae2a96
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 18:33:20 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:46:47 2017 -0700

----------------------------------------------------------------------
 subprojects/performance/README.adoc             | 24 ++++++-
 subprojects/performance/build.gradle            |  4 +-
 .../plugin/GroovyRunnerRegistryBench.java       | 67 ++++++++++++++++++++
 3 files changed, 91 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4fae56bb/subprojects/performance/README.adoc
----------------------------------------------------------------------
diff --git a/subprojects/performance/README.adoc b/subprojects/performance/README.adoc
index c134f15..e6e4aa1 100644
--- a/subprojects/performance/README.adoc
+++ b/subprojects/performance/README.adoc
@@ -21,15 +21,21 @@
 
 = Performance
 
-This subproject contains two sets of performance related tests.  The first
-are compiler tests that can be run using the following Gradle task:
+This subproject contains two sets of performance related tests, compiler tests
+and benchmarks.
+
+== Compiler Performance Tests
+
+The compiler tests can be run using the following Gradle task:
 
     ./gradlew :perf:performanceTests
 
 This will compile various source files using several past versions of Apache
 Groovy in addition to the current source version.
 
-This subproject also contains `JMH` Benchmarks which can be run using:
+== Benchmarks
+
+JMH Benchmarks can be run using:
 
     ./gradlew :perf:jmh
 
@@ -37,3 +43,15 @@ In order to run the benchmarks against InvokeDynamic generated classes use
 the `indy` property:
 
     ./gradlew -Pindy=true :perf:jmh
+
+Groovy and Java sources placed in `src/test` will also be available to the
+benchmarks.
+
+To run a single benchmark or a matched set of benchmarks, use the
+`benchInclude` property:
+
+    ./gradlew -PbenchInclude=CallsiteBench :perf:jmh
+
+The `benchInclude` property will perform a partial match against package
+names or class names. It is equivalent to `.*${benchInclude}.*`.
+

http://git-wip-us.apache.org/repos/asf/groovy/blob/4fae56bb/subprojects/performance/build.gradle
----------------------------------------------------------------------
diff --git a/subprojects/performance/build.gradle b/subprojects/performance/build.gradle
index bf30ff3..f8ba8d8 100644
--- a/subprojects/performance/build.gradle
+++ b/subprojects/performance/build.gradle
@@ -36,7 +36,9 @@ dependencies {
 
 jmh {
     jmhVersion = '1.19'
-    include = ['.*']
+    if (project.hasProperty('benchInclude')) {
+        include = ['.*' + project.benchInclude + '.*']
+    }
     includeTests = true
     resultsFile = project.file("target/results${useIndy() ? '_indy' : ''}.txt")
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/4fae56bb/subprojects/performance/src/jmh/java/org/apache/groovy/plugin/GroovyRunnerRegistryBench.java
----------------------------------------------------------------------
diff --git a/subprojects/performance/src/jmh/java/org/apache/groovy/plugin/GroovyRunnerRegistryBench.java b/subprojects/performance/src/jmh/java/org/apache/groovy/plugin/GroovyRunnerRegistryBench.java
new file mode 100644
index 0000000..a419e54
--- /dev/null
+++ b/subprojects/performance/src/jmh/java/org/apache/groovy/plugin/GroovyRunnerRegistryBench.java
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.plugin;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
+@Fork(3)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class GroovyRunnerRegistryBench {
+
+    static List<Object> control = new LinkedList<>();
+    static GroovyRunnerRegistry registry = GroovyRunnerRegistry.getInstance();
+    static {
+        control.add(new Object());
+        control.add(new Object());
+        control.add(new Object());
+        registry.load(GroovyRunnerRegistryBench.class.getClassLoader());
+    }
+
+    @Benchmark
+    public void registryIterator(Blackhole bh) {
+        for (GroovyRunner runner : registry) {
+            bh.consume(runner);
+        }
+    }
+
+    @Benchmark
+    public void linkedListIterator(Blackhole bh) {
+        for (Object obj : control) {
+            bh.consume(obj);
+        }
+    }
+
+}


[3/6] groovy git commit: GROOVY-8251: rename withAutoCloseable to withCloseable

Posted by jw...@apache.org.
GROOVY-8251: rename withAutoCloseable to withCloseable

AutoCloseables and Closeables should both be handled consistently.
Naming the method withCloseable is general enough to handle both
cases without requiring distinct naming.


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/b9541f92
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/b9541f92
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/b9541f92

Branch: refs/heads/master
Commit: b9541f92c57a2f6e86eb4e634ab216464c42ce08
Parents: daee97c
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 11:03:12 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:45:24 2017 -0700

----------------------------------------------------------------------
 src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java      | 2 +-
 .../org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy     | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b9541f92/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
index 789e0fd..f33d377 100644
--- a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
@@ -1633,7 +1633,7 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
      * @throws Exception if an Exception occurs.
      * @since 2.5.0
      */
-    public static <T, U extends AutoCloseable> T withAutoCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
+    public static <T, U extends AutoCloseable> T withCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
         Throwable thrown = null;
         try {
             return action.call(self);

http://git-wip-us.apache.org/repos/asf/groovy/blob/b9541f92/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
index c5b42d2..e7baa43 100644
--- a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
+++ b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
@@ -25,7 +25,7 @@ class IOGroovyMethodsTest extends GroovyTestCase {
     void testWithAutoCloseable() {
         def closeable = new DummyAutoCloseable()
         def closeableParam = null
-        def result = closeable.withAutoCloseable {
+        def result = closeable.withCloseable {
             closeableParam = it
             123
         }
@@ -37,7 +37,7 @@ class IOGroovyMethodsTest extends GroovyTestCase {
     void testWithAutoCloseableDoesNotSuppressException() {
         def closeable = new DummyAutoCloseable(new Exception('close exception'))
         def throwable = GroovyAssert.shouldFail(UnsupportedOperationException) {
-            closeable.withAutoCloseable {
+            closeable.withCloseable {
                 throw new UnsupportedOperationException('not a close exception')
             }
         }
@@ -50,7 +50,7 @@ class IOGroovyMethodsTest extends GroovyTestCase {
         def closeable = new DummyAutoCloseable(new Exception('close exception'))
         def result = null
         def message = shouldFail(Exception) {
-            closeable.withAutoCloseable {
+            closeable.withCloseable {
                 result = 123
             }
         }


[2/6] groovy git commit: removed unneeded method

Posted by jw...@apache.org.
removed unneeded method


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/85295fb0
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/85295fb0
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/85295fb0

Branch: refs/heads/master
Commit: 85295fb0eeaed8fd41e30e40b298954f6f429cb8
Parents: b9541f9
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 17:23:12 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:45:24 2017 -0700

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethodsSupport.java         | 9 ---------
 1 file changed, 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/85295fb0/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
index 69f387a..e3ef111 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
@@ -90,15 +90,6 @@ public class DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Close the AutoCloseable. Logging a warning if any problems occur.
-     *
-     * @param closeable the thing to close
-     */
-    public static void closeWithWarning(AutoCloseable closeable) {
-        tryClose(closeable, true); // ignore result
-    }
-
-    /**
      * Attempts to close the closeable returning rather than throwing
      * any Exception that may occur.
      *


[4/6] groovy git commit: GROOVY-8259: add suppressed exceptions for with[Auto]Closeable methods

Posted by jw...@apache.org.
GROOVY-8259: add suppressed exceptions for with[Auto]Closeable methods


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/daee97c4
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/daee97c4
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/daee97c4

Branch: refs/heads/master
Commit: daee97c40f9fdf316fbc764593c41b7a9f7270a5
Parents: 9d8e433
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 10:55:24 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:45:24 2017 -0700

----------------------------------------------------------------------
 .../runtime/DefaultGroovyMethodsSupport.java    | 25 ++++++++--
 .../groovy/runtime/IOGroovyMethods.java         | 50 +++++++++++++-------
 .../groovy/runtime/IOGroovyMethodsTest.groovy   | 14 ++++--
 3 files changed, 64 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
index dc370d8..69f387a 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
@@ -83,10 +83,10 @@ public class DefaultGroovyMethodsSupport {
     /**
      * Close the Closeable. Logging a warning if any problems occur.
      *
-     * @param c the thing to close
+     * @param closeable the thing to close
      */
-    public static void closeWithWarning(Closeable c) {
-        closeWithWarning((AutoCloseable) c);
+    public static void closeWithWarning(Closeable closeable) {
+        tryClose(closeable, true); // ignore result
     }
 
     /**
@@ -95,13 +95,30 @@ public class DefaultGroovyMethodsSupport {
      * @param closeable the thing to close
      */
     public static void closeWithWarning(AutoCloseable closeable) {
+        tryClose(closeable, true); // ignore result
+    }
+
+    /**
+     * Attempts to close the closeable returning rather than throwing
+     * any Exception that may occur.
+     *
+     * @param closeable the thing to close
+     * @param logWarning if true will log a warning if an exception occurs
+     * @return throwable Exception from the close method, else null
+     */
+    static Throwable tryClose(AutoCloseable closeable, boolean logWarning) {
+        Throwable thrown = null;
         if (closeable != null) {
             try {
                 closeable.close();
             } catch (Exception e) {
-                LOG.warning("Caught exception during close(): " + e);
+                thrown = e;
+                if (logWarning) {
+                    LOG.warning("Caught exception during close(): " + e);
+                }
             }
         }
+        return thrown;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
index 57ea844..789e0fd 100644
--- a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
@@ -1589,6 +1589,10 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Allows this closeable to be used within the closure, ensuring that it
      * is closed once the closure has been executed and before this method returns.
+     * <p>
+     * As with the try-with-resources statement, if multiple exceptions are thrown
+     * the exception from the closure will be returned and the exception from closing
+     * will be added as a suppressed exception.
      *
      * @param self the Closeable
      * @param action the closure taking the Closeable as parameter
@@ -1597,22 +1601,31 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.0
      */
     public static <T, U extends Closeable> T withCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws IOException {
+        Throwable thrown = null;
         try {
-            T result = action.call(self);
-
-            Closeable temp = self;
-            self = null;
-            temp.close();
-
-            return result;
+            return action.call(self);
+        } catch (Throwable e) {
+            thrown = e;
+            throw e;
         } finally {
-            DefaultGroovyMethodsSupport.closeWithWarning(self);
+            if (thrown != null) {
+                Throwable suppressed = tryClose(self, true);
+                if (suppressed != null) {
+                    thrown.addSuppressed(suppressed);
+                }
+            } else {
+                self.close();
+            }
         }
     }
 
     /**
      * Allows this AutoCloseable to be used within the closure, ensuring that it
      * is closed once the closure has been executed and before this method returns.
+     * <p>
+     * As with the try-with-resources statement, if multiple exceptions are thrown
+     * the exception from the closure will be returned and the exception from closing
+     * will be added as a suppressed exception.
      *
      * @param self the AutoCloseable
      * @param action the closure taking the AutoCloseable as parameter
@@ -1621,16 +1634,21 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.5.0
      */
     public static <T, U extends AutoCloseable> T withAutoCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
+        Throwable thrown = null;
         try {
-            T result = action.call(self);
-
-            U temp = self;
-            self = null;
-            temp.close();
-
-            return result;
+            return action.call(self);
+        } catch (Throwable e) {
+            thrown = e;
+            throw e;
         } finally {
-            DefaultGroovyMethodsSupport.closeWithWarning(self);
+            if (thrown != null) {
+                Throwable suppressed = tryClose(self, true);
+                if (suppressed != null) {
+                    thrown.addSuppressed(suppressed);
+                }
+            } else {
+                self.close();
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
index b66936c..c5b42d2 100644
--- a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
+++ b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
@@ -18,6 +18,8 @@
  */
 package org.codehaus.groovy.runtime
 
+import groovy.test.GroovyAssert
+
 class IOGroovyMethodsTest extends GroovyTestCase {
 
     void testWithAutoCloseable() {
@@ -34,13 +36,14 @@ class IOGroovyMethodsTest extends GroovyTestCase {
 
     void testWithAutoCloseableDoesNotSuppressException() {
         def closeable = new DummyAutoCloseable(new Exception('close exception'))
-        def message = shouldFail(UnsupportedOperationException) {
+        def throwable = GroovyAssert.shouldFail(UnsupportedOperationException) {
             closeable.withAutoCloseable {
                 throw new UnsupportedOperationException('not a close exception')
             }
         }
         assert closeable.closed
-        assert message == 'not a close exception'
+        assert throwable.message == 'not a close exception'
+        assert throwable.suppressed.find { it.message == 'close exception' }
     }
 
     void testWithAutoCloseableAndException() {
@@ -69,13 +72,14 @@ class IOGroovyMethodsTest extends GroovyTestCase {
 
     void testWithCloseableDoesNotSuppressException() {
         def closeable = new DummyCloseable(new IOException('close ioexception'))
-        def message = shouldFail(UnsupportedOperationException) {
+        def throwable = GroovyAssert.shouldFail(Exception) {
             closeable.withCloseable {
-                throw new UnsupportedOperationException('not a close ioexception')
+                throw new Exception('not a close ioexception')
             }
         }
         assert closeable.closed
-        assert message == 'not a close ioexception'
+        assert throwable.message == 'not a close ioexception'
+        assert throwable.suppressed.find { it.message == 'close ioexception' }
     }
 
     void testWithCloseableAndException() {


[5/6] groovy git commit: cache GroovyRunnerRegistry values (closes #575)

Posted by jw...@apache.org.
cache GroovyRunnerRegistry values (closes #575)

The registry should be read heavy and most use made of the
iterator.  Few writes/loads should occur, so values should
be cached in order to optimize iteration.


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8ae2a964
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8ae2a964
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8ae2a964

Branch: refs/heads/master
Commit: 8ae2a9647ba57bf72eeec22a341ca6d7a43cb8e8
Parents: 85295fb
Author: John Wagenleitner <jw...@apache.org>
Authored: Sat Jul 15 07:00:29 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:46:04 2017 -0700

----------------------------------------------------------------------
 .../groovy/plugin/GroovyRunnerRegistry.java     | 40 +++++++++++++++-----
 1 file changed, 31 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/8ae2a964/src/main/org/apache/groovy/plugin/GroovyRunnerRegistry.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/groovy/plugin/GroovyRunnerRegistry.java b/src/main/org/apache/groovy/plugin/GroovyRunnerRegistry.java
index c9f65e8..4ed02e2 100644
--- a/src/main/org/apache/groovy/plugin/GroovyRunnerRegistry.java
+++ b/src/main/org/apache/groovy/plugin/GroovyRunnerRegistry.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
@@ -79,6 +80,15 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
     // Lazily initialized and loaded, should be accessed internally using getMap()
     private volatile Map<String, GroovyRunner> runnerMap;
 
+    /*
+     * Cached unmodifiable List used for iteration. Any method that mutates
+     * the runnerMap must set to null to invalidate the cache. Volatile is
+     * used because reads for DCL are faster than a lock/unlock.
+     * The values are cached in order to speed up iteration and avoid
+     * allocation of new collections on each call to the iterator.
+     */
+    private volatile List<GroovyRunner> cachedValues;
+
     private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
     private final Lock readLock = rwLock.readLock();
     private final Lock writeLock = rwLock.writeLock();
@@ -145,6 +155,7 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
             if (classLoader == null) {
                 classLoader = Thread.currentThread().getContextClassLoader();
             }
+            cachedValues = null;
             loadDefaultRunners();
             loadWithLock(classLoader);
         } catch (SecurityException se) {
@@ -305,6 +316,7 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
         Map<String, GroovyRunner> map = getMap();
         writeLock.lock();
         try {
+            cachedValues = null;
             return map.put(key, runner);
         } finally {
             writeLock.unlock();
@@ -326,6 +338,7 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
         Map<String, GroovyRunner> map = getMap();
         writeLock.lock();
         try {
+            cachedValues = null;
             return map.remove(key);
         } finally {
             writeLock.unlock();
@@ -342,10 +355,14 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
      */
     @Override
     public void putAll(Map<? extends String, ? extends GroovyRunner> m) {
+        Map<String, GroovyRunner> map = getMap();
         writeLock.lock();
         try {
+            cachedValues = null;
             for (Map.Entry<? extends String, ? extends GroovyRunner> entry : m.entrySet()) {
-                put(entry.getKey(), entry.getValue());
+                if (entry.getKey() != null && entry.getValue() != null) {
+                    map.put(entry.getKey(), entry.getValue());
+                }
             }
         } finally {
             writeLock.unlock();
@@ -362,6 +379,7 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
         Map<String, GroovyRunner> map = getMap();
         writeLock.lock();
         try {
+            cachedValues = null;
             map.clear();
             loadDefaultRunners();
         } finally {
@@ -399,16 +417,20 @@ public class GroovyRunnerRegistry implements Map<String, GroovyRunner>, Iterable
      */
     @Override
     public Collection<GroovyRunner> values() {
-        Map<String, GroovyRunner> map = getMap();
-        readLock.lock();
-        try {
-            if (map.isEmpty()) {
-                return Collections.emptyList();
+        List<GroovyRunner> values = cachedValues;
+        if (values == null) {
+            Map<String, GroovyRunner> map = getMap();
+            // racy, multiple threads may set cachedValues but rather have that than take a write lock
+            readLock.lock();
+            try {
+                if ((values = cachedValues) == null) {
+                    cachedValues = values = Collections.unmodifiableList(new ArrayList<>(map.values()));
+                }
+            } finally {
+                readLock.unlock();
             }
-            return Collections.unmodifiableCollection(new ArrayList<>(map.values()));
-        } finally {
-            readLock.unlock();
         }
+        return values;
     }
 
     /**