You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@grails.apache.org by "jamesfredley (via GitHub)" <gi...@apache.org> on 2026/07/17 18:40:02 UTC

[PR] Add optional artefact index reader for startup scanning [grails-core]

jamesfredley opened a new pull request, #16000:
URL: https://github.com/apache/grails-core/pull/16000

   ## Summary
   
   - add an optional internal artefact-index reader for META-INF/grails/artefacts.idx
   - ApplicationArtefactScanner uses a valid application-root index (honoring packageNames) and safely falls back to classpath scanning when the index is absent, malformed, unresolvable, or linkage-invalid
   - deterministic ordering, deduplication, and transformed-class inclusion preserved
   
   ## Scope note
   
   This is a starter/seed: it adds only the reader and its safe fallback. The index producer is not included, so the optimization activates only once an `artefacts.idx` is emitted into the application code-source root; until then behavior is unchanged (fallback scanning).
   
   ## Verification
   
   - :grails-core:test --tests ApplicationArtefactScannerSpec
   - :grails-core:test
   - git diff --check
   
   This is an AI-generated starting point for build-time artefact indexing.
   


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

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

   ## ✅ All tests passed ✅
   
   🏷️ Commit: ccc1a3c86abf8b66d3b94b7bc344a07a2d43187c
   ▶️ Tests:  17227 executed
   ⚪️ Checks: 60/60 completed
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#issuecomment-5006463253

   <!-- Bito Reply -->
   The Javadoc in `ArtefactIndexReader.java` has been updated to accurately reflect the current implementation. It now states that the index contains one fully qualified class name per nonempty line and clarifies that any unreadable or unresolvable entry (including empty lines, as enforced by the `className.isEmpty()` check) causes the entire index to be rejected, falling back to a standard classpath scan.
   
   **grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java**
   ```
   * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
    * class name per nonempty line. Any unreadable or unresolvable entry rejects the
    * complete index so callers can use their normal classpath scan.</p>
   ```


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

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

   ## ✅ All tests passed ✅
   
   🏷️ Commit: 7662a262f16ee6f2e9d4fe3d232b3d1686320f19
   ▶️ Tests:  41891 executed
   ⚪️ Checks: 59/59 completed
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "davydotcom (via GitHub)" <gi...@apache.org>.
davydotcom commented on PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#issuecomment-5007273874

   Trying to understand the intent behind this one. Is it for startup speed and if so, how does it help there. PR description just needs a little more to help me understand intent.


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "jdaugherty (via GitHub)" <gi...@apache.org>.
jdaugherty commented on PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#issuecomment-5815950888

   I'm going to move this out of 8.0 given that this is just a seed / not even fully implemented yet.


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "jdaugherty (via GitHub)" <gi...@apache.org>.
jdaugherty commented on code in PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#discussion_r3610604331


