Friday, December 11, 2009

maven assembly plugin

sometimes you run into the issue that you want to generate jars for a simple project. For example when you want to create an executable jar for each method with a main class.

What do you do?

you call the maven assembly plugin to the rescue and define several executions

<plugin>
<artifactId>maven-assembly-plugin</artifactId>

<executions>
<execution>
<id>MatchLibrary</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>

<archive>
<manifest>
<mainClass>edu.ucdavis.genomics.metabolomics.binbase.binbase.external.tools.api.library.impl.application.ApplicationServerLibraryMatchingImplementation</mainClass>
<packageName>edu.ucdavis.genomics.metabolomics.binbase.binbase.external.tools.api.library.impl.application</packageName>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
<manifestFile>src/main/resources/manifest/ApplicationServerLibraryMatchingImplementation.MF</manifestFile>
</archive>
<descriptors>
<descriptor>src/main/descriptor/jar.xml</descriptor>
</descriptors>
<finalName>MatchLibrary</finalName>
<manifestFile>src/main/resources/manifest/ApplicationServerLibraryMatchingImplementation.MF</manifestFile>
</configuration>
</execution>

<execution>
<id>RegisterLibrary</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>

<archive>
<manifest>
<mainClass>edu.ucdavis.genomics.metabolomics.binbase.binbase.external.tools.api.library.impl.RegisterLibraryImpl</mainClass>
<packageName>edu.ucdavis.genomics.metabolomics.binbase.binbase.external.tools.api.library.impl</packageName>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
<manifestFile>src/main/resources/manifest/RegisterLibrary.MF</manifestFile>
</archive>
<descriptors>
<descriptor>src/main/descriptor/jar.xml</descriptor>
</descriptors>
<finalName>RegisterLibrary</finalName>
<manifestFile>src/main/resources/manifest/RegisterLibrary.MF</manifestFile>
</configuration>
</execution>
</executions>
</plugin>

and this generates two executable jars for us.

The used assembly descriptor is

<assembly>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>

Tuesday, December 8, 2009

jboss maven plugin

since I have issues with jboss jar and maven since I can remember I started to develop a small mojo to deal with this for me.

All it basically does is to parse the local jboss installation and depoys the files in the local repository.

Simple and efficient.

It can be found here

Wednesday, November 18, 2009

SQL - small mistakes, big impact

the last couple of days I was fighting with a database which became slower and slower and slower and now needed close to 24h to execute a rather simple query...

After working for hours on different parameters and tuning the database, including setting up a spare server to see if a dump and restore fixes the issues I got the time down to 5 minutes.

Sounds good?

well not really since I needed an execution in the range of a couple of seconds. So I actually looked at the sql statement which caused issues and found a gigantic error in it...

the statement:


select * from BIN where bin_id not in ( SELECT bin_id from SPECTRA where sample_id = 424105 AND SPECTRA.bin_id = BIN.bin_id)


and the correct statement would be:


select * from BIN a where a.bin_id not in ( SELECT bin_id from SPECTRA where sample_id = 424105 and bin_id is not null) ORDER BY retention_index ASC


the problem?


SPECTRA.bin_id = BIN.bin_id


this little part is totally wrong in the whole statement and causes a seq scan over a table with 70 Million entries against a table with 6000 entries. It does nothing for the queries and I guess it was left over from a copy/paste accident 6 years ago when I wrote this script originally.

let's compare some numbers:

explain before:

Seq Scan on bin (cost=0.00..459513.42 rows=3044 width=1290)
SubPlan
Filter: (NOT (subplan))
-> Bitmap Heap Scan on spectra (cost=75.20..75.42 rows=2 width=8)
Recheck Cond: ((sample_id = 424105::double precision) AND (bin_id = ($0)::double precision))
-> BitmapAnd (cost=75.20..75.20 rows=2 width=0)
-> Bitmap Index Scan on spectra_sample_id (cost=0.00..18.99 rows=5696 width=0)
-> Bitmap Index Scan on spectra_binid (cost=0.00..56.18 rows=17658 width=0)
Index Cond: (sample_id = 424105::double precision)
Index Cond: (bin_id = ($0)::double precision)

explain after:

Sort (cost=1765.47..1766.23 rows=3044 width=1290)
Sort Key: retention_index
-> Seq Scan on bin a (cost=647.21..1747.86 rows=3044 width=1290)
Filter: (NOT (hashed subplan))
SubPlan
-> Index Scan using spectra_sample_id on spectra (cost=0.00..646.42 rows=3138 width=8)
Index Cond: (sample_id = 424105::double precision)
Filter: (bin_id IS NOT NULL)


in real world number this translates to 24 hours before statement compared to 4 seconds after statement...
...

Tuesday, November 17, 2009

maven2 - choose dependcies based on platform

today I run into an old friend. I was compiling my stuff happily under oxs and building eclipse plugins with maven2 and the psteclipse plugin, which I by now more or less rewrote and adapted to my project to perform as good as possible. Anyway, basically I encountered the issue that eclipse ships with different dependencies under osx/win32 and linux.

So promptly it fails to compile under linux...

solution for this problem?

maven2 profiles, your best friend for cross platform development. They actually allow you define dependencies based on the current platform.

Example for out case would be:


<profiles>
<profile>
<id>dev-windows</id>

<dependencies>
</dependencies>

<activation>
<activeByDefault>true</activeByDefault>
<os>
<family>windows</family>
</os>
</activation>
</profile>
<profile>
<id>dev-mac</id>
<dependencies>
<dependency>
<groupId>psteclipse</groupId>
<artifactId>org.eclipse.swt.cocoa.macosx</artifactId>
<version>3.5.1</version>
<scope>provided</scope>
</dependency>

</dependencies>

<activation>
<activeByDefault>false</activeByDefault>
<os>
<family>mac</family>
</os>
</activation>
</profile>
<profile>
<id>dev-linux</id>

<dependencies>
<dependency>
<groupId>psteclipse</groupId>
<artifactId>org.eclipse.swt.gtk.linux.x86</artifactId>
<version>3.5.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

<activation>
<activeByDefault>false</activeByDefault>
<os>
<name>linux</name>
</os>
</activation>
</profile>
</profiles>


