The Adobe Experience Manager as a Cloud Service (AEM) is a very flexible platform. It allows (customer) developers to extend the two main services, author and publish via Java code. In many cases the exact same code needs to run on both services. However, there are use cases where the code should only run on one of them or behave differently. Similar, a different behaviour or configuration should be used in a development environment versus the production environment.
AEM provides the concept of run modes. A run mode indicates the type of the service as well as the environment type the service is running in. Therefore mutual exclusive run modes exists for author and publish as well as for dev, stage, and prod.
It is important to note that the concept of run modes is not a runtime concept. Following the twelve-factory methodology it has been designed as a deployment and provisioning concept. However, over time some bad pracices spread using run mode information at runtime to select different configurations or code paths.
Don’t Deploy Unused Code
If you want to run different code on author and publish, make the distinction through different deployments: deploy different code on author than on publish. This can be easily achieved by putting common code into a shared bundle and creating separate bundles for author or publish. Use a similar approach for components residing in the repository. This way you do not deploy unused or dead code.
It is bad practice to deploy the exact same code and then clutter the code with if statements checking for the run mode. The clean way is to just deploy what needs to run on a service.
Use Environment-Specific Configuration Values
It is a common use case to have different configuration values for different environments. For example when connecting to external services, different endpoints might be used for development than for production. For this create an OSGi configuration that uses placeholders: