Skip to content

Implemented PagedSearchBasedFetcher Of ScholarApi for List API - #16293

Open
thesauravpoddar wants to merge 19 commits into
JabRef:mainfrom
thesauravpoddar:16233
Open

Implemented PagedSearchBasedFetcher Of ScholarApi for List API#16293
thesauravpoddar wants to merge 19 commits into
JabRef:mainfrom
thesauravpoddar:16233

Conversation

@thesauravpoddar

@thesauravpoddar thesauravpoddar commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Related issues and pull requests

Closes #16233

PR Description

This pull Request creates fetcher for ScholarApi for List Api https://scholarapi.net/docs/api#GET/list Implemented all necessary classes and test

ScholarApi fetcher is visible in web search

image image

test connection passed successfully with the real API KEY taken from ScholarApi website

image

Following are the results i got using graphene keyword and the results are 20 per page and next page is loading as we can see

image

Steps to test

export ScholarApiKey='your-api-key'
./gradlew :jablib:fetcherTest --tests "*ScholarApiFetcherTest" 
./gradlew :jablib:Test --tests "*ScholarQueryTransformerTest"

AI usage


AI CHECKLIST.md walkthrough

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • [/] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • [/] I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [/] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@github-actions github-actions Bot added good first issue An issue intended for project-newcomers. Varies in difficulty. component: fetcher labels Jul 20, 2026
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Add ScholarApi-backed paged “Scholar” web search fetcher

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add a new ScholarApi-based fetcher to web search with paged “load more” support.
• Wire ScholarApiKey through build properties, default fetcher keys, and CI secrets.
• Add query transformer and JUnit tests for JSON mapping and paging behavior.
Diagram

graph TD
UI["Web search UI"] --> WF["WebFetchers"] --> SF["ScholarFetcher"] --> API{{"ScholarApi /list"}}
SF --> QT["Query transformer"]
SF --> IP["ImporterPreferences"] --> BI["BuildInfo keys"]
T["Fetcher tests"] --> SF
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Token-based paging instead of in-memory cursor cache
  • ➕ Removes the requirement to fetch pages strictly sequentially
  • ➕ Avoids cursorCacheMap growth/invalidation concerns
  • ➕ Makes paging resilient across new fetcher instances (e.g., UI refresh)
  • ➖ Requires interface/UI changes (Page needs to carry/accept a cursor token)
  • ➖ Higher refactor cost across paging infrastructure
2. Introduce a dedicated paging session object
  • ➕ Encapsulates cursor lifecycle and enables eviction/limits
  • ➕ Avoids embedding state in the fetcher itself
  • ➖ Adds another abstraction to manage and pass around
  • ➖ Still requires session management by callers
3. Standardize on a Parser-based fetcher pipeline
  • ➕ Aligns with other fetchers that use a shared download/parse path
  • ➕ Can simplify testing and reuse post-processing utilities
  • ➖ Still needs custom handling for ScholarApi’s cursor pagination
  • ➖ Potentially over-engineered for a single endpoint

Recommendation: The current cursor-cache approach is a pragmatic fit for the existing pageNumber-based paging API and should work well when pages are fetched sequentially. If the UI or callers ever request pages out of order (or multiple concurrent sessions are common), consider moving to a token/session-based paging design. Also verify CI/env wiring: the workflow exports scholarApiKey, while the build expects ScholarApiKey, which may prevent CI from supplying the key.

Files changed (11) +421 / -3

Enhancement (3) +260 / -2
WebFetchers.javaRegister ScholarFetcher in fetcher registries +5/-2

Register ScholarFetcher in fetcher registries

• Adds ScholarFetcher to the search-based fetcher list and to the customizable-key fetcher set so it appears in web search and key settings.

jablib/src/main/java/org/jabref/logic/importer/WebFetchers.java

ScholarFetcher.javaImplement ScholarApi cursor-paged list fetcher +212/-0

