Bypass error: code too large when initializing byte array [duplicate] - java

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?

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);

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.

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.

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?

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();
}

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

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

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...

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};

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.

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.

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

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.

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
break them
private void rows500() {
//you shoud write 1-500 rows here
}
private void rows1000() {
you shoud write 500-1000 rows here
}
for better performance put an "if" in your codes
if (count < 500) {
rows500();
} else if (count > 500) {
rows1000();
}
I hope this code helps you

Related

Java - Append to files in loop or print entire String

The following Code describes my problem:
private void transact(TreeSet<BankmanagerTransaction> set) {
BankmanagerTransaction transaction;
while(!set.isEmpty()) {
transaction = set.first();
execute(transaction);
printBalance(transaction);
printLedger(transaction);
printJustifiedLedger(transaction);
}
}
Every print function prints to a different File. So I'm wondering what's best practice here.
Is it better to build string and then at the end of the transact method print everything at once, or write to the file line by line?
To make more clear what I'm trying to get at, is the time the file is being edited and therfore used by the program. Because as far as I'm aware I'd have to create a Writer for each file in the transact method and pass it to each of the 3 methods everytime.
In the most cases it's the same, but...
Your answer should change with different critereria, i.e. max String length is limited by ram, so in very very lenght cases it is better to write line by line.
But everytime you write (and flush), you are accessing the disk. In remote file locations, if the connection is very unreliable or you have latency, you can build an entire String and write once.
It depends by what is your situation, in general try to make your code CLEAR.

"Code too large" -- How can I make a huge, compiled lookup table? [duplicate]

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?
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);
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.
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.
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?
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();
}
Try to refactor your code. There is limit on the size of method in Java.
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
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...
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};
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.
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.
this is due to all code in single methods
solution :create more some small methods then this error will be gone
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.
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
break them
private void rows500() {
//you shoud write 1-500 rows here
}
private void rows1000() {
you shoud write 500-1000 rows here
}
for better performance put an "if" in your codes
if (count < 500) {
rows500();
} else if (count > 500) {
rows1000();
}
I hope this code helps you

Java: Setting an array of predetermined length as a method parameter?

I have a method that takes 5 double values and performs an action with them. Right now the argument list is five different doubles. Is there any way to pass a double[] as an argument to the method but make sure its length is exactly 5?
One way is this:
private void myMethod(double[] args) {
if (args.length == 5) {
// do something
}
}
but is there a better way?
If you know you need exactly 5 doubles, then I think you are better off asking for 5 distinct doubles. Having them listed out with meaningful names it will still be hard enough (even with intellisense or whatever it's called) to keep the order of the variables straight. If they are in an array, the user will need to consult the documentation to see which value should go in which index.
No. You can't restrict the length of an array passed to a function.
If your goal is to keep the checking code out of the method so it's cleaner, you could delegate the real work to another method.
If your concern is the length of the parameter list you could pass a parameter object.
You could create a class which is a specialization of a Vector limited to 5 doubles, but it seems like overkill. I would just throw an exception if there are too few or too many entries in the array - this is likely a programming problem rather than a runtime exception.
You could put your code in try-catch block. This provides to miss an unnecessary check.
But if something doing wrong you could avoid the problems with exception.

help with this section of the work, arraylists objects lists

private List<MyShape> childShapes;
public ShapeCreator() {
super();
frame = new DrawGUI();
this.childShapes = new ArrayList<MyShape>();
}
I have this piece of code and i have got to insert an infinite amount of data(the array size not fixed), which consists of integers, how would i do that, i think i must be getting confused with the this.childShapes
I would appreciate some help thanks
I could not say you formulated your question well enough... but i'll make my suggestion:
you probably want to have a method that will take the new data in as argument and insert it into the list of childShapes;
public void addShape(int whateverInt){
childShapes.add(new MyShape(whateverInt));
}
That should do. You can call this method as many times as you like... until you run out of memory. There's no such thing as infinite amount of data. :-)

Hit-Count (reads) of an array in Java

For evaluating an algorithm I have to count how often the items of a byte-array are read/accessed. The byte-array is filled with the contents of a file and my algorithm can skip over many of the bytes in the array (like for example the Boyer–Moore string search algorithm). I have to find out how often an item is actually read. This byte-array is passed around to multiple methods and classes.
My ideas so far:
Increment a counter at each spot where the byte-array is read. This seems error-prone since there are many of these spots. Additionally I would have to remove this code afterwards such that it does not influence the runtime of my algorithm.
Use an ArrayList instead of a byte-array and overwrite its "get" method. Again, there are a lot of methods that would have to be modified and I suspect that there would be a performance loss.
Can I somehow use the Eclipse debug-mode? I see that I can specify a hit-count for watchpoints but it does not seem to be possible to output the hit count?!
Can maybe the Reflection API help me somehow?
Somewhat like 2), but in order to reduce the effort: Can I make a Java method accept an ArrayList where it wants an array such that it transparently calls the "get" method whenever an item is read?
There might be an out-of-the-box solution but I'd probably just wrap the byte array in a simple class.
public class ByteArrayWrapper {
private byte [] bytes;
private long readCount = 0;
public ByteArrayWrapper( byte [] bytes ) {
this.bytes = bytes;
}
public int getSize() { return bytes.length; }
public byte getByte( int index ) { readCount++; return bytes[ index ]; }
public long getReadCount() { return readCount; }
}
Something along these lines. Of course this does influence the running time but not very much. You could try it and time the difference, if you find it is significant, we'll have to find another way.
The most efficient way to do this is to add some code injection. However this is likely to be much more complicated to get right than writing a wrapper for your byte[] and passing this around. (tedious but at least the compiler will help you) If you use a wrapper which does basicly nothing (no counting) it will be almost as efficient as not using a wrapper and when you want counting you can use an implementation which does that.
You could use EHCache without too much overhead: implement an in-memory cache, keyed by array index. EHCache provides an API which will let you query hit rates "out of the box".
There's no way to do this automatically with a real byte[]. Using JVM TI might help here, but I suspect it's overkill.
Personally I'd write a simple wrapper around the byte[] with methods to read() and write() specific fields. Those methods can then track all accesses (either individually for each byte, or as a total or both).
Of course this would require the actual access to be modified, but if you're testing some algorithms that might not be such a big drawback. The same goes for performance: it will definitely suffer a bit, but the effect might be small enough not to worry about it.

Categories

Resources