A .class file is a rather well documented format that defines sections and size, and therefore maximum sizes as well.
For instance, a .class
It's quite easy to make huge StackMapTable using nested finally blocks as javac unwisely generates separate variables for each nesting level. This allows to produce several megabytes from very simple method like this:
class A {{
int a;
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
a=0;
}}}}}}}}}}}}
}}
Adding more nesting level is not possible as you will exceed code size for single method. You can also duplicate this using the fact that instance initializer is copied to every constructor:
class A {{
int a;
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
try {a=0;} finally {
a=0;
}}}}}}}}}}}}
}
A() { }
A(int a) { }
A(char a) { }
A(double a) { }
A(float a) { }
A(long a) { }
A(short a) { }
A(boolean a) { }
A(String a) { }
A(Integer a) { }
A(Float a) { }
A(Short a) { }
A(Long a) { }
A(Double a) { }
A(Boolean a) { }
A(Character a) { }
}
This simple java file when compiled with Java 8 javac produces 105,236,439 bytes .class-file. You can also add more constructors, though there's a risk that javac will fail with OutOfMemoryError (use javac -J-Xmx4G to overcome this).