27 min read

Install and Run the jforgame Java Game Server Demo

Set up and verify the jforgame demo, then expose its configured TCP socket securely for remote access with Localtonet.

A local jforgame server connects through a Localtonet TCP tunnel to a remote client.
The demo runs locally, while Localtonet carries remote TCP connections to its configured listening port.
Developer Tools · jforgame Java Game Server · Localtonet · 2026

Build the official jforgame demo locally, verify its client and server flow, then publish the configured TCP endpoint

jforgame is a component-based Java framework for game servers and other socket applications. This guide follows the project’s documented demo workflow: clone the repository, import its root Maven project, prepare the two required databases, configure the demo working directory, and launch the server before the client. After the demo works locally, we explain how to expose its actual TCP listening port with Localtonet without configuring inbound router port forwarding, changing firewall rules, setting up a VPN, or requiring a public IP address. Because the project documentation does not establish a universal port, bind address, database connection configuration, Java version, or demo credentials, this guide shows how to identify those values without inventing them.

🔒 Validate locally before allowing remote connections 🌐 TCP socket and WebSocket-capable framework ⚡ Installation first, Localtonet integration second

What the jforgame demo contains

jforgame is a lightweight Java framework intended primarily for mobile game servers, although its networking components can also be used for other socket applications such as real-time chat. The repository is organized as a multi-module Maven project. Instead of treating networking, message encoding, persistence, threading, runtime monitoring, and application behavior as one inseparable package, it separates them into modules that developers can select according to an application’s requirements.

The repository’s jforgame-demo module demonstrates the basic game components and business modules. It is the right starting point when the goal is to understand the complete sample rather than immediately assemble a custom server from individual dependencies. The documented quick-start process expects an IDE with Maven support and uses Java entry classes to start both sides of the example.

🔌 Socket server and client The socket modules provide the server and client foundations, message routing, session management, and TCP communication through Netty or Mina implementations.
🌐 WebSocket option The Netty implementation includes WebSocket server and client support. The Mina implementation is documented without WebSocket support.
📨 Selectable message codecs The framework documents JSON, Protobuf, and standard JavaBean-oriented communication choices, with codec functionality organized into separate modules.
🧵 Threading components The thread-model module includes actor and keyword-dispatch approaches. The project documentation recommends the actor implementation to reduce uneven thread workload.
🗄️ Data and ORM modules The project includes a game-oriented ORM and a configuration-data module for CSV, Excel, and JSON loading, validation, hot reload, and secondary caching.
🧩 Component-based adoption A custom application can import only the required modules. For example, a socket-focused application can select the Netty or Mina socket implementation rather than adopting the entire demo.

The demonstrated TCP startup code uses TcpSocketServerBuilder. Its binding value is supplied by ServerConfig.getInstance().getServerPort(), so the listening port comes from the application configuration rather than from a universal port documented in the README. This distinction matters later: a Localtonet TCP tunnel must target the port your running copy actually uses.

TcpSocketServerBuilder.newBuilder()
    .bindingPort(HostAndPort.valueOf(
        ServerConfig.getInstance().getServerPort()
    ))
    .setMessageFactory(GameMessageFactory.getInstance())
    .setMessageCodec(new StructMessageCodec())
    .setSocketIoDispatcher(
        new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)
    )
    .build()
    .start();
The demo and a production deployment are different scopes

Completing this tutorial proves that the documented sample can start in your environment and that its supplied client can attempt the expected protocol flow. It does not by itself establish production capacity, operational hardening, application-level authentication, authorization, monitoring, backup, or abuse controls. Review and adapt the code before exposing a real service to untrusted users.

Prerequisites and information you must determine

Prepare the development environment before cloning the repository. The official quick start establishes several requirements, but it does not state every version or platform detail needed for a universally reproducible setup. Where a value is not documented, use the repository’s current Maven metadata and your chosen database configuration as the authority rather than copying an arbitrary value from another tutorial.