And sets a different library for osx and linux. Sweet!

Wednesday, November 11, 2009

hibernate - configure caching

since the hibernate tools for eclipse need to have the caching enabled, something I'm not the biggest fan off for several reason.

Well


<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>


so this makes the binbase configuration run in the eclipse tools.

Monday, November 2, 2009

Log4J and eclipse

sometimes you want to use the log4j system instead of the internal eclipse provide logging framework.

The use of this is rather simple and straight forwarded. You only need to register an ILogListener at the platform object and implement it.

An example would be:


package edu.ucdavis.genomics.metabolomics.binbase.gui.swt.logging;

import org.apache.log4j.Logger;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;

/**
* used to forward eclipse logging to log4j
*
* @author wohlgemuth
*
*/
public class Log4JListener implements ILogListener {

static Logger LOGGER = Logger.getLogger(Log4JListener.class);

public void logging(IStatus status, String plugin) {
if (status.getSeverity() == IStatus.WARNING) {
if (status.getException() == null) {
LOGGER.warn(status.getMessage() + "(" + status.getCode() + ")");
} else {
LOGGER.warn(status.getMessage() + "(" + status.getCode() + ")",
status.getException());
}
} else if (status.getSeverity() == IStatus.ERROR) {
if (status.getException() == null) {
LOGGER
.error(status.getMessage() + "(" + status.getCode()
+ ")");
} else {
LOGGER.error(
status.getMessage() + "(" + status.getCode() + ")",
status.getException());
}

} else if (status.getSeverity() == IStatus.INFO) {
if (status.getException() == null) {
LOGGER.info(status.getMessage() + "(" + status.getCode() + ")");
} else {
LOGGER.info(status.getMessage() + "(" + status.getCode() + ")",
status.getException());
}

}
}

}



and to register it


this.listener = new Log4JListener();
Platform.addLogListener(this.listener);

Tuesday, October 27, 2009

Eclipse SWT 3.5 and an annoying change...

after I moved a part of my software over to eclipse 3.5 to take advantage of bug fixes and new features I noticed that some of my dialogs don't work anymore.

For example the login dialog has 2 fiels. A username and a password. These fields are defiend like this:


password = new Text(content, SWT.BORDER | SWT.PASSWORD);
user = new Text(content, SWT.BORDER);

user.addKeyListener(this);
password.addKeyListener(this);


and in the key listener I validate the inputs. But with version 3.5 key listener won't work on password fields anymore and I didn't find any documentation about it. So instead you need to use a modify listener now


password.addModifyListener(new ModifyListener() {

public void modifyText(ModifyEvent e) {
}
});

Friday, October 23, 2009

duplicating a disk under OSX

since my laptop has no cd drive anymore I have no the need of cloning all my cd's with my mac pro.

How to do this?

1. Insert CD/DVD source
2. Fire up a Terminal, you can then determine the device that is you CD/DVD drive using the following command:
$ drutil status
 Vendor   Product           Rev
 MATSHITA DVD-R   UJ-835E   GAND

           Type: DVD-ROM              Name: /dev/disk1
      Cur Write:    8x DVD          Sessions: 1
      Max Write:    8x DVD            Tracks: 1
   Overwritable:   00:00:00         blocks:        0 /   0.00MB /   0.00MiB
     Space Free:   00:00:00         blocks:        0 /   0.00MB /   0.00MiB
     Space Used:  364:08:27         blocks:  1638627 /   3.36GB /   3.13GiB
    Writability:
      Book Type: DVD-ROM
3. Umount the disk with the following command:
$ diskutil unmountDisk /dev/disk1
Disk /dev/disk1 unmounted
4. Create the ISO file with the dd utility (may take some time):
$ dd if=/dev/disk1 of=file.iso bs=2048
5. Test the ISO image by mounting the new file (or open with Finder):
$ hdid file.iso





taken from here

Friday, October 16, 2009

OSX - upgraded my macbook pro to an SSD and the differences

After long considerations I updated my macbook pro to a SSD, from corsair. Since the price seemed to be not to outragios.

Now the tests are clear:

SSD

Drive Type CORSAIR CMFSSD-128GBG2D


Disk Test    173.68   
    Sequential    132.15   
        Uncached Write    143.67    88.21 MB/sec [4K blocks]
        Uncached Write    101.53    57.44 MB/sec [256K blocks]
        Uncached Read    94.19    27.56 MB/sec [4K blocks]
        Uncached Read    351.79    176.81 MB/sec [256K blocks]
    Random    253.29   
        Uncached Write    121.43    12.85 MB/sec [4K blocks]
        Uncached Write    196.26    62.83 MB/sec [256K blocks]
        Uncached Read    1503.47    10.65 MB/sec [4K blocks]
        Uncached Read    556.60    103.28 MB/sec [256K blocks]


Drive Type ST9500325AS

 Disk Test    43.26  
    Sequential    80.53  
        Uncached Write    78.89    48.44 MB/sec [4K blocks]
        Uncached Write    68.76    38.91 MB/sec [256K blocks]
        Uncached Read    77.68    22.73 MB/sec [4K blocks]
        Uncached Read    104.42    52.48 MB/sec [256K blocks]
    Random    29.57  
        Uncached Write    10.43    1.10 MB/sec [4K blocks]
        Uncached Write    73.40    23.50 MB/sec [256K blocks]
        Uncached Read    64.02    0.45 MB/sec [4K blocks]
        Uncached Read    98.74    18.32 MB/sec [256K blocks]

I think these result's speak for them self!

my trouble with snowleopard and java5

well snow leopard messed up my java installation.

Luckily there is an easy fix to it!

taken from here


cd /tmp/
curl -o java.1.5.0-leopard.tar.gz http://www.cs.washington.edu/homes/isdal/snow_leopard_workaround/java.1.5.0-leopard.tar.gz
tar -xvzf java.1.5.0-leopard.tar.gz
sudo mv 1.5.0 /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0-leopard
cd /System/Library/Frameworks/JavaVM.framework/Versions/
sudo rm 1.5.0
sudo ln -s 1.5.0-leopard 1.5.0
open "/Applications/Utilities/Java Preferences.app"


