"Code too large" compilation error in Java
Asked Answered
P

14

113

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?

Pinwheel answered 9/3, 2010 at 9:33 Comment(9)
I'm just stunned... There's bound to be a better way to do this.Homopterous
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 !Pinwheel
Juts out of curiosity. Would it work using an array literal?Religieux
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.Tokyo
You really need to look at a database for this type of thing, failing that a property file.Aeri
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.Middlebrooks
@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.Deterrence
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).Laughing
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.Berget
L
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);
Luhe answered 9/3, 2010 at 9:35 Comment(12)
"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.Tokyo
where can i find the .properties filePinwheel
you create your own then put it on the classpathTurnbow
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..Pinwheel
@Pinwheel yes, a database is a good option as well. Still, you are free to mark the answer as accepted, I guess :)Luhe
ok, how the contents of .properties file should look like? I'm trying to increase the size for methods.Reiners
@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.Recap
@Milack how? like size= 100MReiners
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?Recap
@AvinashRaj I'm not sure if I understand, but if you have large data, try to use a lightweight format, like lean binary.Recap
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<String> includedStrings;Tremendous
what would be the property name to increase the code_length @LuheTerrence
I
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.

Incantatory answered 9/3, 2010 at 9:36 Comment(4)
how about enums? i get the same issue with large sets of enumsPannier
@Toby: Never faced this issue with enum myself. There are posts by other users here on SO about the same issue though. For example - stackoverflow.com/questions/2546470 It may be worthwhile to look into the generated .class file for an enum to seeIncantatory
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.Mechanist
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.Wood
T
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.

Tokyo answered 9/3, 2010 at 9:47 Comment(4)
It's not only about method size.. If you make the array a static class member, it will also fail.Coons
@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.Tokyo
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?Coons
@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.Tokyo
U
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?

Ulund answered 9/3, 2010 at 9:35 Comment(1)
(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.Nickelodeon
D
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();
}
Downrange answered 23/7, 2017 at 5:54 Comment(0)
D
3

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};
Dryer answered 28/1, 2021 at 23:47 Comment(0)
O
2

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

Orthodontia answered 9/3, 2010 at 9:39 Comment(4)
refactoring doesn't seam as a reasonable idea if all he does in that method is array initialization.Plaza
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.Orthodontia
you can create and initialize large arrays without resorting to this kind of nonsense; see @Kris's answer.Koontz
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?Orthodontia
A
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

Alber answered 9/3, 2010 at 9:44 Comment(3)
Correct answer is to treat data as data and code as code.Haddad
@Haddad 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.Nickelodeon
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.Deterrence
B
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...

Breed answered 26/9, 2014 at 23:31 Comment(0)
A
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.

Adlib answered 23/12, 2015 at 11:5 Comment(1)
This is more of a comment than an answer.Cresol
V
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.

Viridian answered 29/11, 2019 at 19:50 Comment(0)
N
1

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

Nietzsche answered 13/2, 2020 at 22:47 Comment(0)
M
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.

Merna answered 29/11, 2019 at 20:8 Comment(0)
B
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

Brobdingnagian answered 15/4, 2020 at 8:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.