Javascript inside Java

I recently ran into a situation where we wanted to provide extensibility to end-users without development team getting involved – think you are writing a generic framework where you want to provide ability to users to receive a Java object & produce different output formats & pass back the resulting object to Java. The formats users want to produce could be different for each use-case, if there was only one format, you could code it up in factory – no problem, but when users want to format it entirely different based on whatever it is they wanted – we figured it’d be wonderful to allow users to write their Javascript code, drop in their files & pass back & forth objects.

We are still in the middle of designing things – I may write back more once done, but here’s a quick hack prototype of how to create an object instance in Java, pass it to Javascript & interact with that object as a javascript object. I’ll provide two code samples – one for omnipresent “Person” & other one for actually pulling a JSON response by making an HTTP call & dealing with response as a JSON object in Javascript (while running inside JVM)

Example 1: Using a Java object in Javascript

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class JavaToJavaScript {

    static public class Person {
        private String first_name;
        private String last_name;

        public Person() {
        }

        public Person(String f, String l) {
            first_name = f;
            last_name=l;
        }

        public String getFirstName() {
            return first_name;
        }

        public String getLastName() {
            return last_name;
        }

        public String toString() {
            return first_name + " " + last_name;
        }
    }

    public static void main(String... args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");
        Person james = new Person("James", "Bond");
        String script = "var jsInstance = passedFromJava;"
                .concat("var fname = jsInstance.getFirstName();")
                .concat("var lname = jsInstance.getLastName();")
                .concat("print ('Person object set in Java but accessed from Javascript: ' + fname + ' ' + lname)");
        try {
            engine.put("passedFromJava", james);
            engine.eval(script);
        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

Example 2: Using HTTP response from a URL in Javascript

(URL used in this example has usage limits, don’t run it multiple times … I have not dealt with error handling – whatsoever!)

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.stream.Collectors;

public class JavaToJavaScript2 {
    public static void main(String... args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");
        String response;
        String url = "http://api.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT&username=demo";

        try {
            InputStreamReader is = new InputStreamReader(new URL(url).openStream());
            BufferedReader reader = new BufferedReader(is);
            response = reader.lines().collect(Collectors.joining());
            engine.put("response", response);
            System.out.println(engine.eval("var obj = JSON.parse(response); print(obj.postalcodes[0].placeName);"));
        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

References:

Separate password for each VNC session

I often setup VNC sessions for various uses, one being – I keep a “personal” session where my emails, browsing & other documents are – the things I typically don’t want to share with my coworkers, but then there are other sessions where I want to share, collaborate & let someone else work out a problem. Having same VNC session password isn’t optimal (true you can use VNC session port to obfuscate things, but that’s not ‘complete’).

You can setup different passwords, tuck them away in different files and when you start a VNC session you can specify which file to use for which session. Here’s how to …

Step 1: Generate a password

$ vncpasswd ~/.vnc/personal-pwd
Password: <type your password here>
Verify: <type same password as earlier>

Step 2: Specify the password file to use when starting a VNC session

$ vncserver:34  -rfbauth ~/.vnc/personal-pwd

This will start a VNC session secured by the password you setup on port :34
$ vncserver:1 

This will start a VNC session by using whatever default password you have (assuming you have one) on port :1