Collaborating on Java objects within Rhino's Javascript

Admitting that I am a JavaScript novice, I must acknowledge that my question might be lacking in clarity and detail.

Background

Within my organization, we use an internal Eclipse-based IDE for JavaScript development. The IDE allows us to write scripts in JavaScript and execute them directly. From what I have observed in stack traces of exceptions, it seems like the IDE uses Rhino.

The code I am working with is spread across 3 ".js" files:

Script-1: Declares global variables and instantiates Java objects

importClass(java.util.HashMap);
var hmTCResult = new HashMap();

Script-2: Performs actions using the global variables defined in Script-1

Script-2.prototype.run = function() {
hmTCResult.put("Result", "Fail");
};

changeStatus = function(strStatus){
hmTCResult.put("Result", strStatus);
};

Script-3: Calls a function from Script-2 which utilizes the global variables

changeStatus("Pass") 

Problem Definition

When I call the function from Script-3 that interacts with the global variables in Script-2, it fails to recognize the instance variables and throws an exception stating "hmTCResult not set to the instance of an object." It's important to note that the same variable works perfectly fine within Script-1.

I have tried to understand the concept of Scope and Context in JavaScript by reading up on it, but I haven't been able to find explicit information about these concepts in the IDE. If needed, I can provide additional information for better clarification.

Answer №1

Make sure to juggle your scopes and set up prototype search properly for everything to work smoothly:

Context cx = Context.enter();
try {
    // Cache and reuse:
    ScriptableObject sealedSharedScope = cx.initStandardObjects(null,
            true);
    // Load necessary LiveConnect components.
    String loadMe = "RegExp; getClass; java; Packages; JavaAdapter;";
    cx.evaluateString(sealedSharedScope, loadMe, "preLoadLazyLoad", 0,
            null);

    cx.evaluateString(sealedSharedScope, "varInRoot = 'blah';",
            "setVarInRoot", 0, null);

    // Additional cx.evaluateString calls can be added here to customize the environment (e.g., hmTCResult)

    // Create a new throw-away scope within the hierarchy, with local variables:
    Scriptable scope = cx.newObject(sealedSharedScope);
    // Ensure that definitions in the root scope are accessible
    scope.setPrototype(sealedSharedScope);
    // Make sure new global variables are created in this scope (avoid using var)
    scope.setParentScope(null);

    cx.evaluateString(scope, "localVar = varInRoot;", "mySource", 0,
            null);
    assertEquals("blah", scope.get("localVar", scope).toString());
    // Check for variable not in root:
    assertEquals(ScriptableObject.NOT_FOUND,
            sealedSharedScope.get("localVar", scope));
} finally {
    Context.exit();
}

Note that scope.get does not automatically search the prototype chain - you need to do it manually!

Remember that scopes are separate from Context and persist even after Context.exit().

Answer №2

When trying to run a JavaScript script in Java, you can use the following steps:

ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType( "text/javascript" );
Bindings bindings = engine.getBindings( ScriptContext.GLOBAL_SCOPE );
bindings.put( "varname", ... );
bindings.put( ... );
engine.put( ScriptEngine.FILENAME, script.toString());
engine.eval( new FileReader( script ));

If all 3 scripts are loaded into the same engine and bindings, everything works fine. However, if a new engine is created specifically for executing script3, the context will be cleared.

This message doesn't exactly provide an answer, but it's too lengthy to be just a comment.

Answer №3

Based on the information provided and assuming the accuracy of your edited transcripts, it seems likely that your scripts are running in isolated scopes with the global scope as the parent.

It appears that the changeStatus function works in the third script because it is not declared with the keyword var, making it a variable in the global scope shared by all three scripts.

On the other hand, the hmTCResult variable may not work as expected because it is declared using var, indicating a local variable specific to each script's scope. This can cause issues when trying to access the variable from different scripts operating in separate scopes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Periodically transmit information to a Google Script web application

I am currently working on a Google Script web app to automatically update data from a Google Sheet every 30 minutes. I initially attempted using the page refresh method, but encountered an issue where the web app would display a blank page upon refreshin ...

Establishing a connection to an Express SQL Server causes the webpage to endlessly load

const PostgresConfig = { server: "CatchNotConnected", connectionTimeout: 10000, requestTimeout: 10000 }; const express = require('express'); const pg = require('pg'); const app = express(); app.listen(80); app.ge ...

A program that saves numerous data from a JSON dictionary into an array

I have a large collection of dictionaries in JSON format obtained through an API request totaling over 1000. How can I develop a script that can loop through all the dictionaries and extract the values from one specific key-value pair? For instance: "te ...

