`

Java中嵌入Javascript遭遇“"The choice of Java constructor replace matching JavaScript”

阅读更多

今天在使用Solr的DataImportHandler时,需要用一个JavaScript函数来对数据做预处理,写的JS代码如下:

 

<script>
<![CDATA[
var reg = new RegExp("[^\\d,]|^,+|,+$","g");
function cleanFJID(row){
  var val = row.get("FJ");
  var val = val.replace(reg,"");  //把无效字符去掉 
  if(val=="") val = "null";
  row.put('FJ', val);
  return row;
}
]]>
</script>

 这段代码如果在浏览器里执行,应该是没有问题的,但是DIH执行时却报错:

警告: transformer threw error
org.apache.solr.handler.dataimport.DataImportHandlerException: Could not invoke method :cleanFJID
 <script>
null</script> Processing Document # 1
	at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:58)
	at org.apache.solr.handler.dataimport.EntityProcessorWrapper.applyTransformer(EntityProcessorWrapper.java:195)
	at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:241)
	at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:357)
	at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:242)
	at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:180)
	at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:331)
	at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:389)
	at org.apache.solr.handler.dataimport.DataImporter$1.run(DataImporter.java:370)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:53)
	... 8 more
Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor replace matching JavaScript argument types (function,string) is ambiguous; candidate constructors are: 
    class java.lang.String replace(char,char)
    class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence) (<Unknown source>#6) in <Unknown source> at line number 6
	at com.sun.script.javascript.RhinoScriptEngine.invoke(RhinoScriptEngine.java:184)
	at com.sun.script.javascript.RhinoScriptEngine.invokeFunction(RhinoScriptEngine.java:142)
	... 13 more
2010-6-18 1:43:40 org.apache.solr.handler.dataimport.DocBuilder buildDocument
严重: Exception while processing: XZ_SJFW document : SolrInputDocument[{}]

 

 

看字面的意思是JS的replace函数与java的replace方法混淆,导致javascript引擎不知该调用哪个方法,所以,我就使用了另外一种方法来引用正则表达式,修改后JS如下:

<script>
<![CDATA[
//var reg = new RegExp("[^\\d,]|^,+|,+$","g");
function cleanFJID(row){
  var val = row.get("FJ");
  var val = val.replace(/[^\\d,]|^,+|,+$/g,"");  //把无效字符去掉 
  if(val=="") val = "null";
  row.put('FJ', val);
  return row;
}
]]>
</script>

 

满以为这样修改就不会再有问题,可以一执行,还是报差不多的错:

警告: transformer threw error
org.apache.solr.handler.dataimport.DataImportHandlerException: Could not invoke method :cleanFJID
 <script>
null</script> Processing Document # 1
	at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:58)
	at org.apache.solr.handler.dataimport.EntityProcessorWrapper.applyTransformer(EntityProcessorWrapper.java:195)
	at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:241)
	at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:357)
	at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:242)
	at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:180)
	at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:331)
	at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:389)
	at org.apache.solr.handler.dataimport.DataImporter$1.run(DataImporter.java:370)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:53)
	... 8 more
Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor replace matching JavaScript argument types (function,string) is ambiguous; candidate constructors are: 
    class java.lang.String replace(char,char)
    class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence) (<Unknown source>#5) in <Unknown source> at line number 5
	at com.sun.script.javascript.RhinoScriptEngine.invoke(RhinoScriptEngine.java:184)
	at com.sun.script.javascript.RhinoScriptEngine.invokeFunction(RhinoScriptEngine.java:142)
	... 13 more
2010-6-18 1:46:50 org.apache.solr.handler.dataimport.DocBuilder buildDocument
严重: Exception while processing: XZ_SJFW document : SolrInputDocument[{}]

 

这下我可傻眼了,搞不懂是什么原因了

上网一顿狠找,找到洋鬼子的一个贴子:

http://www.mirthcorp.com/community/forums/showthread.php?t=235

 

英文水平差,意思没看明白,但看到5楼有人回复,建议把字符串改成

var input = new String(strOut);

再调用replace试试,我照猫画虎,也把代码改成这样:

<script>
<![CDATA[
//var reg = new RegExp("[^\\d,]|^,+|,+$","g");
function cleanFJID(row){
  var val = row.get("FJ");
  var str = new String(val);
  var val = str.replace(/[^\d,]|^,+|,+$/g,"");  //把无效字符去掉 
//  var val = val.replace(reg,"");  //把无效字符去掉 
  if(val=="") val = "null";
  row.put('FJ', val);
  return row;
}
]]>
</script>

 

再试了一下,我的乖乖,问题解决了。不过仅管问题已经解决,但其中的子丑寅卯还是没弄明白

 

分享到:
评论
1 楼 hoszb 2010-09-08  
java有个script引擎,不导入第三方jar的情况下可以处理javascript,导入第三方jar的话,可以处理python,perl等

我实验过,java中运行js的效率极其低下,我的一个实验中同样的js代码运行时间是java的10倍,所以要做预处理的话还是扩展solr的Transformer接口吧,功能更多而且效率更好

相关推荐

Global site tag (gtag.js) - Google Analytics