112

Is there any maximum size for code in Java? I wrote a function with more than 10,000 lines. Actually, each line assigns a value to an array variable.

arts_bag[10792]="newyorkartworld";
arts_bag[10793]="leningradschool";
arts_bag[10794]="mailart";
arts_bag[10795]="artspan";
arts_bag[10796]="watercolor";
arts_bag[10797]="sculptures";
arts_bag[10798]="stonesculpture"; 

And while compiling, I get this error: code too large

How do I overcome this?

Naman
  • 27,789
  • 26
  • 218
  • 353
trinity
  • 10,394
  • 15
  • 49
  • 67
  • 10
    I'm just stunned... There's bound to be a better way to do this. – Thanos Papathanasiou Mar 09 '10 at 09:46
  • 3
    yeah , yeah , i agree - the design is hopeless. Initially , the array's size was just 64 , so i didn't find the need to read from a file.. now the rest of the code depends on this being an array , so i thought i could get a temporary solution , and then later arrange things by reading from a file. okay ,'ll try your suggestions , thanks ! – trinity Mar 09 '10 at 09:46
  • Juts out of curiosity. Would it work using an array literal? – Alex Jasmin Mar 09 '10 at 09:48
  • Alexandre: no, because array literals are compiled into initializer blocks that do effectively the same thing that code does and initializer blocks have the same code size limit as methods. – Joachim Sauer Mar 09 '10 at 09:54
  • 9
    You really need to look at a database for this type of thing, failing that a property file. – Paul Whelan Mar 09 '10 at 09:54
  • 1
    Trinity. You say initially this was only limited to 64 so this was OK. You should always program with unintended expansion in mind, doing it right the first time will save time down the road and to be honest a .properties file with a lookup method would not have really been any extra work. Always really think about if whatever you're coding could expand in the future and code accordingly. Putting in 'temporary' solutions never ends well, they end up in production code and get forgotten until you have an issue and you or someone else has to do a big re-factor to fix it further down the line. – David Billings Mar 17 '14 at 08:49
  • 1
    @webuster I came across this "bug" with my code generation tool. It just make my code generation tool more complicated.I have to cut one method into 7 methods with the code generation tool. – bronze man Jan 06 '16 at 11:47
  • 9
    Why have your application startup spend a lot of time by parsing some text file when you can have the compiler pre-generate everything at compile time? This is bad design if you want to change the data without recompiling, or write the method manually, but it's not bad design at all if you generate the source code. (At least if you do it in a way that actually allows the compiler to pregenerate the array). – Guntram Blohm Mar 05 '17 at 16:36
  • I'm going to have to side with the OP here. Arbitrary limits -- even big ones -- just *suck*. You can say, "Why would you ever want to do it that way?", but I would counter "Why should you *not* be able to do it that way?" Is this a failure of technique on the user's part, or a failure of generality on the tool's part, or a failure of imagination on the part of those here who are criticizing the user? Me, I had this problem today, trying to write a unit test, with a (machine generated) array of 8191 `double` values. I wanted a nice, self-contained unit test, but no, I guess I can't. – Steve Summit Sep 28 '21 at 17:20

14 Answers14

112

A single method in a Java class may be at most 64KB of bytecode.

But you should clean this up!

Use .properties file to store this data, and load it via java.util.Properties

You can do this by placing the .properties file on your classpath, and use:

Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);
Wyetro
  • 8,439
  • 9
  • 46
  • 64
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 2
    "No matter what the actual size for your JDK/JVM is"? Are you implying that this limit is not fixed? Because it is fixed and required by the class file format specification. – Joachim Sauer Mar 09 '10 at 09:43
  • 1
    where can i find the .properties file – trinity Mar 09 '10 at 10:05
  • 1
    you create your own then put it on the classpath – Mark Mar 09 '10 at 10:14
  • 3
    i didnt use your suggestion , though i am eager to try it next time.. have now used a database to store this information , and 've modified the rest of the code accordingly.. – trinity Mar 11 '10 at 18:05
  • @trinity yes, a database is a good option as well. Still, you are free to mark the answer as accepted, I guess :) – Bozho Mar 11 '10 at 19:11
  • ok, how the contents of `.properties` file should look like? I'm trying to increase the size for methods. – Avinash Raj Sep 25 '15 at 11:07
  • @AvinashRaj I guess you can write the file the way you want. You can use plain text, binary data, whatever. Just be sure to read the data accordingly. – Milack27 Sep 25 '15 at 14:22
  • @Milack how? like size= 100M – Avinash Raj Sep 25 '15 at 14:23
  • 1
    I'm sorry if this is a stupid question, but.. Where should this .properties file be put? I mean, ok, it's in the classpath, but where is it? – Milack27 Sep 25 '15 at 14:25
  • @AvinashRaj I'm not sure if I understand, but if you have large data, try to use a lightweight format, like lean binary. – Milack27 Sep 25 '15 at 14:29
  • Inline with the answer specified by @Bozho. In Spring Boot, if the entry in application.properties file is strings.included.list=ab,bc,cd,de Then we can retrieve this in any spring wired java files as @Value("#{'${strings.included.list}'.split(',')}") private List includedStrings; – Madhu Tomy May 15 '20 at 13:24
  • what would be the property name to increase the code_length @Bozho – sachith Sep 22 '21 at 05:48
22

There is a 64K byte-code size limit on a method

Having said that, I have to agree w/Richard; why do you need a method that large? Given the example in the OP, a properties file should suffice ... or even a database if required.

Everyone
  • 2,366
  • 2
  • 26
  • 39
  • 6
    how about enums? i get the same issue with large sets of enums – Toby May 11 '12 at 12:15
  • 1
    @Toby: Never faced this issue with enum myself. There are posts by other users here on SO about the same issue though. For example - http://stackoverflow.com/questions/2546470/ It may be worthwhile to look into the generated .class file for an `enum` to see – Everyone May 11 '12 at 12:32
  • Enum instances (i.e. the objects that represent the constants) are created in the class' static initializer, which is a method and has the same limitation. – juancn Apr 13 '15 at 18:30
  • I faced the same problem with framework-generated code for a really complex web form. The solution was to split the form in components, so the generated code for each component was also split. – SebaGra Jan 17 '18 at 18:50
18

According to the Java Virtual Machine specification, the code of a method must not be bigger than 65536 bytes:

The value of the code_length item gives the number of bytes in the code array for this method.

The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.

code_length defines the size of the code[] attribute which contains the actual bytecode of a method:

The code array gives the actual bytes of Java Virtual Machine code that implement the method.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 1
    It's not only about method size.. If you make the array a static class member, it will also fail. – ACV Apr 29 '21 at 21:17
  • 1
    @ACV: that's because array members are actually initialized item-by-item in synthetic code put into the static initializer block which ends up in a code block and is treated like a method as well. – Joachim Sauer Apr 29 '21 at 21:26
  • that's great insight. Thanks. I didn't know about that, but also looking at bytecode, it's not very obvious. I guess then any block that in `javap` is marked as `Code: ` is one of these methods? – ACV Apr 29 '21 at 22:15
  • 1
    @AVC: The `Code:` sections are just the bytecode of various methods and initializers (for example the static initializer is labelled as `static {};`). So it contains both "normal" code of methods and synthetic code generated by the compiler, with no obvious distinction. – Joachim Sauer Apr 30 '21 at 07:09
6

This seems a bit like madness. Can you not initialize the array by reading the values from a text file, or some other data source?

RichardOD
  • 28,883
  • 9
  • 61
  • 81
  • 7
    (Downvoted because) This needs at least one reason _why_ such a technique is bad. It's not easy to come up with a good reason. – Evgeni Sergeev Nov 26 '14 at 04:41
5

This error sometimes occur due to too large code in a single function... To solve that error, split that function in multiple functions, like

//Too large code function
private void mySingleFunction(){
.
.
2000 lines of code
}
//To solve the problem
private void mySingleFunction_1(){
.
.
500 lines of code
}
private void mySingleFunction_2(){
.
.
500 lines of code
}
private void mySingleFunction_3(){
.
.
500 lines of code
}
private void mySingleFunction_4(){
.
.
500 lines of code
}
private void MySingleFunction(){
mySingleFunction_1();
mySingleFunction_2();
mySingleFunction_3();
mySingleFunction_4();
}
DevLoverUmar
  • 11,809
  • 11
  • 68
  • 98
2

Try to refactor your code. There is limit on the size of method in Java.

