Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

Monday, May 19, 2014

Using grails for restful services

Well if you use grails for restful services, it saves a lot of time to ensure that you add the following mapping to your controller.


class SubmitterController extends RestfulController{

//response format avoid the error that views are not found
    static responseFormats = ['json']

    static allowedMethods = [list:"GET", save: "POST", update: "POST", delete: "DELETE", show: "GET"]

    public SubmitterController(){
        super(Submitter)
    }


}

once you did this, everything works as it should and it's rather obvious. But sometimes we forget. Nearly as stupid as font-awesome not working fonts, if you use...
< i class="fa-minus-square"></i>

you will only see a stupid utf square. Instead you need to use...
< i class="fa fa-minus-square"></i>

Friday, April 19, 2013

cdk and grails - why don't get they along. This time using maven for dependency management...

...

Recently I posted about grails2 and the CDK using the BuildConfig.groovy approach.

Now it's only fair that I show the maven approach as alternative. It's aint pretty...

But it works and allows you to build grails 2.1 project with the CDK. Now i just need to integrate scala into the mix...


<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>edu.ucdavis.fiehnlab.cts</groupId>
    <artifactId>cts</artifactId>
    <packaging>grails-app</packaging>
    <version>2.0-beta-2</version>
    <name>cts</name>
    <description>2.0-beta-2</description>

    <parent>
        <artifactId>web</artifactId>
        <groupId>edu.ucdavis.fiehnlab.cts.web</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.grails</groupId>
            <artifactId>grails-dependencies</artifactId>
            <version>${grails.version}</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.grails</groupId>
            <artifactId>grails-test</artifactId>
            <version>${grails.version}</version>
            <type>pom</type>
        </dependency>


        <dependency>
            <groupId>org.grails</groupId>
            <artifactId>grails-plugin-testing</artifactId>
            <version>${grails.version}</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>net.sf.jni-inchi</groupId>
            <artifactId>jni-inchi</artifactId>
            <version>${jni.inchi.version}</version>
        </dependency>

        <dependency>

            <groupId>org.openscience.cdk</groupId>
            <artifactId>cdk-inchi</artifactId>
            <version>${cdk.version}</version>

            <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xmlParserAPIs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>java3d</groupId>
                    <artifactId>vecmath</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xmlpull</groupId>
                    <artifactId>xmlpull</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>cml</groupId>
                    <artifactId>cmlxom</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xom</groupId>
                    <artifactId>xom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>jdom</groupId>
                    <artifactId>jdom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xpp3</groupId>
                    <artifactId>xpp3</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>jama</groupId>
                    <artifactId>jama</artifactId>
                </exclusion>

            </exclusions>
        </dependency>

        <dependency>

            <groupId>org.openscience.cdk</groupId>
            <artifactId>cdk-fingerprint</artifactId>
            <version>${cdk.version}</version>

            <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xmlParserAPIs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>java3d</groupId>
                    <artifactId>vecmath</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xmlpull</groupId>
                    <artifactId>xmlpull</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>cml</groupId>
                    <artifactId>cmlxom</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xom</groupId>
                    <artifactId>xom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>jdom</groupId>
                    <artifactId>jdom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xpp3</groupId>
                    <artifactId>xpp3</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>jama</groupId>
                    <artifactId>jama</artifactId>
                </exclusion>

            </exclusions>
        </dependency>
        <dependency>

            <groupId>org.openscience.cdk</groupId>
            <artifactId>cdk-renderawt</artifactId>
            <version>${cdk.version}</version>

            <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xmlParserAPIs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>java3d</groupId>
                    <artifactId>vecmath</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xmlpull</groupId>
                    <artifactId>xmlpull</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>cml</groupId>
                    <artifactId>cmlxom</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xom</groupId>
                    <artifactId>xom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>jdom</groupId>
                    <artifactId>jdom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xpp3</groupId>
                    <artifactId>xpp3</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>jama</groupId>
                    <artifactId>jama</artifactId>
                </exclusion>

            </exclusions>
        </dependency>


        <dependency>

            <groupId>org.openscience.cdk</groupId>
            <artifactId>cdk-render</artifactId>
            <version>${cdk.version}</version>

            <scope>runtime</scope>


            <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xmlParserAPIs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>java3d</groupId>
                    <artifactId>vecmath</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xmlpull</groupId>
                    <artifactId>xmlpull</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>cml</groupId>
                    <artifactId>cmlxom</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xom</groupId>
                    <artifactId>xom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>jdom</groupId>
                    <artifactId>jdom</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xpp3</groupId>
                    <artifactId>xpp3</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>jama</groupId>
                    <artifactId>jama</artifactId>
                </exclusion>

            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.codehaus.groovy.modules.http-builder</groupId>
            <artifactId>http-builder</artifactId>
            <version>0.5.2</version>
            <scope>runtime</scope>

            <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xmlParserAPIs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>8.2-504.jdbc3</version>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>cache</artifactId>
            <version>1.0.1</version>
            <type>zip</type>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>jquery-ui</artifactId>
            <version>1.8.24</version>
            <type>zip</type>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>jquery</artifactId>
            <version>1.8.3</version>
            <type>zip</type>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>export</artifactId>
            <version>1.5</version>
            <type>zip</type>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>resources</artifactId>
            <version>1.1.6</version>
            <type>zip</type>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>jquery-ui-extensions</artifactId>
            <version>0.5.8</version>
            <type>zip</type>
        </dependency>

        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>hibernate</artifactId>
            <version>${grails.version}</version>
            <type>zip</type>

        </dependency>

        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>spock</artifactId>
            <version>0.6</version>
            <type>zip</type>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-grails-support</artifactId>
            <version>0.6-groovy-1.8</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>functional-test</artifactId>
            <version>1.2.7</version>
            <type>zip</type>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>webxml</artifactId>
            <version>1.4.1</version>
            <type>zip</type>
        </dependency>

        <dependency>
            <groupId>org.grails.plugins</groupId>
            <artifactId>tomcat</artifactId>
            <version>2.1.0</version>
            <type>zip</type>
            <scope>runime</scope>
        </dependency>


    </dependencies>

    <build>
        <pluginManagement/>

        <plugins>
            <!-- Disables the Maven surefire plugin for Grails applications, as we have our own test runner -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>surefire-it</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                        <configuration>
                            <skip>false</skip>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>plugins</directory>
                            <includes>
                                <include>**/*</include>
                            </includes>
                            <followSymlinks>false</followSymlinks>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.grails</groupId>
                <artifactId>grails-maven-plugin</artifactId>
                <version>${grails.version}</version>
                <configuration>
                    <!-- Whether for Fork a JVM to run Grails commands -->
                    <fork>true</fork>
                </configuration>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>grails</id>
            <name>grails</name>
            <url>http://repo.grails.org/grails/core</url>
        </repository>
        <repository>
            <id>grails-plugins</id>
            <name>grails-plugins</name>
            <url>http://repo.grails.org/grails/plugins</url>
        </repository>

        <repository>
            <id>ambit-public</id>
            <name>ambit-public</name>
            <url>http://ambit.uni-plovdiv.bg:8083/nexus/content/repositories/public/</url>
        </repository>


        <repository>
            <id>ambit-thirdparty</id>
            <name>ambit-thirdparty</name>
            <url>http://ambit.uni-plovdiv.bg:8083/nexus/content/repositories/thirdparty/</url>
        </repository>


        <repository>
            <id>codehaus</id>
            <name>codehaus</name>
            <url>http://snapshots.repository.codehaus.org</url>
        </repository>


    </repositories>
</project>


Thursday, March 14, 2013

cdk and grails, why don't they get along...

so apperently the cdk depends on some xml libaries, which causes us all kind of error messages like this in grails:


| Loading Grails 2.1.0
| Configuring classpath
| Error Error executing script Help: loader constraint violation: when resolving overridden method "org.apache.tools.ant.helper.ProjectHelper2$RootHandler.setDocumentLocator(Lorg/xml/sax/Locator;)V" the class loader (instance of org/codehaus/groovy/grails/cli/support/GrailsRootLoader) of the current class, org/apache/tools/ant/helper/ProjectHelper2$RootHandler, and its superclass loader (instance of ), have different Class objects for the type org/xml/sax/Locator used in the signature (Use --stacktrace to see the full trace)

IDEA hook: Grails not found!
| Error java.lang.NullPointerException
| Error  at org.jetbrains.groovy.grails.rt.Agent$2.run(Agent.java:135)
| Error  at java.lang.Thread.run(Thread.java:680)




which are rather annoying since all the mailing list say, to just run the dependency report to see what causes this problem. Great idea exact that grails crashes before it can generate the report...

So after a while of searching and goggling and shouting random words at my imac, I found an ugly solution which works rather well for now.
Basically make your BuildConfig.groovy file look like this and it should fix your current issues...
    dependencies {
        
        runtime 'postgresql:postgresql:8.2-504.jdbc3'

        compile('xmlpull:xmlpull:1.1.3.1')

        compile('org.openscience.cdk:cdk-fingerprint:1.4.16') {
            transitive = false
        }
        compile('org.openscience.cdk:cdk-inchi:1.4.16') {
            transitive = false
        }
        compile('org.openscience.cdk:cdk-standard:1.4.16')
        compile('org.openscience.cdk:cdk-interfaces:1.4.16')
        compile('org.openscience.cdk:cdk-annotation:1.4.16')
        compile('org.openscience.cdk:cdk-io:1.4.16')
        compile('org.openscience.cdk:cdk-isomorphism:1.4.16')
        compile('org.openscience.cdk:cdk-render:1.4.16')
        compile('org.openscience.cdk:cdk-renderbasic:1.4.16')
        compile('org.openscience.cdk:cdk-renderawt:1.4.16')
        compile('org.openscience.cdk:cdk-smarts:1.4.16')  {
            transitive = false
        }
        compile('org.openscience.cdk:cdk-extra:1.4.16')  {
            transitive = false
        }
        compile('org.openscience.cdk:cdk-dict:1.4.16')  {
            transitive = false
        }
        compile('jama:jama:1.0.2')  {
            transitive = false
        }
        compile('org.openscience.cdk:cdk-formula:1.4.16')
        compile('org.openscience.cdk:cdk-smsd:1.4.16')
        compile('xpp3:xpp3:1.1.4c')
        compile('java3d:vecmath:1.3.1')
        compile('net.sf.jni-inchi:jni-inchi:0.7')
    }
Maybe this help someone, who has the same issues with old XML-Apis and Xerces and so

Thursday, December 13, 2012

grails 1.3.8 and java 1.6

since we still have a lot of grails 1.3.8 application, we are forced to use them and apparently sometimes all the test fail with the following exception:


java.lang.IllegalAccessError: tried to access class org.apache.xml.serializer.XSLOutputAttributes from class org.apache.xalan.transformer.TransformerImpl at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2387) at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2255) at org.apache.xalan.lib.Redirect.write(Redirect.java:212) at org.apache.xalan.extensions.ExtensionHandlerJavaClass.processElement(ExtensionHandlerJavaClass.java:495) at org.apache.xalan.templates.ElemExtensionCall.execute(ElemExtensionCall.java:230) at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes(ElemApplyTemplates.java:395) at org.apache.xalan.templates.ElemApplyTemplates.execute(ElemApplyTemplates.java:177) at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2336) at org.apache.xalan.transformer.TransformerImpl.applyTemplateToNode(TransformerImpl.java:2202) at org.apache.xalan.transformer.TransformerImpl.transformNode(TransformerImpl.java:1276) at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:673) at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1192) at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1170) at org.apache.tools.ant.taskdefs.optional.TraXLiaison.transform(TraXLiaison.java:187) at org.apache.tools.ant.taskdefs.XSLTProcess.process(XSLTProcess.java:709) at org.apache.tools.ant.taskdefs.XSLTProcess.execute(XSLTProcess.java:333) at org.apache.tools.ant.taskdefs.optional.junit.AggregateTransformer.transform(AggregateTransformer.java:264) at org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator.execute(XMLResultAggregator.java:158) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) 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:199) at TestApp$_run_closure1.doCall(TestApp: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)
fix in the BuildConfig.groovy file:


inherits("global") { // uncomment to disable ehcache // excludes 'ehcache' excludes 'serializer' }

Friday, February 3, 2012

integration testing with the grails export plugin

currently I'm testing a lot of controllers in my miniX application and run into the issue that it's nearly impossible to test the grails export plugin. Since the setup tends to get more complicated than your actual test.

Obviously I could redesign my controllers and make them more transparent. But this is not the point right now.

So lets look at our controller:



/**
* should be a service and not a method in the controller, bad design from me. -5 points
*/
def exportStudies(def studies, def response, String format, String extension, String filename) {

//title of the file
def parameters = [title: "Study Design"]

//required labels and mappings
def label = [
"classId": "Class Id",
"comment": "Comment",
"fileName": "Filename",
"label": "Label",
"organName": "Organ",
"speciesName": "Species",
"treatment": "Treatment"
]

//required fields
def fields = [
"classId",
"comment",
"fileName",
"label",
"organName",
"speciesName",
"treatment"
]
//contains out data for the save
def data = []

studies.each {Studie studie ->

//fill our object with data
studie.classes.each {BaseClass clazz ->
if (clazz instanceof ExperimentClass) {
clazz.samples.each {Sample sample ->

StudieExportObject exportObject = new StudieExportObject()

exportObject.classId = clazz.id
exportObject.speciesName = clazz.species.name
exportObject.organName = clazz.organ.name
exportObject.treatment = clazz.treatmentSpecific.toParentString()
exportObject.fileName = "${sample.fileName}_${sample.fileVersion}"
exportObject.comment = sample.comment
exportObject.label = sample.label

data.add(exportObject)

}
}
}
}

//set the extension to xls
response.setHeader("Content-disposition", "attachment; filename=${filename}.${extension}")

//calling the export service, which is really uggly implemented
exportService.export(format, response.outputStream, data, fields, label, [:], parameters)

}

