dotCMS / dotCMS/core

Remove dead enterprise licensing infrastructure (BSL transition cleanup)

Open
#34,956 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Epic stale
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

The dotCMS license system has been fully disabled in code as part of the BSL transition. All license checks are hardcoded to pass, making the entire enterprise licensing infrastructure dead code. The BSL transition is settled — no features are gated behind licensing. This issue tracks the phased removal of all dead license code, database artifacts, and UI components.

Evidence — License checks are no-ops
Method File Returns
LicenseUtil.getLevel() dotCMS/src/enterprise/.../LicenseUtil.java Hardcoded LicenseLevel.PLATFORM.level (500 — highest tier)
LicenseManager.checkValidity() dotCMS/src/enterprise/.../LicenseManager.java Hardcoded true
LicenseManager.isAuthorized() dotCMS/src/enterprise/.../LicenseManager.java Hardcoded true
LicenseManager.isASEnabled() dotCMS/src/enterprise/.../LicenseManager.java Hardcoded true
DotLicense() default constructor dotCMS/src/enterprise/.../DotLicense.java PLATFORM level, perpetual, 100-year expiry
LicenseOps default dotCMS/src/main/.../LicenseOps.java Integer.MAX_VALUE (all features pass)

No license is needed to get all features. Every license gate is a no-op.


Scope of Dead Code

Tier 1 — Pure license infrastructure (safe to remove first)
  • LicenseManager.java — singleton manager, RSA verification, all methods return true/constants
  • LicenseTransformer.java — RSA signature verification with BouncyCastle (completely unused)
  • LicenseRepoDAO.javasitelic database table CRUD
  • LicenseCleanupShutdownTask.java — shutdown hook to release license
  • LicenseResource.java — REST endpoints (/api/license/*) for upload/delete/pick/apply
  • LicenseType.java — enum (COMMUNITY, TRIAL, DEV, PROD)
  • LicenseLevel.java — enum (COMMUNITY through PLATFORM)
  • DotLicense.java — license data model
  • DotInvalidLicenseException.java — exception class
  • InvalidLicenseException.java — legacy exception
  • LicenseValiditySupplier.java — validity check helper
  • Task00002LoadClusterLicenses.java — startup task loading license files
  • Task03042AddLicenseRepoModel.java — DB migration creating sitelic table
Tier 2 — License check callsites (~179 references)
  • @EnterpriseFeature annotation + interceptors (EnterpriseFeatureInterceptor, EnterpriseFeatureAdvice, EnterpriseFeatureHandler)
  • Manual LicenseUtil.getLevel() < LicenseLevel.XXX.level checks scattered across:
    • Publishing bundlers (~10 files in enterprise/publishing/)
    • Site search (ESSiteSearchAPI, ESSiteSearchPublisher)
    • CAS authentication (CASAuthUtils)
    • Static publishing (StaticFolderBundler, AWSS3Publisher, StaticPublisher)
    • Content type operations (ContentTypeAPIImpl.copyContentType())
    • Accessibility checker (ACheckerAPIImpl)
  • EnterpriseType marker interface on content types
  • LicenseOps / CoreLicenseOps SPI abstraction
  • InterceptorServiceProvider license ops registration
Tier 3 — Database & UI
  • sitelic table (needs DB migration to drop)
  • License management UI in Angular frontend
  • License-related portlet configuration
  • License upload/management screens
Tier 4 — Tests
  • WorkflowResourceLicenseIntegrationTest.java
  • Any other tests asserting license behavior

Phased Removal Plan

Phase 1: Remove annotation-based gating (lowest risk, highest clarity)
  • Remove @EnterpriseFeature annotation from all methods/classes
  • Remove EnterpriseFeatureInterceptor, EnterpriseFeatureAdvice, EnterpriseFeatureHandler
  • Remove LicenseOps, CoreLicenseOps, related InterceptorServiceProvider wiring
  • Remove DotInvalidLicenseException and InvalidLicenseException
Phase 2: Remove manual license checks
  • Delete all if (LicenseUtil.getLevel() < ...) guard clauses
  • Remove LicenseValiditySupplier
  • Remove EnterpriseType marker interface (if truly unused beyond gating)
Phase 3: Remove license infrastructure
  • Delete LicenseUtil, LicenseManager, LicenseTransformer, LicenseRepoDAO
  • Delete DotLicense, LicenseLevel, LicenseType
  • Delete LicenseCleanupShutdownTask
  • Delete Task00002LoadClusterLicenses
  • Remove LicenseResource REST endpoints
Phase 4: Database & UI cleanup
  • Add DB migration to drop sitelic table
  • Remove license management UI components
  • Remove license-related portlet config
Phase 5: Maven & build cleanup
  • Remove license.use property from all pom.xml files (parent/pom.xml, dotcms-integration/pom.xml, dotcms-postman/pom.xml, test-karate/pom.xml, e2e/*/pom.xml, core-web/apps/dotcms-ui-e2e/pom.xml)
  • Remove license.user.path and docker.license.volume.internal properties from parent/pom.xml
  • Remove the use-license Maven profile from parent/pom.xml (mounts license files into Docker)
  • Remove license-maven-plugin configuration if only used for enterprise license headers (vs BSL headers)
  • Remove test.license.dir from build-parent/pom.xml
Phase 6: Test cleanup
  • Remove or update license-gated tests
  • Verify full build passes

Acceptance Criteria

  • Phase 1 completed — annotation-based gating removed
  • Phase 2 completed — manual license checks removed
  • Phase 3 completed — license infrastructure classes deleted
  • Phase 4 completed — database migration added, UI cleaned up
  • Phase 5 completed — Maven/build license artifacts removed
  • Phase 6 completed — tests updated, full build green
  • No regressions in publishing, site search, content types, or REST API
  • Each phase is a separate PR for safe, incremental review

Additional Context

Verification (per phase)
  • Full Maven build: ./mvnw clean install -DskipTests
  • Run targeted integration tests for affected areas (publishing, site search, content types)
  • Verify REST API still works without license endpoints
  • Check Angular frontend compiles without license UI references
Risks & Considerations
  • Database migration — dropping sitelic requires a proper upgrade task
  • Plugin/extension compatibility — external plugins may reference LicenseUtil.getLevel()
  • Scope is large — ~179 callsites + infrastructure classes; should be split across multiple PRs per phase
Priority

Medium — this is tech-debt cleanup, not a functional change. No user-facing behavior changes since all license gates already pass.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Begin with Phase 1 by locating @EnterpriseFeature usages and reading EnterpriseFeatureInterceptor, EnterpriseFeatureAdvice, EnterpriseFeatureHandler, LicenseOps, and CoreLicenseOps. Work phase by phase, using the listed affected classes, POM files, migrations, UI components, and tests as the map. A phase is done when its references and tests are updated, targeted checks pass, and the full build command succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, java
Domain
backend, build-system, database, frontend, testing
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.