YOUR FEEDBACK
Immo Huneke wrote: A well written article, an ingenious solution to a real problem often encountere...
Cloud Computing Conference
March 30 - April 1, New York
Register Today and SAVE !..

SYS-CON.TV

2008 East
DIAMOND SPONSOR:
Data Direct
Frontiers in Data Access: The Coming Wave in Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
Intel
Virtualization – Path to Predictive Enterprise
Green Hills
IT Security in a Hostile World
JBoss / freedom oss
Practical SOA Approach
GOLD SPONSORS:
Software AG
The Art & Science of SOA: How Governance Enables Adoption
PlateSpin
Effective Planning for Virtual Infrastructure Growth
Fujitsu
Automated Business Process Discovery & Virtualization Service
Ceedo
Workspace Virtualization
Click For 2007 West
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
TOP THREE LINKS YOU MUST CLICK ON


Lesson Learnd from Using Rhino to Process JavaScript
This entry documents a few tips related to using Rhino JavaScript Engine to process JavaScript code

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

at org.mozilla.classfile.ClassFileWriter?.add(ClassFileWriter?.java:541) at org.mozilla.classfile.ClassFileWriter?.addLoadConstant(ClassFileWriter?.java:601) at org.mozilla.classfile.ClassFileWriter?.addPush(ClassFileWriter?.java:837) at org.mozilla.javascript.optimizer.BodyCodegen?.visitSpecialCall(Codegen.java:2571) at org.mozilla.javascript.optimizer.BodyCodegen?.generateExpression(Codegen.java:1763) at org.mozilla.javascript.optimizer.BodyCodegen?.visitSetProp(Codegen.java:3743) at org.mozilla.javascript.optimizer.BodyCodegen?.generateExpression(Codegen.java:2118) at org.mozilla.javascript.optimizer.BodyCodegen?.generateStatement(Codegen.java:1660) at org.mozilla.javascript.optimizer.BodyCodegen?.generateStatement(Codegen.java:1510) at org.mozilla.javascript.optimizer.BodyCodegen?.generateBodyCode(Codegen.java:1181) at org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:285) at org.mozilla.javascript.optimizer.Codegen.compileToClassFile(Codegen.java:157) at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:67) at org.mozilla.javascript.Context.compileImpl(Context.java:2327) at org.mozilla.javascript.Context.compileString(Context.java:1323) at org.mozilla.javascript.Context.compileString(Context.java:1312) at org.mozilla.javascript.tools.shell.Main.loadScriptFromSource(Main.java:500) at org.mozilla.javascript.tools.shell.Main.processFileSecure(Main.java:439) at org.mozilla.javascript.tools.shell.Main.processFile(Main.java:406) at org.mozilla.javascript.tools.shell.Main.processSource(Main.java:397) at org.mozilla.javascript.tools.shell.Main.processFiles(Main.java:181) at org.mozilla.javascript.tools.shell.Main$IProxy.run(Main.java:102) at org.mozilla.javascript.Context.call(Context.java:540) at org.mozilla.javascript.ContextFactory?.call(ContextFactory?.java:447) at org.mozilla.javascript.tools.shell.Main.exec(Main.java:164) at org.mozilla.javascript.tools.shell.Main.main(Main.java:142)

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:
java -Xmn100M -Xms500M -Xmx500M -jar custom_rhino.jar -opt -1 -c HUGE.js > smaller.js

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-native, non-abstract method is limited to 65536 bytes by the sizes…

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) {
// See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html,
// section 4.10, “The amount of code per non-native, non-abstract
// method is limited to 65536 bytes…
throw new ClassFileFormatException(
“generated bytecode for method exceeds 64K limit.”);
}

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:

context.setOptimizationLevel(-1);

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.

About Coach Wei
Coach Wei is the Founder and Chairman of Nexaweb (www.nexaweb.com), developers of the leading software platform for building and deploying Web 2.0 and AJAX applications. Previously, he played a key role at EMC Corporation in the development of a new generation of storage network management software. Wei has his master's degree from MIT, holds several patents, is the author of several technology publications including JDJ, Web 2.0 Journal, and AJAXWorld Magazine, and is an industry advocate for the proliferation of open standards.

LATEST AJAXWORLD RIA STORIES
Synology has announced the availability of its Disk Station Manager 2.1 beta which further utilizes AJAX technology, adds new mail server capability with 1-click installation Mail Station add-on, enhances the Synology Surveillance Station, storage management, user management, and...
Vik Chaudhary, VP of Product Management & Corporate Development at Keynote Syustems, will be presenting at SYS-CON's 2nd International Cloud Computing Conference & Expo in New York City this coming March 30-April 1. Chaudhary, who is a frequent speaker at industry events on softw...
rPath and WANdisco today announced that WANdisco has selected the rPath rBuilder and rPath Lifecycle Management Platform to build and maintain its Subversion MultiSite solution as a manageable set of application images for delivery in virtualized and cloud-based environments. rPa...
Curl announced the release of Curl Data Kit Data Services (CDK-DS) for enterprise developers building new applications using Adobe Flex or Flash, as well as developers upgrading existing Curl applications. This addition to the Curl Rich Internet Application (RIA) Platform is an i...
MuleSource has announced a partnership with FastConnect that will provide Mule architecture and implementation services throughout the French market. FastConnect spans the domains of data and service integration, through to the user interface, using technologies such as SOA, dist...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

Click Here

SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE