Skip to content
Advertisement

javascript execution failing in java with XPathResult undefined

I’m trying to execute the javascript function with java, and I’m getting an error message that it is not able to find some of the classes. can someone please help me to clear this issue?

My Java class

public class TestException {

    public static void main(String[] args) throws IOException, ScriptException {
        ScriptEngineManager engineMgr=new ScriptEngineManager();
        ScriptEngine engine=engineMgr.getEngineByName("JavaScript");
        Document doc=HtmlPage.getHTML("", "C:\Users\DELL\Desktop\PHPTRAVELS.html", "https://phptravels.com");
        String xpath="//input";
        
        //for single value
    /*  String jscript="return document.evaluate('"+xpath+"',document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;";
        WebElement element=(WebElement)jse.executeScript(jscript);
        System.out.println(element.getAttribute("name"));*/
        
        String multiCode="var test=function(document){"
                + "var results=document.evaluate('//input', document,null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);"+
                "var tagNames = [];rn"
                + "var count=0;" +
                "while(node = results.iterateNext()) {rn" + 
                "  count=count+1;" + 
                "}"
                + "rn return count}";
        /*FileWriter fileWrite=new FileWriter(new File(System.getProperty("user.dir")+"\jScript.js"));
        fileWrite.write(multiCode);
        fileWrite.flush();
        fileWrite.close();*/
        
        try{
            engine.eval(multiCode);
            Invocable invc=(Invocable) engine;
            Long count=(Long)invc.invokeFunction("test", doc);
        //Long count=(Long) jse.executeScript(multiCode);
        System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }
        }

Exception

javax.script.ScriptException: ReferenceError: "XPathResult" is not defined in <eval> at line number 1
    at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470)
    at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:392)
    at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)
    at demo.TestException.main(TestException.java:58)
Caused by: <eval>:1 ReferenceError: "XPathResult" is not defined
    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
    at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319)
    at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291)
    at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1441)
    at jdk.nashorn.internal.scripts.Script$Recompilation$1$27A$^eval_.test(<eval>:1)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:639)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
    at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:199)
    at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:386)

please let me know if data required from my side.

Advertisement

Answer

The problem with your code is, you are using XPathResult which present under window object, window object implementation is provided by the web browser. Nashorn (ScriptEngine) doesn’t provide window implementation.

From Java Docs:

While Oracle Nashorn runs ECMA-compliant JavaScript, it is important to note that objects normally accessible in a web browser are not available, for example, console, window, and so on.

You can execute and verify your js code with Nashorn using jjs option:

> jjs test.js
abc.js:2 ReferenceError: "XPathResult" is not defined

As you want to parse the HTML file, you can achieve it by using HTML parser such as https://jsoup.org/ , if are using this code for testing you can use Selenium’s API JavascriptExecutor#executeScript(...)

Advertisement