and move java5 to the top.

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

Thursday, September 10, 2009

groovy 1.5.6 and delegates

while trying to write a DSL I discovered an annoying bug in groovy 1.5.6, I guess. Basically if I define a delegate for a closure it has to be in the same file as the closure. If i define it in another file I always get a nullpointer exception...


example:



class MyDelegate {
def test() {
println "tada"
}
}

static ExpandoMetaClass createEMC(Class clazz, Closure cl) {
ExpandoMetaClass emc = new ExpandoMetaClass(clazz, false)

cl(emc)

emc.initialize()
return emc
}

Script dslScript = new GroovyShell().parse("test{\ntest()\n}")

dslScript.metaClass = createEMC(dslScript.class, {
ExpandoMetaClass emc ->

emc.test = {

Closure closure ->
closure.delegate = new MyDelegate()
closure.resolveStrategy = Closure.DELEGATE_FIRST

try {
closure()
}
catch (Exception e) {
e.printStackTrace()
}
}
})
dslScript.run()



this works fine. Now if I move the class 'MyDelegate' to it's own file I end up with the following exception.


java.lang.NullPointerException
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.getDelegateMethod(ClosureMetaClass.java:207)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:280)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:78)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrent0(ScriptBytecodeAdapter.java:112)
at Script1$_run_closure1.doCall(Script1.groovy:2)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:248)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:78)
at Script1$_run_closure1.doCall(Script1.groovy)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:248)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:778)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:758)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeClosure(ScriptBytecodeAdapter.java:605)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.Tester$_run_closure1_closure2.doCall(Tester.groovy:38)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:248)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at groovy.lang.Closure.call(Closure.java:292)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod.invoke(ClosureMetaMethod.java:72)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:946)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:78)
at Script1.run(Script1.groovy:1)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:946)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:778)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:758)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethod0(ScriptBytecodeAdapter.java:198)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.Tester.run(Tester.groovy:45)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:778)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:758)
at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:401)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1105)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:749)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at edu.ucdavis.genomics.metabolomics.binbase.quantificator.dsl.Tester.main(Tester.groovy)
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:585)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1105)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:749)
at groovy.lang.GroovyShell.runMainOrTestOrRunnable(GroovyShell.java:244)
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:585)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:101)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)


time to give groovy 1.6.4 a try and maybe migrate my project over to it.

Wednesday, September 9, 2009

DSL - love or hate?

recently I started to work more with DSL's (domain specific language) since I wanted to go away from doing everything in XML.

The approach of XML is great, but I'm not a big fan of the overhead with it.

So the first approach was to create a DSL for the BinBase system, precisely to provide the user with a really simple way of calculating an experiment.

It should look something like this:


/**
* our quantification dsl
*/
quantify {

//define the name of the setup
name "quantification for ${new Date()}"

//define the samples for the calculations
sample "sample 1"
sample "sample 2"
sample "sample 3"
sample "sample 4"
sample "sample 5"
sample "sample 6"
sample "sample 7"
sample "sample 8"
sample "sample 9"
sample "sample 10"

//defines the bins in the table
bin 321, 22.0
bin 322
bin 323
bin 324
bin 325, 22.0

//report definition
report {

sizeDown 50

format "xls"

replace true
}
}


And the result should calculate the data, send them to the cluster and generates a quantification report. If this all works out the way we want it. We will than adapt it to schedule BinBase experiment's this way.

My current fazit is that I love the idea of DSL's, but hate the implementations of it.

jboss - binding to all registered network cards

The JBoss Application server binds only to the local interface '127.0.0.1' since the version 4.0

Since this is not desired in a production system you can override this feature with the '-b' command.

An example to start jboss in the all configuration and bound to all registered interfaces would be


sh run.sh -b 0.0.0.0 -c all

Thursday, September 3, 2009

creating a project with maven2

it is kinda pathetic I'm using maven since several years now and just can't remember this one command.


mvn archetype:create -DgroupId=myGroup -DartifactId=myArtifact


so I write it down here to make it easier for me to lookup.

Wednesday, September 2, 2009

osx - set disk as startup disk via terminal

to set a disk as startup disk is quite simple just execute:


sudo bless -mount /Volumes/"name of your startup disk" -setBoot

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.

Monday, August 31, 2009

maven2 - define the context root of an webapp

Basically I have an application (ear) based on several jars and a war which I want to easily access with a context root of my choice.

Solution:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<jboss>
<version>4</version>
</jboss>
<bundleFileName>
binbase-quality-control.ear
</bundleFileName>

<modules>
<webModule>
<groupId>edu.ucdavis.genomics.metabolomics.binbase.quality
</groupId>
<artifactId>quality-war</artifactId>
<contextRoot>/quality-war</contextRoot>
</webModule>
</modules>

</configuration>
</plugin>

Sunday, August 9, 2009

Method "ApplyConfiguration" with signature "" on interface "org.gnome.SettingsDaemon.XRANDR" doesn't exist

today I wanted todo nothing else than the change the primaery output of my laptop to the 40" display attached over DVI to watch movies on it.

Sadly since ubuntu 8.something I kept getting the following error message


Method "ApplyConfiguration" with signature "" on interface "org.gnome.SettingsDaemon.XRANDR" doesn't exist


So I upgraded to the newest ubuntu version. Didn't make it much better. So I could had given up here and start shouting all kinds off stuff about linux or trying to make it work.

So here is the solution:

the gui is basically broken and you need to execute the commands to adjust everything your self. Using 'xandr'

for example to turn off a monitor:


xandr --output LVDS --off


or to change the resolution


xandr --output DVI-0 --mode 1360x768 --pos 0x0


2 minutes later I had my configuration up and running.

Tuesday, August 4, 2009

synchornized groovy

Today I discovered the question:

I want to have a websites which fires calculations to a database server, but the controller should only execute one calculation at a time

how do you do this?

The first approach was to try to queue the ajax calls, which obviously won't work if two people run calculations at the same time.

So plan b was to use synchronized groovy code.



