We manage multi-tenancy with our clients by providing an app+database for each one of them, but in a single tomcat in order to avoid multiplying public IPs.
I try to deploy 2cuba apps on the same tomcat on 2 different contexts but when deploying the 2nd one I have errors when trying to register mbeans, so the deployment stops.
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [com.haulmont.addon.admintools.core.tomcat.TomcatCore@2a038721] with key 'cuba-at:type=TomcatCore'; nested exception is javax.management.InstanceAlreadyExistsException: cuba-at:type=TomcatCore
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:628)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
I guess that I have to change mbean configuration in some way but Iām not sure how.
Plus, Iām quite sure that I will have to change other config items for the 2nd app, and guidance would be much appreciated in order not to miss one. Both apps must be hermetically segregated.
We need to automate the process, so let me explain what we have for now.
In the single-war-web.xml we have introduced new properties files specific to client/tenant local.{core,web}-app.properties.
<context-param>
<description>List of app properties files for Web Client</description>
<param-name>appPropertiesConfigWeb</param-name>
<param-value>classpath:com/busy/app/web-app.properties
classpath:com/busy/app/busy-app.properties
/WEB-INF/local.app.properties
/WEB-INF/local.web-app.properties</param-value>
</context-param>
<context-param>
<description>Web resources version for correct caching in browser</description>
<param-name>webResourcesTs</param-name>
<param-value>${webResourcesTs}</param-value>
</context-param>
<!-- Middleware parameters -->
<context-param>
<description>List of app properties files for Middleware</description>
<param-name>appPropertiesConfigCore</param-name>
<param-value>classpath:com/busy/app/app.properties
classpath:com/busy/app/busy-app.properties
/WEB-INF/local.app.properties
/WEB-INF/local.core-app.properties</param-value>
</context-param>
In addition we have an additional properties file for each client/tenant. We have a created a ādistrimakeā task in build.gradle that generates a war for each client/tenant with specific configuration.
In this war, 3 files are generated in WEB-INF: local.app.properties (global), local.web-app.properties, local.core-app.properties.
For instance for one client/tenant named ātenantā we have local.app.properties
Just for clarity. Do you understand that one single OutOfMemoryError will ruin all your apps simultaneously? Moreover, you will not be able to update Tomcat without downtime for all clients.
It is possible to set up Tomcat as you wish, but there are more advanced techniques for deployment, for instance Docker containers.
Indeed. More precisely the current case is 1 customer with several companies, and the plan is to have 1 single tomcat instance for the client but with 1 app+database per company (currently 2, a 3rd one is coming). For cost reasons client is ok with 1 instance and its consequences.
I have Docker+uberjar in mind for mid-term future, this is our target, but I donāt know how it works yet. So in the meantime, if you could provide guidance on setting up tomcat as intended, that would be great.
EDIT : by guidance I mean how to avoid JMX exception mentionned in OP and any other guidelines you may provide
The problem is with the Admin Tools add-on. Itās MBean registration is written in such a way that doesnāt consider the cuba.webContextName property and hence prevents from using multiple times in a single JVM.
Weāll fix it ASAP, see the issue.