众所周知,jdk1.6中添加了对动态脚本的支持,可以在java中执行js脚本,如果要在jdk1.4,1.5下使用这个功能,可以使用http://www.mozilla.org/rhino/上提供的jar,jdk1.6将这个开源项目集成进了jdk(jsr_223)。
在浏览器中,js是解释执行的,在java中,javascript脚本自然没有了window,document等对象,但这不影响javascript的强大,可以解释执行,也可以编译执行,大大提高了效率,所谓编译,也就是把javascript脚本编译成java方法的字节码。
标题中的错误Encountered code generation error while compiling script: generated bytecode for method exceeds 64K 是在使用Rhino编译js脚本的时候发生的,查看Rhino的实现,在org.mozilla.classfile.ClassFileWriter中public voidstopMethod(short maxLocals)方法中,有这样一段代码:
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.");
}
也就是说,当Method的bytecode的长度超过65536字节(64K)的时候,就会报这样的错误。
有人在1999年已经以Maximum method size is too small (64Kb)为由作为bug提交给了官方,但至今,至少在1.5中都没有改变,1.6中似乎也没有改变
在这一段代码的注释部分,我们可以看到,说jvm spec第二版中4.10章对方法长度有规定,我在这里摘抄如下:
4.10 Limitations of the Java Virtual MachineThe following limitations of the Java virtual machine are implicit in the class file format:
The per-class or per-interface constant pool is limited to 65535 entries by the 16-bit constant_pool_count field of the ClassFile structure(§4.1). This acts as an internal limit on the total complexity of a single class or interface.
The amount of code per non-native, non-abstract method is limited to 65536 bytes by the sizes of the indices in the exception_table of the Code attribute (§4.7.3), in the LineNumberTable attribute(§4.7.8), and in the LocalVariableTable attribute(§4.7.9).
The greatest number of local variables in the local variables array of a frame created upon invocation of a method is limited to 65535 by the size of the max_locals item of the Code attribute(§4.7.3)giving the code of the method. Note that values of type long and double are each considered to reserve two local variables and contribute two units toward the max_locals value, so use of local variables of those types further reduces this limit.
The number of fields that may be declared by a class or interface is limited to 65535 by the size of the fields_count item of the ClassFile structure(§4.1). Note that the value of the fields_count item of the ClassFile structure does not include fields that are inherited from superclasses or superinterfaces.
The number of methods that may be declared by a class or interface is limited to 65535 by the size of the methods_count item of the ClassFile structure(§4.1). Note that the value of the methods_count item of the ClassFile structure does not include methods that are inherited from superclasses or superinterfaces.
The number of direct superinterfaces of a class or interface is limited to 65535 by the size of the interfaces_count item of the ClassFile structure(§4.1).
The size of an operand stack in a frame(§3.6)is limited to 65535 values by the max_stack field of the Code_attribute structure(§4.7.3). Note that values of type long and double are each considered to contribute two units toward the max_stack value, so use of values of these types on the operand stack further reduces this limit.
The number of local variables in a frame(§3.6)is limited to 65535 by the max_locals field of the Code_attribute structure(§4.7.3)and the 16-bit local variable indexing of the Java virtual machine instruction set.
The number of dimensions in an array is limited to 255 by the size of thedimensionsopcode of themultianewarrayinstruction and by the constraints imposed on themultianewarray,anewarray, andnewarrayinstructions by§4.8.2.
The number of method parameters is limited to 255 by the definition of a method descriptor(§4.3.3), where the limit includes one unit for this in the case of instance or interface method invocations. Note that a method descriptor is defined in terms of a notion of method parameter length in which a parameter of type long or double contributes two units to the length, so parameters of these types further reduce the limit.
The length of field and method names, field and method descriptors, and other constant string values is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANT_Utf8_info structure(§4.4.7). Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.
就是阴影部分的内容,如果编译不了,那么怎么办呢?很显然,可以解释执行,当然也可以选择将方法体分的更小,但有时候方法是自动生成的,我们也不愿意去更改这样的内容。用Rhino怎么解释与编译执行方法呢,部分代码如下:
String scriptContent = ".........";//这里是js脚本,里面可能有很长的一个自动生成的方法
org.mozilla.javascript.Context context = org.mozilla.javascript.Context.enter();
org.mozilla.javascript.Script script = null;
try {
script = context.compileString(scriptContent , null, 1, null);
} catch (Throwable t) {
context.setOptimizationLevel(-1);
script = context.compileString(scriptContent , null, 1, null);
}
//这里就可以执行上面的script对象了,如果可以被编译,那么就执行字节码,如果编译失败,就解释执行,虽然影响性能,但在没有更好的解决方案的时候,也不影响程序的功能。
分享到:
相关推荐
Rhino的jar包。 Rhino 是开源的 JavaScript 引擎,是完全基于 Java 实现,几乎可以使用 JavaScript 完成 Java 所有的工作。
RhinoResurf_x64.rhp文件是RhinoResurf的64位版本,专为64位系统的Rhino软件设计,它可以充分利用64位系统的内存资源,处理更大、更复杂的模型。安装这个插件后,用户将在Rhino的工作环境中看到RhinoResurf的全部...
快速,简单,精确的 2D 到3D 展开软件 ExactFlat ExactFlat软件
**Millipede for Rhino5 x64** 是一个专门针对Rhino 5 64位版本的插件,用于执行高级的结构力学分析。这款工具旨在帮助用户在设计过程中理解和评估其模型在受力情况下的行为,比如计算应力分布和挠度等关键参数。...
rhino中专门用来汽车和工业产品a级曲面的插件工具,适用5
标题“Python for Rhino教程”表明本文将专注于在Rhinoceros(犀牛)软件中使用Python编程语言。Rhinoceros,通常称为Rhino,是一个三维建模工具,广泛应用于工业设计、建筑、汽车设计、船舶设计、3D打印、珠宝设计...
grasshopper for rhino5(犀牛参数化插件)是一款参数化建模插件,grasshopper for rhino5主要应用在建筑室内外设计、规划设计、园林景观设计、工业产品设计等领域一些,grasshopper for rhino5还可以应用于造型创作,...
RhinoCommon and Grasshopper templates for Rhino 7
Clayoo是一款专为Rhino 5设计的强大3D建模插件,特别针对64位平台进行了优化,旨在为设计师提供更为高效和创新的设计体验。Rhino,全称Rhinoceros 3D,是一款广泛使用的NURBS(非均匀有理B样条)建模软件,以其强大...
Rhino_Debugger Rhino引擎的JS调试工具 直接可运行Jar
在Rhino JavaScript引擎中使用字节数组 注意 由该代码制成的字节数组可以与Java中的字节数组不同,但它似乎可以像Java字节数组一样完美地工作。 用 let b = ( new ByteArray ( size ) ) . init ( ) ;
基于Rhino引擎的低侵入式JavaScript内置对象扩展方法.pdf 本文主要介绍了基于Rhino引擎的低侵入式JavaScript内置对象扩展方法。Rhino引擎是一个JavaScript解析引擎,可以解析JavaScript脚本并生成网页信息。为了...
《TS_for_Rhino3.3:犀牛建模插件的详解与应用》 TS_for_Rhino3.3,作为一个专为Rhino(犀牛)设计的强大建模插件,它极大地拓展了这款三维建模软件的功能,提升了设计师的工作效率。这款插件适用于Rhino4.9及以上...
《深入浅出Rhino:Java与JS互操作》是一本专注于探讨如何在Java环境中使用Rhino JavaScript引擎进行交互的书籍。Rhino是Mozilla基金会开发的一个开源JavaScript解释器,它完全用Java编写,使得JavaScript能够在Java...
全网络最完全的中文化版。 安装T-Splines 1,运行TSplines4.0 For Rhino5.0 安装英文原版,默认路径,否则汉化不成功。 2,复制 TSplines.rhp 到安装盘Program Files\Autodesk\T-...*提示* 只支持Rhino5.0 x64-bit
本篇文章将深入探讨如何在Java项目中使用Rhino来执行JavaScript,并展示从Java调用JavaScript函数以及从JavaScript调用Java方法的实例。 首先,你需要下载Rhino的jar包。你可以在Mozilla的开发者网站上找到它...
Rhino,全称为Mozilla Rhino,是一款由Mozilla基金会开发的JavaScript引擎,它以Java语言实现,因此具有很高的可移植性。Rhino在JavaScript的世界里扮演着重要角色,因为它将JavaScript的动态性和灵活性带入了Java...
grasshopper for rhino5(犀牛参数化插件)是一款参数化建模插件,grasshopper for rhino5主要应用在建筑室内外设计、规划设计、园林景观设计、工业产品设计等领域一些,grasshopper for rhino5还可以应用于造型创作,...
最初,Rhino通过将JavaScript编译成Java字节码的方式来获得最佳性能,但由于这种方式在垃圾回收、编译和加载方面的开销较大,无法满足某些场景下的需求,Rhino随后提供了动态解释执行模式。 随着Rhino的开源,...