A modular voting platform composed of an RMI microservice (business logic + database access), a Spring Boot API layer, and an optional Vite/React frontend. This document walks through the exact manual steps to run the backend stack (no Docker required).
| Layer | Folder | Description |
|---|---|---|
| Shared contracts | shared | VotingService, EventInfo, and other DTOs consumed by both JVM services |
| RMI microservice | rmi-server | Core voting logic, AES password encryption, direct MySQL access |
| REST bridge | api-bridge | Spring Boot 3 API exposing REST endpoints to browsers and the frontend |
| React client (optional) | react-frontend | Admin dashboard, voter UI, live results |
- Java 17+ (to run Spring Boot) and Java 15+ (to compile the standalone RMI module)
- Maven 3.9+
- Node.js 20+ (only if you plan to run the React frontend)
- MySQL 8.x reachable at
localhost:3306
git clone https://github.com/pyaephyo11979/VotingSystem.git
cd VotingSystem
mvn -pl shared clean install # publishes org.example:shared to ~/.m2- Create a schema named
votingdband grant a user (root/rootby default in code) full access. - Seed the tables:
mysql -h localhost -u root -p votingdb < rmi-server/src/main/resources/init-database.sqlThe same structure exists in rmi-server/src/main/java/SchemaCreator.java if you prefer a Java-based creator.
- Open rmi-server/src/main/java/DBController.java.
- Update the
url,username,password, andSECRETconstants so they match your MySQL instance and 32-char AES secret. - (Optional) Adjust the registry host exposing RMI by exporting
RMI_HOSTbefore launch. The default host is0.0.0.0and the registry port is1099(see rmi-server/src/main/java/Server.java).
cd rmi-server
mvn compile exec:java -Dexec.mainClass=ServerYou should see ✅ RMI Server is running... in the console along with future log lines from VotingServiceImpl.
- Open api-bridge/src/main/resources/application.properties.
- Set
rmi.server.hostandrmi.server.portif the RMI service is running on a different machine. - For browser access, list the allowed origins in
app.cors.allowed-origins(comma-separated). Usehttp://localhost:5173while developing the React client.
cd api-bridge
mvn spring-boot:runWhen the app starts it will log Looking up RMI service at rmi://HOST:PORT/VotingService. The REST endpoints are implemented in api-bridge/src/main/java/org/example/apibridge/controller/VotingController.java.
cd react-frontend
npm install
VITE_API_BASE_URL=http://localhost:8080/api/events npm run dev -- --host 0.0.0.0 --port 5173The frontend consumes the REST endpoints through react-frontend/src/utils/api.ts. Skip this step if you only need the backend.
- Create an event:
curl -X POST http://localhost:8080/api/events/create \
-H "Content-Type: application/json" \
-d '{"eventName":"Student Council 2026"}'Response example: { "data": { "eventId": "AB12CD34", "eventName": "Student Council 2026", "eventPassword": "3F8A1C" } }.
2. Add candidates (multipart for optional photos):
curl -X POST http://localhost:8080/api/events/AB12CD34/candidates \
-F name="Alice" -F photo=@/path/to/photo.jpg- Generate accounts to distribute to voters:
curl -X POST http://localhost:8080/api/events/AB12CD34/accounts \
-H "Content-Type: application/json" \
-d '{"eventSize": 100}'- Login:
POST /api/events/loginwith{ "username": "generatedUser", "password": "plainPassword" }. - Load ballot:
GET /api/events/AB12CD34/candidates?password=EVENT_PASSWORD. - Cast vote:
POST /api/events/AB12CD34/votewith{ "userId": "...", "candidateId": "..." }. - Confirm status:
GET /api/events/AB12CD34/vote-status/{userId}. - Monitor results:
GET /api/events/AB12CD34/resultsfor aggregate counts.
| Endpoint | Description |
|---|---|
/api/events/create |
Create event and return eventId, eventPassword |
/api/events/{eventId}/candidates |
POST add, PUT update, DELETE remove, GET list candidates |
/api/events/{eventId}/accounts |
POST bulk-generate login credentials, GET list |
/api/events/login |
Validate username/password via VotingService.Login |
/api/events/{eventId}/vote |
Cast vote; rejects duplicates with ALREADY_VOTED |
/api/events/{eventId}/results |
Aggregate vote totals per candidate |
/api/events/{eventId}/vote-status/{userId} |
Check if a given user already voted |
/api/events/{eventId}/candidates?password=... |
Public ballot retrieval for voters |
IllegalStateException: RMI service unavailable: ensure the RMI process is running, the host/port in application.properties is correct, and no firewall blocks port1099.Communications link failureinDBController: verify MySQL is listening onlocalhost:3306, credentials in DBController are valid, and the schema contains the required tables.- Voters always “already voted”: clear the
votestable or use uniqueuserIdvalues per event. The schema enforces a composite key(user_id, event_id). - Photos missing on the frontend: confirm the
photocolumn isMEDIUMBLOBand the upload request actually includes a file.
# Build every Maven module
mvn clean install
# Run only the API bridge with tests skipped
cd api-bridge && mvn spring-boot:run -DskipTests
# Run unit tests for the backend modules
cd api-bridge && mvn test
cd rmi-server && mvn test
# Frontend production bundle
cd react-frontend && npm run build && npm run previewWith the steps above you can run the University of Computer Studies Pathein Voting System entirely on bare metal and iterate on either the RMI or Spring Boot layers with confidence.