Moses created FLINK-40605:
-----------------------------
Summary: Code splitting still exceeds 64 KB for large if blocks
containing loops with break or continue
Key: FLINK-40605
URL: https://issues.apache.org/jira/browse/FLINK-40605
Project: Flink
Issue Type: Bug
Components: Table SQL / Runtime
Affects Versions: 2.4.0
Environment: Apache Flink master / 2.4-SNAPSHOT at
4e9d5412d3dcd4776b750e8a94ba6e86d2b409c6; JDK 17; Janino 3.1.12; repository
Maven wrapper 3.9.16. Reproduced on 9 September 2026.
Reporter: Moses
h2. Problem
A large generated {{if}} block can still fail Janino compilation with {{Code
grows beyond 64 KB}} when it contains a small, self-contained loop with
{{break}} or {{continue}}, even after the full {{JavaCodeSplitter.split(...)}}
pipeline has run.
This is a remaining code-splitting corner case, rather than a request to reopen
FLINK-23007. FLINK-23007 introduced the splitter, and FLINK-27246 subsequently
added block rewriting. The current implementation still conservatively rejects
an enclosing statement whenever any descendant contains a jump.
h2. Reproduction
Reproduced on Apache Flink {{master}} / {{2.4-SNAPSHOT}} at commit
{{4e9d5412d3dcd4776b750e8a94ba6e86d2b409c6}} on 9 September 2026, with JDK 17
and Janino 3.1.12. Released versions have not been tested for this specific
reproduction.
Run the following with {{JavaCodeSplitter}} and Janino on the classpath. Repeat
with {{jump = "continue"}} to reproduce the second case.
{code:java}
import org.apache.flink.table.codesplit.JavaCodeSplitter;
import org.codehaus.janino.SimpleCompiler;
public class CodeSplitReproducer {
public static void main(String[] args) throws Exception {
String jump = "break";
String code =
"public class Generated { public void run(int[] a) {"
+ "if (a[0] >= 0) {"
+ "a[1] += 1;".repeat(15000)
+ "for (int i = 0; i < 5; i++) {"
+ "a[2]++; if (i == 2) { " + jump + "; } a[3]++;"
+ "}} a[4] = 1; }}";
String split = JavaCodeSplitter.split(code, 4000, 10000);
SimpleCompiler compiler = new SimpleCompiler();
compiler.cook(split);
Class<?> generated = compiler.getClassLoader().loadClass("Generated");
Object instance = generated.getDeclaredConstructor().newInstance();
int[] result = {0, 0, 0, 0, 0};
generated.getMethod("run", int[].class).invoke(instance, result);
System.out.println(java.util.Arrays.toString(result));
}
}
{code}
*Actual:* compilation of the transformed code fails with:
{noformat}
Caused by: org.codehaus.commons.compiler.InternalCompilerException: Code grows
beyond 64 KB
{noformat}
*Expected:* the large enclosing block is split into compilable methods without
changing control flow. The result is {{[0, 15000, 3, 2, 1]}} for {{break}} and
{{[0, 15000, 5, 4, 1]}} for {{continue}}. For an input of {{[-1, 0, 0, 0, 0]}},
the branch is skipped and the result is {{[-1, 0, 0, 0, 1]}}.
h2. Cause and proposed fix
{{BlockStatementSplitter.BlockStatementVisitor.visitStatement}} currently
returns early when {{getNumOfReturnOrJumpStatements(ctx) != 0}}. Counting every
nested {{break}}/{{continue}} prevents splitting the entire enclosing {{if}},
even though the loop and its jump targets can remain together inside an
extracted method.
Track returns separately, retain the conservative return guard and the jump
guard when traversing loop bodies, and allow enclosing blocks containing
complete loops to be extracted. This does not attempt to support arbitrary
oversized loop bodies containing jumps.
h2. Patch and verification
A candidate fix with regression tests is available in [this fork
commit|https://github.com/ChaomingZhangCN/flink/commit/12da06a50a0e7fe321560b28c9ab1b65f4fd9a53]
(branch {{codex/fix-code-splitter-nested-jumps}}).
* Both oversized-branch regression cases fail on the unmodified base commit
with the 64 KB error and pass with the fix.
* Execution assertions cover {{break}}, {{continue}}, skipped branches, labeled
jumps and early returns.
* The complete code-splitter module suite passes against its {{2.4-SNAPSHOT}}
reactor dependencies: 54 tests, 0 failures, 0 errors and 1 pre-existing skipped
test.
* Spotless, Checkstyle and a module-scoped RAT check pass. The full repository
test suite has not been run.
Related: FLINK-23007 and FLINK-27246.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)