Rusty
Rusty

Reputation: 169

How do I solve Nashorn removal and JS replacement in Netbeans 22?

Despite having followed every procedure exactly as specified to install an alternative to Nashorn in Netbeans 22, I still get the following error when trying to build a FXML project:

Java 15 has removed Nashorn, you must provide an engine for running JavaScript yourself.

GraalVM JavaScript is the js that I am trying to integrate. Following the Oracle graalvm page I downloaded and extracted the following:

https://download.oracle.com/graalvm/22/latest/graalvm-jdk-22_windows-x64_bin.zip

Extracted the download to the directory C:Program Files/Java/graalvm-jdk-22.0.1+8.1 and renamed the folder graalvm-22

In an admin cmd shell, set JAVA_HOME environment variable with:

setx /M JAVA_HOME "C:\Progra~1\Java\graalvm-22"

and set the path with:

setx /M PATH "C:\Progra~1\Java\<graalvm>\bin;%PATH%"

Checked these variables with echo, which showed:

echo %JAVA_HOME%
C:\Progra~1\Java\graalvm-22

echo %PATH%
C:\Progra~1\Java\graalvm-22\bin;
C:\Program Files\CommonFiles\Oracle\Java\javapath;
C:\WINDOWS\system32;
C:\WINDOWS;
C:\WINDOWS\System32\Wbem;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\WINDOWS\System32\OpenSSH\;
C:\Program Files\HP\HP One Agent;C:\Users\qabpa\AppData\Local\Microsoft\WindowsApps;

I have been stuck for a few days with this issue and would appreciate help. Thanks.

Upvotes: 1

Views: 1345

Answers (1)

life888888
life888888

Reputation: 3144

This is just an example of Java + JavaFX + nashorn Script Engine.

