You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "paulk-asert (via GitHub)" <gi...@apache.org> on 2026/09/03 02:06:12 UTC

[PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

paulk-asert opened a new pull request, #2868:
URL: https://github.com/apache/groovy/pull/2868

   …tHashMap
   
   The cache was a WeakHashMap keyed on file.getAbsolutePath() or url.toString(). Both are freshly built strings local to getTemplate, and TemplateCacheEntry retains only lastModified, length, a Date and the Template, never the File, so nothing outside the map referred to a key once its request returned. Weakly held keys made every entry collectible as soon as it was stored, and the cache emptied at each collection however hot a template was.
   
   The map was also read and written from service() without synchronization. WeakHashMap did not receive the JDK 8 rewrite that ended the HashMap resize infinite-loop, so its transfer() still head-inserts and concurrent resizes can build a cycle that leaves get() spinning.
   
   ConcurrentHashMap addresses both, and is faster besides: WeakHashMap.get polls a ReferenceQueue on every read and dereferences a WeakReference per probe. Templates are now retained for the servlet's lifetime, which is bounded by the templates that exist, since service() answers 404 before getTemplate is reached for a missing file or unresolvable resource. Staleness handling is unchanged, as validate() still compares lastModified and length.
   
   The cache field is private and of declared type Map, TemplateCacheEntry is private, and only get and put are used, so the change is source and binary compatible.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "paulk-asert (via GitHub)" <gi...@apache.org>.
paulk-asert merged PR #2868:
URL: https://github.com/apache/groovy/pull/2868


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2868:
URL: https://github.com/apache/groovy/pull/2868#issuecomment-5519468773

   ## 🚨 TestLens detected 3 failed tests 🚨
   
   Here is what you can do:
   
   1) Inspect the test failures carefully.
   2) If you are convinced that some of the tests are flaky, you can mute them below.
   3) Finally, trigger a rerun by checking the rerun checkbox.
   
   ### Test Summary
   
   #### [Build and test / lts \(17, windows-latest, 1\)](https://github.com/apache/groovy/actions/runs/33706324746/job/100496088822?pr=2868) > :groovy-groovysh:test
   
   | Test | Runs | Flakiness |
   |---|---|--:|
   | GroovyPosixCommandsTest > headAndGrepAndWcStripControlCharactersFromNames\(\) | ❌ | 23%&nbsp;🔴 |
   | GroovyPosixCommandsTest > lsStripsControlCharactersFromFileNames\(\) | ❌ | 23%&nbsp;🔴 |
   | GroovyPosixCommandsTest > lsStripsControlCharactersFromSymlinkTargets\(\) | ❌ | 23%&nbsp;🔴 |
   
   🏷️ Commit: 38f658d078cb97ae4ef242cc104b2f5542125600
   ▶️ Tests:  84130 executed
   🟡 Checks: 19/29 completed
   
   ### Test Failures
   
   <details><summary><strong>GroovyPosixCommandsTest > headAndGrepAndWcStripControlCharactersFromNames()</strong> (:groovy-groovysh:test in <a href="https://github.com/apache/groovy/actions/runs/33706324746/job/100496088822?pr=2868">Build and test / lts (17, windows-latest, 1)</a>)</summary>
   
   ```
   java.nio.file.InvalidPathException: Illegal char <> at index 2: oktrap.txt
   	at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
   	at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
   	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
   	at java.base/java.nio.file.Path.resolve(Path.java:515)
   	at java.base/jdk.internal.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
   	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:391)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.vmplugin.v8.IndyInterface.invokeColdReflective(IndyInterface.java:648)
   	at org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest.headAndGrepAndWcStripControlCharactersFromNames(GroovyPosixCommandsTest.groovy:123)
   ```
   
   </details>
   <details><summary><strong>GroovyPosixCommandsTest > lsStripsControlCharactersFromFileNames()</strong> (:groovy-groovysh:test in <a href="https://github.com/apache/groovy/actions/runs/33706324746/job/100496088822?pr=2868">Build and test / lts (17, windows-latest, 1)</a>)</summary>
   
   ```
   java.nio.file.InvalidPathException: Illegal char <> at index 2: oktrap.txt
   	at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
   	at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
   	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
   	at java.base/java.nio.file.Path.resolve(Path.java:515)
   	at java.base/jdk.internal.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
   	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:391)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.vmplugin.v8.IndyInterface.invokeColdReflective(IndyInterface.java:648)
   	at org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest.lsStripsControlCharactersFromFileNames(GroovyPosixCommandsTest.groovy:97)
   ```
   
   </details>
   <details><summary><strong>GroovyPosixCommandsTest > lsStripsControlCharactersFromSymlinkTargets()</strong> (:groovy-groovysh:test in <a href="https://github.com/apache/groovy/actions/runs/33706324746/job/100496088822?pr=2868">Build and test / lts (17, windows-latest, 1)</a>)</summary>
   
   ```
   java.nio.file.InvalidPathException: Illegal char <> at index 2: oktrap.txt
   	at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
   	at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
   	at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
   	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
   	at java.base/java.nio.file.Path.resolve(Path.java:515)
   	at java.base/jdk.internal.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
   	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:391)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.vmplugin.v8.IndyInterface.invokeColdReflective(IndyInterface.java:648)
   	at org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest.lsStripsControlCharactersFromSymlinkTargets(GroovyPosixCommandsTest.groovy:108)
   ```
   
   </details>
   
   ### Rerun Controls
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 GroovyPosixCommandsTest > headAndGrepAndWcStripControlCharactersFromNames\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest]/[method:headAndGrepAndWcStripControlCharactersFromNames()] -->
   🔲 GroovyPosixCommandsTest > lsStripsControlCharactersFromFileNames\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest]/[method:lsStripsControlCharactersFromFileNames()] -->
   🔲 GroovyPosixCommandsTest > lsStripsControlCharactersFromSymlinkTargets\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:org.apache.groovy.groovysh.jline.GroovyPosixCommandsTest]/[method:lsStripsControlCharactersFromSymlinkTargets()] -->
   
   Reuse successful test results:
   
   🔲 ♻️ Only rerun the tests that failed or were muted before
   
   Click the checkbox to trigger a rerun:
   
   🔲 **Rerun jobs**
   
   ---
   _Learn more about TestLens at [testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "paulk-asert (via GitHub)" <gi...@apache.org>.
paulk-asert commented on code in PR #2868:
URL: https://github.com/apache/groovy/pull/2868#discussion_r3929548795


##########
subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java:
##########
@@ -187,7 +187,7 @@ public String toString() {
      * Create new TemplateServlet.
      */
     public TemplateServlet() {
-        this.cache = new WeakHashMap<String, TemplateCacheEntry>();
+        this.cache = new ConcurrentHashMap<String, TemplateCacheEntry>();

Review Comment:
   In the PDF, I sent out-of-band, you will see that the existing implementation never fulfilled the memory sensitive idea, but I'll do some further work.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2868:
URL: https://github.com/apache/groovy/pull/2868#issuecomment-5534546653

   ## 🚨 TestLens detected 1 failed test 🚨
   
   Here is what you can do:
   
   1) Inspect the test failures carefully.
   2) If you are convinced that some of the tests are flaky, you can mute them below.
   3) Finally, trigger a rerun by checking the rerun checkbox.
   
   ### Test Summary
   
   #### [Build and test / lts \(17, windows-latest, 1\)](https://github.com/apache/groovy/actions/runs/33825312242/job/100876600742?pr=2868) > :test
   
   | Test | Runs | Flakiness |
   |---|---|--:|
   | ChannelSelectTest > testTimerCreatedOnceIsAFixedDeadlineAcrossSelects\(\) | ❌ | 5%&nbsp;🟠 |
   
   🏷️ Commit: 9baad8650cccbb75eae03613bc3e9bfd7f4244f7
   ▶️ Tests:  103336 executed
   🟡 Checks: 21/29 completed
   
   ### Test Failures
   
   <details><summary><strong>ChannelSelectTest > testTimerCreatedOnceIsAFixedDeadlineAcrossSelects()</strong> (:test in <a href="https://github.com/apache/groovy/actions/runs/33825312242/job/100876600742?pr=2868">Build and test / lts (17, windows-latest, 1)</a>)</summary>
   
   ```
   Assertion failed: 
   
   assert deadline.closed
          |        |
          |        false
          AsyncChannel{capacity=1, buffered=0, waitingSenders=0, waitingReceivers=0, closed=false}
   
   	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:409)
   	at TestScript38.run(TestScript38.groovy:20)
   	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:552)
   	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:587)
   	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:571)
   	at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:106)
   	at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:96)
   	at groovy.concurrent.ChannelSelectTest.testTimerCreatedOnceIsAFixedDeadlineAcrossSelects(ChannelSelectTest.groovy:1179)
   ```
   
   </details>
   
   ### Rerun Controls
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 ChannelSelectTest > testTimerCreatedOnceIsAFixedDeadlineAcrossSelects\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:groovy.concurrent.ChannelSelectTest]/[method:testTimerCreatedOnceIsAFixedDeadlineAcrossSelects()] -->
   
   Reuse successful test results:
   
   🔲 ♻️ Only rerun the tests that failed or were muted before
   
   Click the checkbox to trigger a rerun:
   
   🔲 **Rerun jobs**
   
   ---
   _Learn more about TestLens at [testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "paulk-asert (via GitHub)" <gi...@apache.org>.
paulk-asert commented on code in PR #2868:
URL: https://github.com/apache/groovy/pull/2868#discussion_r3930079310


##########
subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java:
##########
@@ -187,7 +187,7 @@ public String toString() {
      * Create new TemplateServlet.
      */
     public TemplateServlet() {
-        this.cache = new WeakHashMap<String, TemplateCacheEntry>();
+        this.cache = new ConcurrentHashMap<String, TemplateCacheEntry>();

Review Comment:
   Updated to use `SoftReference`s. Also considered Weak and ConcurrentSoftCache but the soft references seemed best.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #2868:
URL: https://github.com/apache/groovy/pull/2868#discussion_r3930197170


##########
subprojects/groovy-servlet/src/test/groovy/groovy/servlet/TemplateServletTest.groovy:
##########
@@ -69,6 +69,34 @@ class TemplateServletTest {
         assert responseData.status == null
     }
 
+    @Test
+    void test_compiled_template_is_cached_across_garbage_collection() {
+        def templateFile = new File(temporaryFolder, 'cached.gsp').tap { write 'hello' }
+        def url = templateFile.toURI().toURL()
+        servlet.init(mockServletConfigForUrlResource(url))
+
+        def first = servlet.getTemplate(url)
+        forceGarbageCollection()
+        def second = servlet.getTemplate(url)
+
+        assert second.is(first)
+    }

Review Comment:
   This test asserts template identity across a forced GC (`second.is(first)`), but the implementation now caches via `SoftReference<TemplateCacheEntry>` and the TemplateServlet Javadoc explicitly says callers must not rely on being given the same instance twice. Since soft references may be cleared at any GC (policy/JVM dependent), this assertion can be flaky. Consider asserting the intended regression instead: that the cache key survives GC (i.e., the cache is not a WeakHashMap of weak keys), by reflectively reading the private `cache` and checking it still contains `url.toString()` after `forceGarbageCollection()`.



##########
subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java:
##########
@@ -165,9 +166,11 @@ public String toString() {
     }
 
     /**
-     * Simple file name to template cache map.
+     * File name to template cache, safe for concurrent use. Entries are held softly, so a
+     * template survives ordinary collection but can be reclaimed under memory pressure and
+     * compiled again on the next request.
      */
-    private final Map<String, TemplateCacheEntry> cache;
+    private final Map<String, SoftReference<TemplateCacheEntry>> cache;

Review Comment:
   PR description states templates are retained for the servlet's lifetime once the cache is moved to ConcurrentHashMap, but the code now stores `SoftReference<TemplateCacheEntry>` values (and the Javadoc documents reclaim under memory pressure). Please reconcile the PR description with the implemented behavior (either update the description, or switch back to strong cache values if lifetime retention is the goal).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #2868:
URL: https://github.com/apache/groovy/pull/2868#issuecomment-5519523923

   ## [Codecov](https://app.codecov.io/gh/apache/groovy/pull/2868?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :white_check_mark: All modified and coverable lines are covered by tests.
   :white_check_mark: Project coverage is 70.9426%. Comparing base ([`2ca5668`](https://app.codecov.io/gh/apache/groovy/commit/2ca56681c42e8b0599a878de848098df2155d25e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`38f658d`](https://app.codecov.io/gh/apache/groovy/commit/38f658d078cb97ae4ef242cc104b2f5542125600?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   :warning: Report is 2 commits behind head on master.
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   [![Impacted file tree graph](https://app.codecov.io/gh/apache/groovy/pull/2868/graphs/tree.svg?width=650&height=150&src=pr&token=1r45138NfQ&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)](https://app.codecov.io/gh/apache/groovy/pull/2868?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   
   ```diff
   @@                Coverage Diff                 @@
   ##               master      #2868        +/-   ##
   ==================================================
   + Coverage     70.9418%   70.9426%   +0.0007%     
   - Complexity      37054      37055         +1     
   ==================================================
     Files            1576       1576                
     Lines          134857     134857                
     Branches        24973      24973                
   ==================================================
   + Hits            95670      95671         +1     
   + Misses          30530      30526         -4     
   - Partials         8657       8660         +3     
   ```
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/groovy/pull/2868?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [.../src/main/java/groovy/servlet/TemplateServlet.java](https://app.codecov.io/gh/apache/groovy/pull/2868?src=pr&el=tree&filepath=subprojects%2Fgroovy-servlet%2Fsrc%2Fmain%2Fjava%2Fgroovy%2Fservlet%2FTemplateServlet.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LXNlcnZsZXQvc3JjL21haW4vamF2YS9ncm9vdnkvc2VydmxldC9UZW1wbGF0ZVNlcnZsZXQuamF2YQ==) | `42.9578% <100.0000%> (+3.5211%)` | :arrow_up: |
   
   ... and [4 files with indirect coverage changes](https://app.codecov.io/gh/apache/groovy/pull/2868/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   </details>
   <details><summary> :rocket: New features to boost your workflow: </summary>
   
   - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
   - :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12344: TemplateServlet: hold the template cache in a Concurren… [groovy]

Posted by "blackdrag (via GitHub)" <gi...@apache.org>.
blackdrag commented on code in PR #2868:
URL: https://github.com/apache/groovy/pull/2868#discussion_r3920659834


##########
subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java:
##########
@@ -187,7 +187,7 @@ public String toString() {
      * Create new TemplateServlet.
      */
     public TemplateServlet() {
-        this.cache = new WeakHashMap<String, TemplateCacheEntry>();
+        this.cache = new ConcurrentHashMap<String, TemplateCacheEntry>();

Review Comment:
   I agree that the concurrency issue is fixed very well with ConcurrentHashMap. But even if done wrong, the idea before was a memory sensitive cache. Your solution is removing that idea. Why not a Weak/SoftReference for the value? or a LRUCache or ConcurrentLinkedHashMap



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org