SNHU IT-511 — Object-Oriented Application Development (Final Project)
This project is a command-line “virtual world” application written in Java.
In 2026 it gained a browser-friendly UI and a tiny Java HTTP server so it can run as a small website. All of the web + deployment details are grouped in the 2026 Updates section below.
It walks the user through creating a “clone” profile, optionally creating a dog profile, and then interacting with a ShoutBox that can output either canned or randomly generated messages.
The code is intentionally object-oriented and interactive (console version uses Scanner on System.in), showcasing:
- constructors and method overloading
- encapsulation via getters/setters
- input validation
- collection usage
- Prompts for first name, last name, age, gender, height, weight, hair color, and eye color
- Validates inputs (e.g., numeric ranges, word validation)
- Prints a confirmation summary
The app also introduces a preset clone (“Frank”) before prompting the user.
- Asks whether you own a dog
- If yes, prompts for dog name, breed, age, gender, size, weight, hair color, eye color
- Prints a confirmation summary
The app also introduces a preset dog (“Baby”) before prompting the user.
The ShoutBox supports two modes:
- Preset mode: includes pre-filled canned messages and word lists
- Custom mode: lets the user enter:
- a chosen number of canned messages
- a chosen number of words per list (subject/verb/adjective/object/adverb)
During interaction you can choose:
- Canned Message: select from the list
- Random Message: generated from the word lists (Subject + Verb + Adjective + Object + Adverb)
You can continue shouting messages until you answer “N”.
- Java JDK (a
javaccompiler) - A terminal capable of interactive input
No third-party libraries are required.
In 2026, this project gained:
- A browser UI (
index.html,app.js,styles.css) served from the project root - A tiny Java HTTP server (
VirtualWorldWebServer) that serves the UI +/api/* - Subpath-safe frontend routing for hosting at
/projects/2016VirtualWorld/ - Production deployment guidance (Apache/Webuzo reverse proxy + optional
systemdservice)
- Java sources in
VirtualWorld/VirtualWorld.java— console entry pointVirtualWorldWebServer.java— tiny HTTP server (static UI + API)MyClone.java,MyDog.java,ShoutBox.java— models + ShoutBox logic
- Static website files in the project root
index.html,app.js,styles.css
- Optional Apache examples in
apache/ - VS Code tasks in
.vscode/tasks.json
All Java source files declare the package:
package VirtualWorld;- The codebase is written to be Java 8 compatible for production hosting (AlmaLinux in 2026 was running OpenJDK 8).
- If you compile with a newer JDK locally, either compile on the server or target Java 8 (e.g.
-source 1.8 -target 1.8).
Open a terminal in the project folder and run:
cd /d d:\Websites\2026FCJamison\projects\2016VirtualWorld
rem Compile
mkdir bin
javac -d bin .\VirtualWorld\*.java
rem Run console app
java -cp bin VirtualWorld.VirtualWorldRun the web server (localhost only):
mkdir bin
javac -d bin .\VirtualWorld\*.java
java -cp bin VirtualWorld.VirtualWorldWebServer --host 127.0.0.1 --port 8093Open:
What it supports:
- View preset profiles (Frank + Baby)
- Create a clone and dog via forms (no console prompts)
- Guided ShoutBox flow (tab hidden until needed)
- ShoutBox: random, canned, and custom typed messages
Implementation notes:
- The frontend is subpath-safe: it computes a base URL from
window.locationand builds API calls relative to that base. - The Java server serves only the allowlisted static files from the project root.
GET /api/health→{"ok":true,...}GET /api/preset→ preset clone, dog, and canned messagesPOST /api/clone→ acceptsapplication/x-www-form-urlencodedPOST /api/dog→ acceptsapplication/x-www-form-urlencodedGET /api/shout/randomGET /api/shout/canned?i=<1-based index>POST /api/shout/custom→ form bodymessage=<text>
Recommended production shape:
- Serve the project root (static UI files) via Apache
- Run the Java service as a separate process bound to localhost
- Reverse-proxy API requests from Apache to the Java service
If the Create Clone call returns 404 in production, it usually means the reverse-proxy is missing or pointing at the wrong port.
Example proxy config is included here:
apache/virtualworld-proxy.conf
If you want to open the app at:
Run Apache and use the example vhost in apache/virtualworld-proxy.conf, and add this to your Windows hosts file:
127.0.0.1 virtualworld.localhost
Then run the Java server on 127.0.0.1:8080 (or update the proxy port).
This project is commonly hosted under:
https://fcjamison.com/projects/2016VirtualWorld/
In that case, proxy:
/projects/2016VirtualWorld/api/*→http://127.0.0.1:8093/api/*
On the 2026 production host, fcjamison.com had a catch-all reverse proxy to a Python waitress app (localhost port 8010) defined in:
/var/webuzo-data/apache2/custom/domains/fcjamison.com.conf
To ensure VirtualWorld is handled by Apache/Java instead of waitress, add early exit rules above the catch-all proxy rule:
# Allow VirtualWorld paths to be handled by Apache/Java
RewriteCond %{REQUEST_URI} ^/projects/2016VirtualWorld/api/ [NC]
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} ^/projects/2016VirtualWorld/ [NC]
RewriteRule ^ - [L]And in the fcjamison.com vhost blocks (both :80 and :443 in /usr/local/apps/apache2/etc/conf.d/webuzoVH.conf), ensure these appear:
ProxyPreserveHost On
ProxyPass /projects/2016VirtualWorld/api/ http://127.0.0.1:8093/api/
ProxyPassReverse /projects/2016VirtualWorld/api/ http://127.0.0.1:8093/api/The Java web server supports:
- Environment variables:
VW_HOST,VW_PORT - Args:
--host <host> --port <port>
Example (bind only to localhost on port 8080):
set VW_HOST=127.0.0.1
set VW_PORT=8080
java -cp bin VirtualWorld.VirtualWorldWebServerImportant:
- Put Apache (HTTPS) in front for TLS and public access.
- Keep the Java service on
127.0.0.1(not publicly exposed) when using a reverse proxy.
If your server uses systemd, create:
/etc/systemd/system/virtualworld.service
Example unit (compiles on start using Java 8 and runs on 127.0.0.1:8093):
[Unit]
Description=VirtualWorld Java Web Server
After=network.target
[Service]
Type=simple
User=frankjamison
WorkingDirectory=/home/frankjamison/public_html/fcjamison.com/projects/2016VirtualWorld
ExecStartPre=/usr/bin/mkdir -p bin
ExecStartPre=/usr/bin/javac -source 1.8 -target 1.8 -d bin VirtualWorld/MyClone.java VirtualWorld/MyDog.java VirtualWorld/ShoutBox.java VirtualWorld/VirtualWorld.java VirtualWorld/VirtualWorldWebServer.java
ExecStart=/usr/bin/java -cp bin VirtualWorld.VirtualWorldWebServer --host 127.0.0.1 --port 8093
Restart=on-failure
RestartSec=2
SuccessExitStatus=143
[Install]
WantedBy=multi-user.targetEnable/start:
sudo systemctl daemon-reload
sudo systemctl enable --now virtualworld.service
sudo systemctl status virtualworld.service --no-pager -lIf you see UnsupportedClassVersionError, it means the bin/ class files were compiled with a newer Java. Rebuild on the server with Java 8 (javac 1.8) or target Java 8.
- The
bin/directory is a build output and is safe to delete/recreate. - When deploying, prefer compiling on the server (avoids Java class version mismatch).
Clean build artifacts:
rmdir /s /q binThe app is interactive. It will:
- Introduce a preset clone
- Ask for your personal details and confirm them
- Introduce a preset dog
- Ask whether you own a dog; if yes, collect dog details and confirm them
- Ask whether you want a custom ShoutBox or a preset one
- Let you shout messages (canned or random) until you stop
For Y/N prompts, enter Y/y or N/n.
- The code compares some strings using
==(e.g., checking presets and message types). In Java, string equality should typically use.equals(...). Depending on the JVM and how strings are created, this may cause certain checks to behave unexpectedly. - Several methods create new
Scanner(System.in)instances instead of reusing one shared scanner. This is fine for a small console app, but it’s generally cleaner to share a single scanner.
Educational project (coursework). If you want an explicit open-source license added (MIT/Apache-2.0/etc.), say which one and I can add it.