Implement ScholarApi cursor-paged list fetcher

• Introduces a new PagedSearchBasedFetcher + CustomizableKeyFetcher that calls ScholarApi’s /api/v1/list endpoint with X-API-Key, converts JSON items into BibEntry fields, and supports paging via 'next_indexed_after' cursor caching.

jablib/src/main/java/org/jabref/logic/importer/fetcher/ScholarFetcher.java

ScholarApiQueryTransformer.javaAdd ScholarApi query transformer +43/-0

Add ScholarApi query transformer

• Implements logical operators and adjusts unsupported field scoping: author/title become quoted free-text and journal scoping is dropped with a warning; year constraints are extracted for client-side filtering.

jablib/src/main/java/org/jabref/logic/importer/fetcher/transformers/ScholarApiQueryTransformer.java

Tests (2) +151 / -0
ScholarApiFetcherTest.javaAdd ScholarFetcher tests for mapping and paging +133/-0

Add ScholarFetcher tests for mapping and paging

• Adds tests for JSON-to-BibEntry mapping and blank-query paging behavior; integrates with shared capability/paging test interfaces and disables unsupported capability tests (author/journal) and an unstable CI paging test.

jablib/src/test/java/org/jabref/logic/importer/fetcher/ScholarApiFetcherTest.java

ScholarApiQueryTransformerTest.javaAdd ScholarApiQueryTransformer test coverage +18/-0

Add ScholarApiQueryTransformer test coverage

• Reuses the shared year/year-range transformer test suite for ScholarApiQueryTransformer and disables journal-prefix behavior as unsupported by the API.

jablib/src/test/java/org/jabref/logic/importer/fetcher/transformers/ScholarApiQueryTransformerTest.java

Documentation (1) +1 / -1
fetchers.mdDocument ScholarApi fetcher and API key variable +1/-1

Document ScholarApi fetcher and API key variable

• Adds ScholarApi to the fetcher documentation table, including signup link, key name (ScholarApiKey), and credit limits.

docs/code-howtos/fetchers.md

Other (5) +9 / -0
tests-code.ymlExpose ScholarApi test secret to CI environment +1/-0

Expose ScholarApi test secret to CI environment

• Adds a ScholarApi key secret to the workflow environment so fetcher tests can call the real API during CI.

.github/workflows/tests-code.yml

build.gradle.ktsInject ScholarApiKey into processed build resources +3/-0

Inject ScholarApiKey into processed build resources

• Reads ScholarApiKey from the environment, registers it as a ProcessResources input, and writes it into build.properties placeholders.

jablib/build.gradle.kts

ImporterPreferences.javaAdd default key mapping for Scholar fetcher +2/-0

Add default key mapping for Scholar fetcher

• Registers ScholarFetcher in the default fetcher-key map so the API key can be resolved from BuildInfo and shown in preferences.

jablib/src/main/java/org/jabref/logic/importer/ImporterPreferences.java

BuildInfo.javaAdd ScholarApi key to BuildInfo +2/-0

Add ScholarApi key to BuildInfo

• Adds a scholarApiKey field and loads it from build.properties so defaults/tests can access the key.

jablib/src/main/java/org/jabref/logic/util/BuildInfo.java

build.propertiesAdd scholarApiKey property placeholder +1/-0

Add scholarApiKey property placeholder

• Adds the scholarApiKey placeholder to build.properties so it is generated during resource processing.

jablib/src/main/resources/build.properties

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. ScholarFetcher unused imports ✓ Resolved 📘 Rule violation ≡ Correctness
Description
ScholarFetcher introduces several unused imports, which will break the build by causing Java
compilation errors and also violate the repository’s Checkstyle UnusedImports rule. This violates
the requirement that new/updated code must compile under the configured Gradle toolchain and will
block merging until fixed.
Code

jablib/src/main/java/org/jabref/logic/importer/fetcher/ScholarFetcher.java[R3-36]

