Creating a Java WebSocket Endpoint in NetBeans with GlassFish

WebSockets provide a persistent, two-way connection between a browser and a Java server. They suit live dashboards, chat panels, auction updates, delivery tracking and notifications where repeatedly polling an HTTP endpoint would add unnecessary traffic and delay. Learn more about Fashionistainsuburbia.com.

NetBeans and GlassFish provide a practical development combination for a Java WebSocket application. NetBeans manages the Maven project, source files and deployment workflow, while GlassFish supplies the WebSocket runtime defined by Java EE or Jakarta EE.

The examples below use the older javax.websocket namespace, which is appropriate for Java EE 7 and Java EE 8 servers such as GlassFish 4 or 5. Newer GlassFish releases use jakarta.websocket, so the imports must match the server and dependency versions selected for the project.

The same workflow is useful whether the application is being tested on a laptop in Brisbane, a workstation in Melbourne or a small office using an Australian NBN connection. A local server keeps testing quick, while production configuration must account for security, privacy and network reliability.

Prepare NetBeans And GlassFish

Install a supported JDK, NetBeans and a compatible GlassFish distribution before creating the project. Register GlassFish in NetBeans through the Services window, then check that the server starts without a port conflict. The default administration and HTTP ports are commonly 4848 and 8080, although an existing application or development tool may already use them.

Create a Maven Web Application and select the GlassFish server when NetBeans asks for a target runtime. Choose the Java EE Web or Web Application profile, depending on the NetBeans version. A project built for Java EE 8 should use a Java EE 8-compatible GlassFish installation rather than mixing Jakarta dependencies into a javax application.

A WebSocket endpoint does not need a traditional servlet mapping. The server discovers the endpoint through its annotation, packages it inside the WAR file and exposes it below the application context. This keeps the configuration small and makes redeployment from NetBeans straightforward.

Add The Endpoint Class

Create a package such as com.example.realtime and add a class named UpdatesEndpoint. The @ServerEndpoint annotation defines the WebSocket path, while lifecycle annotations connect Java methods to browser events.

package com.example.realtime;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/updates")
public class UpdatesEndpoint {
    private static final Set<Session> clients =
            new CopyOnWriteArraySet<>();

    @OnOpen
    public void open(Session session) {
        clients.add(session);
    }

    @OnMessage
    public void message(String text, Session sender) {
        broadcast(sender.getId() + ": " + text);
    }

    @OnClose
    public void close(Session session) {
        clients.remove(session);
    }

    private void broadcast(String text) {
        for (Session client : clients) {
            try {
                client.getBasicRemote().sendText(text);
            } catch (IOException exception) {
                clients.remove(client);
            }
        }
    }
}

@OnOpen runs when the handshake succeeds, @OnMessage receives text frames and @OnClose removes disconnected clients. CopyOnWriteArraySet avoids a concurrent modification problem when a browser disconnects while the server is broadcasting.

This example stores connections in memory, which is suitable for a tutorial or single GlassFish instance. A clustered application needs a shared messaging design, such as JMS, so that a message received by one server reaches clients connected to another server.

Connect A Browser Client

Add an HTML page under src/main/webapp, for example index.html. The browser constructs a WebSocket URL using the current host, which means the same page can work on localhost during development and behind a production hostname after deployment.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Live updates</title>
</head>
<body>
    <input id="text" type="text" placeholder="Message">
    <button id="send">Send</button>
    <ul id="events"></ul>

    <script>
        const scheme = location.protocol === "https:" ? "wss://" : "ws://";
        const socket = new WebSocket(
            scheme + location.host + "/realtime/updates"
        );

        socket.onmessage = event => {
            const item = document.createElement("li");
            item.textContent = event.data;
            document.querySelector("#events").appendChild(item);
        };

        document.querySelector("#send").onclick = () => {
            const input = document.querySelector("#text");
            if (socket.readyState === WebSocket.OPEN) {
                socket.send(input.value);
                input.value = "";
            }
        };
    </script>
</body>
</html>

Replace /realtime with the context path generated by the project. Using textContent rather than assigning received data to innerHTML prevents a message from being interpreted as browser markup.

Use wss:// whenever the page is served over HTTPS. Mixed content rules will block an insecure ws:// connection from a secure page, and public services should protect WebSocket traffic with TLS, authentication and sensible session timeouts.

Deploy And Test In NetBeans

Right-click the Maven project in NetBeans and select Run or Deploy. GlassFish should compile the application, create the WAR archive and display deployment output in the IDE. Open the page in two browser tabs, send a message from one tab and check that the other receives it.

The browser’s developer tools are useful for inspecting the WebSocket handshake and individual frames. A failed connection often indicates an incorrect context path, a server that has not deployed the latest build or a mismatch between javax.websocket and jakarta.websocket libraries.

When comparing a working and failing configuration, NetBeans can make the difference visible with its compare NetBeans files feature. Check pom.xml, server settings and the endpoint package rather than assuming the Java class is the only source of the problem.

Handle Messages And Application State

For a real application, define a message format instead of passing unstructured strings. JSON objects can carry an event name, identifier, timestamp and payload, making it easier for the browser to distinguish a stock update from a system notification. Jackson or JSON-B can serialise Java objects, provided the selected Java EE platform includes the required API.

Avoid placing database calls or slow external requests directly inside a broadcast loop. A busy endpoint can delay every connected browser. Use an executor, a managed component or a JMS queue for work that may block, and send a clear error event when processing fails.

Australian applications also need a privacy review when messages contain customer names, location data or account details. The Privacy Act 1988 and Australian Privacy Principles may apply, particularly when an organisation collects personal information through a public-facing service. Store only what the feature needs and avoid exposing private data to every connected session.

Prepare For Production Use

A local GlassFish deployment is a development environment, not a complete production architecture. Configure authentication before allowing clients to subscribe to private events, validate every incoming message and apply limits to message size and connection counts. Reverse proxies must also support the HTTP upgrade request used during the WebSocket handshake.

Plan for interrupted connections. A browser may move between Wi-Fi and mobile data, and users travelling between Sydney, Perth and other regions may experience short network changes. Add reconnect logic with a back-off delay, and make server events idempotent so that a repeated message does not corrupt application state.

Keep the NetBeans project focused on its Java server role if it does not need mobile tooling. If the same team also maintains a companion application, its separate Android setup guide can help establish an appropriate IDE configuration without changing the GlassFish WebSocket runtime.

Practical Deployment Checklist

A small checklist catches most endpoint problems before a live release. Test with several browser tabs, stop and restart GlassFish, and observe what happens when a client disconnects during a broadcast.

For Australian organisations, also record where logs and message data are stored. Cloud hosting, overseas support providers and analytics services may affect privacy disclosures and internal data-handling policies. A clear operational record is valuable whether the service supports a local retailer, a national marketplace or an internal team.

  • Match the WebSocket API namespace to the GlassFish version.
  • Confirm the application context path and endpoint path separately.
  • Use wss:// and HTTPS for deployed services.
  • Authenticate private channels and validate incoming payloads.
  • Add reconnect handling and remove stale sessions.
  • Review personal-information handling under the Australian Privacy Principles.