ujcms is a Java CMS that lets you pick template rendering or a Vue API
Java开源网站内容管理系统(java cms)。使用SpringBoot、MyBatis、Spring Security、Lucene、FreeMarker、TypeScript、Vue3、ElementPlus等技术开发。
At a glance
- What is it?
- ujcms is a GPL-3.0 Java content management system built on Spring Boot, MyBatis, Spring Security, FreeMarker and Vue 3, offering a headless architecture with two development modes, template plus tags or Vue plus API. It runs on JDK 17 or 21 with MySQL 8, packages as a war or a jar, and ships a Docker Compose file with MySQL for a first run.
- Who is it for?
- ujcms suits a Java team that wants one codebase to serve both server rendered pages and a headless API, and it does not suit a team that cannot host MySQL 8, and a Tomcat 10.1 server is additionally required only if you choose war deployment. Before deploying, create the database with the utf8mb4 charset, give the database user rights to create tables, and change the default admin credentials, because the documentation ships the account name admin with the password password.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two ways to build on the same CMS
ujcms is an open source enterprise website content management system written in Java, developed with Spring Boot, MyBatis, Spring Security, Lucene, FreeMarker, TypeScript, Vue 3 and Element Plus. The project site is ujcms.com, with separate pages for the documentation and for downloads, and a public demo front end and admin console.
The architectural decision that defines the project is the headless CMS support and the two development modes that come with it. One mode is template plus tags, which is the traditional server rendered approach where a FreeMarker template produces the page. The other is Vue plus API, where the front end is a separate application calling a backend API. The documentation presents the two as covering traditional template rendering and modern separated front end and back end scenarios respectively.
That is the interesting part of the design. Instead of a CMS that is either a template engine or an API server, one deployment can serve both, and a site can move page by page between the two styles.
The audience is Java development teams building content sites, and the project sits in the Dromara organisation, the same community group that hosts several other Chinese open source Java projects. It is licensed under GPL-3.0, the default branch is main, and the last push was on 2026-10-22.
Version floors that decide whether the program starts
The environment requirements are specific, and the documentation opens with a warning that low patch versions cause the program to fail to start, giving MySQL 8.0.12 as the example and asking you to upgrade to MySQL 8.0.20 or later.
On the back end the requirements are JDK 17 or 21, MySQL 8.0, where the acceptable versions are given as 5.7.22 or later and 8.0.20 or later, and Tomcat 10.1 or later, but only for war deployment. On the front end the requirement is Node 22.12 or later, plus pnpm, and the documentation suggests setting the taobao npm mirror with npm config set registry https://registry.npmmirror.com/ as an accelerator if you are in a region where the default registry is slow.
The gap between the two supported JDK versions is worth a note. The requirements say 17 or 21, which excludes 25 even though the Docker image is built on a Java 25 runtime base, and the Tomcat requirement applies only when you package as a war, so a jar deployment does not need a servlet container at all.
The repository ships a Maven wrapper, mvnw and mvnw.cmd, so the build does not depend on a system Maven installation. The project is a multi-module Maven build, with modules for the CMS itself, the starter application, a code generator, a common module, the admin console front end and a separate Vue SSR module.
The database schema creates and upgrades itself
Database setup is unusually light, and that is a deliberate design choice worth understanding before you deploy.
You create the database yourself, with any name, ujcms or something else. The character set should be utf8mb4, and the documentation warns against plain utf8 because that character set can corrupt some special characters. Beyond creating the database, there is no manual SQL step. The program creates the tables and initial data when it starts, and on later upgrades it detects the version by itself and applies the schema upgrade, so there are no SQL upgrade scripts to run by hand.
The one thing you have to get right is privileges. The database account needs the rights to create tables, write data and update the structure, because the automatic schema management depends on all three. A locked-down account that can only read and write existing tables will fail at startup, and the error will not make the cause obvious.
The automatic approach has a documented failure mode, and the fix is in the same page. If startup fails with a LockException about not being able to acquire the change log lock, or with a waiting for changelog lock message, the cause is that a previous run was killed while it was creating or upgrading the schema. The fix is to clear the data in the databasechangeloglock and flw_ev_databasechangeloglock tables, and the documentation is careful to point out that these are the lock tables and not the changelog tables themselves, or to drop all tables and start again.
A second startup error has a different cause. A message about the specified key being too long, with a maximum key length of 767 bytes, is fixed by setting the MySQL parameter innodb_large_prefix to ON, because a panel or cloud provider may have changed the default that MySQL itself sets from 5.7.7 onwards.
The theme needs its static assets built before anything renders
The front end templates are FreeMarker, and the default theme lives under the starter module's webapp themes directory. The template files control what the site shows, and the deployment location of that directory depends on the packaging: themes for a war, static/themes for a jar.
The default theme depends on third party front end libraries, cropperjs, sm-crypto and pdfjs among them, which the theme's own npm scripts copy into an assets/vendor directory. That directory is not in version control, and several features need those files at runtime, including member avatar cropping, registration and password recovery with SM2 encryption, and the document library pages. So the assets have to be built before the first run:
cd ujcms-starter/src/main/webapp/themes/1/default && npm install && npm run buildThe build generates icons, copies the vendor libraries and compiles the Tailwind styles into assets/css/style.css. The style and icon outputs are committed, which is why continuous integration packaging only needs the vendor step:
npm --prefix ujcms-starter/src/main/webapp/themes/1/default ci
npm --prefix ujcms-starter/src/main/webapp/themes/1/default run build:vendorThe theme's node_modules directory is around 500 MB and is only needed at build time. The war packaging excludes it automatically, and when you copy the webapp directory for a jar deployment you should leave it out.
Building the console and starting the application
The admin console is a separate front end that has to be compiled into the starter module's webapp/cp directory so that it can be served directly, which means you do not have to start a separate console front end server:
pnpm --dir ujcms-ui-console install
pnpm --dir ujcms-ui-console build:starterWith the console and the theme assets in place, the application runs from the project root with the Maven wrapper:
./mvnw clean spring-boot:runThe instruction to run it from the root rather than from inside the starter module is there because running it in the wrong directory produces an error.
On the first run the program creates the tables and seeds the data, which takes a while, and the log line that tells you it worked is the Spring Boot startup message naming the Application class and reporting the seconds it took to start. The front end is then at http://localhost:8080/ and the admin console at http://localhost:8080/cp, with the default administrator account admin and the password password. The documentation asks you to change that password after the first login.
There is a specific IntelliJ IDEA trap worth knowing. If you start the application with the IDE's Run button, you have to go to Edit configurations, click Modify options, tick Working directory and choose the starter module, otherwise the front end fails with a missing static resource error for the default template index. A page that loads without styles is usually the same underlying problem, the theme assets were never built, or the application is not deployed at the root of the container.
war for Tomcat, jar for a plain Java process
The project packages in two ways, and the choice changes the deployment layout.
For a war, the console front end is compiled the same way, the theme vendor assets are generated first, and the build runs with the war profile:
./mvnw -P war clean package -DskipTestsThat produces a war file and an exploded folder under the starter module's target directory. The exploded folder can be copied into the Tomcat webapps/ROOT directory, or the war can be renamed to ROOT.war and placed there, with the existing contents of the webapps directory removed first. Tomcat has to unpack the war, which is its default, and the documentation points at the unpackWARs setting in server.xml if it does not.
For a jar, the profile is different:
./mvnw -P jar clean package -DskipTestsThe jar is copied to a deployment directory, a static directory is created next to it, and the contents of the starter module's webapp directory are copied into it, excluding the theme node_modules. An application.yaml can be placed in a config directory alongside the jar, and that file overrides the copy inside the jar, so you can change configuration without repackaging. The application then starts with java -jar on the jar file.
The -DskipTests flag skips the unit tests, which is fine for packaging. The documentation also explains what a failing test run looks like when you do want them: the tests deliberately trigger and assert various exceptions, so stack traces in the console are expected and the result to look for is the final count line and a successful build.
Docker Compose with MySQL 8.4 and an unattended first run
The repository includes a Dockerfile and a compose file, and the compose file carries the build steps in its own comments so the order is visible before you run anything. The sequence is the theme install, the theme vendor build, the console install, the console build, the Maven package, and then docker compose up.
The service definition is short, and the part that matters is the environment block, which is where the database and the initial administrator are configured:
environment:
UJCMS_DB_HOST: mysql
UJCMS_DB_PORT: 3306The compose file also defines a MySQL service on the mysql:8.4 image with a health check that goes over TCP rather than the socket, because a socket based check reports healthy before the database has finished initialising. The application service waits for that healthy state, publishes port 8080, and keeps a named volume for its static content.
The unattended install is controlled by variables such as UJCMS_INSTALL_AUTO and the administrator username and password, with a default administrator password that the documentation says should be changed for production, either through a secret mounted at run time or after installation. Removing the auto install variable sends you to the install wizard at the admin path instead, with the token in the container startup log.
The image is built from a Java 25 base and layers a jarmode tools extraction of the application jar, and it installs extras with real consequences: a process utility so the document conversion tool can start, LibreOffice for converting Office documents to PDF and importing wps, rtf and odt files, a MySQL client for the database backup feature, and a set of open source fonts. The font choice is deliberate, and the documentation is explicit that Windows and Office fonts must not be copied into the image because their licence does not permit redistribution with the image.
Editorial conclusion
ujcms suits a Java team that wants one codebase to serve both server rendered pages and a headless API, and it does not suit a team that cannot host MySQL 8, and a Tomcat 10.1 server is additionally required only if you choose war deployment. Before deploying, create the database with the utf8mb4 charset, give the database user rights to create tables, and change the default admin credentials, because the documentation ships the account name admin with the password password.
Frequently asked questions
What is ujcms and which technologies does it use?
ujcms is an open source enterprise website content management system written in Java, built with Spring Boot, MyBatis, Spring Security, Lucene, FreeMarker, TypeScript, Vue 3 and Element Plus. It supports a headless architecture and offers two development modes, template plus tags and Vue plus API.
What does ujcms need to run?
The back end needs JDK 17 or 21 and MySQL 8.0, with MySQL 5.7.22 or later and 8.0.20 or later, and Tomcat 10.1 or later is needed only for war deployment. The front end build needs Node 22.12 or later and pnpm.
Do I have to run SQL scripts to set up the ujcms database?
No. You create the database yourself, with the utf8mb4 character set, and the program creates the tables and seed data at startup, then applies schema upgrades automatically by detecting the version. The database account does need rights to create tables, write data and update the structure.
How do I build the ujcms front end static assets?
Run npm install and npm run build in the default theme directory, which copies the third party libraries into assets/vendor and compiles the Tailwind styles into assets/css/style.css. For CI packaging only the vendor step is needed, using npm run build:vendor.
How do I deploy ujcms, and what are the default credentials?
It can be packaged as a war for Tomcat with ./mvnw -P war clean package -DskipTests, or as a jar started with java -jar, or run from source with ./mvnw clean spring-boot:run. The front end is at http://localhost:8080/ and the console at http://localhost:8080/cp, with the default administrator account admin and the password password, which the documentation asks you to change after the first login.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dromara-ujcms)Was this useful?