##########
grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java:
##########
@@ -0,0 +1,83 @@
+/*
+ *  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
+ *
+ *    https://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 grails.boot.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import grails.io.IOUtils;
+
+/**
+ * Reads the optional application artefact index.
+ *
+ * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
+ * class name per nonempty line. Any unreadable or unresolvable entry rejects the
+ * complete index so callers can use their normal classpath scan.</p>
+ */
+final class ArtefactIndexReader {
+
+    static final String RESOURCE_NAME = "META-INF/grails/artefacts.idx";
+
+    private ArtefactIndexReader() {
+    }
+
+    static Collection<Class> read(Class<?> applicationClass, Collection<String> packageNames) {
+        try {
+            URL resource = new URL(IOUtils.findRootResource(applicationClass), RESOURCE_NAME);
+            Set<Class> classes = new LinkedHashSet<>();
+            return readResource(resource, applicationClass.getClassLoader(), packageNames, classes) ? classes : null;
+        } catch (IOException ignored) {
+            return null;
+        }
+    }
+
+    private static boolean readResource(URL resource, ClassLoader classLoader, Collection<String> packageNames, Set<Class> classes) {
+        try (InputStream inputStream = resource.openStream();
+             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+            String className;
+            while ((className = reader.readLine()) != null) {
+                if (className.isEmpty()) {

Review Comment:
   Rejecting the entire index on an empty line is stricter than it needs to be — a trailing blank line is the most common artifact of text-file generation and concatenation (the spec's own `writeIndex` has to `.trim()` to avoid it). Skipping blank lines (`continue`) keeps the strict-reject behavior for genuinely malformed content while tolerating the boring case. If strictness is intentional as a whole-file integrity signal, the javadoc should say the producer must not emit blank lines, including trailing ones.



##########
grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java:
##########
@@ -0,0 +1,83 @@
+/*
+ *  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
+ *
+ *    https://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 grails.boot.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import grails.io.IOUtils;
+
+/**
+ * Reads the optional application artefact index.
+ *
+ * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
+ * class name per nonempty line. Any unreadable or unresolvable entry rejects the
+ * complete index so callers can use their normal classpath scan.</p>
+ */
+final class ArtefactIndexReader {
+
+    static final String RESOURCE_NAME = "META-INF/grails/artefacts.idx";
+
+    private ArtefactIndexReader() {
+    }
+
+    static Collection<Class> read(Class<?> applicationClass, Collection<String> packageNames) {

Review Comment:
   Two operational concerns for production startup code:
   
   1. **Silence.** Both outcomes are invisible — no log when the index is used, none when it's rejected. A corrupted index silently degrades to slow scanning and nobody finds out; a working index can't be confirmed either. Suggest debug-level logs for "index used (N entries)" and "index rejected, falling back".
   2. **Stale-index hazard.** A valid but *incomplete* index is the dangerous case: developer adds an artefact, index isn't regenerated, and the new class is silently absent from the application — no error, no fallback. The producer side will need a freshness guarantee (or the index should carry a hash/marker the reader can validate), and a kill-switch system property to force scanning would be a cheap escape hatch worth adding in the seed.



##########
grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java:
##########
@@ -0,0 +1,83 @@
+/*
+ *  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
+ *
+ *    https://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 grails.boot.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import grails.io.IOUtils;
+
+/**
+ * Reads the optional application artefact index.
+ *
+ * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
+ * class name per nonempty line. Any unreadable or unresolvable entry rejects the
+ * complete index so callers can use their normal classpath scan.</p>
+ */
+final class ArtefactIndexReader {
+
+    static final String RESOURCE_NAME = "META-INF/grails/artefacts.idx";
+
+    private ArtefactIndexReader() {
+    }
+
+    static Collection<Class> read(Class<?> applicationClass, Collection<String> packageNames) {
+        try {
+            URL resource = new URL(IOUtils.findRootResource(applicationClass), RESOURCE_NAME);
+            Set<Class> classes = new LinkedHashSet<>();
+            return readResource(resource, applicationClass.getClassLoader(), packageNames, classes) ? classes : null;
+        } catch (IOException ignored) {

Review Comment:
   `IOUtils.findRootResource` throws **IllegalStateException**, not IOException, when the class resource can't be resolved (`targetClass.getResource(...)` returning null — e.g. an application class from a classloader that doesn't expose `.class` resources). That escapes this catch and would fail startup, where today the same situation just scans. Since the whole contract of this reader is "never make things worse than the fallback," this should catch that too (e.g. `catch (IOException | RuntimeException)`).



##########
grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java:
##########
@@ -0,0 +1,83 @@
+/*
+ *  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
+ *
+ *    https://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 grails.boot.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import grails.io.IOUtils;
+
+/**
+ * Reads the optional application artefact index.
+ *
+ * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
+ * class name per nonempty line. Any unreadable or unresolvable entry rejects the
+ * complete index so callers can use their normal classpath scan.</p>
+ */
+final class ArtefactIndexReader {
+
+    static final String RESOURCE_NAME = "META-INF/grails/artefacts.idx";
+
+    private ArtefactIndexReader() {
+    }
+
+    static Collection<Class> read(Class<?> applicationClass, Collection<String> packageNames) {
+        try {
+            URL resource = new URL(IOUtils.findRootResource(applicationClass), RESOURCE_NAME);
+            Set<Class> classes = new LinkedHashSet<>();
+            return readResource(resource, applicationClass.getClassLoader(), packageNames, classes) ? classes : null;
+        } catch (IOException ignored) {
+            return null;
+        }
+    }
+
+    private static boolean readResource(URL resource, ClassLoader classLoader, Collection<String> packageNames, Set<Class> classes) {
+        try (InputStream inputStream = resource.openStream();
+             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+            String className;
+            while ((className = reader.readLine()) != null) {
+                if (className.isEmpty()) {
+                    return false;
+                }
+                if (isInPackage(className, packageNames)) {
+                    classes.add(classLoader.loadClass(className));
+                }
+            }
+            return true;
+        } catch (IOException | ClassNotFoundException | LinkageError ignored) {
+            return false;
+        }
+    }
+
+    private static boolean isInPackage(String className, Collection<String> packageNames) {

Review Comment:
   Worth documenting the semantic differences from the `ClassPathScanner` path this replaces, since the future index producer has to compensate for them:
   
   - The scanner only returns classes carrying an annotation whose name starts with `grails.` (default `annotationFilter`); the reader trusts every listed entry with no annotation check, so a hand-edited or buggy index can inject arbitrary classes into the artefact set.
   - The scanner skips `DEFAULT_IGNORED_ROOT_PACKAGES` (`com`, `org`, `net`, …) even when explicitly passed as packageNames; the reader honors them.
   
   Both are fine if the producer mirrors scan semantics exactly, but that contract currently lives nowhere — a sentence in the class javadoc would pin it.



-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

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

   ## 🚨 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
   
   #### [CI / Spring Security Tests \(25\)](https://github.com/apache/grails-core/actions/runs/30209746220/job/89813870535?pr=16000) > :grails-test-examples-spring-security-core-misc-functional-test-app-roles:integrationTest
   
   | Test | Runs | Flakiness |
   |---|---|--:|
   | SecuredControllerSpec > test RoleHierarchyEntry lifecycle | ❌ | 0%&nbsp;🟢 |
   
   🏷️ Commit: 20543425f89a1e0b1154c6140f4b26acba363826
   ▶️ Tests:  40073 executed
   🟡 Checks: 31/53 completed
   
   ### Test Failures
   
   <details>
   
   <summary><strong>SecuredControllerSpec > test RoleHierarchyEntry lifecycle</strong> (:grails-test-examples-spring-security-core-misc-functional-test-app-roles:integrationTest in <a href="https://github.com/apache/grails-core/actions/runs/30209746220/job/89813870535?pr=16000">CI / Spring Security Tests (25)</a>)</summary>
   
   ```
   Condition not satisfied:
   
   pageSource.contains('Sorry, you\'re not authorized to view this page.')
   |          |
   |          false
   <html lang="en" class="no-js"><head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <title>
           Login
       </title>
       <meta name="viewport" content="width=device-width, initial-scale=1">
       
       <meta name="layout" content="main">
       
    
   </head>
   <body>
    
   <div class="container py-5">
       <div class="row justify-content-center">
           <div class="col-11 col-sm-9 col-md-7 col-lg-5 col-xl-4">
               <div class="card shadow-sm">
                   <div class="card-body p-4 p-sm-5">
                       <h1 class="h4 card-title text-center mb-4">Please Login</h1>
    
                       
    
                       <form action="/login/authenticate" method="POST" id="loginForm" autocomplete="off">
                           <div class="mb-3">
                               <label for="username" class="form-label">Username</label>
                               <input type="text" class="form-control" name="username" id="username" autocapitalize="none" autocomplete="username">
                           </div>
    
                           <div class="mb-3">
                               <label for="password" class="form-label">Password</label>
                               <div class="input-group">
                                   <input type="password" class="form-control" name="password" id="password" autocomplete="current-password">
                                   <button class="btn btn-outline-secondary" type="button" id="passwordToggler" onclick="passwordDisplayToggle()" aria-pressed="false" aria-label="Show or hide password">
                                       <i id="passwordTogglerIcon" class="bi bi-eye" aria-hidden="true"></i>
                                   </button>
                               </div>
                           </div>
    
                           <div class="mb-3 form-check">
                               <input type="checkbox" class="form-check-input" name="remember-me" id="remember_me">
                               <label class="form-check-label" for="remember_me">Remember me</label>
                           </div>
    
                           <button type="submit" id="submit" class="btn btn-primary w-100">Login</button>
                       </form>
                   </div>
               </div>
           </div>
       </div>
   </div>
   <script type="text/javascript">
       document.addEventListener("DOMContentLoaded", function () {
           var form = document.forms['loginForm'];
           if (form) {
               form.elements['username'].focus();
           }
       });
    
       function passwordDisplayToggle() {
           var button = document.getElementById("passwordToggler");
           var icon = document.getElementById("passwordTogglerIcon");
           var field = document.getElementById("password");
           var hiding = field.type === "text";
           field.type = hiding ? "password" : "text";
           icon.classList.toggle("bi-eye", hiding);
           icon.classList.toggle("bi-eye-slash", !hiding);
           button.setAttribute("aria-pressed", String(!hiding));
       }
   </script>
    
    
    
   </body></html>
   
   	at demo.SecuredControllerSpec.test RoleHierarchyEntry lifecycle(SecuredControllerSpec.groovy:37)
   ```
   
   </details>
   
   ### Muted Tests
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 SecuredControllerSpec > test RoleHierarchyEntry lifecycle <!-- uniqueId=[engine:spock]/[spec:demo.SecuredControllerSpec]/[feature:$spock_feature_1_0] -->
   
   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](https://testlens.app)._
   


-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#discussion_r3605412376


##########
grails-core/src/main/groovy/grails/boot/config/ArtefactIndexReader.java:
##########
@@ -0,0 +1,83 @@
+/*
+ *  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
+ *
+ *    https://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 grails.boot.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import grails.io.IOUtils;
+
+/**
+ * Reads the optional application artefact index.
+ *
+ * <p>The index is UTF-8 text at {@value #RESOURCE_NAME}, with one fully qualified
+ * class name per nonempty line. Any unreadable or unresolvable entry rejects the
+ * complete index so callers can use their normal classpath scan.</p>
+ */

Review Comment:
   The Javadoc says the index contains one class name per “nonempty line”, but the implementation treats any empty line as a fatal format error (and also ignores entries that don’t match the provided packageNames filter). Please update the Javadoc to reflect the actual parsing/validation rules so index producers don’t get conflicting guidance.



-- 
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@grails.apache.org

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


Re: [PR] Add optional artefact index reader for startup scanning [grails-core]

Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #16000:
URL: https://github.com/apache/grails-core/pull/16000#issuecomment-5006736656

   ## [Codecov](https://app.codecov.io/gh/apache/grails-core/pull/16000?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :x: Patch coverage is `84.00000%` with `4 lines` in your changes missing coverage. Please review.
   :white_check_mark: Project coverage is 51.1265%. Comparing base ([`b980413`](https://app.codecov.io/gh/apache/grails-core/commit/b980413820757347744aa6c10c44d7103babea39?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`ccc1a3c`](https://app.codecov.io/gh/apache/grails-core/commit/ccc1a3c86abf8b66d3b94b7bc344a07a2d43187c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/grails-core/pull/16000?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
   |---|---|---|
   | [...groovy/grails/boot/config/ArtefactIndexReader.java](https://app.codecov.io/gh/apache/grails-core/pull/16000?src=pr&el=tree&filepath=grails-core%2Fsrc%2Fmain%2Fgroovy%2Fgrails%2Fboot%2Fconfig%2FArtefactIndexReader.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-Z3JhaWxzLWNvcmUvc3JjL21haW4vZ3Jvb3Z5L2dyYWlscy9ib290L2NvbmZpZy9BcnRlZmFjdEluZGV4UmVhZGVyLmphdmE=) | 80.0000% | [2 Missing and 2 partials :warning: ](https://app.codecov.io/gh/apache/grails-core/pull/16000?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   [![Impacted file tree graph](https://app.codecov.io/gh/apache/grails-core/pull/16000/graphs/tree.svg?width=650&height=150&src=pr&token=qJrryhpk7u&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)](https://app.codecov.io/gh/apache/grails-core/pull/16000?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   
   ```diff
   @@               Coverage Diff                @@
   ##             8.0.x     #16000         +/-   ##
   ================================================
   + Coverage         0   51.1265%   +51.1265%     
   - Complexity       0      17611      +17611     
   ================================================
     Files            0       2042       +2042     
     Lines            0      95516      +95516     
     Branches         0      16594      +16594     
   ================================================
   + Hits             0      48834      +48834     
   - Misses           0      39393      +39393     
   - Partials         0       7289       +7289     
   ```
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/grails-core/pull/16000?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [...ails/boot/config/ApplicationArtefactScanner.groovy](https://app.codecov.io/gh/apache/grails-core/pull/16000?src=pr&el=tree&filepath=grails-core%2Fsrc%2Fmain%2Fgroovy%2Fgrails%2Fboot%2Fconfig%2FApplicationArtefactScanner.groovy&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-Z3JhaWxzLWNvcmUvc3JjL21haW4vZ3Jvb3Z5L2dyYWlscy9ib290L2NvbmZpZy9BcHBsaWNhdGlvbkFydGVmYWN0U2Nhbm5lci5ncm9vdnk=) | `75.0000% <100.0000%> (ø)` | |
   | [...groovy/grails/boot/config/ArtefactIndexReader.java](https://app.codecov.io/gh/apache/grails-core/pull/16000?src=pr&el=tree&filepath=grails-core%2Fsrc%2Fmain%2Fgroovy%2Fgrails%2Fboot%2Fconfig%2FArtefactIndexReader.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-Z3JhaWxzLWNvcmUvc3JjL21haW4vZ3Jvb3Z5L2dyYWlscy9ib290L2NvbmZpZy9BcnRlZmFjdEluZGV4UmVhZGVyLmphdmE=) | `80.0000% <80.0000%> (ø)` | |
   
   ... and [2040 files with indirect coverage changes](https://app.codecov.io/gh/apache/grails-core/pull/16000/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@grails.apache.org

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