/**
* export the studie as xls file
*/
def exportStudieToXLS = {

Studie studie = Studie.get(params.id)

if (studie == null) {
flash.message = "sorry this object wasn't found!"
redirect(action: "list", controller: "studie")
}
else if (!studie.canAccess()) {
flash.message = "sorry you do not have the permission to access this object!"
redirect(action: "list", controller: "studie")
}
else {

//run the export
exportStudies([studie], response, "excel", "xls", studie.id.toString())
}
}



after spending some time with the attempt to setup the export service correctly, I just scrapped this approach and figured. I assume it works and it's well tested. So lets rather test our logic and make sure it works. Hence we just mock the service in our test.


void testExportStudies() {


Studie studie = AquisitionTableServiceTests.generateNamedStudie(20, false)

GCTof tof = GCTof.list()[0]

AquisitionTableService service = new AquisitionTableService()
GenerateFileNameService generateFileNameService = new GenerateFileNameService()
generateFileNameService.modifyClassService = new ModifyClassService()

generateFileNameService.addCalibrationSamples(studie, tof, new Date(), ShiroUser.list()[0])
generateFileNameService.addReactionBlankSamples(studie, tof, new Date(), ShiroUser.list()[0])
generateFileNameService.addQualityControlSamples(studie, tof, new Date(), ShiroUser.list()[0])


ExportStudieController controller = new ExportStudieController()

//mocking the export service, since the developer of it did a really shitty job to ensure it can be easily tested, FAIL
controller.exportService = [
export : { def a, def b, def c, def d, def e,def f, def g ->
assertTrue(a instanceof String)
assertTrue(b instanceof OutputStream)
assertTrue(c instanceof Collection)
assertTrue(d instanceof Collection)
assertTrue(e instanceof Map)
assertTrue(f instanceof Map)
assertTrue(g instanceof Map)

//some cool testing logic gets here...
}
] as ExportService

controller.metaDataService = new MetaDataService()

controller.exportStudies([studie], controller.response, "csv", "txt", "test")
}

