1 2 Previous Next 22 Replies Latest reply: Mar 25, 2014 2:27 PM by jschellSomeoneStoleMyAlias RSS

    "Code too large"

    User772606-Oracle

      Hi,

       

      We are getting "Code too large" compilation error for one of our class. This class contains public String fields for label ID and value. We use this class for localization, except for English all other language labels come from .properties files.

       

      The reason we are getting this error is because we have a static block in which using reflection we are populating a HashMap with all public fields and their value. The number of fields have gone up to the extinct where we are crossing the 64K limit for a static method. One of the most feasible solution was to use .properties files for English labels as well.

       

      The issue is resolved, and here is the proposed solution.

      For the sake of discussion I will be calling this class MyLabels. We defined a super class for MyLabels called MyLabelsExt. And now we are adding labels into the super class instead of the MyLabels. By running some tests we confirmed that the map that we initialize in MyLables class contains all the fields from both MyLabels and MyLabelsExt class.

       

      How is the 64K limit error not coming if the labels are defined in a super class. Does that mean Java is able to identify that some of the fields are coming from parent class, and that is being treated as separate from the child class. And how is the map that we initialize having all the value.

       

      Can you please share your thoughts on this resolution.

       

      Thanks,

      Manish.

        • 1. Re: "Code too large"
          jwenting

          Why are you preloading every single string from that file at compile time? Massive waste.

          Just load what and when you need them at runtime instead. Problem solved.

          • 2. Re: "Code too large"
            User772606-Oracle

            Hi Jwenting,

             

            Thanks for your suggestion. Can you please share on this 64K limit error, how this gets resolved using the super class.

             

            Thanks,

            Manish.

            • 3. Re: "Code too large"
              gimbal2

              Probably because you separate code, it just happens to stay under the 64k limit. If you add some more labels it will probably break again.

              • 4. Re: "Code too large"
                jwenting

                or worse, start changing a few variable names so they're a few characters longer...

                • 5. Re: "Code too large"
                  User772606-Oracle

                  I went on adding few hundred of labels and it did not break, but if I added one single label in the MyLables class it would fail to compile. I am just worried that the solution we have adopted is not some sort of loop hole, and its just working for the time being.

                   

                  Thanks,

                  Manish.

                  • 6. Re: "Code too large"
                    gimbal2

                    user772606 wrote:

                     

                    I went on adding few hundred of labels and it did not break, but if I added one single label in the MyLables class it would fail to compile. I am just worried that the solution we have adopted is not some sort of loop hole, and its just working for the time being.

                     

                    Thanks,

                    Manish.

                    Why do you think jwenting provided you an alternative solution which you are at this point completely ignoring? We're right now only in a theoretical discussion after the fact; you need to change your solution so it is more robust regardless of the outcome of this discussion about class sizes. Is there something about jwenting's suggestion that you do not understand? If so admit that you do and ask questions.

                    • 7. Re: "Code too large"
                      User772606-Oracle

                      No Gimbal2, I did not ignore Jwenting's suggestion.

                       

                      Rather I would put it like this. We recently ran into this "Code too large" error, and one member of our team fixed it using the super class approach I described. While I was myself investigating the cause of "Code too large" error, I could not believe if the approach used should solve the issue at the first place. I am just looking for some help to understand how the approach we took resolved the issue. I am just worried if this approach is an expected use.

                       

                      Coming to the issues you site with the approach we are using for localization. We have a separate effort going on to replace this legacy approach with the latest in localization. We are looking at XLIFF and also a mechanism where could customers can have the ability to apply their customization. I would prefer to have this requirement dealt with a separate thread altogether.

                       

                      Hope this clarifies.

                       

                      Thanks,

                      Manish.

                      • 8. Re: "Code too large"
                        gimbal2

                        Let me put it differently: your "solution" is pretty miraculous, I find it very surprising that it even works in its current state. I can't explain WHY it works, I can only explain that it is not a solution for the long run because there is certainly an upper limit on the size of a class which you will eventually reach. If you'd want to know with certainty, you'd have to examine the source of the runtime you're using.

                         

                        Its a risk that is up to you; it seems to work for now and given that you have a replacement solution in the works, perhaps its a risk you can take for now. Fingers crossed that you won't run into problems until you can roll out the replacement solution.

                        • 9. Re: "Code too large"
                          rp0428

                          Rather I would put it like this. We recently ran into this "Code too large" error, and one member of our team fixed it using the super class approach I described. While I was myself investigating the cause of "Code too large" error, I could not believe if the approach used should solve the issue at the first place. I am just looking for some help to understand how the approach we took resolved the issue. I am just worried if this approach is an expected use.

                          Rather I would put it like this:

                           

                          1. You create code version 1 and it does NOT appear to work

                          2. You create code version 2 and it DOES appear to work

                          3. You do NOT post ANY of your code so we can actually SEE it

                          4. You want us to GUESS what your code is doing

                          5. Based on a guess you want us to explain why your unknown code version 2 fixes a problem that your unknown version 1 code has

                           

                          Does that sum it up?

                           

                          Do you think anyone can troubleshoot or explain code that they cannot see?

                           

                          Do you think anyone can 'understand how the approach we took resolved the issue' when you don't provide 'the approach we took'?

                           

                          If you want help with your code then you need to post the code that you need help with.

                          • 10. Re: "Code too large"
                            User772606-Oracle

                            Hi rp0428,

                             

                            I would be more than happy to share the code if that helps. Here it is:

                             

                            public class BaseMsgs extends BaseMsgsExt
                            {
                                private static final Map<String, Field> fieldMap;
                                static
                                {
                                    fieldMap = new HashMap<String, Field>();
                                    initFieldMap();
                                }
                            
                                private static void initFieldMap() {
                                    Field[] fields = BaseMsgs.class.getFields();
                                   
                                    for (int i = 0; i < fields.length; i++) {
                                        fieldMap.put(fields[i].getName(), fields[i]);
                                    }
                                }
                               
                                //Labels
                                public String LABEL_ADD = "Add";
                                public String LABEL_CREATE = "Create";
                                ...
                            }
                            
                            

                             

                            Thanks,

                            Manish.

                            • 11. Re: "Code too large"
                              rp0428
                              I would be more than happy to share the code if that helps.

                              Gee - after seeing it I'm almost sorry I ask. There are SO MANY things wrong with that code I don't know where to begin.

                               

                              First let's dispel you of this notion:

                              The issue is resolved, and here is the proposed solution.

                              No - it isn't. Certainly not with that code you posted. That code can't possibly work properly.

                               

                              Just focusing on the SERIOUS issues:

                               

                              1. static block at line #5 refers to a method at line #8 that may not have been initialized yet

                              2. code at line #11 tries to use reflection on the same class that is being initialized - but it has NOT yet been initialized

                              3. line #19 and #20 variable declarations are NOT static but are trying to be accessed from a STATIC method being called by a  STATIC initializer

                              4. line #19 and #20 (and others) are NOT yet initialized when the static blocks are being executed - those blocks execute in the source-code order; those lines are declared AFTER the static blocks.

                              5. line #19 and #20 are NOT declared FINAL

                              6. line #19 and #20, and the rest of the similar variables are, presumably, over 64k in size which will NEVER work

                               

                              Static code can only reference static variables or constants. Those static variables or constants need to be defined BEFORE they are refenced by a static block.

                               

                              Reflection will NOT work properly on the same class that is being initialized.

                              See section 12.4.2 'Detailed Initialization Procedure' in the Java Language Spec

                              http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2

                               

                              Pay particular attention to steps 7 and 9

                              •   Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

                               

                              Assuming that you really had a use case for doing what you are trying to do (which, IMHO, you don't) the map and the variables would all be declared STATIC, the variables would also be declared FINAL and all would be declared BEFORE the constructor.

                               

                              The constructor would create a new instance of the class and add it to the map. That is a method that was used to implement enums before enums were available:

                              public MyEnum {

                                  private static Map all = new HashMap();

                                  public static final MyEnum ENUM1 = new MyEnum("enumvalue1");

                                  public static final MyEnum ENUM2 = new MyEnum("enumvalue2");

                                  protected MyEnum(String value) {

                                    all.put(value, this);

                                  }

                               

                                 public static MyEnum find(String value) {

                                  return (MyEnum) all.get(value);

                                 }

                              }

                              That methodology was used when the individual class instances (ENUM1 and ENUM2 in the example above) needed to be referenced by name in the code being used.

                               

                              For large numbers of objects and when reference by name wasn't needed all of those values were stored in a properties file and a static block used to load them all. That way it wasn't necessary to create a large number of 'named' constants and there was no 64k limit problem.

                              • 12. Re: "Code too large"
                                User772606-Oracle

                                rp0428, Thanks for looking into so much detail and sharing your feedback.

                                 

                                I am glad that you agree that the problem is not solved and this should not work. You rather have concerns with the very basic design or BaseMsgs. In my defense, lets say we did not go by the book, but this code works, and its been working for more than 8 years (I actually had to dig through the history to find this). For time being, please, just excuse the current design.

                                 

                                What do you have to say about the "Code too large" error getting resolved by using a super class. I am trying to break this fix, and prove that this is not the right way, but not able to find anything discrete.

                                 

                                Thanks,

                                Manish.

                                • 13. Re: "Code too large"
                                  TPD-Opitz

                                  You didn't not tell anything about the problem you try to solve. But from the code snippet you posted I'd say you assign display messages to GUI components.

                                  Java has ResouceBundle to get those messages out of files with appropriate naming conventions.

                                  On the other hand Swing GUI have set/getName() method. Sou you 64K Class could be reduces to a fiew Lines

                                   

                                  ResourceBundle messages = ResourceBundle.getBundle("MyResources", currentLocale);
                                  
                                  // you need a separate Method for each GUI Object type
                                  setTextOf(JLable component) {
                                     component.setText(message.getString( component.getName());
                                  }
                                  

                                   

                                  bye

                                  TPD

                                  • 14. Re: "Code too large"
                                    User772606-Oracle

                                    Thanks to everyone for their time and pouring suggestions and feedback.

                                     

                                    I was very curious to know why the super class approach solved the "Code too large" error. I read the Java docs about the 64K limit, but one thing I repeatedly missed was this 64K limit is just a compile time limit. And it seems the compile time is not including the message labels from the super class, but runtime is correctly including them. Thus, compilation is not throwing the "Code too large error", and runtime is giving me the complete set of messages.

                                     

                                    Thanks again to everyone.

                                    Manish.

                                    1 2 Previous Next