eXo Services: How we leverage IoC
1 Portal Instance
As there can be several portal container instances per JVM it is important to be able to configure the loaded services per instance. Therefore all the default configuration files located in the service impl jar can be overridden from the portal war. For more information refer to the technical documentation of the portal product.2 Introduction to the XML schema of the configuration.xml file
Use component registration tags. We have introduced the key tag that defines the interface and the type tag that defines the implementation. Note that the key tag is not mandatory but it improves performance to reference it.<!-- Portlet container hooks --> <component> <key>org.exoplatform.services.portletcontainer.persistence.PortletPreferencesPersister</key> <type>org.exoplatform.services.portal.impl.PortletPreferencesPersisterImpl</type> </component>
<external-component-plugins>
<target-component>org.exoplatform.services.database.HibernateService</target-component>
<component-plugin>
<name>add.hibernate.mapping</name>
<set-method>addPlugin</set-method>
<type>org.exoplatform.services.database.impl.AddHibernateMappingPlugin</type>
<init-params>
<values-param>
<name>hibernate.mapping</name>
<value>org/exoplatform/services/portal/impl/PortalConfigData.hbm.xml</value>
<value>org/exoplatform/services/portal/impl/PageData.hbm.xml</value>
<value>org/exoplatform/services/portal/impl/NodeNavigationData.hbm.xml</value>
</values-param>
</init-params>
</component-plugin>
</external-component-plugins><external-component-plugins>
<target-component>org.exoplatform.services.organization.OrganizationService</target-component>
<component-plugin>
<name>portal.new.user.event.listener</name>
<set-method>addListenerPlugin</set-method>
<type>org.exoplatform.services.portal.impl.PortalUserEventListenerImpl</type>
<description>this listener create the portal configuration for the new user</description>
<init-params>
<object-param>
<name>configuration</name>
<description>description</description>
<object type="org.exoplatform.services.portal.impl.NewPortalConfig">
<field name="predefinedUser">
<collection type="java.util.HashSet">
<value><string>admin</string></value>
<value><string>exo</string></value>
<value><string>company</string></value>
<value><string>community</string></value>
<value><string>portal</string></value>
<value><string>exotest</string></value>
</collection>
</field>
<field name="templateUser"><string>template</string></field>
<field name="templateLocation"><string>war:/conf/users</string></field>
</object>
</object-param>
</init-params>
</component-plugin>3 JMX auto wiring
Each component loaded in the container will be automatically wrapped by a MBean that will be registered in an associated MBean server. There exist one MBean server per eXo container and you can get the instance from the ExoContainer class using the methodpublic MBeanServer getMBeanServer()<component>
<key>org.exoplatform.services.database.HibernateService</key>
<jmx-name>exo-service:type=HibernateService</jmx-name>
<type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
[...]
</component>| Container Type | Access URL |
|---|---|
| RootContainer or StandaloneContainer | service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root |
| PortalContainer (in Portal mode) | service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root/PORTAL_NAME |
| RepositoryContainer | service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root/PORTAL_NAME/REPOSITORY_NAME in Portal mode or service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root/REPOSITORY_NAME in Standalone mode |
| WorkspaceContainer | service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root/PORTAL_NAME/REPOSITORY_NAME/WORKSPACE_NAME in Portal mode or service:jmx:rmi:///jndi/rmi://localhost:9999/eXo/root/REPOSITORY_NAME/WORKSPACE_NAME in Standalone mode |
<init-params> <value-param> <name>protocol</name> <description>protocol is a short string that represent the protocol such as "rmi", "iiop", "jmxmp" or "soap"</description> <value>rmi:///jndi/rmi</value> </value-param> <value-param> <name>host</name> <description>optional hostname</description> <value>localhost</value> </value-param> <value-param> <name>port</name> <description>optional port</description> <value>9999</value> </value-param> <value-param> <name>path-prefix</name> <description>optional path prefix</description> <value>eXo/</value> </value-param> <value-param> <name>name-separator</name> <description>the separator used between the container names</description> <value>/</value> </value-param> <properties-param> <name>environment</name> <description>a set of attributes to control the new connector server's behaviour</description> <property name="jmx.remote.jndi.rebind" value="true"/> </properties-param> </init-params>
Since kernel 2.0.7, it is possible to register all eXo MBeans in a single local MBeanServer in order to be able to manage them through the JConsole or any another JMX Console.
- The JVM system property org.exoplatform.container.jmx.useExistingServer can set to specify that we would like to use a local MBean server. By default, the default behavior will be preserved.
java -Dorg.exoplatform.container.jmx.useExistingServer ...
- The JVM system property org.exoplatform.container.jmx.findExistingServer can set to specify that we would like to find a specific local MBean server. The value of this parameter is the MBean server agent id. By default, the platform MBean Server will be used.
java -Dorg.exoplatform.container.jmx.findExistingServer=${agent_id} ...java -Dorg.exoplatform.container.jmx.findExistingServer ...
- The JVM system property org.exoplatform.container.jmx.findExistingServerFromDefaultDomain can set to specify our local MBean server research. The value of this parameter is the MBean server default domain name. By default, only the agent id is used to find the local MBean server so if several MBean servers have the same agent id, the first one will be used.
java -Dorg.exoplatform.container.jmx.findExistingServerFromDefaultDomain=${default_domain} ...
4 Configurations search and log of the search
When the RootContainer is starting the configuration search looks for configuration files in each jar available from the classpath at jar path /conf/portal/configuration.xml and from each war at path /WEB-INF/conf/configuration.xml. And adds these configurations to a set. If a component was configured in previous jar and the current jar contains one new configuration of that component the latest (from the current jar) will replace one previous configuration. After the processing of all configuration available on system the container will initialize it and start each component in order of dependency injection (DI). So, in common case the user/developer should be careful in configuration of same components in different configuration files. It's recommended to configure service in own jar only. Or, in case of portal configuration, strictly reconfigure the component in portal files. But, there are components that can be (or should be) configured few times. It's individual and depends on business logic of the component. A component may initialize same resource (shared for other players) or may add a particular object to a set of objects (shared for other players too). In first case it's a critical who will be the last, i.e. whose configuration will be used. In second case it's no matter who the first who the last (if parameter objects are independent). In case of problems with configuration of component it's important to know from which jar/war it comes. For that purpose user/developer can set JVM system property org.exoplatform.container.configuration.debug, in command line:java -Dorg.exoplatform.container.configuration.debug ...
......
Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml
import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml
import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
......
on 12/12/2008 at 18:19