+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jabref.logic.importer.FetcherException;
+import org.jabref.logic.importer.ImporterPreferences;
+import org.jabref.logic.importer.PagedSearchBasedFetcher;
+import org.jabref.logic.importer.ParseException;
+import org.jabref.logic.importer.fetcher.transformers.ScholarApiQueryTransformer;
+import org.jabref.logic.importer.util.JsonReader;
+import org.jabref.logic.net.URLDownload;
+import org.jabref.logic.util.URLUtil;
+import org.jabref.logic.util.strings.StringUtil;
+import org.jabref.model.entry.BibEntry;
+import org.jabref.model.entry.field.StandardField;
+import org.jabref.model.entry.field.UnknownField;
+import org.jabref.model.entry.types.StandardEntryType;
+import org.jabref.model.paging.Page;
+import org.jabref.model.search.query.BaseQueryNode;
+
+import kong.unirest.core.UnirestException;
+import kong.unirest.core.json.JSONArray;
+import kong.unirest.core.json.JSONException;
+import kong.unirest.core.json.JSONObject;
+import org.apache.hc.core5.net.URIBuilder;
+import org.jspecify.annotations.NonNull;
Evidence
PR Compliance ID 1 requires that new/updated code compiles with the configured Gradle toolchain, but
the newly added ScholarFetcher file contains multiple imports that are not referenced anywhere in
the class body, which triggers unused-import failures. In addition, the repository’s Checkstyle
configuration explicitly enables the UnusedImports module, so these unused imports will also fail
the Checkstyle CI job, preventing the PR from merging until the imports are removed or used.

AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Features: AGENTS.md: Use Gradle Toolchain and Modern Java (25+) APIs and Fe...

Comment thread .github/workflows/tests-code.yml Outdated
Comment thread docs/code-howtos/fetchers.md Outdated
@github-actions github-actions Bot mentioned this pull request Jul 20, 2026
2 tasks
@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Jul 20, 2026
@thesauravpoddar

thesauravpoddar commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

fetcher tests are failing not just for the ScholarApi fetcher but others too i tried to look for this i think it has to do something with

paths:
- 'src/main/java/org/jabref/logic/importer/fetcher/**'
In test-code-fetchers.yml

