Showing posts with label groovy. Show all posts
Showing posts with label groovy. Show all posts

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

Monday, March 11, 2013

Lift - getting access to a database

Since I recently started to play more and more with lift. I discovered that it's not always as easy as you think it is and once you find a solution it was easy indeed.

For example I want to connect to my database server, but have no desire to actually use any form of OR mapping.

So after googleing a bit and woundering how todo this. It's all rather simple.

In your Boot.scala file


def boot {
    // where to search snippet
    LiftRules.addToPackages("code")

    // Build SiteMap
    LiftRules.setSiteMap(sitemap)

    //rest based stuff

    /**
     * connection url for lift
     */
    val vendor = new StandardDBVendor("org.postgresql.Driver","jdbc:postgresql://****/****",Full("username"),Full("password")) with ProtoDBVendor{
      override def maxPoolSize = 100
      override def doNotExpandBeyond = 200
    }
    
    DB.defineConnectionManager(DefaultConnectionIdentifier, vendor)

  }

This basically defines what to connect to and a connection pool with a max of 100 connections.

To actually access this connection and todo something with it, well this is remarkable easy.


          DB.performQuery("select * from data")

Wednesday, February 22, 2012

testing all urls in a sitemap.xml file for existence with groovy

While working on some projects I figured out that it would be nice to have a quick and easy way to check all registered urls in a sitemap for existence and that groovy would be the perfect tool for this.

So we wrote a simple script for this


@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
import groovyx.net.http.HTTPBuilder

//small script to verify that an url exist, which was specified in a sitemap
//args[0] is the sitemap

//simple check
if(args.length != 1){
println "Usage\n"
println "please provide one argument, which is a filename pointing to your sitemap file"
println "\n"
return
}

//load file

def file = new File(args[0])

if(file.exists() == false){
println "\nsorry your file was not found. Missing file is ${args[0]}\n"
return
}

//parsing urls
def root = new XmlSlurper().parse(file)

def urls = root.url

println "\nchecking ${urls.size()} urls\n"

def success = 0
def failure = 0

urls.each{
def url = it.loc.text()

print "success:\t"

try {
new HTTPBuilder( url ).get( path:'' ) { response ->
response.statusLine.statusCode == 200

print "true"
success++
}
}
catch( e ) {
print "false"
failure++
}

print "\t that ${url} exists\n"
}

println "\nreport..."
println "\tsuccessful: ${success}"
println "\tfailed: ${failure}"
println "\ttotal: ${urls.size()}"

println "\nchecked ${urls.size()} urls in file ${args[0]}\n\n"



and the output looks something like this...


groovy verifyUrls.groovy Downloads/sitemap.xml

checking 45 urls

