Subj : Unable to access protected fields in compiled script that extends another class To : netscape.public.mozilla.jseng From : vwine@yahoo.com (Vaughn) Date : Fri Apr 25 2003 06:21 pm Hello, I've just discovered that I cannot access protected fields in compiled script that extends another class. It took me quite a while to discover the problem, as all I was getting was a ConversionError. I wrote a very simplified version of our architecture, started tweaking and comparing, and finally figured out what the problem was. Before I begin, let me explain a bit about our project (at least a simplified explanation). First, we have an engine that performs actions. Originally, all of these actions were defined in a UI and saved as XML, but recently an extension mechanism has been developed that allows developers to create their own Actions that plug-in to the framework. Our hope is that we can further the ease-of-use of this process and allow developers to use JavaScript to extend the framework. The idea is that we would expose a TextArea in our UI where the user can simply write JavaScript for the key function bodies in our Action interface. Here's an important facet of our situation: In each function body, the user needs to access some fields that are inherited from the base class. And it is this access that was causing me grief. To illustrate this, I've create a simple example. I've got an Engine, which calls init and perform on an Action. The Engine can be given any custom Action written by the user. In the example below, the Engine sets a value on the Action's vectorTool in the init method. Then, the custom Action takes that value and modifies it in the perform method/function. In the example below, I've got a Java version and a scripted version. They both work, but the script version only works if vectorTool is public. If it's protected, I get the following ConversionError: Exception in thread "main" ConversionError: The undefined value has no properties. (CustomScriptAction.js; line 5) at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:597) at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:557) at org.mozilla.javascript.ScriptRuntime.getProp(ScriptRuntime.java:712) at CustomScriptAction$perform.call(CustomScriptAction.js:5) at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1191) at org.mozilla.javascript.JavaAdapter.callMethod(JavaAdapter.java:366) at CustomScriptAction.perform() at Engine.main(Engine.java:23) Is this a bug? In our project, I can change the field to public, but it's very inconvenient. Is there another way to work around the issue? Thanks for your time! Rhinoscript is great! Vaughn -- Engine.java ----------------------------------- public class Engine { // Run either the java version: // java -cp ".;js.jar" Engine CustomJavaAction // or the script version: // java -cp ".;js.jar" Engine CustomScriptAction // // When I run the script version and the vectorTool field on // Action is changed to protected, I get a ConversionError. public static void main(String[] args) { if (args.length == 0) { System.out.print("Please provide a class name. "); System.out.println("(The class must extend Action.)"); return; } Engine engine = new Engine(); try { Class actionClass = Class.forName(args[0]); if (Action.class.isAssignableFrom(actionClass)) { Action action = (Action) actionClass.newInstance(); action.init(23); action.perform(); System.out.println(action); // Should print out the number 30 } else { System.out.println(args[0] + " does not extend Action!"); } } catch (Exception failure) { failure.printStackTrace(); } } } -- Action.java ----------------------------------- import java.util.*; public abstract class Action { // When I Change this field to protected, I get a ConversionError. public Vector vectorTool = new Vector(); public void init(int initVectorToolValue) { vectorTool.add(new Integer(initVectorToolValue)); } public abstract void perform(); public String toString() { StringBuffer sb = new StringBuffer(); for (Iterator it = vectorTool.iterator(); it.hasNext(); ) { sb.append(((Integer) it.next()).toString()); } return sb.toString(); } } -- CustomJavaAction.java ------------------------- public class CustomJavaAction extends Action { public void perform() { int initVal = ((Integer) vectorTool.get(0)).intValue(); initVal += 7; vectorTool.set(0, new Integer(initVal)); } } -- CustomScriptAction.js ------------------------- // I compile this with -extends Action function perform() { // The next line causes the ConversionError if vectorTool is protected var initVal = Number(this.vectorTool.get(0)); initVal += 7; this.vectorTool.set(0, new java.lang.Integer(initVal)); } .