tl; dr see these two alternatives .
The problem with the above approach is that Target.prototype incorrectly configured in the script scope. For more information on how to correctly define prototypes in the script area, see the ScriptableObject.defineClass() Static Method.
You have several alternatives for providing the Target constructor for your scripts. The first alternative is to always define the Target constructor for all scripts. This works well if you know in advance that you want Target be available worldwide. It basically boils down to the following:
final Context context = Context.enter(); try { final ScriptableObject scope = context.initStandardObjects(); ScriptableObject.defineClass(scope, Target.class, false, true); context.evaluateString(scope, script, "script", 1, null);
If instead you want the script author to determine which constructors are needed, the second alternative is to provide the defineClass function for the script. Using this function, script authors can "import" any script objects into their class path (which may be more than you want to allow). To provide the defineClass functions for scripts, do the following after entering the context:
final Context context = Context.enter(); try { final ScriptableObject scope = context.initStandardObjects(); scope.defineFunctionProperties( new String[] {"defineClass"}, Global.class, ScriptableObject.DONTENUM); context.evaluateString(scope, script, "script", 1, null);
And then the JavaScript author uses the Target constructor with the following:
defineClass("com.acme.rhino.Target"); // whatever `getClassName()` returns is now available var target = new Target();
In both of the above branches I made a couple of other changes that would improve you if you add more to the Target constructor. The null argument constructor does not need the @JSConstructor annotation. If you later want to have a constructor that takes arguments, this null argument constructor will be used as the prototype constructor, and you can use the @JSConstructor annotation for the method that will be used to initialize your object. Depending on how you create this constructor method, it becomes important to use the new keyword in your JavaScript.
In short, the syntax of Packages.com.acme... not useful for accessing ScriptableObject constructors from scripts.