as it should be jablib/src/main/java/org/jabref/logic/importer/fetcher/**

@thesauravpoddar

thesauravpoddar commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

heyy @kopper, @Siedlerchr
can you please review it or guide me how to fix it or is it normal as the fetcher test is failing for others too or i need to do something, i fixed other errors

@subhramit

Copy link
Copy Markdown
Member

Will look at this soon. Tagging our student team as well in the meanwhile as it seems to be a larger PR.
@pluto-han @LoayTarek5 @faneeshh

@LoayTarek5

Copy link
Copy Markdown
Collaborator

Will look at this soon. Tagging our student team as well in the meanwhile as it seems to be a larger PR. @pluto-han @LoayTarek5 @faneeshh

Ok, sure, i will review it

@thesauravpoddar

Copy link
Copy Markdown
Contributor Author

Hii @subhramit i just want to know if you've had any chance to review it? If there's anything to change or update I'd glad to do that

@subhramit

Copy link
Copy Markdown
Member

Hii @subhramit i just want to know if you've had any chance to review it? If there's anything to change or update I'd glad to do that

Hey Saurav, I'll get to it soon. The team of maintainers is currently focusing on a set of milestones for an upcoming release, hence the delay.

@thesauravpoddar

Copy link
Copy Markdown
Contributor Author

Hii @subhramit i just want to know if you've had any chance to review it? If there's anything to change or update I'd glad to do that

Hey Saurav, I'll get to it soon. The team of maintainers is currently focusing on a set of milestones for an upcoming release, hence the delay.

Okay got it

authorsList.add(authors.getString(i));
}
if (!authorsList.isEmpty()) {
entry.setField(StandardField.AUTHOR, String.join(" and ", authorsList));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
entry.setField(StandardField.AUTHOR, String.join(" and ", authorsList));
entry.withField(StandardField.AUTHOR, String.join(" and ", authorsList));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why did you recommend to use the withField? Because we don't really use the result of the withField, so setField should be fine also

entry.withField(StandardField.YEAR, publishedDateOnly.split("-")[0]);

if (scholarJsonEntry.has("id")) {
entry.setField(new UnknownField("scholarapi-id"), scholarJsonEntry.getString("id"));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this. Use withField to keep the pattern consistent.

if (scholarJsonEntry.has("id")) {
entry.setField(new UnknownField("scholarapi-id"), scholarJsonEntry.getString("id"));
}
// doi

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to document self explanatory code. Remove these comments

try {
URLDownload urlDownload = new URLDownload(getTestUrl());
urlDownload.addHeader("X-API-Key", apiKey);
urlDownload.asInputStream().close();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stream not closed.

Comment on lines +216 to +217
throw new URISyntaxException(LIST_URL,
"Page " + pageNumber + " was requested before its cursor was available; pages must be fetched sequentially");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the list URL is not the problem so change the exception message or throw Fetcher Exception


@Override
protected String handleJournal(String journalTitle) {
LOGGER.warn("ScholarAPI has no journal scoped search");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOGGER.warn("ScholarAPI has no journal scoped search");
LOGGER.debug("ScholarAPI has no journal scoped search");

import static org.mockito.Mockito.when;

@FetcherTest
public class ScholarApiFetcherTest implements SearchBasedFetcherCapabilityTest, PagedSearchFetcherTest {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change class name to ScholarFetcherTest. We name classes according to the class under test and I believe here that is Scholar Fetcher

Comment thread docs/code-howtos/fetchers.md Outdated
Comment on lines +20 to +21
| [Zentralblatt Math](https://www.zbmath.org) | (none) | (none) | Depending on the current network |

"Depending on the current network" means that it depends on whether your request is routed through a network having paid access. For instance, some universities have subscriptions to MathSciNet.
| [ScholarApi](https://scholarapi.net/) | [ScholarApi User Account](https://scholarapi.net/auth/register) | `ScholarApiKey` | 1000 free credits per key |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong placement

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@faneeshh check if the placement is fixed, I don't see this comment outdated as well - I'm having to fish for unaddressed comments

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's fine now. However, this PR got too long for me to keep up.

@LoayTarek5 LoayTarek5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thesauravpoddar good work, keep going.

the issue #16233 also asks for a FulltextFetcher (GET /pdf/{id}), or i miss something in past conversation?

also missing CHANGELOG.md entry.

Comment on lines +39 to +41
protected String handleJournal(String journalTitle) {
LOGGER.warn("ScholarAPI has no journal scoped search");
return "";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think that "" breaks the query, try use return StringUtil.quoteStringIfSpaceIsContained(journalTitle)

}
// Journal issue
if (scholarJsonEntry.has("journal_issue")) {
entry.withField(StandardField.NUMBER, scholarJsonEntry.getString("journal_issue"));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that journal_volume : VOLUME looks missing, right?, also pick setField or withField, not both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LoayTarek5 there is no specific filed for journal volume thats why it is missing

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have checked it, the journal_issue returns "Volume 60, Issue 3" on every record, so volume isnot missing, it's inside journal_issue, but you map that whole string into NUMBER, so entries get number = "Volume 60, Issue 3" and empty volume.
try to split it, like parse volume => VOLUME, issue => NUMBER, also i see that still mixing setField/withField

@thesauravpoddar thesauravpoddar Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have checked it, the journal_issue returns "Volume 60, Issue 3" on every record, so volume isnot missing, it's inside journal_issue, but you map that whole string into NUMBER, so entries get number = "Volume 60, Issue 3" and empty volume. try to split it, like parse volume => VOLUME, issue => NUMBER, also i see that still mixing setField/withField

@LoayTarek5
yeah about that volume i too saw that but in schema that is give on scholar api there is no any journal volume specific field adding that won't break it? because when json came from ScholarApi converts to BibText it will expect a journal "Volume 60, Issue 3 for this i just show 3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe i miss something, i dont konw, but keeping just the 3 still loses the "60", you don't need a schema field for volume, put it in JabRef's own StandardField.VOLUME, the issue in NUMBER so "Volume 60, Issue 3" => VOLUME = 60, NUMBER = 3, ithink it won't break anything, just fills a field that's empty now( the MAINTAINERS can confirm this)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay understood i will parse that and add separate fields for journal volume

import org.slf4j.LoggerFactory;

public class ScholarFetcher implements PagedSearchBasedFetcher, CustomizableKeyFetcher {
public static final String FETCHER_NAME = "Scholar";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is wrong, yse "ScholarAPI" / ScholarApi*(correct me if i am wrong),also ScholarQueryTransformerTest already exists, so your tests filter runs the old one

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LoayTarek5 the class name is ScholarApiQueryTransformerTest not ScholarQueryTransformerTest and I'll update the fetcher name

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, you're right i was wrong about that, i am get confused by names

entry.withField(StandardField.YEAR, publishedDateOnly.split("-")[0]);

if (scholarJsonEntry.has("id")) {
entry.setField(new UnknownField("scholarapi-id"), scholarJsonEntry.getString("id"));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also ZbMATH uses "zbmath", no -id, suggest "scholarapi"

@Test
@Override
@DisabledOnCIServer("Unstable on CI")
public void pageSearchReturnsUniqueResultsPerPage() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm, i think Empty override runs nowhere, and itis the only test of this feature, maybe try add offline cursor tests

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still an empty override, so it runs nowhere, also the cursor logic still has no test

Comment thread docs/code-howtos/fetchers.md
@thesauravpoddar

thesauravpoddar commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

@thesauravpoddar good work, keep going.

the issue #16233 also asks for a FulltextFetcher (GET /pdf/{id}), or i miss something in past conversation?

also missing CHANGELOG.md entry.

yes you are right FulltextFetcher (GET /pdf/{id}) it was there in issue but is it okay to open another pr for that? separate pr's for separate work and i will make the CHANGELOG.md entry

@LoayTarek5

Copy link
Copy Markdown
Collaborator

yes you are right FulltextFetcher (GET /pdf/{id}) it was there in issue but is it okay to open another pr for that? separate pr's for separate work and i will make the CHANGELOG.md entry

yeah, ok, very good 💯

try {
URLDownload urlDownload = new URLDownload(getTestUrl());
urlDownload.addHeader("X-API-Key", apiKey);
urlDownload.asInputStream().close();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is like off pattern, and it uses up an API credit on every check, maybe better to verify the key by checking the HTTP status code instead, like SpringerNatureWebFetcher/MedlineFetcher do

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure i will do that

@thesauravpoddar

thesauravpoddar commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

@kopper @subhramit whenever you get time can i get a review and can you explain about these fails

@subhramit

Copy link
Copy Markdown
Member

For checkstyle, did you set up your IDE as per our contributing guidelines/steps to set up local development environment?

@subhramit

Copy link
Copy Markdown
Member

If you click on a failing workflow, it shows details of its run and why it failed.

For example on line 622 of the checkstyle test

IMG-20260729-WA0000.jpg

@subhramit

Copy link
Copy Markdown
Member

Similarly figure out the rest.
And double check that you read our contributing guidelines (contributing.md)

@thesauravpoddar

Copy link
Copy Markdown
Contributor Author

Similarly figure out the rest.
And double check that you read our contributing guidelines (contributing.md)

Okay understood

@thesauravpoddar

Copy link
Copy Markdown
Contributor Author

@subhramit hii I know you guys must be busy and sorry for bothering but whenever you get time please do review this

Comment thread jablib/src/main/java/org/jabref/logic/importer/fetcher/ScholarFetcher.java Outdated
String publishedDateOnly = publishedDate.split("T")[0];
entry.withField(StandardField.DATE, publishedDateOnly);
entry.withField(StandardField.YEAR, publishedDateOnly.split("-")[0]);
entry.withField(new UnknownField("scholarApiHasText"), String.valueOf(scholarJsonEntry.getBoolean("has_text")));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these two for? they put "true"/"false" on every entry, right?, so if they are groundwork for the fulltext fetcher, a short comment would help

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes they are on every entry i will add a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's okay to add them

@Test
@Override
@DisabledOnCIServer("Unstable on CI")
public void pageSearchReturnsUniqueResultsPerPage() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still an empty override, so it runs nowhere, also the cursor logic still has no test

Comment thread docs/code-howtos/fetchers.md
Comment thread docs/code-howtos/fetchers.md

@LoayTarek5 LoayTarek5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work so far, keep going @thesauravpoddar


private static final int NO_YEAR_BOUND = Integer.MIN_VALUE;

private static final Pattern JOURNAL_VOLUME = Pattern.compile("Volume\\s+([^,]+)", Pattern.CASE_INSENSITIVE);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think [^,]+ is somewhat greedy and only stops at a comma, like "Volume 9 Issue 4" (no comma) gives VOLUME = "9 Issue 4".
so using (\d+) or ([^,\s]+) maybe better


@Test
@Override
public void pageSearchReturnsUniqueResultsPerPage() throws FetcherException {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The body is identical to the interface default, so you can just delete the override

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so i should delete this method from my test?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe remove it, if it's identical to default?

}

@Test
@Disabled("ScholarAPI has no journal scoped search")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the @disabled now, handleJournal returns "Nature" and the inherited test expects getJournalPrefix() + "Nature", where the default prefix is ""

@subhramit

Copy link
Copy Markdown
Member

Thank you for persevering @thesauravpoddar
And also @LoayTarek5 @faneeshh - I think this was one of your best review work, it took multiple rounds of effort and careful inspection.

I only went through the PR in a shallow way, so will wait for your approvals.

@faneeshh

Copy link
Copy Markdown
Collaborator

Thank you for persevering @thesauravpoddar And also @LoayTarek5 @faneeshh - I think this was one of your best review work, it took multiple rounds of effort and careful inspection.

I only went through the PR in a shallow way, so will wait for your approvals.

Looks good to me! Great job on not giving up and addressing the feedback with patience @thesauravpoddar

authorsList.add(authors.getString(i));
}
if (!authorsList.isEmpty()) {
entry.withField(StandardField.AUTHOR, String.join(" and ", authorsList));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think more idiomatic JabRef way is to do something like this:

List<Author> authors = List.of(
        new Author("John", "", null, "Smith", null),
        new Author("Peter", "", null, "Black Brown", null)
);

entry.setField(StandardField.AUTHOR, AuthorList.of(authors).getAsFirstLastNamesWithAnd());

(you can leave the withField)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thesauravpoddar please take this suggestion as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okayyy

@thesauravpoddar thesauravpoddar Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so here the the format is something like

List<Author> authors = List.of(
        new Author(firstName, "", null, lastName, null)
);

according to example give for john smith and peter Black brown
but

"authors": [
    "Feder, Jacob S.",
    "Soloway, Benjamin S."
]

above is one of response for authors give on ScholarApi docs so there is a comma then how we will decide which is lastName and which is firstName?

@subhramit subhramit Aug 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In standard bibtex (which is also Jabref's format), a comma is explicitly used to separate the last name from the first name. The format is "LastName, FirstName".

So, in the response "Feder, Jacob S." the first name is Jacob S. and lastname is Feder.

Because the API is already returning the names in this standard format, you can join the authors with "and" (the way you are doing now) and let the built-in AuthorList parser normalize to it how Ruslan is suggesting..

String rawAuthors = String.join(" and ", authorsList); 
AuthorList parsedAuthors = AuthorList.parse(rawAuthors);
entry.withField(StandardField.AUTHOR, parsedAuthors.getAsFirstLastNamesWithAnd());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okayy understood I'll do this way

InAnYan
InAnYan previously approved these changes Aug 11, 2026

@InAnYan InAnYan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think everything is good now!

Though I only don't think that these fields should be added in the entry:

Image

Maybe leave only scholarapi but rename it to something with id so that user could understand what is this.

UPD: Sorry, read the discussion, and it seems that just leaving the api name is an established norm, so it's okay to leave it, but I think those booleans shouldn't be added.

Looking forward to the full text fetcher! (if you want to continue to work on it, of course)

@LoayTarek5 LoayTarek5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @thesauravpoddar so far, and thanks for your prsistence.
just small things left

Optional<String> cursor = Optional.ofNullable(response.optString("next_indexed_after", null))
.filter(StringUtil::isNotBlank);
if (cursor.isEmpty()) {
throw new FetcherException(url, "More results are available but returned no pagination cursor", null);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks searches returning 20 results or more, like isLastPage = 20 < 20 is false, so the code expect anther page, the API sends no cursor and this throws, so i think it better to go back to .ifPresent, keep the isNotBlank filter

* `FulltextFetcher`: Searches for a PDF for an exiting bibliography entry
* `SearchBasedFetcher`: Searches providers using a given query and returns a set of (new) bibliography entry. The user-facing side is implemented in the UI described at [https://docs.jabref.org/collect/import-using-online-bibliographic-database](https://docs.jabref.org/collect/import-using-online-bibliographic-database).

`JournalInformationFetcher` supplies the Entry Editor's journal-information popup. It uses Crossref for journal identity (title, publisher, ISSNs) and OpenAlex for the h-index and yearly work and citation counts. If enabled in the preferences, it uses the configured OpenAlex API key.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that paragraph looks unrelated to ScholarAPI, is it leftover from a rebase?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so should be removed please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this js good here i was experiencing errors with fetchers.md whenever i was fixing so i kept the new changes from main branch and added new so this is right here just when i started working on this pr this text was not there but this is not breaking anything here

@subhramit subhramit Aug 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On merging main, the diff is gone, so it's alright now. This was indeed a result of a faulty merge/rebase.
It was added in #16504 so you just had to pull/merge the changes, not add it as a diff yourself by looking at main.
The addition (without merge) was made in your commit 97470eb

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is already on main, it should not appear in your diff at all.
merge main into your branch instead, and the paragraph stays without being part of this PR, becuase showing up there means it is being readded by hand, right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, this was somehow manually added


private static final int NO_YEAR_BOUND = Integer.MIN_VALUE;

private static final Pattern JOURNAL_VOLUME = Pattern.compile("Volume\\s+([^,\s]+)", Pattern.CASE_INSENSITIVE);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Single backslsh \s in a string literal means a literal space,right? so this compiles to [^, ]+, try use [^,\\s]+, worth a test with a tab or comma less variant

Comment on lines +126 to +134
@Override
public List<String> getTestAuthors() {
return List.of();
}

@Override
public String getTestJournal() {
return "";
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Override
public List<String> getTestAuthors() {
return List.of();
}
@Override
public String getTestJournal() {
return "";
}
@Override
public List<String> getTestAuthors() {
return List.of("unsupported");
}
@Override
public String getTestJournal() {
return "unsupported";
}

or put comments

@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: fetcher good first issue An issue intended for project-newcomers. Varies in difficulty. status: no-bot-comments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create fetchers for ScholarAPI

5 participants