success: true that http://metacore-ucdavis.appspot.com/ exists
success: true that http://metacore-ucdavis.appspot.com/services exists
success: true that http://metacore-ucdavis.appspot.com/techno1 exists
success: true that http://metacore-ucdavis.appspot.com/techno2 exists
success: true that http://metacore-ucdavis.appspot.com/techno3 exists
success: true that http://metacore-ucdavis.appspot.com/setupx exists
success: true that http://metacore-ucdavis.appspot.com/projects exists
success: true that http://metacore-ucdavis.appspot.com/staff exists
success: true that http://metacore-ucdavis.appspot.com/login_form exists
success: true that http://metacore-ucdavis.appspot.com/join_form exists
success: true that http://metacore-ucdavis.appspot.com/mail_password_form exists
success: true that http://metacore-ucdavis.appspot.com/Members/admin exists
success: true that http://metacore-ucdavis.appspot.com/services/ exists
success: true that http://metacore-ucdavis.appspot.com/services/statistics exists
success: true that http://metacore-ucdavis.appspot.com/services/protocols exists
success: true that http://metacore-ucdavis.appspot.com/techno1/ exists
success: true that http://metacore-ucdavis.appspot.com/techno1/compounds exists
success: true that http://metacore-ucdavis.appspot.com/techno1/statistics exists
success: true that http://metacore-ucdavis.appspot.com/techno2/ exists
success: true that http://metacore-ucdavis.appspot.com/techno3/ exists
success: true that http://metacore-ucdavis.appspot.com/setupx/ exists
success: true that http://metacore-ucdavis.appspot.com/projects/ exists
success: true that http://metacore-ucdavis.appspot.com/staff/ exists
success: true that http://metacore-ucdavis.appspot.com/join_form?came_from= exists
success: true that http://metacore-ucdavis.appspot.com/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/Members/ exists
success: true that http://metacore-ucdavis.appspot.com/Members/admin/ exists
success: true that http://metacore-ucdavis.appspot.com/services/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/statistics/ exists
success: true that http://metacore-ucdavis.appspot.com/services/protocols/ exists
success: true that http://metacore-ucdavis.appspot.com/services/protocols/Metabolomics%20Vol.%201%2C%20No.%201%2C%20January%202005%20%28%202005%29.pdf exists
success: true that http://metacore-ucdavis.appspot.com/services/protocols/Proteomics%202004%2C%204%2C%2078-83.pdf exists
success: true that http://metacore-ucdavis.appspot.com/services/protocols/SulfurDeprivation.pdf exists
success: true that http://metacore-ucdavis.appspot.com/techno1/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/techno1/compounds/ exists
success: true that http://metacore-ucdavis.appspot.com/techno2/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/techno3/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/setupx/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/projects/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/staff/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/Members exists
success: true that http://metacore-ucdavis.appspot.com/Members/admin/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/statistics exists
success: true that http://metacore-ucdavis.appspot.com/statistics/index_html/view exists
success: true that http://metacore-ucdavis.appspot.com/techno1/compounds/index_html/view exists

report...
successful: 45
failed: 0
total: 45

checked 45 urls in file Downloads/sitemap.xml


Wednesday, August 10, 2011

groovy - a quick way to copy a list of files to the local directory

don't we love these tasks? We get a list of files to look at and they are in a directory with thousands of other files and now we need to copy them one, by one, by one and there is no clear patter, which could ease the pain of doing so.

But like always there is a simple groovy way todo this in a quicker fashion.


def values = [
1333020,
1332872,
1332428,
1332280,
1331984,
1331836,
1331688,
1331540
]

values.each{def value ->
new File("${value}.xml") << new File("/Users/****/Documents/metadata/${value}.xml").text
}


this does simplify your life once in a while to copy a quick list of text files to a different folder.

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.

Sunday, July 10, 2011

Groovy HTTP Builder- fetching JSON data over post and supply parameters

Right now I'm playing around with the MtGox api to issue online transactions to buy and sell bitcoins. Yes I'm still obsessed with these and don't think this is going to change anytime soon, since It's starting to actually generate money.

But the big pain right now is that you have togo to so many different websites todo a simple transaction and I really want to have this all combined in one single tool.

So the api exspects from you to be queried over post arguments and the first thing which came to my mind was to use the fantastic HttpBuilder in groovy.

so let's define a simple method to simplify life a bit for us