/**
* does the actual calculation
*/
def calculate_ajax = {

assert params.database != null, "you need to provide 'database' in the params object"
assert params.date != null, "you need to provide 'date' in the params object"
assert params.machine != null, "you need to provide 'machine' in the params object"
assert params.pattern != null, "you need to provide 'pattern' in the params object"
assert params.position != null, "you need to provide 'position' in the params object"

//needs to be synchronized so we don't kill the database server with this task
synchronized (LOCK) {
println new Date()
BinBaseQualityConnector.getQualityService().calculateSingleStandard(params.pattern, params.database, new Date(Long.parseLong(params.date)), params.machine, BinBaseQualityConnector.getKey())
render("<div class=\"after_complete\" style=\"width:${100 / BinBaseQualityConnector.getPattern(params).size()}%\"></div>")

}
}

static final def LOCK = "lock"


and a possible ajax call for this looks like this


<script type="text/javascript">
YAHOO.util.Event.onDOMReady(
function() {
new Ajax.Updater('${i}_${y}_${z}', '/quality-war/processing/calculate_ajax', {
method: 'get', frequency: 3,parameters:'date=${date.getTime()}&database=${database}&machine=${machine}&pattern=${pattern}&position=${z}'
});
});
</script>

Tuesday, July 28, 2009

updating more than one div with grails and ajax

sometimes it happens that you have to update several div's on one webpage, when you click on a form or a button.

Now you can either reload the complete page, which can take a while with a lot of data or just queue remote functions in a java script function like this


function addStandard() {

if (YAHOO.example.container.addstandard) {
YAHOO.example.container.addstandard.hide();
}

//get our element values
var conc = document.getElementsByName('qs_concentration')[0].value;
var pattern = document.getElementsByName('qs_pattern')[0].value;

//calls the remote functions
${remoteFunction(
controller: 'management',
action: 'addStandard_ajax',
params: '\'conc=\' + escape(conc) + \'&pattern=\' + escape(pattern)',
update: 'registered_standards')}

${remoteFunction(
controller: 'messenger',
action: 'showMessage',
params: '\'message=you should recalculate the database now!\'',
update: 'messenger')}
}

javascripts and maps

since java script contains no Maps, well use an object instead with dynamic properties.


var test = new Object();
test['tada'] = 'yada';

alert(test['yada']);
alert(test.yada);

distinct or group by, what's more expensive

today I was asking my self about the best approach for a performance critical application.

Distinct or group by '*'



select name from table group by name



or



select distinct name from table



after all they both return the exact same result.

Some explain statements later it turned out that the group by clause is 18% faster than the distinct statement.

Monday, July 27, 2009

sometimes it's simpler to use plain ajax...

today I was struggling for a bit with generating the update part of a remote function on the fly and after a couple of minutes. I started thinking, do I have to really use this tag? Why don't I use just plain Ajax, since grails will generate the same code anyway.

Solution:


<div class="center">
<img name="${bin.getId()}" src="${createLinkTo(dir: 'images', file: 'remove.gif')}" alt="zoom" onclick="new Ajax.Updater

('bin-container-${db}', '/quality-war/management/remove_bin_ajax', {asynchronous:true,evalScripts:true,parameters


:'bin=${bin.getId()}&database=${db}'});"/>
</div>


this also shows how to submit several parameters at once in plain ajax style.

lesson of the day...

and god said you shall no duplicate div ids,
cause if you do,
you shall be send to the hell of css,
constant torture and misfortune will await you,

so do not duplicate your id's!

problem:

updating a you tab with some dynamic generated content, which generate the same div id over and over again...

Annoying maven bug

well tonight I got an interesting error message from my bamboo build server


[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error installing artifact's metadata: Error installing metadata: Error updating group repository metadata

input contained no data
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch


without actually doing any changes at the pom.xml. The problem turned out that the repository was corrupt.

So all I had todo was to delete my project from the local build repository.

Thursday, July 23, 2009

Grails - using several arguments with a remote function

in grails it's a bit tricky to use a remote function and pass more than one parameter, since it does not follow the map approach like the usual approach

After a bit of asking Dr Google I finally found an approach which worked


var conc = document.getElementsByName('qs_concentration')[0].value;
var pattern = document.getElementsByName('qs_pattern')[0].value;

${remoteFunction(
controller: 'management',
action: 'addStandard_ajax',
params: '\'conc=\' + escape(conc) + \'&pattern=\' + escape(pattern)',
update: 'registered_standards')}


now I just wish there would be an easier approach

grails remote function on image or checkbox

Today I was in the situation that I wanted to call a remote function on an image to emulate a button, to delete an object with a specific id.

It's simple enough,



<img name="${standard.getPosition()}" src="${createLinkTo(dir: 'images', file: 'remove.gif')}" alt="zoom" onclick="${remoteFunction(
controller: 'management',
action: 'removeStandard_ajax',
params: '\'standard=\' + + escape(this.name)',
update: 'registered_standards')}"/>


To make live easy we just save the id in the name field of the image, but you can also save it somewhere else, depending on your requirements.

Now another thing you can do is todo the same thing for checkfields.


<input type="checkbox" id="cacheSetting" name="cacheSetting" onchange="${remoteFunction(
controller: 'management',
action: 'updateCache_ajax',
params: '\'cacheSetting=\' + escape(this.checked)',
update: 'general_config')}"/>


If you want to preserve the check state you can do this with this


<input type="checkbox" id="cacheSetting" name="cacheSetting" <%if(cacheSetting) println "checked"%> onchange="${remoteFunction(
controller: 'management',
action: 'updateCache_ajax',
params: '\'cacheSetting=\' + escape(this.checked)',
update: 'general_config')}"/>


and an example controller function could look like this



def updateCache_ajax = {
assert params.cacheSetting != null, "you need to provide \"cacheSetting\" in the params object"
BinBaseQualityConnector.getQualityConfigService().setCaching(Boolean.parseBoolean(params.cacheSetting))

//define our model
def model = new HashMap()

//build the model
model.cacheSetting = BinBaseQualityConnector.getQualityConfigService().isCaching()

render(template: "general", model: model)
}

Monday, July 20, 2009

scala in grails

