Javlo2 — Configuration
Complete reference for the three configuration layers: Maven build properties,
the webapp_config.properties bridge file, and the
static-config.properties runtime configuration.
Javlo2 uses three configuration layers that are applied at different stages:
| Layer | File | When applied | Purpose |
| 1 — Maven |
pom.xml / CLI -D |
Build time |
Embeds build metadata and deployment-environment paths into the WAR. |
| 2 — Bridge |
src/main/config/webapp_config.properties |
Build time (filtered) |
Maven placeholders resolved and written to WEB-INF/config/webapp_config.properties inside the WAR. |
| 3 — Runtime |
static-config.properties |
Server startup |
All operational settings: folders, security, mail, cache, URLs. Lives outside the WAR on the server. |
Folder variables #
Path values in static-config.properties support the following token substitutions:
| Token | Resolved to |
| $HOME / ~ | Home directory of the OS user running Tomcat. |
| $JAVLO_HOME | Value of the JAVLO_HOME environment variable. |
| $CATALINA_HOME | Value of the CATALINA_HOME environment variable. |
Paths that do not start with / or a token are treated as relative to the webapp root when data-folder-relative=true (the default).
Maven build & WAR packaging #
The default active profile is webapp, which packages a javlo.war file. During the process-resources phase, Maven:
- Filters
src/main/config/ → WEB-INF/config/ (with token substitution).
- Filters
src/main/webapp/WEB-INF/*.xml → WEB-INF/.
- Copies
src/main/lib/ JARs → WEB-INF/lib/ (no filtering).
Profiles
| Profile | Default | Output | Description |
| webapp | yes | javlo.war | Standard web application. Activates resource filtering and WAR packaging. |
| core | no | javlo-core.jar | Produces a plain JAR for embedding Javlo as a library. |
| securitycheck | no | — | Runs OWASP dependency-check during verify. |
Build commands
# Standard WAR build
mvn package
# Pass deployment properties on the CLI
mvn package \
-Dconfig.relative=false \
-Dconfig.dir=/opt/javlo/config \
-Djavlo.god=admin,<SHA1-password>
# Security audit
mvn verify -P securitycheck
buildnumber-maven-plugin
The buildnumber-maven-plugin generates ${buildNumber} from the Git SCM during the validate phase. The resulting string is written into webapp_config.properties as product.version.
# Format: Rev={7-char-git-hash} BuildTime={yyyy-MM-dd--HH-mm-ss}
product.version=Rev=c1e1d99 BuildTime=2026-03-25--08-44-09
# Falls back to "NO-GIT" when git is not available
webapp_config.properties #
src/main/config/webapp_config.properties → WEB-INF/config/webapp_config.properties (in WAR)
This file is the bridge between the Maven build and the running webapp. It is processed by Maven resource filtering — every ${token} is replaced at build time.
# Source file — tokens replaced by Maven at build time
product.version=${buildNumber}
static-config.relative=${config.relative}
static-config.directory=${config.dir}
edit.users=${javlo.god}
| Key (in WAR) | Maven property | Default | Description |
| product.version |
${buildNumber} |
NO-GIT … |
Build identifier generated by buildnumber-maven-plugin. Read-only — shows in the admin interface. |
| static-config.relative |
${config.relative} |
true |
true = the path in static-config.directory is relative to the webapp root. false = absolute OS path. |
| static-config.directory |
${config.dir} |
/WEB-INF/config |
Directory where static-config.properties is stored. Can also be set via the JAVLO_HOME environment variable (takes priority). |
| edit.users |
${javlo.god} |
admin / admin |
Bootstrap admin credentials in the format login,SHA1password;login2,SHA1password2. Used only if not overridden in static-config.properties. If the placeholder ${…} is not replaced, defaults to admin/admin. |
SHA-1 password encoding: Use echo -n "mypassword" | sha1sum | awk '{print $1}' | xxd -r -p | base64 or any SHA-1 + Base64 tool.
The default hash for admin is 0DPiKuNIrrVmD8IUCuw1hQxNqZc=.
static-config.properties — location & loading #
StaticConfig is a singleton stored in the ServletContext. It is loaded once at startup via StaticConfig.getInstance(ServletContext). The file is resolved in priority order:
| Priority | Source | Path |
| 1 (highest) | Environment variable | $JAVLO_HOME/static-config.properties |
| 2 | webapp_config.properties key | {static-config.directory}/static-config.properties |
| 3 (default) | Built-in fallback | WEB-INF/config/static-config.properties |
A sample file is provided at src/main/webapp/WEB-INF/config/static-config__SAMPLE__.properties.
If no file is found, all settings fall back to their hardcoded defaults.
Primary settings #
static-config.properties
| Key | Default | Description |
| default-cms-name | javlo | Name of the CMS instance shown in the admin interface. |
| default-context | default.javlo.org | Context used to initialise a new host that has no existing context. |
| master-context | admin | Context with super-admin privileges (can manage other contexts). |
| deploy.env | dev | Deployment environment: local, dev, pprod, or prod. Affects caching and compression. |
| deploy.infra | back | back (editing + serving) or front (serving only, DMZ). |
| deploy.compress-jsp | false | Minify generated JSP in production mode. |
| edit.users | admin / admin | Bootstrap admin accounts. Format: login,SHA1pwd;login2,SHA1pwd2. Overrides webapp_config.properties value if set here. |
| site.email | webmaster@javlo.org | Default site contact email (used in alerts and automated messages). |
| site.help-url | http://help.javlo.org | Base URL for contextual help links in the admin. |
| default-date-format | dd/MM/yyyy | Default date format used in admin and as fallback for contexts. |
| calendar.zone | Europe/Brussels | Default timezone for date/time operations. |
| locale.country | be | Default locale country code. |
| instance-name | OS username | Human-readable name for this server instance (shown in error mails). |
| synchro-code | — | Shared secret for DMZ ↔ back synchronisation and remote status checks. |
| auto-creation | false | Automatically create a context when an unlisted domain hits the server. |
| image.max-width | 0 | Maximum width (px) for uploaded images. 0 = no reduction. |
Folder paths #
All paths are relative to the webapp root when data-folder-relative=true. Use $HOME, $JAVLO_HOME, or $CATALINA_HOME for absolute paths outside the webapp.
In most single-server deployments the defaults work without change. The most important
folder to customise is data-folder — point it outside the
webapp so data survives WAR redeployments.
| Key | Default | Description |
| data-folder | /WEB-INF/data-ctx | Root of all site data: content, files, users, tracking. Persist this folder. |
| data-folder-relative | true | true = relative to webapp root. false = absolute OS path. |
| data-folder-random | false | Append a random ID to each site's data folder (extra isolation). |
| context-folder | /WEB-INF/context | Global context metadata (languages, aliases, mailing settings). |
| template-folder | /WEB-INF/template | Website templates root. See Template docs. |
| mailing-template-folder | /WEB-INF/mailing/todo | Mailing queue folder. |
| mailing-history.folder | /WEB-INF/mailing/history | Completed mailings archive. |
| thread-folder | /WEB-INF/thread | Internal background-job state. |
| trash-folder | /WEB-INF/.trash | Global trash (used when a context ZIP is uploaded with download.clean-data-folder=true). |
| share-folder | /WEB-INF/share-folder | Files shared across all sites on this instance. |
| external-components-folder | external-components | Dynamic components installed outside the template. |
| backup-folder | backup | Subfolder name inside each site's data folder for backups. |
| temp-web-folder | /web-tmp | Temporary web-accessible folder. |
Security & users #
| Key | Default | Description |
| security.encrypt-password | true | Store user passwords as SHA-1 hashes. |
| security.high | false | Enables high-security mode: stricter limits, disables some features. |
| security.use-https | false | Force HTTPS redirect for all requests. |
| security.secret-key | ??? | Secret key for symmetric encryption. Change this in production. |
| security.default-password | changeme | Default password assigned to newly created users. |
| security.change-password | true | Force users to change their password on first login. |
| security.login.max-error-hour | 100 | Maximum failed login attempts per IP per hour before blocking. 10 in high-security mode. |
| security.remote-login | false | Allow login from remote applications via token. |
| security.login.token | false | Enable token-based login (API / MCP). |
| security.rest-servlet | true | Enable the REST/remote API servlet. Automatically false in high-security mode. |
| security.header.xss | true | Emit X-XSS-Protection: 1; mode=block header. |
| security.oauth.view | false | Enable Google OAuth login on the public site. |
| security.oauth.google-id-client | — | Google OAuth client ID. |
| security.oauth.google-secret | — | Google OAuth client secret. |
| security.application-login | — | Application-level login for inter-service authentication. |
| security.application-password | — | Application-level password. |
| security.password.regular-expression | .+ | Password validation regex shown to users. |
| user_roles | guest;member;mailing | Available user roles, semicolon-separated. |
| adminuserfactory.class | org.javlo.user.AdminUserFactory | Class responsible for admin user management. Override for LDAP. |
LDAP
| Key | Default | Description |
| ldap.provider-url | — | LDAP server URL (e.g. ldap://ldap.example.com:389/). |
| ldap.security.principal | — | Bind DN for LDAP authentication. |
| ldap.security.credentials | — | Bind password. |
| ldap.security.login | — | Login DN template. Use #login# as placeholder for the username. |
Mail / SMTP #
| Key | Default | Description |
| mail.smtp.host | required | SMTP server hostname. |
| mail.smtp.port | 25 | SMTP port (use 587 for STARTTLS, 465 for SSL). |
| mail.smtp.user | — | SMTP authentication username. |
| mail.smtp.password | — | SMTP authentication password. |
| mail.default.sender | — | Default From address for all outgoing mail. |
| mail.default.report | — | Address for error/exception reports. |
| mail.default.subject | — | Default subject prefix for system mails. |
| mailing.thread | true | false if a DMZ front-end handles the mailing queue instead. |
| mailing.tracking | true | Track mailing open/click events. |
| mailing.time-between-two-mailing.second | 360 | Minimum seconds between two separate mailing batches. |
| mailing.time-between-two-send.second | 70 | Delay in seconds between individual email sends within a batch. |
| mailing.feedback.class | DefaultMailingFeedback | Feedback handler class (comma-separated list for multiple handlers). |
Cache & backup #
Page & resource cache
| Key | Default | Description |
| cache.max-size | 10 000 | Maximum number of entries in the page cache. |
| cache.max-time | 86 400 s | Page cache TTL (1 day). |
| cache.linked-page | 30 s | Cache TTL for inter-page link resolution. |
| resources.cache-time | 86 400 s | Cache-Control max-age sent for static resources. |
Backup threads
| Key | Default | Description |
| backup.interval | 86 400 s | Full site backup interval. 0 = disabled. |
| backup.count.db | 7 | Number of database backup copies to keep. |
| backup.interval.db | 86 400 s | Database backup interval. |
| backup.count.users | 120 | Number of user-file backup copies to keep. |
| backup.interval.users | 7 200 s | User-file backup interval. |
| backup.exclude-patterns | /backup;/static;… | Semicolon-separated path patterns excluded from the backup archive. |
URL & navigation #
| Key | Default | Description |
| url.host-define-site | true | true = hostname determines the site context. false = first URL segment determines the context. |
| url.view | false | Prefix public URLs with /view. |
| url.context | true | Include the context name in the URL. |
| url.redirect-secondary-url | true | 301-redirect non-canonical URLs to the canonical URL. |
| url.jsessionid | false | Append jsessionid to URLs (disable for SEO). |
| url.short.size | 3 | Number of characters for short-URL codes. |
| url.domain-no-context | — | Comma-separated domains that bypass context-path detection. |
| navigation.url.max-size | 140 | Maximum character length for generated page slugs. |
| sitemap.maxsite | 12 582 912 B | Maximum sitemap.xml file size (12 MB). |
| sitemap.news-days | 2 | Number of past days included in the Google News sitemap. |
Deploy & logging #
Logging
| Key | Default | Levels |
| log.all.level | INFO | Global log level override for all Javlo loggers. |
| log.access.level | INFO | AccessServlet log level. |
| log.navigation.level | INFO | Navigation / MenuElement log level. |
| log.login.level | INFO | Login log level. |
| log.component.all.level | INFO | All component classes. |
| log.synchro | INFO | Synchronisation process. |
| log.file | ../../logs/catalina.out | Path to the Tomcat log file read by the LogService module. |
| log.dir | /../../logs/ | Log directory for access-log rotation. |
| debug.id | — | Instance identifier in debug emails. |
Available levels: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST
Advanced #
Image
| Key | Default | Description |
| image.max-width | 0 | Resize uploaded images to this max width (px). 0 = no resize. |
| image.short-url | false | Use short URL codes for image requests. |
| image.webp.encoder | — | Path to an external WebP encoder binary. |
| image.auto-focus | true | Auto-detect focal point for smart cropping. |
Search engine
| Key | Default | Description |
| searchengine.class | LuceneSearchEngine | Full class name of the search engine implementation. |
| searchengine.lucene.pattern | level3:{Q}^3 … | Lucene query boosting pattern ({QUERY} placeholder). |
External services
| Key | Description |
| shared.pixabay.key | Pixabay API key for stock image search in the media library. |
| shared.freepik.key | Freepik API key. |
| dropbox.app-key / .app-secret | Dropbox integration credentials. |
| proxy.host / proxy.port | HTTP proxy for outgoing requests (defaults to JVM system proxy). |
Content
| Key | Default | Description |
| content.edit-repeat | true | Allow editing of inherited repeated components on child pages. |
| content.integrity-checker | true | Run link integrity checks in preview mode. |
| content.extension | html,pdf,png,… | Comma-separated list of valid page content extensions. |
| content.undo-depth | — | Number of undo steps. null = unlimited. |
| function.undo | false | Enable the undo function in the editor. |
Tomcat deployment #
The recommended production layout keeps all mutable data (data-folder,
context-folder, template-folder) outside the Tomcat
webapps/ directory so they are not overwritten on WAR redeployment.
Recommended directory layout
# Tomcat root
$CATALINA_HOME/
├── webapps/
│ └── ROOT/ # or javlo.war expanded here
│ └── WEB-INF/
│ └── config/
│ └── webapp_config.properties # generated by Maven
│
└── javlo-data/ # outside webapps — survives redeploys
├── config/
│ └── static-config.properties
├── data-ctx/ # data-folder
├── context/ # context-folder
└── template/ # template-folder
Corresponding static-config.properties
data-folder-relative=false
data-folder=$CATALINA_HOME/javlo-data/data-ctx
context-folder=$CATALINA_HOME/javlo-data/context
template-folder=$CATALINA_HOME/javlo-data/template
Pointing the webapp to an external config directory
Set the Maven property at build time (or in the WAR's webapp_config.properties):
mvn package \
-Dconfig.relative=false \
-Dconfig.dir=$CATALINA_HOME/javlo-data/config
Or set the environment variable before starting Tomcat:
# setenv.sh (Linux) or setenv.bat (Windows)
export JAVLO_HOME=/opt/javlo-data/config
Minimum production checklist
| Setting | Recommended value |
| deploy.env | prod |
| security.secret-key | Random 32+ char string |
| security.default-password | Strong random value |
| security.use-https | true |
| data-folder | Absolute path outside webapps/ |
| edit.users | Change default admin credentials |
| mail.smtp.host | Your SMTP relay |
| synchro-code | Random secret if using DMZ |