Requirement Why it is needed What is established
Git Downloads the official repository The project documents a standard git clone workflow.
Java development environment Compiles and runs the Java modules The supplied evidence does not establish one universal JDK version. Inspect the checked-out root pom.xml and current project guidance before choosing a JDK.
Maven-capable IDE Imports the multi-module build and launches entry classes The documented workflow imports the root pom.xml. A specific IDE is not mandatory.
Database service and administration access Hosts the demo’s two required databases The quick start requires game_data_001 and game_user_001. Confirm the database engine and connection details from the checked-out project configuration.
Repository SQL files Creates the schema and any supplied initial data The corresponding SQL files are documented under test/resources. Locate them in the checked-out revision rather than guessing a deeper path.
Localtonet client Creates the later outbound connection to our relay Install it only on a device that can reach the running jforgame TCP service.

Use a consistent repository revision

The default branch can change over time. For repeatable team work, agree on the exact commit or release to test and keep the source code, SQL resources, and Maven files from that same revision. Do not combine schema files from one version with source code from another unless the project’s migration guidance explicitly calls for it.

A release such as v4.1.0 provides a named revision, but this guide does not assert that it is the correct release for every application. Select a revision based on your own compatibility and maintenance review. If you use the moving default branch, record the commit identifier in your internal setup notes so another developer can reproduce the result.

Plan the two database names exactly

The documented demo expects databases named game_data_001 and game_user_001. Create them using an account authorized to create databases, and import each same-named SQL resource into the matching database. Do not swap the files. The data and user databases have distinct purposes in the sample, and a successful SQL import into the wrong target can still leave the application unable to initialize correctly.

Do not guess database credentials or commit real secrets

The supplied project evidence does not establish a universal database host, port, username, password, or configuration file for every revision. Locate the relevant settings in your checked-out source, provide values for your own database service, and keep credentials out of source control. Use a dedicated account with only the permissions required by the demo whenever your database platform supports that model.

Install and run the official jforgame demo

The following sequence follows the repository’s documented quick-start order. Complete the database preparation before launching the server, and start the server before the client. The project uses IDE entry classes for this workflow, so this guide does not invent command-line startup targets that the supplied documentation does not provide.

1

Clone the jforgame repository

Open a terminal in the parent directory where you keep development projects and clone the official repository. After cloning, enter the repository and record the revision you intend to test if reproducibility matters to your team.

git clone https://github.com/kingston-csj/jforgame
2

Import the root Maven project

In an IDE with Maven support, open or import the pom.xml located at the repository root. Importing only an arbitrary child directory can prevent the IDE from resolving relationships among the modules. Allow Maven synchronization to finish, then inspect unresolved dependencies or JDK compatibility messages before proceeding.

3

Create and populate the two databases

Create game_data_001 and game_user_001 in the database environment selected for this project. Locate the corresponding same-named SQL files under the repository’s test/resources areas, then import each file into its matching database. Review the import output for failed statements instead of assuming that an apparently completed operation succeeded.

4

Configure the demo working directory and launch ServerStartup

Find the ServerStartup entry class in the imported project and create an IDE run configuration for it. When all modules are imported, set that run configuration’s working directory to the checked-out jforgame-demo directory, as required by the project’s quick start. Start the class and keep the process running while you inspect its output.

5

Configure the same working directory and launch ClientStartup

Find ClientStartup, create its IDE run configuration, and use the same jforgame-demo working directory when the complete multi-module project is imported. Start the client only after the server remains running. Observe both consoles because the server and client can report different sides of a connection or protocol failure.

Why the working directory matters

A Java process resolves relative paths from its current working directory. The demo can depend on resources addressed relative to jforgame-demo, so launching an entry class with the repository root or an IDE-generated output directory as the process directory can make valid files appear missing. This is why merely finding and running ServerStartup is not always sufficient.

In IntelliJ IDEA, the project documentation describes the path through Run, Edit Configurations, and Working directory. Other Maven-capable IDEs provide an equivalent process-directory setting, although its label and location can differ. Point it to the real jforgame-demo directory in your clone. The notation shown in the project documentation is illustrative, so replace it with the absolute local path rather than entering wildcard characters literally.

What a clean startup should tell you