I know it's evil and I know you don't want todo this, but what the heck. This plugin allows you to compile and use scala code in grails.

I don't know why I would want to use scala right now in this, but I'm sure I find out a reason or two :)

Thursday, July 16, 2009

YUI and Prototype - updating an element

Well currently I'm working a lot with YUI and specially tabs. So one of the first things I wanted todo is to select a tab and this selections should do two things
  • show the content of the tab, happens by default
  • update a div on the page somewhere with some content related to the tab content
so how do you do this?

Quite simple.



<script type="text/javascript">
var myTabs = new YAHOO.widget.TabView('demo');
var tab0 = myTabs.getTab(0);

function handleClick(e,tab) {
${"div_to_update"}.update("I just clicked on my tab!");
}

tab0.addListener('click', handleClick,tab0);
</script>



and as you can see we use the 'update' function from the prototype library.

Wednesday, July 15, 2009

Grails - ajax driven select and saving the selection

A couple of days ago I discovered the need of ajax populated forms to improve the navigation of the current website I'm working on.

And some nice person wrote a great tutorial about this here, but there was one thing missing. I wanted to render some elements on the same page and keep the selection stored in the text field.

The default approach is the following grails tag:


<g:select id="machine" name="machine" value = "${machine}"/>


but since this field is populated by an ajax function, the value can never be set,since the population happens after the page is loaed, so what can we do?

We enhance our little bit of java script and define the selection in there


//update the machine tag with the received values
function updateMachine(e) {
// The response comes back as a bunch-o-JSON
var machines = eval("(" + e.responseText + ")"); // evaluate JSON


if (machines) {
var rselect = document.getElementById('machine');

// Clear all previous options
var l = rselect.length;

while (l > 0) {
l--;
rselect.remove(l) ;
}

// Rebuild the select
for (var i = 0; i < machine =" machines[i];" opt =" document.createElement('option');" text =" machine;" machine = <%=machine%>'){
opt.selected = machine;
}
//just add another field and work with the default selection
else{
opt.value = machine;
}
try {
rselect.add(opt, null); // standards compliant; doesn't work in IE
}
catch(ex) {
rselect.add(opt); // IE only
}
}
}
}

//initilaize the variables on page load
var zselect = document.getElementById('database') ;
var zopt = zselect.options[zselect.selectedIndex]
${remoteFunction(controller: 'query', action: 'listmachines_ajax', params: '\'database=\' + zopt.value', onComplete: 'updateMachine(e)')}



we basically assume that our controller inject a variable with the name 'machine' on submitting the form. A controller closure could look like this:


def showTimeLine_ajax = {

assert params.database != null, "you need to provide the database in the params object"
assert params.machine != null, "you need to provide the machine in the params object"

def model = new HashMap()

//build our model, implementation not shown because of copyright
//model = buildModel(params.database,params.machine)

model.database = params.database
model.machine = params.machine

return model
}



and our form is simple enough


<g:form name="select_database_machine_form" method="post">
<g:select id="database" name="database" from="${dbs}" value="${database}"

onchange="${remoteFunction(
controller:'query',
action:'listmachines_ajax',
params:'\'database=\' + escape(this.value)',
onComplete:'updateMachine(e)')}"/>
<g:select id="machine" name="machine"/>

<g:submitToRemote action="showTimeLine_ajax" update="graph_content" value="execute query"/>
</g:form>

Tuesday, July 14, 2009

Groovy and Grails - why assert is great

well as always when you work with grails, well you work with closures in the controller and want an easy way to check if the parameter you require actually exist.

Now there are different ways to check for this, the old and long java version:


if(params.get("myField") == null){
throw new RuntimeException("please provide the\"myField\" argument");
}


now the assert statement makes this a lot easier to read and saves code


assert params.myField != null. "please provide the \"myFiled\" argument"


now isn't this simpler?

Monday, July 13, 2009

SetupX - bug repository

so the first step of taking an existing project over is to setup a repository to track bugs and changes to make it easier to discover problems by the users.

The new setupx bug repository can now be found here

What's more expensive IN or BETWEEN statement

This morning I spend a couple of hours tuning and testing different SQL statements to find the fastest way to fetch some data for a real time application.

While doing this I discovered that the IN query cost slightly more than the BETWEEN query.
It's not a lot, but still something.

IN query:


explain select sample_name,class,date_of_import,date from samples where visible = 'TRUE' and sample_name like '%q%' and date in( '5/26/2009 12:00:00 AM', '6/11/2009 12:00:00 AM','5/26/2009 12:00:00 AM','2009-06-01 12:00:00 AM') order by 1 desc


result:

QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=8126.07..8126.42 rows=139 width=37)
Sort Key: sample_name
-> Seq Scan on samples (cost=0.00..8121.12 rows=139 width=37)
Filter: (((sample_name)::text ~~ '%q%'::text) AND ((visible)::text = 'TRUE'::text) AND (date = ANY ('{"2009-05-26 00:00:00","2009-06-11 00:00:00","2009-05-26 00:00:00","2009-06-01 00:00:00"}'::timestamp without time zone[])))

4 record(s) selected [Fetch MetaData: 0/ms] [Fetch Data: 0/ms]

[Executed: 7/13/09 1:11:46 PM PDT ] [Execution: 2/ms]





BETWEEN query:


explain select sample_name,class,date_of_import,date from samples where visible = 'TRUE' and sample_name like '%q%' and date between '5/26/2009 12:00:00 AM' and '6/11/2009 12:00:00 AM' order by 1 desc


Result:


QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=8123.15..8123.32 rows=67 width=37)
Sort Key: sample_name
-> Seq Scan on samples (cost=0.00..8121.12 rows=67 width=37)
Filter: (((sample_name)::text ~~ '%q%'::text) AND (date >= '2009-05-26 00:00:00'::timestamp without time zone) AND (date <= '2009-06-11 00:00:00'::timestamp without time zone) AND ((visible)::text = 'TRUE'::text))

4 record(s) selected [Fetch MetaData: 0/ms] [Fetch Data: 0/ms]

[Executed: 7/13/09 12:53:32 PM PDT ] [Execution: 2/ms]

Friday, July 10, 2009