private executeQuery(Map parameter, String path) {

def http = new HTTPBuilder("https://mtgox.com/")

def result = ""
http.post(body: parameter, path: path, requestContentType: URLENC) { resp, json ->

if (resp.statusLine.statusCode == 200) {
result = json
}
else {
result = false
}

}

return result


and a second method to actually call this


def getCurrentBalance() {

if (MtGoxAccessHandler.isConfigured()) {
def values = executeQuery([

name: MtGoxAccessHandler.getUserName(),
pass: MtGoxAccessHandler.getPassword()],
"/code/getFunds.php")

return [usd: values.usds, coins: values.btcs]
}
else {
return false
}
}



The class MtGoxAccessHandler is just a little helper, which stores the username and password and allows me to simplify the code a bit and easy testing.

This post is also related to the google code project DeepBitView

Wednesday, June 22, 2011

groovy - parsing reading builder content from an external file

we all know that groovy builders are great and fun and can make your life so much easier.

For example if you want to create a simple xml file in your groovy script you can just do the following


def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.records() {
car(name:'HSV Maloo', make:'Holden', year:2006) {
country('Australia')
record(type:'speed', 'Production Pickup Truck with speed of 271kph')
}
car(name:'P50', make:'Peel', year:1962) {
country('Isle of Man')
record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg in weight')
}
car(name:'Royale', make:'Bugatti', year:1931) {
country('France')
record(type:'price', 'Most Valuable Car at $15 million')
}
}



looks easy and is easy. But now you come to the point where you think. Mhm it would be nice, if I could just read the builder code from an external file and generate the xml on the fly using this. For example you have to generate an xml configuration file and rather simplify this process using groovy and this has to be done more than once...

After a couple of hours googleing the best solution I came up with, was to provide your own binding to the builder, which simplified things quite a bit.



class XmlBinding extends Binding{
def builder


Object getVariable(String name) {
return { Object... args -> builder.invokeMethod(name,args) }
}
}


let's assume we like to read the following builder code, defined in a file named 'test.groovy'



config{
bin{
allow(minimumClassSize:1)
}
}



which all you need to do, now you could for example have a main method somewhere containing this:


def groovyScriptContent = new File("test.groovy").text
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
def binding = new XmlBinding()
binding.builder = xml

def dslScript = new GroovyShell().parse(groovyScriptContent)
dslScript.binding = binding
dslScript.run()

println writer.toString()


and as a result it generates the following xml document


<config>
<bin>
<allow minimumClassSize='1' />
</bin>
</config>

Thursday, December 16, 2010

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 :)

Thursday, March 11, 2010

i just love groovy for tasks like this...

sometimes you have these annoying little tasks on your hands and I always forget the bash syntax and it’s been a while since I seriously played with python.

So I thought, hey let’s try groovysh.

task?

  • read wordlist
  • convert to lowercase
  • remove parts of words
solution

new File("en_US.dic").text.split("\n").each{ new File("result.txt").append "${it.split("/")[0].toLowerCase()}\n" }

ok after a bit more coding I actually wrote a groovy script

  • read file
  • read file with words we do not want in word list
  • convert all values to lowercase
  • remove duplicated values
  • save to output file
really nothing fancy, but get’s the job done and took like 3 minutes to write and won’t be used again.

Set<String> cache = new HashSet<String>()
Set<String> result = new HashSet<String>()

new File(“whitelist.txt”).text.split(“\n”).each{ it.split("\t").eachWithIndex{

        String s, int index ->

                if(index > 0){
                        cache.add(s.toLowerCase())
                }
        }
}

new File(“blacklist.txt”).text.split(“\n”).each{
        if(cache.contains(it.toLowerCase()) == false){
                result.add(it.toLowerCase())
        }
}

File out = new File("wordlist.txt")

result.each{
        out.append it
        out.append "\n"
}


Wednesday, March 10, 2010

calculating exact molare masses using the cdk 1.3.1

I needed a simple way to calculate the exact mass for a couple of millions compounds and so decided to give it another try with the CDK.

After googleing a bit I found something what put me in the right direction and worked with the current version of the cdk, so it was rather simple

class ConvertInchi {

/**
* converts an inchi code to a molare mass
* @param inchi
* @return
*/
public static double convertInchiToMolareMass(String inchi) {

IMolecularFormula moleculeFormula = MolecularFormulaManipulator.getMolecularFormula(convertInchiToMolecularFormula(inchi),DefaultChemObjectBuilder.getInstance())

return MolecularFormulaManipulator.getTotalExactMass(moleculeFormula)

}

/**
*
* converts an inchi to a molecular formula
* @param
inchi
* @return
*/
public static String convertInchiToMolecularFormula(String inchi) {
return inchi.split("/")[1]

}
}

Monday, March 1, 2010

scala/groovy on rocks linux

well since there is not scala/groovy roll for rocks we need to install it the traditional way.

  • go into the directory /shared/apps on the frontend
  • if apps doesn't exist create it
  • copy your scala/groovy tgz there
  • gunzip and untar it
  • edit your extend-compute.xml as shown here
  • add a new file modification section like this


<file name="/etc/profile" mode="append">

GROOVY_HOME=/share/apps/groovy
SCALA_HOME=/share/apps/scala

export GROOVY_HOME
export SCALA_HOME

PATH=$GROOVY_HOME/bin:$PATH
PATH=$SCALA_HOME/bin:$PATH

export PATH

</file>


  • rebuild your dist as shown here
  • reinstall you nodes as shown here

Friday, February 26, 2010

backup! we got REG Expressions!

recently I got an interesting task handed
please extract all words out of a text...
ok simple enough, we know regular expression and we know word boundaries.

So we just do

\b\w+\b


and this simple expression applied to the following sentence
Glucose (Glc), a monosaccharide (or simple sugar) also...
gives us the following list
  • Glucose
  • Glc
  • a
  • monosaccharide
  • or simple
  • sugar
  • also
Sadly the sentence didn't stop at this and continued to include the following tricky statement...
...including as much as possible chemical names
Ok time to read on the reg expressions in groovy and java
Now let's discover a regular expression which helps us with this.

Ok let's try this again with a different sentence
...as glucose, only one of which (D-glucose) is biologically...
our first expression would miss
  • D-glucose
and return for this
  • D
  • glucose
so we need to modify it a bit to include the first seperation. So it becomes

\b(\w\-)*\w+\b

and the day is saved till we try a new sentence and try to discover compounds like

  1. 1,3-Diaminopropane
  2. N-(3S-hydroxydecanoyl)-L-serine
  3. 3,9-divinyl-2,4,8,10-tetraoxaspiro[5.5]undecane
  4. 2-(allyloxy)-1,3,5-trimethylbenzene
  5. 3-hydroxy-2-butanone
  6. 3,3'-Oxybis(1-propene)
  7. 1,1,1,2,2,3,3,4,4-nonafluoro-4-(1,1,2,2,3,3,4,4,4-nonafluorobutoxy)butane
  8. 2-(Formamido)-N1-(5-phospho-D-ribosyl)acetamidine
  9. 1,6,9,13-tetraoxadispiro[4.2.4.2]tetradecane
  10. 3-(N, N-Diethylamino)-1-propylamine
  11. D-Glucose
  12. (R)-3-Hydroxybutyric acid
Or to make it more realistic, find all the words in this completely pointless and scientific wrong text
 bunch of rumble to find 1,3-Diaminopropane in D-Glucose and 1,1,1,2,2,3,3,4,4-nonafluoro-4-(1,1,2,2,3,3,4,4,4-nonafluorobutoxy)butane.
 It's also nice to have 3,3'-Oxybis(1-propene) or (R)-3-Hydroxybutyric acid. Last bot not least I'm a huge fan or 3,9-divinyl-2,4,8,10-tetraoxaspiro[5.5]undecane.
 Also it's a great feeling if we can find (glucose) in brakets without finding statement like (help i'm surrounded by brackets).

So do you see a pattern here?
  • everything in () or [] or {} can be part of a chemical so we use ((\[.*\])|(\(.*\))) for this part 
  • everything separated by a ',' and followed by another character ending with a dash can be a chemical, so we use (\w+(,\w+)*\-) for this part
  • it ends all with a word \w+ or a ) (masked as \) )
so this expression would work for all these

