## 12.10 Understanding Plug-in Load Order

#### Controlling Plug-in Dependencies

Plug-ins often depend on the presence of other plugins and can also adapt depending on the presence of others. To cover this, a plugin can define two properties. The first is called `dependsOn`. For example, take a look at this snippet from the Grails Hibernate plugin:

    class HibernateGrailsPlugin {
    	def version = 1.0
    	def dependsOn = [dataSource:1.0,
    	                 domainClass:1.0,
    	                 i18n:1.0,
    	                 core: 1.0]}

As the above example demonstrates the Hibernate plugin is dependent on the presence of 4 plugins: The `dataSource` plugin, The `domainClass` plugin, the `i18n` plugin and the `core` plugin.

Essentially the dependencies will be loaded first and then the Hibernate plugin. If all dependencies do not load, then the plugin will not load.

The `dependsOn` property also supports a mini expression language for specifying version ranges. A few examples of the syntax can be seen below:

    def dependsOn = [foo:"* > 1.0"]
    def dependsOn = [foo:"1.0 > 1.1"]
    def dependsOn = [foo:"1.0 > *"]

When the wildcard * character is used it denotes "any" version. The expression syntax also excludes any suffixes such as -BETA, -ALPHA etc. so for example the expression "1.0 > 1.1" would match any of the following versions:

- 1.1
- 1.0
- 1.0.1
- 1.0.3-SNAPSHOT
- 1.1-BETA2

#### Controlling Load Order

Using `dependsOn` establishes a "hard" dependency in that if the dependency is not resolved, the plugin will give up and won't load. It is possible though to have a "weaker" dependency using the `loadAfter` property:

    def loadAfter = ['controllers']

Here the plugin will be loaded after the `controllers` plugin if it exists, otherwise it will just be loaded. The plugin can then adapt to the presence of the other plugin, for example the Hibernate plugin has this code in the `doWithSpring` closure:

    if(manager?.hasGrailsPlugin("controllers")) {
    	openSessionInViewInterceptor(OpenSessionInViewInterceptor) {
            	flushMode = HibernateAccessor.FLUSH_MANUAL
    	        sessionFactory = sessionFactory
    	}
            grailsUrlHandlerMapping.interceptors << openSessionInViewInterceptor
      }

Here the Hibernate plugin will only register an `OpenSessionInViewInterceptor` if the `controllers` plugin has been loaded. The manager variable is an instance of the api:org.codehaus.groovy.grails.plugins.GrailsPluginManager interface and it provides methods to interact with other plugins and the `GrailsPluginManager` itself from any plugin.