OSX and SuperDuper - bug on raid systems

If you hapend to restore your superduper backup to a raid system you will encounter a small bug which prevents you from booting your nearly restored system.

For some reason super duper cannot choose the active device to boot from, if it's a software raid. And it result's in a hanging system at boot.

Fix

go into system preferences before you boot and set your raid as the boot device. This should make it work.

Tested on
  • raid 1 of 2 disks
  • raid 0 of 4 disks (450mb/s transfer rate)

Thursday, July 9, 2009

Restoring OSX, backups are great

well my mac pro was running happily since january 2008 on a raid 10 configuration without any major issues. Sure it forgot it's keyboard from time to time and once a week I have to recharge all batteries. But otherwise it was the most reliable pc I ever had.

The wonderful timemachine software also did it's best to keep my backups up to date. So I never worried about a thing.

Till 2 harddrives started to report read/write errors 2 weeks ago. So I ordered a couple of new harddrives (500Gb x 4, I need speed and not space on this thing, and they are supposed to be nearly as fast as velicio raptors) To replace them.
At the time I noticed that I need more speed and 200mb/s write speed is just not fast enough for my stuff. So I decided to replace all 4 old harddrives with the 4 new ones in a raid 0 configuration.

I like to live risky? Sure, but I got backup's and timemachine is a great piece of software to restore a system...

Ok the idea was nice, but it turned out that you have to boot from the original osx cd to get timemachine to restore the complete system.

So plan B was on the table, let's call superduper to the rescue and use timemachine only for archiving my data.

Basically superduper generates a complete image of my system on an external harddrive and if my system fails, I can boot this HDD, keep working, while my system restores in the background.

And it only cost 27$ and makes live so much easier for me.

My new backup plan?

  • hourly timemachine archives
  • weekly super duper images

OSX and the Keyboard Pain

well it turns out you can only use apple WIRED keyboards to execute boot flags.

You also have to press the button before and during the 'boing'. And you need to keep it pressed!

Now I was thinking you could use just a windows Keyboard. But no it won't work reliable.

Now if you happen to own a wireless bluetooth apple keyboard, like I do. Be prepared to order a second wired keyboard to be able to execute commands before the OS is up.


Conclusion:


lame...

Mac OSX Boot options

taken from here

Boot key combinations:

Everybody knows about some of these boot key combinations, but some of the more obscure combinations have been long forgotten (like how many of us have a Quadra AV and use a TV as a monitor!) – Check these out, you may need one of them someday!

  • C : Forces most Macs to boot from the CD-Rom drive instead of the internal hard drive. Only works with Apple ROM drives and with bootable CD discs.
  • D : Forces the first internal hard drive to be the startup disk.
  • N : Netboot (New World ROM machines only) – Looks for BOOTP or TFTP Server on the network to boot from.
  • R : Forces PowerBooks to reset their screen to default size (helpful if you’ve been hooked up to an external montior or projector!)
  • T : Target Disk Mode (FireWire) – Puts machines with built-in FireWire into target Disk mode so a system attached with a FireWire cable will have that device show up as a hard drive on their system. Very useful for PowerBooks!
  • Mouse Button Held Down : Ejects any mounted removable media.
  • Shift : Disables all extensions (Mac OS 7-9), or disables Login items when using Mac OS X 10.1.3 or later. Also works when booting Classic mode up just like you were using the OS natively.
  • Option : When using an Open Firmware "New World ROM" capable system, the System Picker will appear and query all mounted devices for bootable systems, returning a list of drives & what OS they have on them. On "Old World" systems the machine will simply boot into it’s default OS without any Finder windows open.
  • Space bar : Brings up Apple’s Extension Manager (or Casady & Greene’s Conflict Catcher, if installed) up at startup to allow you to modify your extension set.
  • Command-V : Boots Mac OS X into "Verbose Mode", reporting every console message generated during startup. Really shows what’s going on behind the scenes with your machine on startup!
  • Command-S : Boots Mac OS X into "Single User Mode" – helpful to fix problems with Mac OS X, if necessary.
  • Command-Option : Rebuilds the Desktop (Mac OS 7-9).
  • Command-Option-P-R : Erases PRAM if held down immediately after startup tone. Your machine will chime when it’s erased the PRAM, most people will hold this combination for a total of 3 chimes to really flush the PRAM out.
  • Command-Option-N-V : Erases NVRAM (Non-Volatile RAM). Used with later Power Macintosh systems mostly.
  • Command-Option-O-F : Boots the machine into Open Firmware (New World ROM systems only).
  • Command-Option-Shift-Delete : Forces your Mac to startup from its internal CD-ROM drive or an external hard drive. Very helpful if you have a 3rd party CD-ROM drive that is not an Apple ROM device.
  • Command-Option-Shift-Delete-#(where #= a SCSI DEVICE ID) : Boot from a specific SCSI device, if you have your 3rd party CD-ROM drive set to SCSI ID 3, you would press "3" as the # in the combination.

And, the obscure ones :>) Older computers only, on some.

  • Command-Option-I : Forces the Mac to read the disc as an ISO-9000 formatted disk
  • Command : Boots with Virtual Memory turned off.
  • Command-Option-T-V : Forces Quadra AV machines to use TV as a monitor.
  • Command-Option-X-O : Forces the Mac Classic to boot from ROM.
  • Command-Option-A-V : Forces an AV monitor to be recognized correctly.

Hacking SetupX - working on the sql tables instead of hibernate

Currently one of my jobs is to get data out of the setupX system, since the developer left us and nobody has a clue how it actually works.

So far the basic understanding is that the system has one major table and all queries are executed by building sub queries in it.

Advantage of the technique:

it's extremely flexible,
Disadvantage?

It's ridiculous slow and a nightmare to figure out, since you got so many possible sub graphs.

Don't we love reverse engineering an existing software?

So this is just a small collection of statements to get data out.

get list of available questions and attributes


select question from formobject group by question;


get the list of registered species


select value from formobject where question = 'species' group by value;



The final idea is to make a snapshot of the database every night and transform it into a real database structure. Like having several tables and so.

Ajax and Grails and YUI

currently I'm trying to work more with ajax and grails.