(\([\w\+]+(,\w+)*\)-)?\b[(\w+(,\w+[\'])*\-)*((\[.*\])|(\(.*\))|(\{.*\}))*\w+]+(\b)( (acid)|(anhydride)|(\sbenzoate)|(\sketone)|(\sether)|(\sester)|(\scyanide))?


except
  1. 3-(N, N-Diethylamino)-1-propylamine
  2. glucose instead we get 'glucose)'
no solution for the 1 or 2 yet. Still trying to figure it out.

now the nicest thing is the groovy closure + match example to get all the content in a text.


def match = (text =~ pattern)


congrats now all you words are in the match variable! Text is just a string containing our text.

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...

Sunday, January 24, 2010

how to handle 400 Billion rows in postgress

well currently I try to optimize an denoising and replacement algorithm. This includes calculating ion traces over thousands files which have 20k peaks or 1 Million ions each.
To make this more challenging we don't do this once, we do it during every BinBase export. Since this is the base algorithm for the Zero replacement.

Short we do the same calculation over and over again, like to calculate the minimum intensity for 100 files between 15 and 20 seconds for the ion 87.

Short this shouts use a SQL database.

Now how much data do we have?

  • 40k files
  • each file has around 20k spectra
  • each spectra has up to 500 ion

which translates into

400 000 000 000 rows

Performance Issues and how to make Postgres handle this amount of data

The first attempt was to just store all these files into a single table using hibernate. Which caused an OutOfMemory exception, surprise surprise.

So the next attempt was to use a stateless session which worked quite well and up to 1 Billion rows we had a query speed of under 20ms. Quite nice for no tuning of the database. But once we hit a bit over 1 Billions rows the query speed got worse and worse. Shor this was not an acceptable solution.

So we tried to use partions with postgres and define one table for each ion, inheriting from a master table.


Table "public.iontrace"
Column | Type | Modifiers
------------+------------------+-----------
id | bigint | not null
intensity | double precision |
ion | integer |
spectra_id | bigint |
Indexes:
"iontrace_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fk4f93923dc3b62c9a" FOREIGN KEY (spectra_id) REFERENCES spectra(id)
Rules:
rule_index_iontrace_100 AS
ON INSERT TO iontrace
WHERE new.ion = 100 DO INSTEAD INSERT INTO iontrace_100 (id, intensity, ion, spectra_id)
VALUES (new.id, new.intensity, new.ion, new.spectra_id)
rule_index_iontrace_101 AS
ON INSERT TO iontrace
WHERE new.ion = 101 DO INSTEAD INSERT INTO iontrace_101 (id, intensity, ion, spectra_id)
VALUES (new.id, new.intensity, new.ion, new.spectra_id)
rule_index_iontrace_102 AS
ON INSERT TO iontrace
WHERE new.ion = 102 DO INSTEAD INSERT INTO iontrace_102 (id, intensity, ion, spectra_id)



which didn't work with hibernate. It kept complaining about


org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1


so we had to write our own batcher as was described here

a bit later we rewrote the example to actually work, since the field batch size is set to private.


/**
* hibernate partion batcher
*/
public class HibernatePartionBatcher extends BatchingBatcher {

public HibernatePartionBatcher(org.hibernate.jdbc.ConnectionManager connectionManager, org.hibernate.Interceptor interceptor) {
super(connectionManager, interceptor)
}


@Override
protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {

//use reflections to access the private field of the super class ugly but neccessaery
Field field = this.getClass().getSuperclass().getDeclaredField("batchSize")
field.setAccessible(true)

int value = field.getInt(this)

if (value != 0) {
try {
ps.executeBatch()
}
catch (RuntimeException re) {
throw re;
}
finally {
field.setInt(this, 0)
}
}
}
}

/**
* hibernate factory to intitialize the factory
*/
public class HibernatePartitionBatcherFactory extends BatchingBatcherFactory {

public HibernatePartitionBatcherFactory() {
}

public org.hibernate.jdbc.Batcher createBatcher(org.hibernate.jdbc.ConnectionManager connectionManager, org.hibernate.Interceptor interceptor) {
return new HibernatePartionBatcher(connectionManager, interceptor);
}
}



and to register this in our groovy script


def hibProps = [
"hibernate.jdbc.factory_class": HibernatePartitionBatcherFactory.class.getName()
]



A first test with just a single sample reveals that we are executing a sequential scan over all partions.


explain SELECT * from iontrace where ion = 105;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
Result (cost=0.00..1163.25 rows=3374 width=28)
-> Append (cost=0.00..1163.25 rows=3374 width=28)
-> Seq Scan on iontrace (cost=0.00..10.46 rows=7 width=28)
Filter: (ion = 105)
-> Index Scan using index_iontrace_20 on iontrace_20 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_21 on iontrace_21 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_22 on iontrace_22 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_23 on iontrace_23 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_24 on iontrace_24 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_25 on iontrace_25 iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)



to avoid this you have to change a parameter in postgresql.


SET constraint_exclusion = on;


and the new result shows that we only work on the correct partition now


explain SELECT * from iontrace where ion = 105;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
Result (cost=0.00..13.03 rows=14 width=28)
-> Append (cost=0.00..13.03 rows=14 width=28)
-> Seq Scan on iontrace (cost=0.00..10.46 rows=7 width=28)
Filter: (ion = 105)
-> Index Scan using index_iontrace_105 on iontrace_105 iontrace (cost=0.00..2.57 rows=7 width=28)
Index Cond: (ion = 105)



it still executes a sequential scan, but now it only does it on the correct partion with the stored data.

Now to reduce the likelihood for an index scan over the database we will define indexes on all the table (the script at the end of this post does this for you)

the new query plan is


explain SELECT * from iontrace where ion = 105;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
Result (cost=0.00..4.15 rows=14 width=28)
-> Append (cost=0.00..4.15 rows=14 width=28)
-> Index Scan using index_iontrace_ion on iontrace (cost=0.00..1.57 rows=7 width=28)
Index Cond: (ion = 105)
-> Index Scan using index_iontrace_105 on iontrace_105 iontrace (cost=0.00..2.57 rows=7 width=28)
Index Cond: (ion = 105)


The result is slightly different since we generate by now more data in the database. Sorry for that. But you can see that the query plan is much more efficient with the index.

Important is that you need an index for ion on every partition and on the main 'iontrace' table, if you don't have an index on the main table you will keep getting sequential scans.

The next snatch we encountered was the speed of the actual data insert. Since the check constraints seem to be rather slow and expensive.

First this is a hibernate insert on the main datatable:


LOG: duration: 8.961 ms statement: EXECUTE [PREPARE: insert into IonTrace (intensity, ion, spectra_id, id) values ($1, $2, $3, $4)]
LOG: duration: 8.951 ms statement: EXECUTE [PREPARE: insert into IonTrace (intensity, ion, spectra_id, id) values ($1, $2, $3, $4)]
LOG: duration: 8.966 ms statement: EXECUTE [PREPARE: insert into IonTrace (intensity, ion, spectra_id, id) values ($1, $2, $3, $4)]


Second this is plain old sql inserted into the main iontrace table:


LOG: duration: 6.608 ms statement: EXECUTE [PREPARE: insert into iontrace(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),1418.0,237,700013)]
LOG: duration: 6.610 ms statement: EXECUTE [PREPARE: insert into iontrace(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),1373.0,238,700013)]
LOG: duration: 6.605 ms statement: EXECUTE [PREPARE: insert into iontrace(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),1383.0,239,700013)]


Third this is plain old sql inserted in each partition:


LOG: duration: 0.055 ms statement: EXECUTE [PREPARE: insert into iontrace_475(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),27.0,475,680203)]
LOG: duration: 0.058 ms statement: EXECUTE [PREPARE: insert into iontrace_489(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),13.0,489,680203)]
LOG: duration: 0.051 ms statement: EXECUTE [PREPARE: insert into iontrace_496(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),13.0,496,680203)]
LOG: duration: 0.138 ms statement: EXECUTE [PREPARE: insert into Spectra (file_id, retentionTime, id) values ($1, $2, $3)]


From this we can see that it makes the most sense to use plain sql to insert the data into the related partitions and to avoid the checks during the insert phase.

For this we used the following approach


//build the ion trace
Statement statement = session.connection().createStatement()

for (int mass = 0; mass < mz.length; mass++) { if (mass >= beginMass && mass <= endMass) { if (intensity[mass] > 0) {
IonTrace trace = new IonTrace(ion: mz[mass], intensity: intensity[mass])
trace.spectra = spectra


statement.addBatch("insert into iontrace(id, intensity, ion, spectra_id) values (nextval('SEQ_TRACE'),${intensity[mass]},${(int)(mz[mass])},${spectra.id})")
}
}
}

statement.executeBatch()