Padmarag
  • 7,067
  • 1
  • 25
  • 29
  • 1
    refactoring doesn't seam as a reasonable idea if all he does in that method is array initialization. – Gabriel Ščerbák Mar 09 '10 at 09:43
  • 2
    He said that the rest of his code depends on this being an array. So he could refactor the method to pass the responsibility of loading data to some other method/Factory from file/database. – Padmarag Mar 09 '10 at 09:50
  • you can create and initialize large arrays without resorting to this kind of nonsense; see @Kris's answer. – Stephen C Mar 09 '10 at 11:04
  • Refactor - "Process of changing a computer program's source code without modifying its external functional behavior in order to improve some of the nonfunctional attributes of the software." How are other answers different from this? – Padmarag Mar 10 '10 at 05:34
2

As mentioned in other answers there is a 64KB of bytecode limit for a method (at least in Sun's java compiler)

Too me it would make more sense to break that method up into more methods - each assigning certain related stuff to the array (might make more sense to use a ArrayList to do this)

for example:

public void addArrayItems()
{
  addSculptureItems(list);
  ...
}

public void addSculptureItems(ArrayList list)
{
  list.add("sculptures");
  list.add("stonesculpture");
}

Alternatively you could load the items from a static resource if they are fixed like from a properties file

saret
  • 2,217
  • 13
  • 12
  • Correct answer is to treat data as data and code as code. – Malcolm Jul 22 '14 at 17:39
  • @Malcolm Well, this is clearly data, and not code. Your comment is misleading, because what you shouldn't do is _mix_ data and code, but here they are not mixed. – Evgeni Sergeev Nov 26 '14 at 04:48
  • 1
    I think this is a good work around.I come cross with this problem with about 21k lines of code with 7000 route messages in it.I fix it by div those route messages into 7 function with name xxx0 xxx1 xxx2. – bronze man Jan 06 '16 at 11:41
2

I have run into this problem myself. The solution that worked for me was to refactor and shrink the method to more manageable pieces. Like you, I am dealing with a nearly 10K line method. However, with the use of static variables as well as smaller modular functions, the problem was resolved.

Seems there would be a better workaround, but using Java 8, there is none...

Azadi B.
  • 56
  • 3
2

I came to this question because I was trying to solve a similar problem. I wanted to hard code a graph that had 1600 elements into a 2D integer array for performance reasons. I was solving a problem on a leetcode style website and loading the graph data from a file was not an option. The entire graph exceeded the 64K maximum so I could not do a single static run of assignments. I split the assignments across several static methods each below the limit and then called each method one by one.

private static int[][] G = new int[1601][];

static {
    assignFirst250();
    assignSecond250();
    assignSecond500();
    assignThird500();
}

private static void assignFirst250() {
    G[1] = new int[]{3,8,15,24,35,48,63,80,99,120,143,168,195,224,255,288,323,360,399,440,483,528,575,624,675,728,783,840,899,960,1023,1088,1155,1224,1295,1368,1443,1520,1599};
    G[2] = new int[]{2,7,14,23,34,47,62,79,98,119,142,167,194,223,254,287,322,359,398,439,482,527,574,623,674,727,782,839,898,959,1022,1087,1154,1223,1294,1367,1442,1519,1598};
mba12
  • 2,702
  • 6
  • 37
  • 56
1

You can add another method to create space for your code for additional data space, you might have a method that is taking a large amount of data space. Try dividing your methods because I had the same issue and and fix it by creating another an additional method for the same data in my java Android code, The issue was gone after I did that.

FermDroi
  • 11
  • 1
1

I have an enum that causes the .java file to be over 500KB in size. Eclipse can build it for some reason; the eclipse-exported ant build.xml cannot. I'm looking into this and will update this post.

Richard Jessop
  • 897
  • 1
  • 12
  • 19
1

this is due to all code in single methods solution :create more some small methods then this error will be gone

jaigish
  • 157
  • 2
  • 4
0

As there is a size limit for methods and you don't want to redesign your code as this moment, may be you can split the array into 4-5 parts and then put them into different methods. At the time of reading the array, call all the methods in a series. You may maintain a counter as well to know how many indexes you have parsed.

0

ok maybe this answer is too late but I think this way is better than another way so

for example, we have 1000 rows data in code

  1. break them

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
    
  2. for better performance put an "if" in your codes

    if (count < 500) {
        rows500();
    } else if (count > 500) {
        rows1000();
    }
    

I hope this code helps you