Thursday, January 26, 2012

grails plugins and feedback

once in a while I get emails like this, which makes me really happy to put effort into open source projects.

Hi Gert,

I'm fairly new to Grails and Java and I've been using your Grails jprogress plugin the past few days and it works great - thanks.

I wanted to update the message text as a process went along but didn't see that featured defined in the service. I assumed that you were using the jProgressBar java class and that I could define it's setString method but as I look around I don't think that's the case. Is there a way to do that with your plugin?

Thanks,

Greg

obviously it also means I need todo some more stuff to keep people happy, hence even less spare time for other stuff :(

Wednesday, December 14, 2011

CKEditor plugin + grails submitTorRemote == fail

so people in my office talked to me now a couple of times that they like to have a formating option for text in the comment field.

So my first thought was to use the mighty ckeditor and there is a grail plugin already around. SO we should be done with this in 5 minutes...

Wrong it took a bit longer, since my form kept refusing to save my content and always reported the original content instead.

After quite a bit of googleling and the mandatory
I'm pissed about grails beer, this time it was a nice Aventinius

I found a solution to make it work.

Basically if you want to use CKEditor with JQuery you need to update it fields before (the plugin should really handle this! Do you hear me? I mean I fixed to many plugins by now...)




<g:form name="createNewComment" id="createNewComment" controller="comment">


<ckeditor:editor height="300px" width="80%" name="text ">

test
</ckeditor:editor>

<g:hiddenField name="id" value="${id}"/>
<g:hiddenField name="type" value="${type}"/>
<g:hiddenField name="destination" value="${destination}"/>


<g:javascript>
function CKupdate() {
for (instance in CKEDITOR.instances)
CKEDITOR.instances[instance].updateElement();
return true;
}
</g:javascript>

<g:submitToRemote before="CKupdate();" class="save" action="saveAjax" update="${destination}" value="save comment"/>


</g:form>




And this is all, now before we press the button, we always call the method to update the editor and everybody is happy...

Friday, December 9, 2011

jQuery + grails and my missing buttons...

currently I'm switching miniX over to use jQueryUi style buttons, since this makes life so much easier to maintain them.

Except during my event processing my buttons keep disappearing, which is rater annoying, to say at least.

Couple of hours later I finally found a crude but working solution. I just create a simple event handler, which re renders all by buttons...


$(document).ajaxComplete(function() {
$("input:submit, a.button, input:button, div.qq-upload-button").button()
});

$(document).ready(function() {
$("input:submit, a.button, input:button, div.qq-upload-button").button()
});

Wednesday, November 2, 2011

grails quartz plugin - don't repeat jobs

well it might be obvious, but sometimes you just want to execute a simple job once during the startup and than let them be.

For an example I needed this to synchronize a database and run statistics over it. So the simples trigger I could come up with, was


static triggers = {
simple name: 'synchronize', startDelay: 60000, repeatCount: 0
}


An alternative way could had been todo schedule the job during the startup phase


SynchronizeExperimentJob.triggerNow([experimentId: id, database: database])


this line should be put into your bootstrapping file.

Personally I feel the trigger is more elegant.

Monday, August 8, 2011

grails + jquery + checkboxes

sometimes forms based on checkboxes can be rather annoying. An example would be that this is the return of a standard html checkbox,

html defined checkboxes:

<g:checkBox name="compare" id="1"/>
<g:checkBox name="compare" id="2"/>
<g:checkBox name="compare" id="3"/>


result of the send parameters to the server:



def compareBins = {
println params
}

out:

compare:[on, on, on]


now this is rather useless, we rather would see the id of the checkbox in the result. So let's call jQuery to the rescue and see how it can save out day!



jQuery(document).ready(function() {
$('input:checkbox').each(
function() {
$(this).click(function() {

if (this.checked) {
var value = $(this).attr('id');
$(this).val(value);
}
});
}
);
});



and promptly we have the following result if all 3 boxes are selected


compare:[1,2,3]


or if 1 and 3 are selected


compare:[1,3]


so we can actually tell, which elements where checked instead of getting just 'on'

Tuesday, August 2, 2011

MedPlan

Over the last couple of days I was thinking about creating a small grails to show the speed of development with grails. The goal was to create an application in less than 24h, which is able to track your medications and at the same time has some important features.

The original idea came from spending the last 5 days with my wife's sick sister and see how difficult and confusing it was to track all her different medications. Specially since there were 3 people involved doing this and nobody really know, which medications did she already receive.

What does the user want:

  • easily enter a new prescription
  • see which medications have been taken
  • show when to take a medication
  • show the medication's in form of a calendar

What did I want as a developer:
  • easy to use
  • multi user access
  • ajax driven/jquery
  • calendar interface
  • auto complete
  • multi platform support (ipad/windows/linux/osx)
  • able to run without a tomcat installation
  • don't look like a standard grails scaffolding application
  • use as few mouse clicks as possible
how does it look after 16h of work?

weekly overview

prescription overview

adding a prescription

What is missing?

I think at this point in time the application does what it's supposed todo, but some nice features would be:

  • iPad support as a native application
  • internationalization
  • share your prescription plan with another user
  • send out an email, 30 minutes before a medication has to be used
  • soap/rest based access 
Where can I get it?

You can download the application here

Monday, July 25, 2011

grails - export plugin, at dynamically more attributes

What is this about?

currently I'm writing on a little tech study application, called times. Which can be accessed here

This application is a very simplistic timetracker, but allows me to play with some api's I normally don't use or to simply test some grails functions.

Right now I had a simple idea.

I want to export all my data, using the grails export plugin, without cluttering my database model with dozens of attributes, which will never be queried. I also did not want to create pojo's, just for the export. Instead I decided to play a bit with the EMC MetaClass again and see if, we can do this on the fly.

Example:



def exports = []

def fields = ["name","organization","project","beginDate","endDate","timeSpend"]
def labels = ["name":"Name","organization":"Organization","project":"Project","beginDate":"Start","endDate":"Finished","timeSpend":"Durations (s)"]
Task.list().each {Task t ->
if (t.endDate != null) {
t.metaClass.timeSpend = (t.endDate.time - t.beginDate.time)/1000

exports.add(t)
}
}
exportService.export(params.format, response.outputStream, exports,fields,labels, [:], [:])


this registers the attribute 'timeSpend' to the lifespan of the Task instance 't'. Which is only be required during the export.

The important line is



t.metaClass.timeSpend = (t.endDate.time - t.beginDate.time)/1000



Short, it can simplify your life a bit and reduces the need of introducing a pojo, just to export data or to permanently add this object to your database. Specially since it's a calculated value and can be regenerated on the fly.

Monday, July 4, 2011

JSON and SSL in groovy, how to ignore certificates

In the last couple of days I became more and more interested in bitmining and the first thing I noticed was the utter lack of integrated tools and hence statistics I would like to associated with my miners.

This resulted in me creating a tiny grails application to synchronzie my deepbit statistics with the current market data from mtgox to calculate at which point it becomes pointless to mine these thing. I basically hope that this pays for the 700$ for my 2x6950 radeons and associated cooling the 100+F heat we have here in California.

Now originally you could assume that this is rather straightforward. After all you got json data, which just need to be parsed.


Map jsonArray = JSON.parse(new InputStreamReader(new URL("https://mtgox.com/code/data/ticker.php").openStream()))

println jsonArray



but sadly the java ssl security manager does not agree here with us and tosses a fit..



javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)