which worked quite well. As a conclusion I removed the complete hibernate layer from this application, since we lost most of it's benefits by now.

To further optimize the insert speed we replace the Statements with PreparedStatements, which improves the speed of the insert by close to 50%.


LOG: duration: 0.035 ms statement: EXECUTE [PREPARE: insert into iontrace_127(id, intensity, ion, spectra_id) values (nextval('seq_trace'),$1,$2,$3)]
LOG: duration: 0.035 ms statement: EXECUTE [PREPARE: insert into iontrace_127(id, intensity, ion, spectra_id) values (nextval('seq_trace'),$1,$2,$3)]
LOG: duration: 0.035 ms statement: EXECUTE [PREPARE: insert into iontrace_127(id, intensity, ion, spectra_id) values (nextval('seq_trace'),$1,$2,$3)]



Storage

as you can imagine this amount of rows can take up quite some space. An initial estimate say it's roughly 20TB with the current table schema.

Which is 20 times more than the files occupy on the harddrive.

So what can you do to keep the storage space down
  • use the smallest possible data types possible
  • only index what is necessary to be index
  • remove columns which are not necessary, like we don't need a primary key on the ion trace table
  • estimate your possible amount of data stored in the database, like we won't store billions of spectra, so we can use integer instead of bigint
  • store intensities as integer and not as double. 

To estimate the required storage we used the following function, which roughly gives us storage capacity for 4 years of netcdf files.


netcdf-repository=# SELECT pg_size_pretty(pg_database_size('netcdf-repository')/(select count(*) from netcdf)* 40000) as "estimated database size";
estimated database size
-------------------------
16 TB
(1 row)


And a server for this would currently cost around 7000$


-END-

Wednesday, October 7, 2009

calculating the variance - groovy style

just had to calculate some variances in a flexible way and like always groovy comes to the rescue.


static double variance(def population) {
long n = 0
double mean = 0
double s = 0.0

population.each {double x ->
n++;
double delta = x - mean
mean += delta / n
s += delta * (x - mean)
}

(s / (n - 1))
}

Thursday, September 17, 2009

Strange XMLParser behaviour - Groovy 1.6.4

ell right now I'm stumbling over a small thing in groovy and don't understand why this is happening.

So this is my code:


