0

I'm working on a payment plugin for the grails framework. I'm using a payment provider which gives me a SOAP API (WSDL) and I need a cxf-client to communicate with the webservice.

I installed https://github.com/ctoestreich/cxf-client (cxf-client plugin) in my grails plugin project (2.2) and want to use the cxf-client I added to my config.groovy in a grails service.

In the Service Class I just added

RecurringPortType recurringPaymentClient

I don't start the plugin project directly, instead i included it in my mainproject where I use some methods of the plugins service (also autowired into my mainproject).

After using the autowired plugin service (which works) I get a nullpointer exception using a method which uses the autowired cxf-client in the plugins service class. The cxf-client bean reuccringPaymentClient is null.

But why? Do I have to include the cxf-client configuration also into my mainprojects config.groovy? Or is there a solution my mainproject can merge or also use the config.groovy of my new plugin? At this time the cxf-configuration is placed in the plugins config.groovy - Maybe that's the problem?

Using

RecurringPortType recurringPaymentClient = ApplicationHolder.application.mainContext.getBean("recurringPaymentClient")

as described in cxf-client documentation didn't help.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
whitenexx
  • 1,350
  • 2
  • 25
  • 53

1 Answers1

1

The Config.groovy file in a plugin only applies when the plugin is run as a standalone application itself. It is not read when the plugin is used in another application. A trick I've seen some plugins use (and which I have stolen for one of my own plugins) is to manipulate the configuration in the plugin descriptor's doWithSpring, which is usually early enough to have the required effect. In your case you'd have to make your plugin loadBefore the cxf-client plugin to ensure that your doWithSpring (creating the config) happens before that of cxf-client (which is where the settings will be used).

class MyCleverGrailsPlugin {
  def version = "0.1-SNAPSHOT"

  def loadBefore = ['cxfClient']

  def doWithSpring = {
    application.config.cxf.client.recurringPaymentClient.clientInterface = com.example.MyClientPortType
    // etc. etc.
  }
}

Or you can use ConfigSlurper by hand

def doWithSpring = {
  ConfigObject pluginConf = new ConfigSlurper(Environment.current.name).parse(com.example.MyPluginDefaultConfig)
  application.config.cxf = pluginConf.cxf.merge(application.config.cxf)
}

This loads a Config.groovy-style script from the plugin's src/groovy/com/example/MyPluginDefaultConfig.groovy, and merges the cxf section of that config into the cxf section of the main application's configuration, with settings in the app overriding the defaults supplied by the plugin.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • What if the user needs another cxf-client instance for some other purposes in his project? In this case, the ConfigSlurper would be better because it does a merge, am i right? – whitenexx Mar 13 '13 at 22:02
  • @whitenexx both cases do a merge - assigning to `application.config.cxf.client.recurringPaymentClient` won't affect any other `cxf.client.somethingElse` settings. But it would mean the plugin overrides explicit settings in the app for `recurringPaymentClient`, the reverse of the ConfigSlurper approach. – Ian Roberts Mar 13 '13 at 22:52
  • I suppose a hybrid would be to create a `new ConfigObject()`, set up the plugin settings directly in there and then `merge` it with the app config like I do with the slurper approach. – Ian Roberts Mar 13 '13 at 22:53