Read the server output from the beginning, not just its final line. A process that continues running may still have reported a failed database initialization or a socket bind problem. Conversely, an informational or warning message is not necessarily fatal. Look for the application’s own indication that initialization completed, then confirm that the process has not terminated.

Next, run ClientStartup and inspect both outputs for evidence of a connection and application-level message handling. The supplied documentation does not define one exact success string, response payload, test account, or exit status. Therefore, this article cannot give a universal line to match. Use the current demo behavior and code path in your selected revision to determine what successful interaction looks like.

Find the actual database and TCP configuration

A project configuration view highlights the database settings and TCP listener settings.
Identify the demo’s real database settings and TCP listening port before testing the server.

The quick start identifies the required database names, while the startup example establishes that the TCP server receives its port from ServerConfig.getInstance().getServerPort(). It does not provide a concrete port number or bind address in the supplied evidence. Before configuring remote access, trace the active configuration used by your checkout.

Trace the server port from code to configuration

Use your IDE’s symbol navigation or text search to find ServerConfig, its getServerPort() method, and the place where that object receives configuration values. Also search for calls to bindingPort. This reveals whether the selected revision obtains the port from a resource file, a generated value, a constant, or another mechanism.

Record the resolved runtime port in your deployment notes, but do not assume that a value found in one branch or old screenshot applies to another revision. If there are multiple startup profiles, verify which profile your IDE run configuration actually activates.

Determine the bind scope

A listening port and a bind address answer different questions. The port identifies the transport endpoint, while the address determines which local interfaces accept traffic. The supplied project material does not establish whether the demo binds only to loopback, to a specific interface, or to all interfaces.

This uncertainty does not prevent a same-device Localtonet deployment. If the Localtonet client and jforgame server run on the same machine, the tunnel’s local target can normally use an address on which the service is actually listening. If the Localtonet client runs on another device, that device must be able to reach the server over the local network, and the jforgame bind scope and host firewall must allow that local path.

Locate the database connection settings

Search the checked-out demo for references to game_data_001 and game_user_001. Following those references is safer than assuming a filename, environment variable, port, or credential convention. Confirm that both connection definitions point to the databases you populated and that the application account can perform the operations required by the demo.

If the server reports missing tables after a successful database connection, verify that each SQL file was imported into the correctly named database. If it reports authentication or connection failures, correct the connection settings first. Re-importing SQL will not repair an invalid host, username, password, or unavailable database service.

Do not configure Localtonet yet

First establish the runtime port and prove that the supplied client can communicate with the server locally. A public tunnel forwards traffic to a local target, but it cannot fix a server that failed to initialize, a port that is not listening, an incompatible protocol, or incorrect database settings.

Verify the jforgame server locally

Five checks verify the database, Java process, TCP listener, local connection, and server logs.
Verify every local dependency and the TCP listener before creating a public tunnel.

Local verification should proceed in layers. This makes failures easier to isolate and prevents the tunnel from becoming an unnecessary variable. The project’s documented functional path is to launch ServerStartup and then ClientStartup.

1️⃣ Process verification Confirm that ServerStartup remains active and has not terminated because of a Java, Maven, resource, or database error.
2️⃣ Listener verification Confirm through your operating system or IDE diagnostics that the Java process is listening on the port resolved from ServerConfig.
3️⃣ Protocol verification Run ClientStartup and inspect both consoles for a successful connection and expected message routing in the selected revision.
4️⃣ Dependency verification Check that both databases are reachable and that the corresponding SQL resources were imported without failed statements.

Why an open TCP port is not enough

A listener check establishes that some process accepted responsibility for the port. It does not prove that the application understands a client’s messages, that the codec matches, that database-backed operations succeed, or that authentication works. A generic TCP connection test can therefore be useful for transport diagnosis, but the supplied ClientStartup path is more meaningful because it exercises the project’s expected client-side behavior.

Capture a local baseline

Before remote testing, save the relevant server and client output from one successful local run. Record the source revision, selected JDK, effective working directory, database names, and actual listening port. If remote access later fails, this baseline helps distinguish a tunnel problem from a change in the application environment.

Restart both processes once after the initial success. A restart can reveal hidden dependence on IDE state, an accidental working directory, or an initialization step that was performed manually but not documented. Start the server first, wait for initialization, and then start the client again.

Do not use a web browser to test an arbitrary TCP game protocol

A raw TCP socket endpoint is not automatically HTTP. Entering its host and port into a browser does not provide a valid test unless the application is specifically running a compatible WebSocket or HTTP-facing endpoint. Use a client that implements the same framing, codec, and message protocol as the jforgame service.

Expose the working jforgame TCP service with Localtonet

Remote TCP traffic passes through Localtonet to the jforgame service on its local configured port.
The public TCP endpoint routes through the tunnel to the verified jforgame listener on the local machine.

Once local startup and client communication work, Localtonet can provide a public host and port for the configured TCP listener. Our client runs on a device that can reach jforgame and establishes an outbound connection to a Localtonet relay server. This avoids inbound router port forwarding, firewall changes, VPN setup, and the need for a public IP address.

Use a TCP tunnel for the demonstrated TcpSocketServerBuilder listener. Do not select an HTTP tunnel merely because a future game client might run in a browser. Transport selection must match the endpoint the application actually exposes. If you separately configure jforgame’s WebSocket capability, evaluate that endpoint as a distinct workflow rather than assuming its settings match the raw TCP listener.

1

Install and run the Localtonet client

Install our client on the jforgame host or on another device that can reach the server’s local IP address and TCP port. Keep the client running because the tunnel is available only while its selected device is connected and the tunnel itself is running.

2

Authenticate or select the client device

Use the device-specific authentication token associated with the client that will run the tunnel. Treat this token as a secret. Do not place it in application source, screenshots, shell history, client configuration examples, or public issue reports.

3

Select an available relay server

Choose a currently available server or region from the Localtonet dashboard. Available values can vary, so obtain the selection from the current product rather than copying a server code from an old guide.

4

Create a TCP tunnel to the real local target

Select the TCP tunnel type. Enter an IP address reachable from the Localtonet client and the actual port returned by the jforgame server configuration. If both processes run on the same device, use an address on which jforgame is confirmed to listen. If they run on different devices, use the jforgame host’s reachable local address.

5

Start the tunnel and obtain its public endpoint

Creating a tunnel does not start it. Press Start and wait for the tunnel to run. Localtonet then supplies the public host and port that remote TCP clients can use while the selected device and tunnel remain connected.

6

Test remotely, then stop or delete when finished

Configure a compatible jforgame client to use the assigned public host and port instead of its local destination, then test from a genuinely external network. When remote access is no longer required, stop the tunnel. Delete it if the configuration should not be retained.

Everything related to the tunnel can be managed from the Localtonet dashboard or REST API, but this guide does not invent API payloads or fields that are not established in the supplied product information. For an initial demo, the dashboard workflow makes it easier to verify the selected device, relay, target, and lifecycle state.

A public endpoint expands the application’s exposure

A Localtonet TCP tunnel transports connections to the configured local service. It does not create application-level login rules for jforgame or determine which game messages a client may send. Before sharing the endpoint, review the demo’s authentication and authorization behavior, remove test credentials, validate message lengths and input, apply least privilege to database accounts, and limit distribution of the public host and port.

Test from outside the server’s network

A same-machine test can accidentally keep using the old local address. For meaningful remote verification, change the compatible client’s destination to the exact public host and port assigned by Localtonet and run it from another network where practical. Keep the local server console and Localtonet client visible during the first attempt.

Interpret the result by layer. If no connection reaches the tunnel, verify that the tunnel is started and the selected Localtonet device remains connected. If the tunnel receives a connection but cannot reach its target, recheck the local IP, listening port, bind scope, and host firewall. If transport succeeds but the application rejects or closes the session, inspect protocol compatibility and the server’s application logs.

Operate the demo and tunnel safely

A development demo benefits from a simple and predictable lifecycle. Start dependencies first, then the application, then remote access. Stop them in the reverse order so new public connections are removed before the server or database disappears.

Operation Recommended order Reason
Start a session Database, jforgame server, local client test, Localtonet client, TCP tunnel Each layer is proven before the next layer depends on it.
Restart jforgame Stop the tunnel, restart and verify the server, then start the tunnel This avoids forwarding new public connections to an unavailable or partially initialized process.
Change the server port Update jforgame, verify locally, update the tunnel target, restart the tunnel The Localtonet target must match the application’s effective listening port.
End remote testing Stop or delete the tunnel, stop the Localtonet client if appropriate, then stop jforgame The public entry point is removed before the local service shuts down.

Protect the device token

A Localtonet authentication token identifies the client device that runs the tunnel. Never publish it with a repository, paste it into a game client, embed it in the Java source, or include it in an article or support screenshot. If your operational process requires automation, use secret-handling practices appropriate to your environment and avoid exposing the value in logs.

Minimize the exposed surface

Expose only the TCP listener required for the test. Database ports, IDE debugging ports, management interfaces, and unrelated services should remain private. A game client needs the game protocol endpoint, not direct access to the persistence layer.

Keep the tunnel stopped outside the testing window when continuous access is unnecessary. Remember that creating a tunnel is not the same as running it, and stopping a tunnel is different from deleting its saved configuration. This separation lets you retain a known target while controlling when the public endpoint is active.

Move beyond the full demo when appropriate

After understanding the sample, a custom application can adopt individual jforgame modules. The repository illustrates Maven dependencies for the Netty socket implementation and the struct codec:

<dependency>
    <groupId>io.github.jforgame</groupId>
    <artifactId>jforgame-socket-netty</artifactId>
    <version>latest</version>
</dependency>

<dependency>
    <groupId>io.github.jforgame</groupId>
    <artifactId>jforgame-codec-struct</artifactId>
    <version>latest</version>
</dependency>

The README uses latest illustratively. For a reproducible application build, select a concrete version verified for your project rather than assuming that the literal value is suitable Maven versioning for every environment. Confirm compatibility among the selected modules and preserve the exact versions in source control.

A custom server also needs its own message factory, codec, dispatcher, routes, configuration, authentication model, and operational safeguards. The concise builder example demonstrates composition, not a complete production architecture.

Troubleshooting the installation and remote connection

The Maven project does not import correctly

Confirm that the IDE imported the pom.xml at the repository root. The project is multi-module, so opening only jforgame-demo as an unrelated folder can leave sibling modules unresolved. Verify that the IDE has an appropriate JDK selected according to the checked-out Maven configuration, then refresh its Maven model.

If dependencies remain unresolved, distinguish repository structure errors from dependency-download errors. An IDE that does not recognize modules points to import or Maven-model configuration. A recognized module with unavailable artifacts points to repository access, version resolution, or dependency metadata. Do not work around either problem by downloading random JAR files.

ServerStartup cannot find files or configuration

Recheck the run configuration’s working directory. When importing all modules, the documented location is the checked-out jforgame-demo directory for both ServerStartup and ClientStartup. Ensure the path is real and absolute in your environment. Do not enter the documentation’s wildcard notation as a literal directory.

The server cannot connect to the databases

Verify that the database service is running, both required databases exist, and the application’s effective connection settings target the correct host. Check authentication separately from schema state. A connection-refused error, an authentication failure, and a missing-table error represent different layers and require different fixes.

For schema problems, locate the two corresponding SQL files under the checked-out revision’s test/resources directories. Import the file associated with game_data_001 into that database and the file associated with game_user_001 into its database. Review failed SQL statements and confirm that the database account used for import had sufficient schema privileges.

The server reports that the port is already in use

Another process or an earlier jforgame run may already own the configured port. Identify the owning process using your operating system’s normal network diagnostics. Stop the stale process if appropriate, or deliberately change the jforgame configuration to an available port. After any change, verify the effective runtime listener and update the Localtonet TCP target to match.

ClientStartup cannot connect locally

Make sure ServerStartup is still running and has completed initialization. Confirm that the client’s destination corresponds to the server’s effective address and port in the selected revision. Then inspect codec and protocol assumptions. A raw TCP connection can open successfully and still fail immediately if the client and server disagree about message framing or encoding.

The tunnel exists but the public endpoint does not respond

