Good First Issues in Java
Explore curated starter issues in high-scoring Java repositories. Every listed issue belongs to a welcoming repository scored by C-Rank™ on PR merge rates, review responsiveness, and first-timer acceptance.
Arm Issue Sniper for fresh Java beginner issues
Beginner issues in welcoming S/A-Tier repositories get snatched within 15 minutes. Receive instant alerts on Discord, Telegram, or Email the minute a maintainer opens a new task.
Live Good First Issues (30)
What happens The transpile cache is keyed by a directory whose name folds a fingerprint of the whole module's inference tables: this.fingerprint = new Sticky<>(() -> new Fingerprint(tables).get()); tables is target/eo/6-inference, holding links.xml, needs.xml and provides.xml — one document each, listing every object of the module (11M, 2.2M and 1.8M for eo-runtime). Adding a single unrelated object changes all three, so version() changes, so every object of the module misses the cache and is transpiled again into a fresh directory under ~/.eo/transpiled. Two builds, the second with the same two sources byte for byte plus one new unrelated object, sharing one cache directory: after the first : [...-70b8ad9105e7-false-false-false-PhDefault] after the second : [...-369675c6fbf9-false-false-false-PhDefault, ...-70b8ad9105e7-false-false-false-PhDefault] Both directories hold bool.xmir and bytes.xmir; the first one is now orphaned and nothing prunes it. Why it is wro
What happens CoverageManifest.locations counts an anonymous formation, and the transpiler never wraps it, so its line can never be hit. For this source: +package examples [] > x bool > @ [] ? >> left ? >> right right > @ the manifest holds three locations: [Φ.examples.x.φ:4:2, Φ.examples.x.φ.α0:5:4, Φ.examples.x.φ.α0.φ:8:6] and the generated Java carries new PhCoverage(...) for two of them. Φ.examples.x.φ.α0:5:4, the [] on line 5, is only in the manifest. Feeding every location the transpiler does instrument into coverage-report as a hit still leaves DA:5,0, so the file reports 2 of 3 lines covered and no test can move it. Why it is wrong The manifest is meant to hold what a transpile would instrument — its javadoc says so, "the same string PhCoverage records a hit under". An anonymous formation becomes a nested class through anonymous-to-nested.xsl, and to-java.xsl never applies its mode="located" template to those, so the two sides of the repo
What happens Source.spans() treats every standalone \\r as a line terminator. A source using classic-Mac line endings therefore parses successfully, although the parser specification allows only LF (\\n) and CRLF (\\r\\n). [] > app\\r foo > x\\r The \\r characters above are literal U+000D bytes, not the two-character escape sequence. The parser accepts the file, emits app with child x, and reports no line-ending diagnostic. What should happen The lexical layer should accept only \\n and \\r\\n as line endings, as required by R-2.1.2. A standalone carriage return should be rejected with a deterministic parse error (or otherwise reported as an unsupported line ending), rather than silently changing the source line structure. How it was verified I rebuilt eo-parser from the current master and parsed the Java string "[] > app\\r foo > x\\r". EoSyntax returned an empty /object/errors list and emitted the two expected object names. The current implementation's Source.spans() branch for gl
The multi-line BYTES merger accepts any continuation that is at least as deep as its opener. It does not enforce R-2.2.2, which limits an indentation increase between consecutive non-blank lines to one level (two spaces). What happens Parse this source: [] > app CA-FE- BE-BE The continuation jumps from two leading spaces to six, skipping the four-space level. EoSyntax accepts the source and merges both chunks into one Φ.bytes value; no indent increased by more than one level error is emitted. What should happen A BYTES continuation should obey the same one-level indentation rule as every other line. The example should be rejected with indent increased by more than one level; a valid continuation may stay at the opener's indent or increase by one level only. How it was verified The example was parsed on the current master; the parser emitted no <errors> entry and returned a single merged bytes value. Significant whitespace determines EO structure. The special BYTES path curren
Describe the issue Summary The parseMode parameter requires uppercase enum values (HTML, MARKDOWNV2) but the documentation contradicts itself: the "Possible Values" list shows uppercase while the description text directly above it shows mixed case (MarkdownV2). The case-sensitivity requirement is stated nowhere, so following the description text produces a silent, cryptic failure. Steps to Reproduce Create a flow with io.kestra.plugin.telegram.TelegramSend task Set parseMode: MarkdownV2 (mixed case, exactly as shown in the doc's description text): - id: send_message type: io.kestra.plugin.telegram.TelegramSend token: "{{ secret('TELEGRAM_TOKEN') }}" channel: "{{ secret('TELEGRAM_CHAT_ID') }}" parseMode: MarkdownV2 payload: "*This is bold*\n_This is italic_" Execute the flow Check the execution logs Expected Result Task accepts MarkdownV2 (or is at minimum consistent with its own documentation) and renders MarkdownV2 formatting. Actual Result Task fails with a JSON parse e
Describe the issue Summary The TelegramSend task documentation states that payload must be a JSON object containing a text field. Testing shows the task actually requires payload to be a plain text or HTML string. Following the documented example sends the literal JSON string as the Telegram message instead of parsing the text content. Steps to Reproduce Create a flow with io.kestra.plugin.telegram.TelegramSend task Set payload exactly per the documented example: payload: | { "text": "Telegram Alert" } Set valid token and channel pointing to a valid bot and chat Execute the flow Check the resulting Telegram message Expected Result Per the documentation, the message should render as: Telegram Alert Actual Result The literal JSON string is sent as the message body: { "text": "Telegram Alert" } Correct Workaround Plain text with line breaks (no parseMode required): payload: "Hello World\nThis is a test from Kestra." This renders with proper line breaks in Telegram. HTML fo
Summary The four Filter-category JFR events report how much a filter skipped, but not which filter did it. In a process that runs many different reads, the counts cannot be attributed: Event Reports Missing dev.hardwood.RowGroupFilter row groups dropped by statistics/bloom push-down which predicate dev.hardwood.PageFilter pages dropped by the Column Index which predicate dev.hardwood.RecordFilter records dropped by per-record evaluation which predicate dev.hardwood.RowGroupByteRangeFilter row groups excluded by split selection which range Thread and timestamp are the only correlation available today, and nothing else in the recording names the predicate, so there is nothing to join them to. Proposal: add a predicate field to each, carrying a structural rendering with the literals elided: and(gt(id, ?), eq(label, ?)) or(isNull(city), lt(zip, ?)) Why literals are elided Two reasons, and they point the same way. Sensitivity. Every field these events carry today is schema
ParquetFileWriter.columnOrders() returns one TYPE_DEFINED_ORDER per leaf column and FileMetaDataWriter writes the list when it is non-empty, so produced files carry it. Nothing checks that they do. It is worth pinning because of what depends on it rather than because it looks fragile. A reader only trusts min_value / max_value under the order the footer declares; with column_orders absent, parquet-java falls back to the deprecated min / max semantics, under which a BYTE_ARRAY bound is compared signed. Hardwood writes STRING bounds unsigned and DECIMAL bounds signed, both correct under TYPE_DEFINED_ORDER — so a file that lost the list would have its string statistics silently misread by every other implementation, and every existing statistics test would still pass, since they all read the file back through Hardwood's own reader, which does not need the list to know its own conventions. That is the shape of bug the interop gate exists to catch and currently cannot. What to do Two asse
Current Behavior For our system we authenticate all connections via oauth2-proxy before they reach the backed. This give us a simple pane of glass when it comes to IT health checks. All authentication for apps that support proxy authentication are done in the same way and we can apply rules to not allow any API traffic without authentication When is comes to application such a dependency track which support the own implementation of OIDC we need to do much more due dilligance to make sure the service complies with our security standards. We have to allow unauthenticated access to the dependency track apis which make our security team nervous. Proposed Behavior Allow Dependency track to support oauth2-proxy so that a user, once authenticate with the gateway, does not have to do any more actions to access the dashboard. Checklist I have read and understand the contributing guidelines I have checked the existing issues for whether this enhancement was already requested
版本号: 3.9.5 分支: master 问题描述: 比如我需要智能体帮我分析数据并绘制可视化图形,动态生成python脚本代码分析数据并绘制图形(返回图形url地址),返回给智能体。 错误截图: 友情提示: 未按格式要求发帖、描述过于简单的,会被直接删掉; 描述问题请图文并茂,方便我们理解并快速定位问题; 如果使用的不是master,请说明你使用的分支;
🆕🐥 First Timers Only This issue is reserved for people who have never contributed or have made minimal contributions to Hiero. We know that creating a pull request (PR) is a major barrier for new contributors. The goal of this issue and all other issues in find a good first issue is to help you make your first contribution to the Hiero. 👾 Description of the issue Fix typo on line 85 in TokenNftAllowance copj→copy 💡 Proposed Solution Fix typo on line 85 in TokenNftAllowance copj→copy 👩💻 Implementation Steps Fix typo on line 85 in TokenNftAllowance copj→copy ✅ Acceptance Criteria To be able to merge a pull request for this issue, we need: Signed commits: commits must be DCO and GPG key signed All Tests Pass: our workflow checks like unit and integration tests must pass Issue is Solved: The implementation fully addresses the issue requirements as described above No Further Changes are Made: Code review feedback has been addressed and no further changes ar
🆕🐥 First Timers Only This issue is reserved for people who have never contributed or have made minimal contributions to Hiero. We know that creating a pull request (PR) is a major barrier for new contributors. The goal of this issue and all other issues in find a good first issue is to help you make your first contribution to the Hiero. 👾 Description of the issue Fix typo on line 414 in ContractCreateTransaction contructor→constructor 💡 Proposed Solution Fix typo on line 414 in ContractCreateTransaction contructor→constructor 👩💻 Implementation Steps Fix typo on line 414 in ContractCreateTransaction contructor→constructor ✅ Acceptance Criteria To be able to merge a pull request for this issue, we need: Signed commits: commits must be DCO and GPG key signed All Tests Pass: our workflow checks like unit and integration tests must pass Issue is Solved: The implementation fully addresses the issue requirements as described above No Further Changes are Made:
Span.leading() (eo-parser/src/main/java/org/eolang/parser/Span.java:137-142) counts by Character.isWhitespace. Span.tabbed() (lines 145-155) walks only ' ' and '\t' characters. Eo.leadingSpaces() (eo-parser/src/main/java/org/eolang/parser/Eo.java:308-314), used by the text-block indent check in Eo.continueTextBlock, counts only literal ' '. The same source line can measure a different "indent" depending on which of the three happens to be called on it, and a line inside a text block passes through both Span's notion (via the ordinary dispatch it bypasses) and Eo's own leadingSpaces without the two ever being reconciled. Routing every leading-whitespace measurement through one shared definition — Span.indent(), since it already backs the odd-indent and tab checks — would remove the risk of the text-block path disagreeing with the rest of the parser about what counts as indentation. @yegor256
Span.head() (eo-parser/src/main/java/org/eolang/parser/Span.java:117-124) returns the NUL character for a blank span, since a blank line has no first non-whitespace character. That relies on the caller either checking blank() first or knowing to treat NUL as "no head" — nothing stops a caller from calling head() alone and getting a value that looks like ordinary data. char in Java has no null-like absent value, so this is the same "no result" sentinel this project's conventions call out elsewhere: throwing when the span is blank, or having callers go through blank() before calling head(), would remove the silent stand-in. @yegor256
PARSER_SPEC R-2.2.5 defines trailing whitespace as the line's last character being a space or a tab. Span.trailing() (eo-parser/src/main/java/org/eolang/parser/Span.java:128-131) instead tests Character.isWhitespace(this.text.charAt(this.text.length() - 1)), which is also true for other whitespace characters such as form feed or vertical tab (U+000B). A line ending in one of those gets rejected with "trailing whitespace at end of line" for a rule the spec only wrote for space and tab. Narrowing the check to glyph == ' ' || glyph == '\t' would match R-2.2.5 exactly instead of isWhitespace's broader definition. @yegor256
Span.leading() (eo-parser/src/main/java/org/eolang/parser/Span.java:137-142) counts any Character.isWhitespace character as leading whitespace. Span.tabbed() (lines 145-155), which backs tab(), instead breaks out of its scan at the first character that is neither ' ' nor '\t'. For a line like "\f\tfoo", indent() comes out 2 (even, so the odd-indent check passes), but tab() returns false because the loop stops at '\f' before ever reaching the tab that follows it — so Eo.java:258's "tab character in leading whitespace" check never fires for a tab that indent() itself already counted as part of the leading whitespace. Having tabbed() scan the same span of characters that leading() counts (rather than stopping early on an unrecognized whitespace character) would make the two agree on what counts as leading whitespace. @yegor256
The class comment on eo-parser/src/main/java/org/eolang/parser/Lines.java:12-13 reads "The source in lines", and the constructor's @param lines on line 25 reads "The source in lines" — the same three words repeated, neither of which says what the class is for or why it exists, just what its one field happens to be called. This project's own convention is that a class docblock says what the class is rather than restating its signature; rewriting the comment to describe the class's purpose (addressing a source's lines by number) would satisfy that instead of paraphrasing the field name. @yegor256
Optional.ofNullable(this.source.get(number - 1)) at eo-parser/src/main/java/org/eolang/parser/Lines.java:41 treats a null Text at a valid index the same as an out-of-range number: both fold into the same "" return value. A caller can never tell a genuinely null entry apart from a legitimate empty line or a bad index. Reading the element directly and letting a NullPointerException surface would flag the corrupted list instead of quietly hiding it behind an empty string. @yegor256
Allow subset search in CSL Style Select Dialog of LibreOffice Integration I don't see any results as I missed a hyphen after "springer". We want to allow subset search.
JavaFiles.total skips every class of an atomic XMIR: if (!atom || jname.endsWith("Test")) { so nothing is added to fresh for that object. removeStale then builds the set of directories to clean out of fresh alone: final Set<Path> expected = new HashSet<>(this.fresh); final Set<Path> dirs = new HashSet<>(); for (final Path file : expected) { for (Path dir = file.getParent(); dir != null && dir.startsWith(this.generated); dir = dir.getParent()) { dirs.add(dir); } } That restriction came from #6760, so that other generators writing into generated-sources are not clobbered. But with fresh empty for the package, its directory never lands in dirs, and a .java left there by an earlier build is never deleted. What happens. Build [] > main with 42 > @, then rewrite the same file as an atom and build again: STEP1 EOmain.java exists=true STEP2 EOmain.java exists=
to-java.xsl names the generated JUnit class after the object plus the literal Test, in the same Java package: <xsl:value-of select="concat(eo:class-name(@name), 'Test')"/> So an object x that has tests gives org.eolang.EO_examples.EOxTest under generated-test-sources, and an object actually named xTest gives org.eolang.EO_examples.EOxTest under generated-sources. MjTranspile attaches both roots, so the same fully qualified name is declared twice. What happens. With both objects present: J:target/generated-test-sources/org/eolang/EO_examples/EOxTest.java J:target/generated/org/eolang/EO_examples/EOx.java J:target/generated/org/eolang/EO_examples/EOxTest.java Both files start with package org.eolang.EO_examples; and public final class EOxTest extends PhDefault {. Compiling them together: duplicate class: org.eolang.EO_examples.EOxTest In a real build the two roots go through separate javac passes, so nothing fails. Instead the test-scope source shadows the object class, and xTest i
eo:loc-to-class turns a locator into the name of a nested Java class: <xsl:function name="eo:loc-to-class"> <xsl:param name="loc"/> <xsl:value-of select="concat('EO', eo:identifier(replace(translate(replace(string-join(tokenize($loc, '\.'), ''), '_', '__'), '-', '_'), $eo:cactoos, $eo:alpha)))"/> </xsl:function> It tokenizes on . and joins with the empty string, so every dot disappears and nothing takes its place. The mapping is not injective. Φ.examples.x.a.bc.φ.α0 and Φ.examples.x.ab.c.φ.α0 both come out as EOΦexamplesxabcφα0. to-java.xsl writes one private static class per anonymous formation of a top-level object, so two such formations inside one object give two declarations of the same class in one file. What happens. Transpiling an object x holding a.bc and ab.c, each with an anonymous formation: LINE:PhDefault rrr1 = new EOΦexamplesxabcφα0(); LINE:PhDefault rrr1 = new EOΦexamplesxabcφα0(); LINE:private static class EOΦexamplesxabcφα0 extends PhDefa
CommitHashesText keeps a built-in table of tags to fall back on when home.objectionary.com/tags.txt cannot be downloaded, and joins it with the platform separator: private static final String FALLBACK = String.join( System.lineSeparator(), "5fe5ad8d21dbe418038fa4c86e096fb037f290a9 0.23.15", ... ChText splits that text on \n alone and then tests each line with matches: t -> t.asString().matches( String.format("^.+\\s\\Q%s\\E$", this.tag) ), new Split(new TextOf(this.source), "\\n") What happens. Where the separator is \r\n, every line keeps a trailing \r after the split. matches has to consume the whole line, and . does not match a carriage return, so no line ever matches. ChText throws HashNotFoundException and ChRemote turns it into: Tag '0.23.15' doesn't exist or the list of all tags was not loaded correctly F
Provided reaches an answer by walking behind φ, so a name taken off an object that delegates is found on whatever it delegates to. Filled.fillings gathers what fills the voids by walking the chain of copies instead: while (this.pairs.containsKey(walked) && seen.add(walked)) { ... walked = this.pairs.get(walked); } Those are two different walks. A filling that lives on the delegation side is never seen, so the answer stays rooted at the void even though a caller does say what fills it. What happens. For this program: [x] > one x > @ [y] > two one y > @ [] > app two u > held held.next > @ [] > u [] > next the answer comes out as: <type id="Φ.app.φ"><ref loc="Φ.one.x.next"/></type> at rung 1, which means "a name rooted at a void". But two u fills y, y fills the x of one, and u has a next, so the answer is known. The one-hop version works. inc u > held with held.next answers Φ.u.next at rung 4. Only the delegation hop breaks it. Wh
Describe the issue I'm new to Kestra and was going through the built-in Getting Started tutorials in the UI. The business-processes flow (namespace tutorial) is described as a vacation-approval workflow: it says it "pauses the flow while waiting for manual approval" and the Slack notification tells the approver to "click on the Resume button" in the execution view. I triggered the flow from the UI and watched the execution: it went to PAUSED as expected. But without me ever clicking "Resume" (or any approve/reject action), the execution automatically flipped to SUCCESS about 30 seconds later, and the final task ran as if the request had been approved. Looking at the flow's source (viewable in the UI's flow editor), the wait_for_approval task is a Pause task configured only with pauseDuration: PT30S, with no onResume inputs. So there's no actual approval gate; it just waits 30 seconds and continues regardless of any human action. Expected: the task should require an explicit resume inpu
SockaddrIn declares the address family as a 2-byte short at offset 0: public short family; public short port; public int addr; public byte[] zero; That is the Linux layout of struct sockaddr_in, which starts with sa_family_t sin_family (2 bytes). On macOS and the BSDs the struct starts with uint8_t sin_len; sa_family_t sin_family;, one byte each. What happens. For AF_INET, port 8080, 127.0.0.1 the struct is written as: sizeof = 16 bytes = 02 00 90 1F 7F 00 00 01 00 00 00 00 00 00 00 00 On Linux the leading 02 00 reads as sin_family = 2, which is AF_INET. On macOS the same bytes read as sin_len = 2 and sin_family = 0, which is AF_UNSPEC. bind, connect and accept all build the struct this way, through BindSyscall, ConnectSyscall and AcceptSyscall, so all three would be handed a family the kernel does not accept. The repository already knows layouts differ per platform: StatSyscall picks between MacFileStat, LinuxArmFileStat and LinuxFileStat, and posix.eo branches on os.is-macos for cr
Motivation There has been community interest in Go support since #73. A previous pure-Go implementation is no longer maintained and is incompatible with the current TsFile format. Now that the C++ implementation and C wrapper have become more mature, Go support can be provided without maintaining another independent implementation of the TsFile format: Go API → cgo → C API → C++ TsFile Core This would allow Go applications to read and write current TsFile files while sharing the format compatibility, bug fixes, and performance improvements of the C++ module. Proposed approach Add a Go module that: exposes idiomatic Go Reader, Writer, Schema, Tablet, and ResultSet APIs; keeps all cgo and unsafe code inside an internal native package; treats C/C++ objects as opaque handles and does not expose their internal representations; provides explicit Close methods with clearly defined memory ownership; maps C API error codes to Go errors; uses batch-oriented, columnar APIs as the primary r
Summary If a project's Flutter SDK path doesn't resolve, the plugin runs its "Fixing Flutter module configuration" path on project open and deadlocks the IDE permanently — no error, no timeout, process kill required. setFlutterModuleWithoutReload calls ProjectImpl.save() from inside a write action on the EDT. That save dispatches document saving to a worker, then parks the EDT in a nested modal pump waiting for it; the worker must call back into the EDT to fire beforeAllDocumentsSaving. Circular wait, write lock held throughout. Same EDT/Semaphore pattern as #9013 and #9055, different call site — those were FlutterSettingsConfigurable, this is project open. Both closed against 2026.1; this reproduces on 2026.2 / plugin 95.0.0. The invalid SDK path is only the trigger; the deadlock is a re-entrancy bug and is not FVM-specific. Environment Plugin 95.0.0 · IntelliJ IDEA 2026.2 (IU-262.9437.185) · JVM 25.0.3 · Windows 11 10.0.26200 · Flutter 3.47.1 stable / Dart 3.13.1 Reproduction
Motivation The Java implementation can reopen a normally closed (complete) TsFile for appending through: RestorableTsFileIOWriter.getWriterForAppendingDataOnCompletedTsFile(File) This method detects a complete file, locates the start of FileMetadata from the footer, truncates the separator marker and all tail metadata, recovers the existing schema/chunk metadata, and then allows new data to be appended. Closing the writer generates a new metadata section and tail magic. The C++ implementation currently supports recovery and continued writing only when the file is incomplete or its tail is damaged. When the tail magic is valid, RestorableTsFileIOWriter::self_check() treats the file as complete, sets can_write_ = false, and closes the write handle. As a result, users of the C++ API and the C wrapper cannot append to a TsFile that was closed normally, even though the equivalent workflow is available in Java. Expected behavior Provide a supported C++ API equivalent to the Java completed-fi
Describe the bug SaturationTemperature.calcSaturationTemperature() and SaturationPressure.calcSaturationPressure() became roughly 20x slower in NeqSim 3.12.0 and remain slow through 3.18.0. The returned values are unchanged — this is purely a performance regression. The bracketing search was rewritten in #2219 ("fix TPflash error"). It now sweeps a fixed full range from a global minimum in coarse steps and never breaks out of the loop when a bracket is found, so every call performs a constant, worst-case number of TPflash evaluations regardless of how close the fluid already is to its saturation boundary: solver swept range step TPflash calls per call, always SaturationTemperature 30 K → 1200 K 10 K ~118 (+ ~20 bisection) SaturationPressure 1 bara → 1000 bara 10 bar ~100 (+ ~20 bisection) Before 3.12.0 the search started from the fluid's current temperature/pressure and walked outward until it crossed the phase boundary — typically a handful of flashes when the flui
Top Java Repositories with Beginner Issues (20)
Updated Daily via GitHub GraphQLVirtual Cell Framework
Sends level up, clue, etc. notifications to a Discord webhook or a custom web server
TripleA is a turn based strategy game and board game engine, similar to Axis & Allies or Risk.
Multi-Agent Transport Simulation
Enterprise-grade, commercial-friendly agentic workflow platform for building next-generation SuperAgents.
Open source IaC Automation and Collaboration Software.
Wynntils (Artemis) is a rewrite of Wynntils in 1.21.11 using Architectury, to support Fabric and Forge.
EOLANG, an Experimental Pure Object-Oriented Programming Language Based on 𝜑-Calculus
Agent-ready RPA suite with out-of-the-box automation tools. Built for individuals and enterprises.
Free and Open Source, Distributed, RESTful Search Engine
Hiero Mirror Node archives data from consensus nodes and serves it via an API
Keycloak Benchmark
MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight using giant robots, tanks, and/or infantry on a hex-based map.
Process Orchestration Framework
Digital logic design tool and simulator
Plinth is an AI-native engineering toolkit for modern Java enterprise SDLC, built around reusable Commands, Agents, Skills, and MCP Servers.
A cluster computing framework for processing large-scale geospatial data
Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus.
Light, fluffy, and always free - The AWS Local Emulator alternative
Eclipse GlassFish
How to make your first Java open-source pull request
Finding approachable Good First Issues in Java allows you to build real-world software engineering experience. Instead of submitting PRs to abandoned repositories, GetMerged verifies maintainer review speeds and first-timer acceptance rates before you write a single line of code.
Select any issue above to claim it directly on GitHub, or click a repository to inspect full maintainer review turnaround metrics and triage guidance!
Get this week's top welcoming repos + fresh Good First Issues for Java
Free weekly email, scoped to Java. No account needed - confirm once and unsubscribe anytime.