Don't use those libraries - instead use the good old grails-xfire plugin. This guy just works out of the box with .NET 3.5 and 4.0. In C# just add a web reference and you're all set!
More on this topic soon - stay tuned!


web.config getting this guy to work was just a matter of minutes. 



dataSource.logSql configurable from an external file so that after deployment I can decide if I want to see the SQL statements in logs or not.dataSource.url parameter in a properties file designated as an external configuration file I did exactly the same with the logSql option. It turned out not to work.dataSource as follows:dataSource {
logSql = false // disable SQL statements logging
}environments block like this:// set per-environment serverURL stem for creating absolute links
environments {
production {
grails.config.locations = [ "file:/etc/example/example-config.groovy" ]
grails.serverURL = "http://www.changeme.com"
}
...dataSource that previously used an embedded HSQL database to use MySQL:dataSource {
logSql = false
driverClassName = 'com.mysql.jdbc.Driver'
dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
dbCreate = 'update'
url = 'jdbc:mysql://127.0.0.1:3306/example'
username = 'root'
password = ....
}Obviously since there's no MySQL JDBC driver in my application I've had to supply one to the common libraries folder in Tomcat (in Ubuntu if you install Tomcat via apt-get then the folder is /var/lib/tomcat6/common, otherwise it's just the lib folder in your tomcat installation) and all worked just perfectly :)log4j = {
appenders {
file name: "application", file: "/var/example/log/example.log"
file name: "stacktrace", file: "/var/example/log/stacktrace.log"
}
debug application: 'grails.app'
(the rest of usual logging settings here...)
}.application.gsp or main.gsp seem like a perfect match for application-wide layouts. The problem with main.gsp is that it's already taken by the scaffolding mechanism and it's very unlikely that the whole application will be based on scaffolded views. The problem with application.gsp however is much more severe. Once you create this guy it'll apply to everything even if there's no layout specified. This also applies not only to views but to static resources as well! So before you go ahead and create the application.gsp file be prepared to what's coming on to you.conf/Config.groovy file:grails.sitemesh.default.layout = "none"none.gsp will be used as the catch-all instead of application.gsp and so I can use the latter one for my evil purposes :)application.gsp looks just wrong all along.
script folder that contained scripts to execute. server, generate those are only a few of the examples. In Grails it is different: you get a global command called grails that invokes scripts from either the scripts folder within your project or from a global folder. Well, the new RoR works exactly the same way :) There's a rails command that does exactly the same work :)appliaction.properties file listing all the required plugins in their respective versions. In RoR 3.0 there's a Gemfile file serving exactly the same purpose :)class ScriptsController {
def home = { }
}
In this case there are no variables passed on from controller to the view but as you can imagine there are possibilities to do that.<script
type="text/javascript"
src="${g.createLink(controller: 'script', action: 'home')}.js">
</script>and instead of rendering plain HTML code from my GSP I'm rendering JavaScript from /views/scripts/home.js.gsp:<%@ page contentType="text/javascript"%>
var HomeLink = "${g.createLink(controller: 'home', action: 'index')}";class ExampleTagLib {
static namespace = 'g'
def script = { attrs ->
def link = g.createLink(
controller: 'scripts',
action: attrs.name ?: controllerName)
out << """<script type="text/javascript" src="${link}.js"></script>"""
}
}So here I ask for the current controller's name (which is btw nicely preprocessed by Grails) and use that instead of passing in the same parameter value every time I need it even if the dynamic portion is named the same as the controller that called it. A convention, so to speak.<g:script />What this will do it will look-up the current controller name and render a script tag that will access the outcome of an action with the same name as the current controller as the src. This is exactly the same as the first version if called from HomeController only shorter.name parameter comes in handy<g:script name="common" />This way the common script will be requested.java.io.IOException: Server returned HTTP response code: 407 for URL: http://cobertura.sourceforge.net/xml/coverage-04.dtd
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1282)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:283)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1194)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1003)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at _Events.replaceClosureNamesInXmlReports(_Events.groovy:118)
at _Events$replaceClosureNamesInXmlReports.callCurrent(Unknown Source)
at _Events.replaceClosureNamesInReports(_Events.groovy:89)
at _Events$_run_closure2.doCall(_Events.groovy:42)
at _GrailsEvents_groovy$_run_closure5.doCall(_GrailsEvents_groovy:58)
at _GrailsEvents_groovy$_run_closure5.call(_GrailsEvents_groovy)
at _GrailsTest_groovy$_run_closure1.doCall(_GrailsTest_groovy:203)
at TestApp$_run_closure1.doCall(TestApp.groovy:82)
at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:427)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:415)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.executeTargets(Gant.groovy:590)
at gant.Gant.executeTargets(Gant.groovy:589)render method. All would be nice and dandy if it'd be the controller itself but it turns out the command object is more like a domain class (with its ability to verify field values and so on) than anything else. But... there's hope!private getController() {
RequestContextHolder.
requestAttributes.
request.
getAttribute(GrailsApplicationAttributes.CONTROLLER)
}
controller that we can use to call the render method. controller.session
controller.request
controller.responseparams element of the controller is available!if(System.properties["${appName}.config.location"]) {
grails.config.locations << "file:" + System.properties["${appName}.config.location"]
}
log4j:ERROR Error initializing log4j: No signature of method:
groovy.util.ConfigObject.leftShift() is applicable for argument
types: (java.lang.String) values: [file:]
Possible solutions: leftShift(java.util.Map$Entry), leftShift(java.util.Map)
groovy.lang.MissingMethodException: No signature of method:
groovy.util.ConfigObject.leftShift() is applicable for argument types:
(java.lang.String) values: [file:]
Possible solutions: leftShift(java.util.Map$Entry), leftShift(java.util.Map)
at Config.run(Config.groovy:17)
2010-12-18 22:30:46 org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
2010-12-18 22:30:46 org.apache.catalina.core.StandardContext start
SEVERE: Context [/] startup failed due to previous errors
grails.config.locations element is not set by default. To fix this simply add the following line just before the the code you've just uncommented:
grails.config.locations = []
if(System.getenv()["${appName}.config.location"]) {
grails.config.locations << "file:" + System.getenv()["${appName}.config.location"]
}