由一个js错误想到的.

[size=large][b]背景知识:Java 6提供对执行脚本语言的支持,这个支持来自于JSR223规范,对应的包是javax.script。默认情况下,Java 6只支持JavaScript脚本,它底层的实现是Mozilla Rhino,它是个纯Java的JavaScript实现。[/b]
详见: [url]http://developer.51cto.com/art/201007/208812.htm[/url][/size]


昨天运行ant脚本时触发了macros.js里这样一个js error: Uncaught TypeError: Cannot call method 'join' of undefined.

根据错误的line位置, 我查看了这个js

function concat(parts) {
[color=red]return parts.join('/');[/color]
}


很难看出来为什么红色这一行会有问题, 但以前没什么没发生呢. 什么地方的改动触发了这个error呢, 我今天的改动只不过是想把下面SilverFabricSDK和DSServer的version和location由4.1.0改为5.0.1, 就这么一个细小的改动跟上面的js有哪门子关系? 看上面js报错的地方实在是没头绪.

    <target name="init">
<init />
<require name="sf-common" when="compile-and-runtime" type="jar"
version="${common_rel_ver}" build-number="${common_build_num}" location="${common.gridlib.dir}"/>

<require name="commons-io" when="compile-and-runtime" type="plain-jar"
version="2.0" location="${basedir}/../../common/lib/thirdparty"/>

<require name="json" when="runtime" type="plain-jar"
version="20080701" location="${basedir}/../../common/lib/thirdparty"/>

<require name="SilverFabricSDK" when="compile" type="plain-jar"
version="5.0.1" location="${basedir}/../../common/lib/sf/5.0.1"/>

<require name="DSServer" when="test" type="plain-jar"
version="4.1.0" location="${basedir}/../../common/lib/sf/4.1.0"/>

...
...
...



于是在js中打印一下parts试试看, 到底是个什么东西.


function concat(parts) {
[color=red]java.lang.System.out.println("**" + parts.toString());[/color]
return parts.join('/');
}


在没错误情况下打印会看得更清楚, 于是先把版本号改回4.1.0, 打印的结果显示原来是把location下的jar文件和版本号拼在一起, 拼成${basedir}/../../common/lib/sf/4.1.0/SilverFabricSDK-4.1.0.jar, 如果location下有这个文件就ok, 没有就会出现上面的error. 于是我又去${basedir}/../../common/lib/sf/5.0.1的下面, 发现SilverFabricSDK.jar这个jar原来不含版本号, 换句话说, 跟没本有${basedir}/../../common/lib/sf/5.0.1/SilverFabricSDK-5.0.1.jar

其实真正引起错误原因的位置并不是显示错误的哪一个行, 而是在下面这一个行时, 传入的参数就已经出问题了:
[color=red]add_element(path, filename, true);[/color]

由于上面找的${basedir}/../../common/lib/sf/5.0.1/SilverFabricSDK-5.0.1.jar不存在, 所以parts实际的类型是不是期望的字符串数组, 而是布尔类型, 因为[b]JavaScript 拥有动态类型,换句话说,相同的变量可用作不同的类型.[/b] 布尔类型自然没有数组的join()这个方法, 所以报Cannot call method 'join' of undefined.

function add_element(path, parts, required) {
file = new File(concat(parts));

if (required) {
file.exists() || self.fail('File [' + file.getAbsolutePath() + '] does`t not exist');

element = path.createPathElement();
element.setLocation(file);
} else {
if (file.exists()) {
element = path.createPathElement();
element.setLocation(file);
}
}
}

filename = exists([location, name + '-' + relVer + '.jar']) || exists([location, name + '_' + relVer + '.jar']);
add_element(path, filename, true);



最后还有一点补充, 如果这样打印

function concat(parts) {
[color=red]java.lang.System.out.println(parts);[/color]
return parts.join('/');
}

会遇到这样的Exception,

D:\cloudteam\SFAMX\bpm-server\container\build.xml:16: javax.script.ScriptExcepti
on: sun.org.mozilla.javascript.internal.EvaluatorException: Cannot convert sun.o
rg.mozilla.javascript.internal.NativeArray@7a1576 to char[] (<Unknown source>#13
9) in <Unknown source> at line number 139

其实本质上还是js类型的问题, 由于parts不出错情况下是js的字符串数组类型, 而java.lang.System.out.println()的参数是java的char[]类型, 这两个类型没法直接直接转化, 所以必须把parts.toString()或者用"+"连接一个字符串类型, 即java.lang.System.out.println("**"+parts); 这样parts才能从js数组类型转化成字符串类型, 供java.lang.System.out.println()使用.


[b]PS:jdk6有一个命令行工具:jrunscript
cd到jire的bin目录,默认为javascript语言,可以直接输入单行js脚本测试语法是否正确, 观察输出[/b]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值