Durch das aufrufen von @JSFunction aus JavaScript TypeError: Cannot find default-Wert für das Objekt
Ich rufe ein @JSFunction
annotierten Methode einer ScriptableObject
Die JavaScript-Datei
Target = Packages.com.acme.rhino.Target;
function evaluate() {
var t = Target();
t.addModifier("foobar", 1);
return t;
}
Die Java-Datei
public class Target extends ScriptableObject {
private static final long serialVersionUID = 1L;
public List<Modifier> modifiers = new LinkedList<>();
@JSConstructor
public Target() {
}
@JSFunction
public void addModifier(final String message, final int value) {
modifiers.add(new Modifier(message, value));
}
public int getValue() {
int sum = 0;
for (final Modifier modifier : modifiers) {
sum += modifier.getValue();
}
return sum;
}
@Override
public String getClassName() {
return "Target";
}
}
Aber ich bekomme
org.mozilla.javascript.EcmaError: TypeError: Cannot find default value for object.
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3687)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3665)
at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3693)
at org.mozilla.javascript.ScriptRuntime.typeError1(ScriptRuntime.java:3705)
at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:976 )
at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:895 )
at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:761)
at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3774)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime. java:2269)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime. java:2251)
at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:83)
at org.mozilla.javascript.gen.script_5._c_evaluate_1(script:6)
at org.mozilla.javascript.gen.script_5.call(script)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
at org.mozilla.javascript.gen.script_5.call(script)
sind und nicht wissen, wo Sie gehen von dort aus. Wenn ich nicht anrufen addModifier
Methode der angegebene code funktioniert, und angesichts der Fehler notFunctionError
unten im stack trace ich denke, dass Rhino nicht interpretieren Sie die vorliegende Methode als JavaScript-Funktion.
- OSX 10.8.2
- Java 7
- Rhino 1.7R4
Kompletten Maven-Projekt, das den Fehler reproduziert werden kann, gefunden hier
Du musst angemeldet sein, um einen Kommentar abzugeben.
tl;dr siehe diese zwei alternativen.
Das problem mit dem Ansatz oben ist, dass
Target.prototype
ist nicht korrekt in den Skriptbereich. Siehe die statischeScriptableObject.defineClass()
Methode für details auf, wie man richtig definieren Prototypen in einem Skriptbereich.Haben Sie ein paar alternativen für die Bereitstellung der
Target
Konstruktor Ihre Skripte. Die erste alternative wäre immer definieren dieTarget
Konstruktor für alle Skripte. Dies funktioniert gut, wenn Sie im Voraus wissen, dass Sie wollenTarget
werden weltweit verfügbar. Diese im Grunde kommt es auf die folgenden:Wenn Sie stattdessen möchten, dass der script-Autor zu entscheiden, welche Konstruktoren sind notwendig, die zweite alternative ist die
defineClass
Funktion zu Skripten. Mit dieser Funktion, script-Autoren können Sie auf "importieren" alle skriptfähigen Objekte, die mit Ihrer Klasse Weg (kann mehr als Sie zulassen möchten). Um diedefineClass
Funktionen für Skripts, führen Sie die folgenden nach der Eingabe der Kontext:Und dann die JavaScript-Autor macht Gebrauch von der
Target
- Konstruktor mit den folgenden:In den beiden oben genannten Zweige, die ich gemacht habe, ein paar andere änderungen, die Sie besser, wenn Sie mehr hinzufügen, um die
Target
Konstruktor. Die null-argument-Konstruktor muss nicht die@JSConstructor
annotation. Wenn Sie später möchten, müssen Sie einen Konstruktor, der Argumente, nimmt dieses null-argument-Konstruktor verwendet werden, da der Prototyp-Konstruktor, und Sie können die@JSConstructor
annotation an einer Methode, die zur Initialisierung des Objekts ein. Je nachdem, wie Sie Autor dieser Konstruktor-Methode, es wird wichtig werden, verwenden Sie dienew
- Schlüsselwort in JavaScript.Kurz gesagt, die
Packages.com.acme...
syntax ist nicht nützlich für den Zugriff aufScriptableObject
Konstruktoren von Skripts.Bekomme ich es funktioniert (sehr ähnlich-code) mithilfe des new-operators. In deinem Beispiel tut
sollte auch funktionieren.