JDK-8172106 : javac throws exception when compiling source file of size 1.5G
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2016-12-28
  • Updated: 2023-01-09
  • Resolved: 2023-01-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 21
21 b04Fixed
Description
FULL PRODUCT VERSION :
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
OSX Yosemite (10.10.5) / Darwin macbook.home 14.5.0 Darwin Kernel Version 14.5.0: Sun Sep 25 22:07:15 PDT 2016; root:xnu-2782.50.9~1/RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
I created a small program that outputs a Java source file. If you try to compile the generated source file, the compiler throws the exception below. This may be related to the size of the source file (1.5Gb).

java.lang.IllegalArgumentException
	at java.nio.ByteBuffer.allocate(ByteBuffer.java:334)
	at com.sun.tools.javac.util.BaseFileManager$ByteBufferCache.get(BaseFileManager.java:325)
	at com.sun.tools.javac.util.BaseFileManager.makeByteBuffer(BaseFileManager.java:294)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:114)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:53)
	at com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:602)
	at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:665)
	at com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:950)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:857)
	at com.sun.tools.javac.main.Main.compile(Main.java:523)
	at com.sun.tools.javac.main.Main.compile(Main.java:381)
	at com.sun.tools.javac.main.Main.compile(Main.java:370)
	at com.sun.tools.javac.main.Main.compile(Main.java:361)
	at com.sun.tools.javac.Main.compile(Main.java:56)
	at com.sun.tools.javac.Main.main(Main.java:42)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code below (change the "folder" variable to a valid directory on your computer) and then try to compile the output (namely the Performance.java file)
-------
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Main {

	public static void main(String[] args) throws IOException {
		final String folder = "/Users/hugo/temp/";
		try (BufferedWriter out = new BufferedWriter(
				new FileWriter(folder + "Performance.java"))
		) {
			out.write("public class Performance {\n");
			out.write("\tpublic static int doNothing() {\n");
			out.write("\t\tint i = 0;\n");
			for (int i = 1; i < 99999999; i++) {
				out.write("\t\ti = " + i + ";\n");
			}
		}
	}
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After trying to compile the generated class, the compiler should print an error message saying that the source file has a syntax error (the compiler should NEVER throw an exception).
ACTUAL -
If you go to the console and try to compile the generated source file (javac Performance.java) you get the following exception:

java.lang.IllegalArgumentException
	at java.nio.ByteBuffer.allocate(ByteBuffer.java:334)
	at com.sun.tools.javac.util.BaseFileManager$ByteBufferCache.get(BaseFileManager.java:325)
	at com.sun.tools.javac.util.BaseFileManager.makeByteBuffer(BaseFileManager.java:294)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:114)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:53)
	at com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:602)
	at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:665)
	at com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:950)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:857)
	at com.sun.tools.javac.main.Main.compile(Main.java:523)
	at com.sun.tools.javac.main.Main.compile(Main.java:381)
	at com.sun.tools.javac.main.Main.compile(Main.java:370)
	at com.sun.tools.javac.main.Main.compile(Main.java:361)
	at com.sun.tools.javac.Main.compile(Main.java:56)
	at com.sun.tools.javac.Main.main(Main.java:42)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
An exception has occurred in the compiler (1.8.0_112). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.IllegalArgumentException
	at java.nio.ByteBuffer.allocate(ByteBuffer.java:334)
	at com.sun.tools.javac.util.BaseFileManager$ByteBufferCache.get(BaseFileManager.java:325)
	at com.sun.tools.javac.util.BaseFileManager.makeByteBuffer(BaseFileManager.java:294)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:114)
	at com.sun.tools.javac.file.RegularFileObject.getCharContent(RegularFileObject.java:53)
	at com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:602)
	at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:665)
	at com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:950)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:857)
	at com.sun.tools.javac.main.Main.compile(Main.java:523)
	at com.sun.tools.javac.main.Main.compile(Main.java:381)
	at com.sun.tools.javac.main.Main.compile(Main.java:370)
	at com.sun.tools.javac.main.Main.compile(Main.java:361)
	at com.sun.tools.javac.Main.compile(Main.java:56)
	at com.sun.tools.javac.Main.main(Main.java:42)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
The code below generates the source file that allows you to reproduce the issue:
-----

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Main {

	public static void main(String[] args) throws IOException {
		final String folder = "/Users/hugo/temp/";
		try (BufferedWriter out = new BufferedWriter(
				new FileWriter(folder + "Performance.java"))
		) {
			out.write("public class Performance {\n");
			out.write("\tpublic static int doNothing() {\n");
			out.write("\t\tint i = 0;\n");
			for (int i = 1; i < 99999999; i++) {
				out.write("\t\ti = " + i + ";\n");
			}
		}
	}
}
---------- END SOURCE ----------


Comments
Changeset: 6a07fd0e Author: Archie L. Cobbs <archie.cobbs@gmail.com> Committer: Vicente Romero <vromero@openjdk.org> Date: 2023-01-04 16:01:59 +0000 URL: https://git.openjdk.org/jdk/commit/6a07fd0ec1e6b57ffff852bcdc4f3304ac828018
04-01-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/10803 Date: 2022-10-20 20:15:12 +0000
20-10-2022

Looking into other way round, user is not directly using ByteBuffer, it was interanlly used by javac compiler. Definetly we should have prompted with proper error message then such an Exception Steps to reproduce == 1. javac Main.java 2. java Main (Geretaes the Performance.java as output file) 3. javac Performance.java ==
29-12-2016

Noit sure about this as an issue when you tried to compile a source file of sizeof 1.5G. java.lang.IllegalArgumentException is occuring as capacity is becoming negative "capacity < 0: (-558594710 < 0)" It depends upon the native IO capacity of buffer allocation, as the spec says "Given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer's content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system's native I/O operations" -sh-4.1$ /opt/java/jdk-9_ea-149/bin/javac /scratch/fairoz/Performance.java An exception has occurred in the compiler (9-ea). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you. java.lang.IllegalArgumentException: capacity < 0: (-558594710 < 0) at java.base/java.nio.Buffer.createCapacityException(Buffer.java:251) at java.base/java.nio.ByteBuffer.allocate(ByteBuffer.java:340) at jdk.compiler/com.sun.tools.javac.file.BaseFileManager$ByteBufferCache.get(BaseFileManager.java:454) at jdk.compiler/com.sun.tools.javac.file.BaseFileManager.makeByteBuffer(BaseFileManager.java:422) at jdk.compiler/com.sun.tools.javac.file.PathFileObject.getCharContent(PathFileObject.java:458) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:607) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:669) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:1029) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:942) at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:307) at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:160) at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:55) at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:41)
29-12-2016