What is the best way to extract a generic class parameter from JSON in Scala?

Has anyone encountered a similar scenario as mine? trait Getter[A] { def get: A } I have defined two implementations of classes that implement this trait: case class CoalesceGetter[A](getters: List[Getter[String]]) extends Getter[A] { override def g ...

Error: The method 'constructAppearances()' in the class 'org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation' cannot be found

When using Selenium with Java and Cucumber, I encountered an issue while trying to generate a PDF report. The HTML report was created successfully without any errors, but the PDF Report folder was not being generated in the test output folder. I have set ...

"Exploring the world of Rails. Any recommendations for useful SDKs and plug-ins to enhance my

After dedicating 6 years to C# programming, I am eager to expand my skills and knowledge. To demonstrate proficiency in Ruby on Rails and seize new opportunities as a Rails programmer, I plan to develop a simple web app. With the growing popularity of Rail ...

In Three JS, shader x, y, z coordinates are based on the orientation of the object rather than the scene itself

Animating the x,y,z coordinates of vertices in a sphere-like manner with horizontal rings around the center using attributes on a THREE.Points() object has been quite intriguing. Initially, with a MeshStandardMaterial(), tilting the Points object along the ...

Obtaining Attribute Value from an Input Field Using Selenium in Java

I'm struggling to retrieve the attribute value from an input field. Upon entering the value "565656565" into the text box, the HTML output is something like this: <input name = "placeHolder" id="$body_Txt"> > #shadow-root (user-agent) & ...

Is there a way to incorporate the 'window' into middleware when using Express?

I am using middleware to retrieve data from a cookie with the help of vue-cookies. try { if (window.$cookies.get('region')) { res.setHeader('Set-Cookie', [ `region=${window.$cookies.get('region')};pat ...

Navigation bar disappears when the page is scrolled to the top

Having an issue with the navbar functionality on my website. It is working properly in Firefox, but not in Chrome and Safari. When scrolling back up to the very top of the page, the navbar hides due to a minor bounce effect which triggers the hide action. ...

Pattern matching expression to divide a string while maintaining spaces

In my current Android project, I am faced with the task of splitting a String into tokens while ensuring that whitespaces are preserved and not splitting at non-word characters such as #, & etc... Although using \b to split does so at any non-word ch ...

"Active engagement" classes versus unchanging utility functions

If you have a class called FileReader with a read method, is it necessary to create an equivalent ReaderUtils class that contains the same attributes within a static read method? Is there a specific reason for having a "Doer" class instead of using static ...

Steps for incorporating extra attributes based on the given text

Here is some of my HTML code: <div id="ccc_new_val_hdn"> <span>9</span> <span>,</span> <span> </span> <span>6</span> <span>2</span> <span>1</span> </d ...

Can you provide instructions on how to configure the npm settings to use the current directory in a pre

I'm currently working on setting the installation directory from where the user is installing to an npm config variable. This will help me reference it in my installation script. Can anyone advise if there is a command line solution for this or will ...

What could be causing my basic Selenium test to not execute properly with Maven?

I'm encountering an issue with running a simple Selenium test through Maven. When I attempt to run the test using Maven, it fails. However, if I right-click on the test and run it as a Java application, it works perfectly fine. Here is the basic Sele ...

Utilizing CSS class names for Xpath or extracting locators with CSS styling

I am currently working on a webpage that features a series of radio buttons, each accompanied by a help icon. When this icon is clicked, it triggers a popup with helpful information. I am in the process of using Selenium WebDriver to extract this help te ...

How can I make the URL dynamically update when loading views into a layout using ajax in CakePHP?

function loadContent(source){        $.ajax({              type: "post",  // Method: post              url: source, // Source URL              success: function(response) {                    ...

Sending a variable to a function in JavaScript (winJs) from a different function

Greetings! Currently, I am developing a Windows 8 app using Java Script. function fetchFromLiveProvider(currentList, globalList,value) { feedburnerUrl = currentList.url, feedUrl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&outpu ...

How come the eval() function is returning an undefined property value?

How can I retrieve the value of a property within an array of objects, where the array itself is a property of another object - specifically this.form.data.output[0].output_total? The array name, index, and property name are passed as parameters and stored ...

The issue of ambiguity in JavaScript base-36 conversion

Currently working on a JavaScript project involving base 36 encoding. Encountered the following issue: parseInt("welcomeback", 36).toString(36) It seems to output "welcomebacg". Confirmed the same result in both Chrome developer's console and Node. ...