|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
TOP THREE LINKS YOU MUST CLICK ON AJAXWorld News Desk Lesson Learnd from Using Rhino to Process JavaScript
This entry documents a few tips related to using Rhino JavaScript Engine to process JavaScript code
By: Coach Wei
Sep. 15, 2008 11:04 AM
This entry documents a few tips related to using Rhino JavaScript Engine to process JavaScript code. If you are using Rhino, you probably won’t run into the issues covered in this post during development or even testing. However, you are fairly likely to run into these issues after your system goes live. It would easily result in days or even weeks of soul searching (speaking from my personal experience:-)). Part of the problem seems to be the lack of documentation from the web. The other part of the problem is that the problem is rather a Java language problem(very convoluted). - Java limits the maximum method size to be 64KB. 1. JVM Byte Code Size Limit Problem On rare occasions, you will see exceptions like the followings from Rhino when processing JavaScript files: Exception in thread “main” java.lang.IllegalArgumentException: out of range index
Here are a few posts you can find when you do a web search that are related to this issue (though don’t seem to offer a solution):
This can be extremely frustrating. For example, if you are a Dojo ShrinkSafe user, you know ShrinkSafe works because you have used it millions of times on many projects successfully. But on a certain situations, you will run into the above problem. When you search specifically for this ShrinkSafe problem, here is the best that I can find: “While it’s not recommended that you develop 2MB JS files, it seems that it *does* happen, and it’s about the time that your files get this large that a project (naturally!) turns to the Dojo compressor. Unfortunantly, the default set of arguments doesn’t hold up to a file this big, and strange exceptions result. Here is a modified recipe for use with the kinds of files that really, *really* need the Dojo compressor: This is not very helpful in my own experience. First of all, there are tons of reasons that Rhino needs to process big JavaScript files (for example, you want to use Rhino to analyze a bunch of JavaScript files concatenated together). Secondly, very little explanation is given about this command line “magic”. Thirdly, this command line “magic” seems to be misleading because the problem is not related to JVM memory limit (no need to do -Xms500M -Xmx500M in my experience). The source of the problem is not your code, not Rhino, but rather a Java language limit. See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html, section 4.10: “The amount of code per non- Rhino implemented correctly by sticking to the Java language specification. In fact, you can see the following comments from <code>org.mozilla.classfile.ClassFileWriter<code>: if (attrLength > 65536) { The Dojo ShrinkSafe issue is fundamentally caused by this problem. Any other software that relies on Rhino will have this problem too. 2. So What Is the Solution? The short answer is, well, there is no solution, if you rely on Rhino to compile JavaScript into Java code. Well, Java code has to subject to the 64KB Java language limit. If you are in desperate need for a solution, you might try to “pre-process” your JavaScript code by breaking apart large JavaScript methods into a bunch of smaller methods, which may yield smaller than 64KB Java byte code for each compiled method. -Thought this approach looks really painful. However, if you are not using Rhino to compile JavaScript to Java, there are easier ways to get around the problem. Rhino does not have to “compile JavaScript to Java code”. You can configure Rhino to run at an “Interpretive mode”. Given that there is Java byte code involved at all, this limit naturally does not apply. This is simple to do. It takes one line of code:
The above set the Rhino Context object to “interpreative” mode. See Rhino Optimization Level for detailed information. 3. Is it time for us to treat the 64KB JVM limit as a bug, rather that a Java language spec item? In the world of JavaScript, well, it is not usual to have methods that far exceeds the 64KB limit. For example, it is very common these days for JavaScript libraries to wrap a lot of functions inside one parent function for the sake of encapsulation and scoping. For example, jQuery wraps all code inside one function block (function(){…})(). Other JavaScript libraries like Dojo use similar techniques too. In such situations, it is fairly easy to exceed the 64KB limit when compiled into Java byte code. For dynamic languages, especially languages that developers tend to nest functions inside functions (”inner function”), the 64KB limit seems to be awfully low. Of course, this problem is not unique to JavaScript developers. For example, JSP developers can easily run into this problem too. See http://forums.sun.com/thread.jspa?threadID=472929&messageID=2296445 for an example. Interesting enough, bug 4262078 at bugs.sun.com, “Maximum method size is too small (64Kb)“, is exactly on this issue. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4262078. The bug was submitted in 1999. Nine years later, in 2008, we are still not sure whether this will be fixed. LATEST AJAXWORLD RIA STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||