Now java is kinda smart, if want's to force you install a security certificate from the server you access and authorize yourself. But sometimes you don't want this. In this case it's overkill, since we are having a readonly transaction.

So what has to be done?

you need to create your own security manager implementation. Which basically is a 3 step procedure


  1. implement an interface


    class TrustManager implements X509TrustManager {

    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
    }

    public void checkClientTrusted(
    java.security.cert.X509Certificate[] certs, String authType) {
    }

    public void checkServerTrusted(
    java.security.cert.X509Certificate[] certs, String authType) {
    }

    }




  2. register the interface and update the context configuration

    TrustManager[] trustAllCerts = new TrustManager[1]

    trustAllCerts[0] = new TrustManager()
    try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
    }

  3. and continue like always with your json script

    Map jsonArray = JSON.parse(new InputStreamReader(new URL("https://mtgox.com/code/data/ticker.php").openStream()))


and the result should be now the current ticker for the USD to BitCoin exchange rate.


    {"ticker":{"high":15.4989,"low":13.31415,"avg":14.726503862,"vol":42862,"last":13.31415,"buy":13.331,"sell":13.35999}}



    Saturday, December 18, 2010

    grails - providing your own plugins configuration

    sometimes you want to share some services in a plugin, which needs to be configured at runtime.

    The easiest way is to provide a simple file in the grails conf diretory of your plugin and just read it and access it at runtime.

    How to?

    our little helper:


    package binbase.core

    import grails.util.GrailsUtil
    import org.codehaus.groovy.grails.commons.GrailsApplication

    /**
    * Created by IntelliJ IDEA.
    * User: wohlgemuth
    * Date: 12/18/10
    * Time: 1:00 AM
    * To change this template use File | Settings | File Templates.
    */
    class BinBaseConfigReader {

    private static ConfigObject config = initialize()

    /**
    * initializes the object
    * @return
    */
    static ConfigObject initialize() {
    return new ConfigSlurper().parse(new GroovyClassLoader(BinBaseConfigReader.class.getClassLoader()).loadClass('BinBaseConfig'))
    }

    /**
    * returns the server
    * @return
    */
    static String getServer() {
    if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_TEST)) {
    return config.binbase.test.server.toString()
    }
    else if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_DEVELOPMENT)) {
    return config.binbase.development.server.toString()
    }
    else if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_PRODUCTION)) {
    return config.binbase.production.server.toString()

    }
    else {
    throw new RuntimeException("unexspected enviroment found")
    }
    }
    }



    our configuration


    /**
    * this file contains the binbase configuration for this plugin.
    *
    */
    binbase {
    production {
    key = "dasdasd"
    server = "10.1.1.1"
    }
    test {
    key = "dasdasd"
    server = "10.2.2.2"
    }
    development {
    key = "dasdasd"
    server = "127.0.0.1"
    }
    }


    and to access it in your, say spring configuration?


    jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

    environment = [
    "java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
    "java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
    "java.naming.provider.url": "${BinBaseConfigReader.getServer()}:1099".toString()
    ]
    }


    easy, isn't it?

    grails - testing service, which accesses ejb's

    this night I just wanted to write a quick grails plugin to access my BinBase database system.

    Since I'm a smart developer I start with a simple spring dsl file and write a test.



    // Place your Spring DSL code here
    beans = {

    jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

    environment = [
    "java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
    "java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
    "java.naming.provider.url": "localhost:1099"
    ]
    }

    /**
    * connection to the cluster configuration
    */
    clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
    businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
    jndiName = "clusterservice/ClusterConfigServiceBean/remote"
    jndiTemplate = ref(jndiBinBaseTemplate)
    }

    }


    and the test code is simple enough



    class BinBaseSchedulingServiceTests extends GroovyTestCase {


    ClusterConfigService clusterConfigService

    protected void setUp() {
    super.setUp()
    }

    protected void tearDown() {
    super.tearDown()
    }

    public void testTest(){
    assertTrue(clusterConfigService.username != null)
    }
    }


    the variable 'ClusterConfigService' is an stateless session bean in a jboss container and I know it works...

    except grails is complaining:



    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clusterConfigService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:135)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at
    ....lots and lots of more...
    Caused by: javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
    at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
    at org.springframework.ejb.access.AbstractRemoteSlsbInvokerInterceptor.lookup(AbstractRemoteSlsbInvokerInterceptor.java:100)
    at org.springframework.ejb.access.AbstractSlsbInvokerInterceptor.refreshHome(AbstractSlsbInvokerInterceptor.java:122)
    at
    ...lots and lots of more...
    [23:59:35,938] [ERROR] [main] [StackTrace] [Sanitizing stacktrace:]
    javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
    at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)




    mhm doesn't make much sense. Reason for the failure is that grails decides to mock the access, which is normally ok. But in our case really really not desired.

    After all we want to access the application server context!

    But it keeps jumping to the 'org.springframework.mock.jndi.SimpleNamingContext' mocking context.

    So the only solution is this slightly dirty hack...


    /***
    * we do not need mocking in this plugin...
    */
    if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
    org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
    }



    and promptly it passes.

    Since we only want to change this for test cases, we add yet another conditon and our resources.groovy file ends up looking like


    import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean
    import grails.util.GrailsUtil
    import org.codehaus.groovy.grails.commons.GrailsApplication

    /** *
    * we do not need mocking in this plugin...
    */
    if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_TEST)) {
    println "warning disabling mocking context!!! to make remote ejb's work"
    if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
    org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
    }
    }

    // Place your Spring DSL code here
    beans = {

    jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

    environment = [
    "java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
    "java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
    "java.naming.provider.url": "eros.fiehnlab.ucdavis.edu:1099"
    ]
    }

    /**
    * connection to the cluster configuration
    */
    clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
    businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
    jndiName = "clusterservice/ClusterConfigServiceBean/remote"
    jndiTemplate = ref(jndiBinBaseTemplate)
    }

    }

    Thursday, December 16, 2010

    Grails 1.3.5 webtests - custom steps to reset the database

    once in a while I have the trouble that I want to reset the complete database during webtests or to make a snapshot of the current database while running the test.

    So we use the great dbunit plugin to dump the database in one step:


    import javax.sql.DataSource
    import grails.plugin.remotecontrol.RemoteControl
    import org.dbunit.database.DatabaseConnection
    import org.dbunit.dataset.IDataSet
    import org.dbunit.database.IDatabaseConnection
    import org.dbunit.dataset.xml.FlatXmlDataSet
    /**
    * Created by IntelliJ IDEA.
    * User: wohlgemuth
    * Date: Nov 24, 2010
    * Time: 3:46:47 PM
    * To change this template use File | Settings | File Templates.
    */
    class DumpDatabaseStep extends com.canoo.webtest.steps.Step {

    String fileName = "result.xml"
    /**
    * resets the database
    */
    void doExecute() {

    RemoteControl remote = new RemoteControl()
    try {

    def outputFile = fileName
    remote {
    File file = new File("target/test-reports/data")
    file.mkdirs()

    DataSource dataSource = ctx.dataSource

    IDatabaseConnection connection = new DatabaseConnection(dataSource.connection)

    IDataSet fullDataSet = connection.createDataSet()

    File out = new File(file, outputFile)

    int counter = 1;

    boolean run = out.exists()
    while (run) {
    out = new File(file, "${counter}-${outputFile}")

    run = out.exists()
    if (counter == 100) {
    println "killed after 100 runs.."
    run = false
    }
    counter++
    }

    FlatXmlDataSet.write(fullDataSet, new FileOutputStream(out))

    null
    }
    }
    catch (Exception e) {
    e.printStackTrace()

    throw e
    }

    }
    }


    and also to reset the complete database in another step


    import grails.plugin.remotecontrol.RemoteControl
    import javax.sql.DataSource
    import groovy.sql.Sql

    /**
    * simple step which resets the complete database
    */
    class ResetDatabaseStep extends com.canoo.webtest.steps.Step {

    /**
    * resets the database
    */
    void doExecute() {

    try {
    DbUnitOperator.create()


    RemoteControl remote = new RemoteControl()

    remote.exec {
    try {
    DataSource dataSource = ctx.dataSource
    Sql sql = Sql.newInstance(dataSource)

    sql.execute("DROP SEQUENCE MINIX_ID")
    sql.execute("CREATE SEQUENCE MINIX_ID START WITH 1000 INCREMENT BY 1")
    }
    catch (Exception e) {
    e.printStackTrace()
    throw e
    }
    }


    }
    catch (Exception e) {
    println "error: ${e.getMessage()}"
    e.printStackTrace()
    throw new RuntimeException(e)
    }

    }
    }

    Grails 1.3.5 webtests and JQuery trouble

    recently I migrated my prototype code over to JQuery and promptly all my webtest's failed with a lot of error messages and exceptions.

    Like:


    "TypeError: Cannot find function createComment in
    object [object]. (FunctionalTestCase.groovy#372)"


    So during some googeling I found these reports:

    old htmlunit version

    replacing version

    Which led to me reporting:

    my approach

    and the final solution was to put this into your 'BuildConfig.groovy'


    plugin("webtest") {
    test('net.sourceforge.htmlunit:htmlunit:2.8-SNAPSHOT') {
    excludes 'xalan'
    excludes 'xml-apis'
    }
    test('com.canoo.webtest:webtest:3.1-SNAPSHOT') {
    excludes 'xalan'
    excludes 'xml-apis'
    }
    test('xalan:xalan:2.7.0') {
    excludes 'xml-apis'
    }
    }

    Wednesday, August 25, 2010

    dynamic fields with groovy

    one of the features I love is to just define new fields in objects whenever I want.

    like:



    def test = ["a","b","c,"]

    Object a = new Object()

    test.each{

    a.metaClass."${it}" = it
    }



    generates te following fields in the object a

    a.a = "a"
    a.b = "b"
    a.c = "c"

    works incredible well with the grails export plugin :)

    Saturday, February 20, 2010

    postgres and insert performance with grails

    recently I spend a lot of time tuning a postgres database and an algorithm (based on grails) to try to insert 80M chemical compounds into a database with reference checks and assurance for there uniqueness.


    The main issue is that the inserts get slower and slower over time and end up taking to long. To improve the performance we started with the following approach:
    • more memory
    • database indexes (obvious)
    • flush the hibernate session all 100 inserts
    • flush the grails cache all 100 inserts
    • tune several postgres parameters
    • re index the database all 10k inserts
    • enable vacuum on a 10k row basis
    • enable analyze on a 10k row basis
    • set auto vacuum to check all 10 minutes
    But after all this work we are still stuck with a problem, the inserts get gradually slower over time, which can be related to the index building time.

    Graph over 1M inserts: TODO, it's still in the calculation...

    Tuesday, September 1, 2009

    run-app vs run-war

    the main differences between these two commands is that:

    run-app runs a grails applications and allows the reloading from resources
    run-war generates a war file and runs the war file, so no reloading of resources.

    Short during development you want to use run-app.