Search code examples
grailsgrails-controller

How to associate a namespaced Controller with same-packaged Service in Grails 2.3.6?


Injecting a Service into a namespaced Controller always resolves to the highest version of the Service, regardless of the namespace declared in the Controller.

    package com.vertest.v1
    class VertestController {
        static namespace = 'v1'
        def vertestService
        def agateSer() {
            render vertestService.agate()
        }
    }
    package com.vertest.v1
    class VertestService {
        def agate() {
            this.getClass().getName()
        }
    }

    package com.vertest.v2
    class VertestController {
        static namespace = 'v2'
        def vertestService
        def agateSer() {
            render vertestService.agate()
        }
    }
    package com.vertest.v2
    class VertestService {
        def agate() {
            this.getClass().getName()
        }
    }

UrlMappings.groovy

    "/v1/agateservice"(controller:"vertest", action:"agateSer", namespace:"v1")
    "/v2/agateservice"(controller:"vertest", action:"agateSer", namespace:"v2")

The v1 VertestController resolves to the v2 VertestService:

    http://localhost:8080/worklists/v1/agateservice > com.iii.worklists.v2.VertestService
    http://localhost:8080/worklists/v2/agateservice > com.iii.worklists.v2.VertestService

Maybe there's a way to force the v1 VertestController to use the v1 VertestService; modify v1 VertestController to declare a fully-qualified VertestService:

    package com.vertest.v1
    class VertestController {
        static namespace = 'v1'
        com.vertest.v1.VertestService vertestService = new com.vertest.v1.VertestService()
        def agateSer() {
            render vertestService.agate()
        }
    }

Ouch! Compile error:

    Error creating bean with name 'com.iii.worklists.v1.VertestController': Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.iii.worklists.v2.VertestService' to required type 'com.iii.worklists.v1.VertestService' for property 'vertestService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.iii.worklists.v2.VertestService] to required type [com.iii.worklists.v1.VertestService] for property 'vertestService': no matching editors or conversion strategy found

What is the preferred method of associating the v1 Controller with a v1 Service?


Solution

  • It is not supported for an application to define 2 services with the same name, even if they are in different packages. The problem with doing that is they would both have the same bean name. There are mechanisms in the framework for dealing with this when services with the same name are provided by different plugins but that is different than defining them in the app, which the framework just doesn't support.