So the first serious project is our quality control webfrontend which needs fancy stuff like

  • progress bars
  • multiple layers, cause they are hip...
and so.

So far one issue was to display a webpage in a layer on top of another webpage and the current soultion is:

controller:


class CompoundController {


/**
* shows the binbase compound
*/
def show_ajax = {
log.info("calling url...")
def id = params.id
def database = params.database

def server = System.getProperty("application.server")
def link = "http://${server}:8080/binbase-compound/bin/show/${id}?db=${database}"
//build our url
log.info("generated url: ${link}");
URL url = new URL(link)
InputStream stream = url.openStream()
Scanner scanner = new Scanner(stream)

//store the output, since this url can take a while to load, if it's not in the server cache
StringBuffer buffer = new StringBuffer()
while(scanner.hasNextLine()){
buffer.append(scanner.nextLine())
}

log.info("render result");

render "<iframe src="$%7Blink%7D" width="\"100%\"" height="\"100%\""></iframe>"
}
}

view:



<g:remotelink onloading="load();" oncomplete="done();" onsuccess="showFiles();" update="window_content" controller="compound" method="show_ajax" params="[database:database,id:id]">199651</g:remoteLink>



our div where we display the result


<div id="window">
<div class="hd"><div class="tl"></div><span></span><div class="tr"></div></div>
<div class="bd"><div id="window_content"></div></div>
</div>



and the related java script, yes I said it I'm using some javascript. Mostly the YUI library.



YAHOO.namespace("example.container");

function load() {

if (!YAHOO.example.container.wait) {

// Initialize the temporary Panel to display while waiting for external content to load

YAHOO.example.container.wait =
new YAHOO.widget.Panel("progress",
{
fixedcenter: true,
close: false,
draggable: false,
zindex:4,
modal: true,
visible: false
}
);

YAHOO.example.container.wait.setHeader("
please wait, this process can take up to 5 minutes
");
YAHOO.example.container.wait.render(document.body);

}


YAHOO.example.container.wait.show();
}

function done() {
YAHOO.example.container.wait.hide();

}

function showFiles() {

if (!YAHOO.example.container.files) {

// Initialize the temporary Panel to display while waiting for external content to load

YAHOO.example.container.files =
new YAHOO.widget.Panel("window",
{
fixedcenter: true,
close: true,
draggable: false,
zindex:5,
modal: false,
visible: false
}
);

//YAHOO.example.container.files.setHeader("Files for day...");
//YAHOO.example.container.files.setBody("<div id=\"showFiles\"></div>
");
YAHOO.example.container.files.render(document.body);

}


YAHOO.example.container.files.show();
}



and than there is some css,


#window.yui-panel .bd {
overflow: hidden;
padding: 0px;
border: 1px solid #aeaeae;
background-color: #FFF;
width:1024px;
height:600px;
}

#window.yui-panel .ft {
font-size: 75%;
color: #666;
padding: 0px;
overflow: hidden;
border: 1px solid #aeaeae;
border-top: none;
background-color: #dfdfdf;
}

#window.yui-panel .hd span {
vertical-align: middle;
line-height: 22px;
font-weight: bold;
}

#window.yui-panel .hd .tl {
width: 7px;
height: 22px;
top: 0;
left: 0px;
position: absolute;
}

#window.yui-panel .hd .tr {
width: 7px;
height: 22px;
top: 0;
right: 0px;
position: absolute;
}
#progress.yui-panel .bd {
overflow: hidden;
padding: 0px;
margin: 5px;
background-color: #FFF;
}

#progress.yui-panel .ft {
font-size: 75%;
color: #666;
padding: 0px;
overflow: hidden;

border: 1px solid #aeaeae;
border-top: none;
background-color: #dfdfdf;
}

/* Provide skin for custom elements */
#progress.yui-panel .hd span {
vertical-align: middle;
line-height: 22px;
font-weight: bold;
padding-left: 60px;
padding-right: 60px;
padding-top: 30px;
padding-bottom: 30px;
border: 1px solid #aeaeae;
background-color: #dfdfdf;
width: 120px;
height: 60px;
}

#progress.yui-panel .hd .tl {
width: 7px;
height: 22px;
top: 0;
left: 0px;
position: absolute;
}

#progress.yui-panel .hd .tr {
width: 7px;
height: 22px;
top: 0;
right: 0px;
position: absolute;



I'm still not a fan of css/js, but sometimes you gotta use what's available.

MockingSpring - Testing ServletFiltes

mocking spring,

well it's hot in davis and I have no AC, so what's better than to run into the nice and cold office and playing with some junit tests.

Basically how to junit test servlet filters. Like always somebody smart wrote some great tools for me to use.

An example of a simple servlet filter which forwads all access to a cutom report factory


package edu.ucdavis.genomics.metabolomics.binbase.filter;

import edu.ucdavis.genomics.metabolomics.util.status.Report;
import edu.ucdavis.genomics.metabolomics.util.status.ReportFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

import org.apache.log4j.Logger;

/**
* forwards all requests to the reporter which deals with it
*


* User: wohlgemuth
* Date: Jun 28, 2009
* Time: 3:33:00 PM
*/
public class IPLogger implements Filter {

/**
* forwards everything to the server
*/
private Report report;

/**
* logging nstances
*/
private Logger logger = Logger.getLogger(getClass().getName());

/**
* initialize the connection to the report method
*
* @param filterConfig
* @throws ServletException
*/
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("initialize filter");

//access the factory we need for the reporter
String factory = filterConfig.getInitParameter("factory");

if (factory == null) {
logger.info("no factory provided, so we use the default factory");

report = ReportFactory.newInstance().create(IPLogger.class.getSimpleName());
} else {
logger.info("using factory: " + factory);
report = ReportFactory.newInstance(factory).create(IPLogger.class.getSimpleName());
}
}