new StreamingMarkupBuilder().bind({

sop(desc: "generated for quantification") {
transform(sizedown: 0, attributes: "height", combine: true) {
header{
param(value:"retention_index")
param(value:"quantmass")
param(value:"id")
param(value:"spectra")
}
}
}


simple enough.

And that's the code to test it


def parser = new XmlParser().parse(source.getStream())

assertTrue parser.@desc != null

assertTrue parser.transform != null

assertTrue Integer.parseInt(parser.transform.@sizedown[0]) == 0
assertTrue parser.transform.@attributes[0] == "height"
assertTrue parser.transform.@combine[0] == "true"

assertTrue parser.transform.header.param[0].@value == "retention_index"
assertTrue parser.transform.header.param[1].@value == "quantmass"
assertTrue parser.transform.header.param[2].@value == "id"
assertTrue parser.transform.header.param[3].@value == "spectra"

assertTrue parser.transform.header.param.size() == 4


also pretty straight forward.

Now why is this part different...


transform(sizedown: 0, attributes: "height", combine: true)

assertTrue Integer.parseInt(parser.transform.@sizedown[0]) == 0
assertTrue parser.transform.@attributes[0] == "height"
assertTrue parser.transform.@combine[0] == "true"


and my attributes are returned as an array list compared to


header{
param(value:"retention_index")
param(value:"quantmass")
param(value:"id")
param(value:"spectra")
}

assertTrue parser.transform.header.param[0].@value == "retention_index"
assertTrue parser.transform.header.param[1].@value == "quantmass"
assertTrue parser.transform.header.param[2].@value == "id"
assertTrue parser.transform.header.param[3].@value == "spectra"


where the attributes are returned as simple string. I has to be something obvious, but right now I'm not getting it.

Wednesday, September 16, 2009

XMLMarkupBuilder in groovy.

Since a while i wanted to find a reason to play with the xml markup builders in groovy, since I think they are an awesome idea.
So I gave it a shot


def document = new StreamingMarkupBuilder().bind({

config {
parameter {
param(name: "java.naming.provider.url", value: "127.0.0.1", public:true)
param(name: "java.naming.factory.initial", value: "org.jnp.interfaces.NamingContextFactory", public:true)
param(name: "java.naming.factory.url.pkgs", value: "org.jboss.naming:org.jnp.interfaces", public:true)
param(name: "edu.ucdavis.genomics.metabolomics.util.status.ReportFactory", value: "edu.ucdavis.genomics.metabolomics.binbase.cluster.status.EJBReportFactory")
param(name: "edu.ucdavis.genomics.metabolomics.util.thread.locking.LockableFactory", value: "edu.ucdavis.genomics.metabolomics.binbase.cluster.locking.EJBLockingFactory")

}
}
})

println document


and the result is


<config><parameter><param name='java.naming.provider.url' value='127.0.0.1' public='true'/><param name='java.naming.factory.initial' value='org.jnp.interfaces.NamingContextFactory'/><param name='java.naming.factory.url.pkgs' value='org.jboss.naming:org.jnp.interfaces'/><param name='edu.ucdavis.genomics.metabolomics.util.status.ReportFactory' value='edu.ucdavis.genomics.metabolomics.binbase.cluster.status.EJBReportFactory'/><param name='edu.ucdavis.genomics.metabolomics.util.thread.locking.LockableFactory' value='edu.ucdavis.genomics.metabolomics.binbase.cluster.locking.EJBLockingFactory'/></parameter></config>


Neat! This was very simple and the validation of the code happens at runtime. The only uggly part is that idea shows this part in red brackets


public:true


since public is a keyword of java/groovy. But it does compile...

Guess I have to change my api a bit to avoid this uggly keyword or at least make it optional.

Tuesday, September 15, 2009

Groovy 1.6.4 + IntelliJ8 + Groovy Plugin - nullpointer

For soem reason I keep get nullpointer exception with IntelliJ, which have nothing todo with my code.
They only happen if I execute the project from intelliJ out.

example for this would be:


src/example/dsl/quant.dsl
Caught: java.lang.NullPointerException
java.lang.NullPointerException
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.QuantificatorDSL.run(QuantificatorDSL.groovy:45)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.QuantificatorDSL$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.QuantificatorDSL.main(QuantificatorDSL.groovy:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1296)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:719)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:262)
at groovy.lang.GroovyShell.run(GroovyShell.java:218)
at groovy.lang.GroovyShell.run(GroovyShell.java:147)
at groovy.ui.GroovyMain.processOnce(GroovyMain.java:493)
at groovy.ui.GroovyMain.run(GroovyMain.java:308)
at groovy.ui.GroovyMain.process(GroovyMain.java:294)
at groovy.ui.GroovyMain.processArgs(GroovyMain.java:111)
at groovy.ui.GroovyMain.main(GroovyMain.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:108)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)


Now this exception does not occur, if I make a complete rebuild.

For some reason it is not able to initialize a class if it defined in another source file. More about this is written here