Extending dotCMS with OSGI Plugins - With Great Power ...

Extending dotCMS with OSGI Plugins - With Great Power ...

Extending dotCMS with OSGi Plugins: Best Practices and Key Concepts

One of the greatest strengths of dotCMS is its extensibility. In fast-paced development environments, the ability to customize or extend platform behavior is not a luxury—it's essential. dotCMS embraces this need through support for OSGi plugins, a modular and powerful way to integrate custom logic into the core platform while keeping your code isolated and maintainable.

This article provides practical guidance and architectural recommendations on how to build OSGi plugins in dotCMS the right way—ensuring long-term compatibility, performance, and clarity in your custom extensions.

What Can Be Extended with a Plugin?

OSGi plugins open the door to a wide range of extension points in dotCMS. Among the most commonly used are:

  • Web Interceptors
    A lightweight abstraction of a traditional ServletFilter, Web Interceptors allow you to intercept and manipulate web requests and responses with minimal overhead.

  • Content Hooks
    These allow you to inject custom logic at the start or end of key operations such as REST API calls to the Contentlet API, offering fine-grained control over content management behavior.

  • Content Validations:
    Create custom and complex validations for content that are verifiedfired before content can be saved.

  • Admin Tools (Portlets):
    Create custom screens/admin tools in the backend of dotCMS that can be provisioned and permissioned just like dotCMS admin tools.

  • Custom REST Endpoints
    You can expose new JAX-RS REST API endpoints under the dotCMS context, secured and versioned as needed.

  • Custom Rules
    Extend dotCMS personalization and business logic by defining new types of rules using your own logic or third-party data sources.

  • Workflow Actions
    Add new custom actions to your content workflows to trigger business logic, integrations, or external services.

  • Velocity ViewTools
    Extend Velocity by adding custom, purpose built viewtools to expose integrations to the dotCMS rendering engine. e.g.  $myapp.get(${productId}).title

  • Apps
    Develop custom apps that can integrate with 3rd party tools and APIs.  Apps have the benefit of allowing users to configure them at runtime from the backend of dotCMS

  • ContentPublishing Listeners
    Listen and react to content publishing events.

    ...and much more.

Important Architectural Note: No More Class Overrides

A key change in recent versions of dotCMS is that class overrides are no longer supported. That is, OSGi plugins can no longer replace existing dotCMS classes. Instead, the override directive simply makes your classes available to the system classloader—particularly useful when working with serializable tasks like Quartz jobs. For example, when you define a custom job class that needs to be persisted, dotCMS must be aware of that class during deserialization.

Dependency Management: Avoid Coupling with dotCMS Internal Libraries

When developing your plugin, it's essential to declare the dotCMS dependency as provided and non-transitive. This ensures that your plugin-specific code only uses classes provided by the dotcms.jar and is not using external libraries/dependencies that dotCMS relies upon.

This is important as you want to avoid depending directly on libraries used internally by dotCMS, as these may change or be removed without notice in future releases. Instead, bundle your own versions of external libraries inside your plugin using a fat (uber) JAR. This isolation protects your code from upstream changes and improves long-term compatibility.

Sample pom.xml Configuration

Below is a simplified Maven configuration that demonstrates these principles:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.dotcms</groupId>
            <artifactId>dotcms</artifactId>
            <version>${dotcms.version}</version>
            <scope>provided</scope> <!-- Avoids packaging dotCMS internals -->
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</dependencyManagement>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>com.yourcompany.myplugin</Bundle-SymbolicName>
                    <Import-Package>
                        com.dotmarketing.*,com.liferay.*,org.osgi.*,javax.servlet.*,
                        org.slf4j,*
                    </Import-Package>
                    <Export-Package>com.yourcompany.myplugin.*</Export-Package>
                    <Private-Package>com.yourcompany.myplugin.internal.*</Private-Package>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

💡 Tip: If you use classes from dotCMS (like interfaces for WebInterceptors or Hooks), ensure the corresponding packages are explicitly declared in the Import-Package section, as shown above. This ensures proper classloading at runtime.

Conclusion

OSGi plugins are a powerful and flexible way to extend dotCMS, enabling teams to inject custom functionality without compromising platform stability. By following best practices—such as avoiding class overrides, isolating dependencies, and properly managing your plugin’s packaging—you ensure that your customizations remain robust, maintainable, and compatible with future versions of dotCMS.

As with any powerful tool, the key to long-term success lies in disciplined design and thoughtful integration. With the right approach, OSGi plugins can transform dotCMS into a platform tailored precisely to your business needs.

Additional Resources

To dive deeper into OSGi plugin development and dotCMS extensibility, the following resources are highly recommended: