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:57:08 UTC

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

Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X a3ad1323c -> 435bb12c3


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/a8c58748
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/a8c58748
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/a8c58748

Branch: refs/heads/GROOVY_2_6_X
Commit: a8c587488a3841e221f997dd6427239e6dad9719
Parents: a3ad132
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:55:14 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/a8c58748/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/a8c58748/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/a8c58748/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/a8c58748/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/a8c58748/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')
-    }
 }


[5/5] 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/3908d139
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3908d139
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3908d139

Branch: refs/heads/GROOVY_2_6_X
Commit: 3908d13905aa1c863f39b33a791b2ee6a434e6f9
Parents: a8c5874
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:55:15 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/3908d139/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/3908d139/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/3908d139/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() {


[3/5] 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/8d70cdb3
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8d70cdb3
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8d70cdb3

Branch: refs/heads/GROOVY_2_6_X
Commit: 8d70cdb31a0fa3aff6ab78e909d98d8485832279
Parents: b05a763
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:55:15 2017 -0700

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


http://git-wip-us.apache.org/repos/asf/groovy/blob/8d70cdb3/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/5] 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/435bb12c
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/435bb12c
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/435bb12c

Branch: refs/heads/GROOVY_2_6_X
Commit: 435bb12c30706d12db644f66e447794049c84343
Parents: 8d70cdb
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:55:15 2017 -0700

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


http://git-wip-us.apache.org/repos/asf/groovy/blob/435bb12c/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;
     }
 
     /**


[2/5] 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/b05a7633
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/b05a7633
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/b05a7633

Branch: refs/heads/GROOVY_2_6_X
Commit: b05a76333c7462c411bdda949261555a2c586b6f
Parents: 3908d13
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:55:15 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/b05a7633/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/b05a7633/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
             }
         }