Closed dhavkuma closed 1 month ago
I'm not sure if I understand your question.
java Strings and Arrays are somewhat unique among Java objects because they are allowed to use String.prototype
and Array.prototype
methods as long as there is not a java method of the same name. String.replace
is a commonly used method which has this conflict. So is String.split
.
So, you really just need to choose which replace method you want to use, and then ensure you are working with the correct String type.
If you want to use javascript replace, ensure you are starting with a javascript string
String(resource.getPath()).replace(/\W/g, '').replace(/+/g, '_')
If you want to use java regex replace, you can't pass a javascript RegExp object as an argument. The java method String.replace
is actually normal string replacement. The Java regex replace methods are replaceFirst
and replaceAll
and take the regex as a string (java does not have a literal regex notation.) In your case, you want to use replaceAll
, because of the g
flag. Since you are in a string now, don't forget to escape your escapes.
// if you aren't sure what your object is starting out as
var javaString = new java.lang.String(obj)
javaString.replaceAll('\\W', '').replaceAll('\\+', '_')
In the future, please open questions like this as a Discussion post. If it's determined that there really is an issue with Rhino, it can be converted to an Issue.
With the code we were getting this
ERROR: The choice of Java method java.lang.String.replace matching JavaScript argument types (function,string) is ambiguous
The question here was why the first argument which is a regular expression converts to a function.
Stacktrace:
Caused by: org.mozilla.javascript.EvaluatorException: The choice of Java method java.lang.String.replace matching JavaScript argument types (function,string) is ambiguous; candidate methods are: _ class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence)_ class java.lang.String replace(char,char) (/libs/screens/core/components/content/video/video.js#169) at org.mozilla.javascript.DefaultErrorReporter.runtimeError(DefaultErrorReporter.java:77) at org.mozilla.javascript.Context.reportRuntimeError(Context.java:954) at org.mozilla.javascript.Context.reportRuntimeError(Context.java:1010) at org.mozilla.javascript.Context.reportRuntimeError4(Context.java:997) at org.mozilla.javascript.NativeJavaMethod.findFunction(NativeJavaMethod.java:468) at org.mozilla.javascript.NativeJavaMethod.findCachedFunction(NativeJavaMethod.java:262) at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:139) at org.mozilla.javascript.optimizer.OptRuntime.call2(OptRuntime.java:42) [org.apache.servicemix.bundles.rhino:1.7.7.1_1] at org.mozilla.javascript.gen._libs_screens_core_components_content_video_video_js_20._c_anonymous_1(/libs/screens/core/components/content/video/video.js:169)
When I do it, it says object instead of function:
js> new java.lang.String().replace(/\W/g, '')
js: The choice of Java method java.lang.String.replace matching JavaScript argument types (object,string) is ambiguous; candidate methods are:
class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence)
class java.lang.String replace(char,char)
at (unknown):22
But that is not what is causing your problem. Your problem is that you are passing a javascript regexp to a java method that expects either a char or a CharSequence as the first argument, and it can't figure out what you were trying to do.
Use one of the two methods I already suggested:
This will prevent any errors about ambiguity.
Thanks @tonygermano. We took your suggestion and refactored the code to
java.lang.String(resource.getPath()).replaceAll('\\W', '_').replaceAll('_+', '_');
which would solve the ambiguity which occurred.
However, please note this error occurs intermittently on our runtime. Could you please suggest what might cause this inconsistent behaviour on rhino processing on the same piece of code?
You will never see that message unless you are calling an overloaded java method with values that make the runtime unsure which method you intended to call. Very rarely you need to explicitly choose which overloaded java method to call since you cannot cast values in javascript, but if you are not trying to call a java method in the first place, then you need to fix your code. In this case, it was expecting the first argument to be either a CharSequence or a char, and you were passing an object that was neither of those.
The error probably saved you in this case, because if the method was only expecting a CharSequence, it likely would have used the .toString value of your regex, which would definitely not have produced the results that you were looking for.
Closing this one, as there doesn't seem to be an issue here
Feel free to reopen if there's an actual issue, preferable with a reproducible example
The code where this ambiguity occurs is
resource.getPath().replace(/\W/g, '').replace(/+/g, '_')
The question still open is:
why
replace(/\W/g, '')
orreplace(/+/g, '_')
is matching toreplace(function, string)
i.e. a regular expression matches with a function-type argument.
Earlier issue https://github.com/mozilla/rhino/issues/1632 answered the part about method overloading.