If you want to integrate GraalVM JavaScript, it should be another answer. ( https://github.com/graalvm/polyglot-embedding-demo ) only GraalVM , not include JavaFX.

Remove or Uninstall All

  • Remove or uninstall JDK , JavaFX, Netbeans...
  • Remove Environment Variable JAVA_HOME

Install zulu JDK include JavaFX

https://www.azul.com/downloads/?version=java-21-lts&os=windows&architecture=x86-64-bit&package=jdk-fx#zulu

Download -> .msi

JDK_000.png

zulu21.34.19-ca-fx-jdk21.0.3-win_x64.msi

click zulu21.34.19-ca-fx-jdk21.0.3-win_x64.msi

Drop down Set JAVA_HOME variable , Select Entire feature will be installed on local hard drive

JDK_001.png

Click Next

JDK_002.png

Please note that you do not need to set the JAVA_HOME or PATH environment variables yourself.

Because the installation program has been automatically configured.

Check JDK install

Open CMD , input command javac -version

javac 21.0.3

input another command : java -version

openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Zulu21.34+19-CA (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Zulu21.34+19-CA (build 21.0.3+9-LTS, mixed mode, sharing)

Install Netbeans 22

Note, please use exe to install and not zip.

click Apache-NetBeans-22-bin-windows-x64.exe

Netbeans_001.png

NetBeans will detected Zulu-21

click Next

Netbeans_002.png

Click Install

Config JavaFX

Menu Tools -> Options

Netbeans_JavaFX_001.png

Click Next

Netbeans_JavaFX_002.png

Select accept the terms in all of the license agreements.

Click Install

Netbeans_JavaFX_003.png

Click Finish

Netbeans_JavaFX_004.png

Click OK

Create JavaFX Example

File -> New Project...

Netbeans_Example_001.png

  • Categories -> Java with Maven
  • Projects -> FXML JavaFX Maven Archetype

Click Next

Netbeans_Example_002.png

  • Peoject Name: hello1fx
  • Group Id: com.exmaple

Click Finish

Netbeans_Example_003.png

Click Icon (Run)

Then appear the javafx window.

Create Script Engine

Project Directory Tree

hello1fx
├── nbactions.xml
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   ├── com
    │   │   │   └── example
    │   │   │       └── hello1fx
    │   │   │           ├── App.java
    │   │   │           └── PrimaryController.java
    │   │   └── module-info.java
    │   └── resources
    │       └── com
    │           └── example
    │               └── hello1fx
    │                   └── primary.fxml
    └── test
        └── java

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>hello1fx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>21</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>21</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.4</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.4</version>
                <configuration>
                    <mainClass>com.example.hello1fx.App</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <!-- Default configuration for running -->
                        <!-- Usage: mvn clean javafx:run -->
                        <id>default-cli</id>
                    </execution>
                    <execution>
                        <!-- Configuration for manual attach debugging -->
                        <!-- Usage: mvn clean javafx:run@debug -->
                        <id>debug</id>
                        <configuration>
                            <options>
                                <option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option>
                            </options>
                        </configuration>
                    </execution>
                    <execution>
                        <!-- Configuration for automatic IDE debugging -->
                        <id>ide-debug</id>
                        <configuration>
                            <options>
                                <option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
                            </options>
                        </configuration>
                    </execution>
                    <execution>
                        <!-- Configuration for automatic IDE profiling -->
                        <id>ide-profile</id>
                        <configuration>
                            <options>
                <option>${profiler.jvmargs.arg1}</option>
                <option>${profiler.jvmargs.arg2}</option>
                <option>${profiler.jvmargs.arg3}</option>
                <option>${profiler.jvmargs.arg4}</option>
                <option>${profiler.jvmargs.arg5}</option>
                            </options>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  • Add nashorn-core for Script Engine
  • Change javafx-xxx version from 13 to 21
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>21</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>21</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.4</version>
        </dependency>

primary.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>

<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.hello1fx.PrimaryController">
   <children>
      <TextArea fx:id="inputArea" text="" promptText="Enter your script here..." />
      <Button fx:id="runButton" text="run" onAction="#execRun"/>
      <Button fx:id="cleanButton" text="clean" onAction="#execClean"/>
      <TextArea fx:id="outputArea" text="" editable="false" />
   </children>
</VBox>

module-info.java

  • ADD requires java.scripting;
  • ADD requires jdk.dynalink;
module com.example.hello1fx {
    requires javafx.controls;
    requires javafx.fxml;
    
    requires java.scripting;
    requires jdk.dynalink;
    
    opens com.example.hello1fx to javafx.fxml;
    exports com.example.hello1fx;
}

App.java

package com.example.hello1fx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

/**
 * JavaFX App
 */
public class App extends Application {

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        scene = new Scene(loadFXML("primary"), 640, 480);
        stage.setScene(scene);
        stage.setTitle("Nashorn JavaScript Engine");
        stage.show();
    }

    static void setRoot(String fxml) throws IOException {
        scene.setRoot(loadFXML(fxml));
    }

    private static Parent loadFXML(String fxml) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
        return fxmlLoader.load();
    }

    public static void main(String[] args) {
        launch();
    }

}

PrimaryController.java

package com.example.hello1fx;

import java.io.IOException;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class PrimaryController {
    ScriptEngineManager manager ;
    ScriptEngine engine;
    @FXML
    private TextArea inputArea;
    
    @FXML
    private TextArea outputArea;
    
    @FXML
    private void execRun() throws IOException {
            manager = new ScriptEngineManager();
            engine = manager.getEngineByName("nashorn");
            StringWriter writer  = new StringWriter();
            engine.getContext().setWriter(writer);

            try {
                String inputText = inputArea.getText();
                System.out.println(">>> inputText = "+inputText);
                engine.eval(inputText );
                System.out.println(">>> OK");
                outputArea.setText( "Processed: \n"+writer.toString());
                System.out.println(">>> set output OK");
            } catch (ScriptException e1) {
                e1.printStackTrace(new PrintWriter(writer));
            }       
    }
    
    @FXML
    private void execClean() throws IOException {
        inputArea.clear();
        outputArea.clear();
    }
}

Final Result

Click Icon Run Again

JavaFX_Script_001.png

in (1) input area put some java code.

print('Hello World!')
print(100 + 200)

Click Button run (3)

Then show the result in (2)

You can click Button clean (4) to clean (1) & (2)

Upvotes: 4

Related Questions