2

In my Java program which is a Chrome extension's host (or a native app), every time the host is called by my Chrome extension, then a new instance of my Applet class is created.

How to prevent that from happening? I mean I need to have one single object of Applet for all host-extension-host calls, how to achieve that?

Here is my program:

import javax.swing.JOptionPane;

public class Applet {

    static Applet myApplet;

    public Applet(){
        System.err.println("new instance created!");
    }

    public static void main(String[] args) {
        try {
            if (myApplet == null)
                myApplet = new Applet();
            myApplet.readMessage();
            myApplet.sendMessage("{\"data\": \"somee data\"}");
        } catch (Exception ex) {
            System.err.println("error");
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    }

    public String readMessage() {
        String msg = "";
        try {
            int c, t = 0;
            for (int i = 0; i <= 3; i++) {
                t += Math.pow(256.0f, i) * System.in.read();
            }

            for (int i = 0; i < t; i++) {
                c = System.in.read();
                msg += (char) c;
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "error in reading message from JS");
        }
        return msg;
    }

    public void sendMessage(String msgdata) {
        try {
            int dataLength = msgdata.length();
            System.out.write((byte) (dataLength & 0xFF));
            System.out.write((byte) ((dataLength >> 8) & 0xFF));
            System.out.write((byte) ((dataLength >> 16) & 0xFF));
            System.out.write((byte) ((dataLength >> 24) & 0xFF));

            // Writing the message itself
            System.out.write(msgdata.getBytes());
            System.out.flush();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "error in sending message to JS");
        }
    }
}

I beleive there is no need for adding any extension or background.js code, but please let me know if you need to see those, too.

Thank you very much.

almightyGOSU
  • 3,731
  • 6
  • 31
  • 41
Reza Ahmadi
  • 357
  • 3
  • 12

3 Answers3

3

First of all - use chrome.runtime.connectNative instead of chrome.runtime.sendNativeMessage (example).

In your native application (Java), use an infinite loop to keep receiving messages. At present, you're only receiving and sending a message. After that, nothing else happens, so your application understandably exits. The stdio native messaging protocol is very simple:

  • Read 32-bit message length (native byte order).
  • Read JSON-encoded message (length as specified before).
  • Write 32-bit message length (native byte order).
  • Write JSON-encoded message (length as specified before).
  • Repeat until either end disconnects the port.

Your program should contain an (infinite) loop that implements the above protocol. This is a program structure that has the desired flow:

class Applet {
    public static void main(String[] args) {
        new Applet(); // Initialize application.
    }

    Applet() {
        while (true) {
            readMessage();
            // ... and save the state for later processing if needed

            // Send the reply:
            sendMessage("{\"data\": \"somee data\"}");
        }
    }

    // TODO: Implement readMessage and sendMessage (see question).
}
Rob W
  • 341,306
  • 83
  • 791
  • 678
1

You need to alter the object as a Singleton. Following code will create the Singleton object in a synchronized way if it's null and return that object.

public class Applet{

    // Object of the class which is going to be Singleton object
    // It's necessary to declare it as static, otherwise it wont work
    private static Applet applet;

    // Private constructor to prevent other classes from initializing this class
    private Applet(){}

    public static Applet getInstance(){
        if( applet == null ){
            // Synchronized to prevent more than one initialization 
            // when two or more methods accessing this method for the first time parallely
            synchronized(Applet.class){
                if( applet == null ){
                    applet = new Applet();
                }
            }
        }
        return applet;
    }

    public static void main(String[] args){
        Applet.getInstance().readMessage();
    }

    public String readMessage(){
        // Some operations
    }

}
The Coder
  • 2,562
  • 5
  • 33
  • 62
0

Use the Singleton Pattern?

  • Ensure that only one instance of a class is created
  • Provide a global point of access to the object

Something like this:

public class Applet {

    private static Applet myApplet = null;

    // Private constructor
    private Applet(){
        System.err.println("New instance created!"); // Should only occur once
    }

    // Use this to get the single instance of Applet?
    public static Applet getInstance() {
        if(myApplet == null) {
            myApplet = new Applet();
        }
        return myApplet;
    }
}

For more on the Singleton pattern, check this.

almightyGOSU
  • 3,731
  • 6
  • 31
  • 41