/**
* does the actual filtering
*
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String host = servletRequest.getRemoteHost();
String address = servletRequest.getRemoteAddr();
int port = servletRequest.getRemotePort();

String uri = "unknown";
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest req = (HttpServletRequest) servletRequest;

uri = req.getRequestURI();
}

//send it out so that we can deal with these event in a different class or so
report.report(new IPRequest(host, uri, address, port), FilterReports.FITLER_URI_ACCESS, FilterReports.FILTER_REQUEST);
}

public void destroy() {
}
}



and the junit test to test it, without a web server or so.


public class IPLoggerTest {

private IPLogger filter;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private MockFilterChain chain;

@Before
public void setUp() throws Exception {
filter = new IPLogger();
MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("factory", TestFactory.class.getName());
filter.init(config);
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
chain = new MockFilterChain();
}

@After
public void tearDown() throws Exception {
}

@Test
public void testDoFilter() throws IOException, ServletException {
request.setRequestURI("http://127.0.0.1/test.html");
filter.doFilter(request, response, chain);


}
}



and our little factory which does the acutal testing of the received object


public class TestFactory extends ReportFactory{


private Logger logger = Logger.getLogger(getClass());
/**
* checks if all the result's fit the exspectations
*
* @param properties
* @param s
* @return
*/
public Report create(Properties properties, String s) {
return new Report() {
public void report(String s, Serializable serializable, ReportEvent reportEvent, ReportType reportType, String s1, Date date, Exception e) {
logger.info("received: " + serializable);
assertTrue(reportEvent.equals(FilterReports.FITLER_URI_ACCESS));
assertTrue(reportType.equals(FilterReports.FILTER_REQUEST));

assertTrue(serializable instanceof IPRequest);
IPRequest request = (IPRequest) serializable;

assertTrue(request.getHost().equals("localhost"));
assertTrue(request.getUri().equals("http://127.0.0.1/test.html"));
assertTrue(request.getAddress().equals("127.0.0.1"));
assertTrue(request.getPort() == 80);
}

public String getOwner() {

return IPLogger.class.getSimpleName();
}
};
}
}

Grails and some annoying CSS in the Body Part

the last 72h I spend with debugging some css, because my webpage did not show in the way I wanted it to show.

So long story short, for some reason grails defines several body elements in the main.css file

body {
background: #cccccc;
color: #333;
font: 11px verdana, arial, helvetica, sans-serif;

width:100%;
height:100%;

}


.body {
float: left;
margin: 0 15px 10px 15px;
}

and the 'float:left' in the second body tag wrecked havoc with my application...

...great 3 days wasted on lay outing...

Creating a minimum and a maximum Date for a Calendar

If there is one thing I hate it's to work with dates. Not that it's hard or so. Just if you want to work with the java core classes it's sometimes a hassle.

For example I needed the minimum and maximum date for a day. After a lot of googleling I came up with a simple? solution.


Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();

c1.set(Calendar.AM_PM,Calendar.AM);
c1.set(Calendar.HOUR, c1.getActualMinimum(Calendar.HOUR));
c1.set(Calendar.MINUTE, c1.getActualMinimum(Calendar.MINUTE));
c1.set(Calendar.SECOND, c1.getActualMinimum(Calendar.SECOND));
c1.set(Calendar.MILLISECOND, c1.getActualMinimum(Calendar.MILLISECOND));

c2.set(Calendar.AM_PM,Calendar.PM);
c2.set(Calendar.HOUR, c2.getActualMaximum(Calendar.HOUR));
c2.set(Calendar.MINUTE, c2.getActualMaximum(Calendar.MINUTE));
c2.set(Calendar.SECOND, c2.getActualMaximum(Calendar.SECOND));
c2.set(Calendar.MILLISECOND, c2.getActualMaximum(Calendar.MILLISECOND));

Date first = c1.getTime();
Date last = c2.getTime();


Result:

Tue Jul 07 00:00:00 PDT 2009
Tue Jul 07 23:59:59 PDT 2009

The important part is here:


c1.set(Calendar.AM_PM,Calendar.AM);


if you don't specify AM/PM you end up with:

Tue Jul 07 12:00:00 PDT 2009

which is a bit annoying...

Installing SetupX under ubuntu

a first try to write a connector to getch all kinds of informations, using a hibernate layer.

how to:
  • install your plain old Ubuntu server box
  • install java 5: apt-get install sun-java5-jdk
  • install subversion: apt-get install subversion
  • install unzip: apt-get install unzip
  • install ant: download ant 1.6.5, unzip it and add it to the path
  • install jboss: download jboss-4.2.3.GA, unzip it in your directoy of choice, let's use opt
  • get setupX:
    svn checkout -r421 http://setupx.googlecode.com/svn/trunk/ /opt/setupx
  • install mysql: apt-get install mysql-server
  • start the mysql server: /etc/init.d/mysql start
let's configure setupX:
  • lims/setup/setup.properties - general configuration
  • lims/setup/resources/system/config.properties - configure where jboss sits
  • lims/setup/resources/system/system.properties - configure email settings and jboss again. Also specify your data directories
let's start our first install
  • go into /opt/jboss/seupx/lims
  • execute 'sh firstinstall.sh'
at this point we run into several issues, since we want to install setupx in '/opt/setupx' and not '/usr/share/setupx'.


[java] Util_____________: DEBUG: Using org.xml.sax.parser : org.apache.xerces.parsers.SAXParser
[java] org.setupx.repository.SettingsUnavailableException: java.io.FileNotFoundException: /usr/share/setupx/lims/conf/system/system.properties (No such file or directory)

This is directly related to a bug in the class "org.setupx.repository.Settings" and can be fixed with a simple change in this file to reflect our directory.

This is a nice example why it's considered to be bad practice to hard code file paths.


private static File file = new File("/opt/setupx/lims/conf/system/system.properties");

Since we already created the database with the 'firstinstall.sh' script we now just need to go into setupx/lims/setup and execute:

sh setup.sh

After the installation finished we could now access setupX under:

http://****:8080/xx1/

your setupx username is the set email address and your password the same.

review:

The installation took a lot of effort to get it working and is not yet perfect. I think the first thing which should be done is to write a graphical ant installer which modifies the files for you, to make this process a bit easier.
The main issue is really the absolute file path in the one java class.

Time cost: a bit over an hour and 30 minutes.

yet another blog

this blog is basically about my coding expirience, since people started to complain that I write to much about work and coding stuff in my other blog