Development Guide
1. Prerequisites
Before building this project, install and configure the following dependencies:
1.1. Node.js and npm
Node.js is used to run a development web server and build the project. Install Node either from source or as a pre-packaged bundle for your system.
Angular CLI with Webpack is used as the build system.
npm manages CSS and JavaScript dependencies. Upgrade dependencies by specifying newer versions in package.json.
npm update
npm install
Run npm run to list all available scripts for this project.
2. Installing Dependencies
After installing Node, run the following command to install dependencies and development tools:
npm install
Run this command again when dependencies change in package.json.
2.1. Adding New Dependencies
To add a runtime dependency (example: Leaflet library):
npm install --save --save-exact leaflet
To add TypeScript type definitions from DefinitelyTyped:
npm install --save-dev --save-exact @types/leaflet
Then import the JS and CSS files in your application:
import 'leaflet/dist/leaflet.js';
@import 'leaflet/dist/leaflet.css';
3. Using Angular CLI
Use Angular CLI to generate custom client code:
ng generate component my-component
This generates:
create src/main/webapp/app/my-component/my-component.component.html
create src/main/webapp/app/my-component/my-component.component.ts
update src/main/webapp/app/app.module.ts
4. PWA Support
This application includes Progressive Web App (PWA) support, disabled by default.
To enable the service worker, uncomment the following in src/main/webapp/app/app.module.ts:
ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
5. Building for Production
5.1. Packaging as JAR
Build the optimized production JAR:
./mvnw -Pprod clean verify
This concatenates and minifies client CSS and JavaScript files and updates index.html to reference them.
Run the built application:
java -jar target/*.jar
Navigate to http://localhost:12505 in your browser.
See Using JHipster in production for more details.
6. Using Docker
Docker configurations are available in src/main/docker to launch required services.
6.1. Starting Services
Start a MySQL database:
docker compose -f src/main/docker/mysql.yml up -d
Stop and remove the container:
docker compose -f src/main/docker/mysql.yml down
6.2. Dockerizing the Application
Build a Docker image:
npm run java:docker
For ARM64 processors (e.g., Apple M1):
npm run java:docker:arm64
Run the dockerized application:
docker compose -f src/main/docker/app.yml up -d
|
On macOS Big Sur or later with Docker Desktop, enable "Use the new Virtualization framework" for better processing performance. |
See Using Docker and Docker-Compose for more information.
7. JHipster Control Center
Start a local JHipster Control Center (accessible at http://localhost:7419):
docker compose -f src/main/docker/jhipster-control-center.yml up
8. Continuous Integration
Configure CI using the JHipster ci-cd sub-generator:
jhipster ci-cd
See Setting up Continuous Integration for more information.
9. Multi-Tenant Development Testing
The Registration Portal supports multi-tenancy, where each tenant is identified by the domain name used to access the application. During development, you can test tenant resolution using custom hostnames.
9.1. How Tenant Resolution Works
The TenantResolutionFilter resolves tenants in the following priority order:
-
Domain match - The full hostname is matched against the
domaincolumn in thetenanttable -
X-TENANT-ID header - Falls back to the
X-TENANT-IDHTTP header if no domain match is found
Localhost and IP addresses are excluded from domain resolution to allow standard development access.
9.2. Setting Up Custom Hostnames
To test tenant resolution locally, configure your system’s hosts file to map custom hostnames to localhost.
9.3. Configuring Tenants in the Database
Insert or update records in the tenant table to match your custom hostnames:
-- Example: Create a tenant for hostname 'reg1'
INSERT INTO tenant (name, domain, registration_system_id)
VALUES ('Test Registration Site 1', 'reg1', 1);
-- Example: Create a tenant for hostname 'runningclub'
INSERT INTO tenant (name, domain, registration_system_id)
VALUES ('Running Club Portal', 'runningclub', 2);
The domain column must contain the exact hostname (without port) that will be used to access the application.
9.4. Accessing the Application
With the hosts file configured and tenants in the database, access the application using the custom hostname:
http://reg1:9000/membership/register/1
http://runningclub:9000/membership/register/1
The tenant context will be automatically resolved based on the hostname, and the TenantContext will be populated with the corresponding tenantId and registrationSystemId.
9.5. Verifying Tenant Resolution
Check the application logs for tenant resolution messages:
TenantResolutionFilter : Attempting to resolve tenant by domain: reg1
TenantResolutionFilter : Resolved tenant by domain: tenantId=1, registrationSystemId=1
If no tenant is found, you will see:
TenantResolutionFilter : No tenant resolved for request to: /membership/register/1 (this may be intentional for public endpoints)
9.6. Troubleshooting
| Hostname not resolving |
Verify the hosts file entry is correct and flush DNS cache if needed ( |
| "Invalid Host header" error |
Ensure the webpack dev server is configured with |
| Tenant not found |
Verify the |
| BrowserSync not accessible |
Ensure BrowserSync is configured with |