First check lifecycle state. A saved tunnel does not run until Start is pressed, and it remains available only while the selected Localtonet client device is connected and the tunnel is running. Next, verify that the tunnel type is TCP and that its target port is the same one used in the successful local baseline.

If Localtonet runs on a separate device, test whether that device can reach the jforgame host locally. A server bound only to loopback will not accept connections arriving from another LAN device. Because the project evidence does not establish a default bind address, inspect the actual runtime listener rather than assuming it is reachable.

A TCP connection opens, but the game operation fails

This usually shifts attention from transport to application behavior. Confirm that the remote client uses the same protocol, codec, and message definitions as the server revision. Inspect jforgame’s logs for route, decoding, login, session, or database failures. Localtonet forwards the TCP stream to the configured target, but it does not translate an incompatible client protocol.

The WebSocket client does not work through the TCP setup

WebSocket is supported by the jforgame Netty implementation, but that does not prove that the demo’s raw TCP listener and a WebSocket endpoint share the same port or startup path. Trace the selected revision’s WebSocket server configuration and verify it locally with a compatible client before exposing it. Do not infer an endpoint, URL path, port, or frame configuration that the current application has not established.

Use a layer-by-layer diagnosis

Check source import, database initialization, server process, listening socket, local application protocol, Localtonet client connectivity, tunnel lifecycle, public TCP transport, and remote application behavior in that order. Changing several layers simultaneously makes the original fault harder to identify.

Frequently asked questions

What Java version does the jforgame demo require?

The supplied quick-start evidence does not establish one universal JDK version. Inspect the root pom.xml and any relevant Maven plugin or compiler settings in the exact revision you checked out. Use those current project constraints instead of guessing a Java version from an unrelated tutorial.

Which port does jforgame use by default?

No concrete universal port is established in the supplied README evidence. The demonstrated server builder obtains its port from ServerConfig.getInstance().getServerPort(). Trace that configuration in your selected revision and confirm the actual listener at runtime before creating a tunnel.

Why does the demo require two databases?

The official quick start explicitly requires game_data_001 and game_user_001, each populated from its corresponding SQL resource. The supplied evidence does not fully document every table’s role, so preserve that separation and avoid combining or renaming the databases unless you also update and validate the application configuration.

Can I run the demo without an IDE?

The documented quick start specifically uses a Maven-capable IDE and launches ServerStartup followed by ClientStartup. A command-line workflow may be possible, but the supplied evidence does not establish exact Maven execution goals, classpaths, or packaging commands for this demo. This guide therefore does not invent them.

Should I use an HTTP or TCP tunnel for jforgame?

Use a Localtonet TCP tunnel for the raw TCP socket listener started through TcpSocketServerBuilder. jforgame also documents WebSocket support through its Netty implementation, but that endpoint must be configured and verified separately. Do not treat a raw game socket as HTTP.

Does Localtonet require router port forwarding or a public IP?

No. Our client establishes an outbound connection to a Localtonet relay server, so this workflow does not require inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The selected client must remain connected, and the tunnel must be running for the public endpoint to remain available.

Does the tunnel add login security to the jforgame demo?

No. The TCP tunnel forwards connections to the configured local target. Authentication, authorization, session handling, message validation, and game permissions remain application responsibilities. Review the demo’s behavior and implement suitable controls before allowing untrusted clients to connect.

Can the Localtonet client run on a different machine from jforgame?

Yes, provided the Localtonet client device can reach the jforgame service at its local IP address and TCP port. Confirm the server’s bind scope and local firewall behavior first. Running both on the same machine is simpler because it removes the extra LAN path from initial troubleshooting.

What happens when I stop the Localtonet client or tunnel?

The public endpoint is available only while the selected client device is connected and the tunnel is running. Stopping the tunnel removes remote availability without necessarily deleting its saved configuration. Deleting the tunnel removes the configuration itself.

Make your verified jforgame TCP demo reachable

Finish the local server and client workflow first, identify the actual configured listener, then create a Localtonet TCP tunnel to that exact target. Keep the endpoint active only when needed and retain application-level access controls for every remote client.

Get Started Free →

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support