Thursday, November 24, 2011

grails dynamic variable in createLink tag

The problem

I was trying to output the value of a variable inside the params attribute of the createLink grails tag, as follows:

<g:createLink action="listSnpsByIglId" params="[iglId:${sampleInstance.iglId}]" />

But that didn't work, with grails failing to evaluate the expression.

The solution

Instead the ${} should be wrapped around the whole expression as follows:

<g:createLink action="listSnpsByIglId" params="${[iglId:sampleInstance.iglId]}" />


References:

Wednesday, November 23, 2011

grails webflow view state events

Some actions can be performed in view state events, such as the following:

onRender {
                    "good"
                }
                onEntry {
                    "enterview"
                }
                onExit {
                    "exitview"
                }




Reference:
http://jira.grails.org/browse/GRAILS-3997

Tuesday, November 22, 2011

grails No such property: errors for command objects

The problem

When attempting to add a custom error message to a command object (non-domain object), I was trying to do this in the following way:

commandObject.errors.reject(null, "Some error msg")

However, when I go to execute the application, I received the following error:

No such property: errors
 It turns out, that the errors property of a command object is not always created.

The Solution

To have grails automatically create the errors object, the command objects must be annotated as "@Validateable"

and in the Config.groovy file add the following line:


grails.validateable.packages=['package.name.containing.command.object']



References: 

http://grails.1312388.n4.nabble.com/Possible-problem-with-Controller-Commands-and-errors-td2257062.html

http://www.grails.org/doc/1.3.7/guide/7.%20Validation.html#7.5%20Validation%20Non%20Domain%20and%20Command%20Object%20Classes

Monday, November 21, 2011

Grails subflows and LazyInitializationException no session bound

When passing objects between the parent flow and subflow I would use the 'conversation' scope. However, any domain objects loaded from the database during the subflow, would later have it's hibernate session dettached when reused in the parent flow.

To workaround this problem, I've reloaded the objects using their ID values in the parent flow to ensure they are associated with a hibernate session


Reference: http://jira.grails.org/browse/GRAILS-2518

Tuesday, September 13, 2011

mvn eclipse:eclipse Request to merge when 'filtering' is not identical

To setup the eclipse IDE environment for a Maven project, I would typically use the following command:

mvn eclipse:eclipse

However, I received the following error:


[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Request to merge when 'filtering' is not identical. Original=resource src/main/resources: output=target/classes, include=[atlassian-plugin.xml], exclude=[**/*.java], test=false, filtering=true, merging with=resource src/main/resources: output=target/classes, include=[], exclude=[atlassian-plugin.xml|**/*.java], test=false, filtering=false
[INFO] ------------------------------------------------------------------------

It turns out there's bug with the latest version of the eclipse plugin for maven.
The workaround was to use:

mvn org.apache.maven.plugins:maven-eclipse-plugin:2.6:eclipse
References:
http://forums.atlassian.com/thread.jspa?threadID=34952

Wednesday, September 7, 2011

IE likes to cache ajax responses

To disable caching of ajax responses in IE when using jQuery use the following:

$.ajax({
  url: "./chat.php?type=json",
  cache: false,
  dataType: "json",
  success: function(data) {
    // Go do this, go do that…
}});


References:

http://i.justrealized.com/2008/jquerys-getjson-failing-randomly-in-internet-explorer

Sunday, August 7, 2011

grails detecting dependency conflicts

To find out what kind of dependency conflicts you might have in your grails application execute the following:


grails dependency-report

A conflict resulted when I had different versions of the slf4j api

Refernece: http://www.grails.org/doc/latest/ref/Command%20Line/dependency-report.html

grails No thread-bound request found

When attempting to save a Domain object outside of a web request (which is running in a forked thread),
I received the following error message:

No thread-bound request found

This has something to do with Grails thinking that the Domain object is a Command object, which is not true.

To workaround this issue, I  had to make some changes in the controller where the binding of the form parameters takes place.

Previously, I would bind parameters as follows:

def save = { MiddlewareCase mCase ->

...
       
}

Now to avoid the error, I do the following:

def save = { 
        
        // IMPORTANT!!! Must bind this way or we get "No thread-bound request found"        
        MiddlewareCase mCase = new MiddlewareCase();
        bindData(mCase, params)

}

Sunday, July 31, 2011

sshj could not load keys

Needed to include bouncy castle in maven dependencies:



         
   
        org.bouncycastle
        bcprov-jdk16
        1.45
   
     
     
   
        net.schmizz
        sshj
        0.3.0
   

apache httpd forbidden selinux

I had an issue where a folder that I was trying to share on the web was not accessible resulting in FORBIDDEN.

It turns out that SELinux policies in Linux were preventing access. To enable it use the following:

/usr/sbin/setsebool -P httpd_disable_trans 1
/etc/init.d/httpd restart

Thursday, July 28, 2011

grails Second-level cache is not enabled for usage

Make sure the domain class doesn't have a mapping with cache usage parameter

    static mapping = {
        cache usage: 'read-only'
    }

Tuesday, June 28, 2011

Associated entities and org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

The problem:
I encountered this problem when attempting to save an entity that had a many-to-one association with an object that was being referenced multiple times in the same hibernate session. Hence the error below:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [au.edu.apf.phenomebank.db.mouse.MouseStrain#5044]
        at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:637)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
Below is the hibernate mapping configuration file that I was using:

    <class name="au.edu.apf.phenomebank.inventory.mouse.EmbryoOocyte" table="embryo_oocyte">
        <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
        
        <many-to-one name="mother" column="mother_id" cascade="save-update" not-null="true" />
        <many-to-one name="father" column="father_id" cascade="save-update" not-null="true" />
        <many-to-one name="strain" column="strain_id" cascade="save-update" not-null="true" />
        <property name="type" column="type" type="au.edu.apf.phenomebank.inventory.mouse.EnumEmbryoOocyteUserType"  not-null="true" />        
        <property name="breedingColour" column="breeding_colour" type="au.edu.apf.phenomebank.inventory.mouse.EnumBreedingColourUserType"  not-null="true" />
        
    </class>


 The Solution:

Since it was the associated objects that were causing the problem, the solution was to get Hibernate to merge them rather than attempt a save or update. This was achieved using the cascade propery as follows:

    <class name="au.edu.apf.phenomebank.inventory.mouse.EmbryoOocyte" table="embryo_oocyte">
        <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
        
        <many-to-one name="mother" column="mother_id" cascade="merge,save-update" not-null="true" />
        <many-to-one name="father" column="father_id" cascade="merge,save-update" not-null="true" />
        <many-to-one name="strain" column="strain_id" cascade="merge,save-update" not-null="true" />
        <property name="type" column="type" type="au.edu.apf.phenomebank.inventory.mouse.EnumEmbryoOocyteUserType"  not-null="true" />        
        <property name="breedingColour" column="breeding_colour" type="au.edu.apf.phenomebank.inventory.mouse.EnumBreedingColourUserType"  not-null="true" />
        
    </class>

Tuesday, April 26, 2011

Securing Tomcat with Apache Web Server mod_proxy

I wanted to enable SSL encryption to allow secure channels (https) to our tomcat server. There were 2 obvious ways to do this:

  1. Secure Tomcat directly
  2. Secure an Apache web server front-end that controls access to tomcat

Secure Tomcat directly

Securing tomcat directly is fairly straight-forward and is the easiest. But it does have some drawbacks. The major drawback for me was restricting access to other webapps running within the tomcat container. I had about 5 different webapps running, but I only wanted one to be publicly available. Now some will argue that you can restrict access by enforcing rules within the firewall, but I found that to be clunky. If you're interested in going this route, here is a link describing how to enable security for tomcat directly:
http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html

Secure an Apache web server front-end

 I prefer using Apache web server as the front-end for many reasons which has been discussed to death. I'll note some of the more important reasons:
  • Apache can server static content much faster
  • Apache can run as a load balancer in front of a cluster of tomcat instances
  • Apache can handle SSL encryption for a cluster of tomcat instances
  • Apache has several modules that can easily be plugged in
For more reasons have a look at this article: http://wiki.apache.org/tomcat/FAQ/Connectors

In this instance I will be using Apache's mod_proxy module to redirect traffic to the tomcat server and use Apache to provide the SSL encryption.


To get an idea of how it works see the diagram below:




When a user visits our website using the default web port of 80, Apache will redirect the traffic to Tomcat on port 8080. Similarly, when browser is communicating on port 443 (https), apache will enable encryption and redirect traffic to tomcat on port 8443.




In my setup of Apache, I have 2 main configuration files:
  1. httpd.conf
  2. ssl.conf
httpd.conf contains the configuration for handling traffic running on port 80:

Listen 80
ProxyRequests Off
ProxyPreserveHost on
<VirtualHost _default_:80>

    ServerName your_company_domain_name
    ProxyPass /app http://localhost:8080/app
    ProxyPassReverse /app http://localhost:8080/app 
  
    RewriteEngine On
    RewriteRule ^(.*)/login$ https://%{SERVER_NAME}$1/login [L,R]      
</VirtualHost>

The ProxyPass and ProxyPassReverse is responsible for the redirection.
The RewriteEngine and RewriteRule is responsible for redirecting  any requrests for the login page on port 80 to the secure channel running on port 443.

ssl.conf contains the configuration for handling traffic running on port 443:
Listen 443
<VirtualHost _default_:443>
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/pki/tls/certs/your_company_certificate.pem
SSLCertificateKeyFile /etc/pki/tls/certs/your_company_private_key.pem
ServerName your_company_domain_name
ProxyPass /app http://localhost:8443/app
ProxyPassReverse /app http://localhost:8443/app
</VirtualHost>

The SSLCertificateFile and SSLCertificateKeyFile are responsible for enabling encryption and requires the private key as well as the certificate file provided by your certificate authority.
Just as before, the lines ProxyPass and ProxyPassReverse are responsible for the redirection of traffic from port 443 to tomcat on port 8443.

server.xml contains the tomcat configuration details
Server.xml
    <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="true" redirectPort="443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"/>  

    <Connector port="8443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="true" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"        
        scheme="https"
        secure="false" 
        SSLEnabled="false" 
        proxyPort="443"
        proxyName="your_company_domain_name"
     />

Importing certficates into keystore

keytool -import -alias auscert -keystore -trustcacerts -file


Extracting existing certificates and private keys from a keystore to be used in Apache in PEM format

Originally, I had setup encryption witin Tomcat rather than apache. When I wanted to  migrate the control of security from Tomcat to Apache, I was faced with the issue that each Tomcat and Apache expected the certificates in different formats. After much researching I found a tool that was helpful in extracting the private key and the certificate out of the keystore into the PEM format expected by Apache. The opensource tool can be downloaded here: http://sourceforge.net/projects/portecle




To extract the private key from JKS keystore, use this:
http://www.softpedia.com/get/Security/Security-Related/KeyTool-IUI.shtml
Select Export -> Keystore's entry -> Private key
When identifying the Target files, remember to choose 'Private key and certificates' and 'PEM Encoded'
And the rest is self explantory


Remove passphrase from key

openssl rsa -in private_key.pem -out private_key_no_passphrase.pem


Here are some articles describing the problem in more detail:
http://techsk.blogspot.com/2009/01/exporting-tomcat-keys-to-apache-httpd.html
http://pnkumaresh.wordpress.com/2010/11/12/exporting-tomcat-ssl-keys-to-apache-httpd/

Verification

To verify that the certificates are properly installed use the following command:

keytool -printcert -sslserver servername

References:

http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
http://thejavamonkey.blogspot.com/2008/07/using-apache-httpd-server-as-secure.html
http://www.mooreds.com/wordpress/archives/223
http://www.customware.net/repository/display/GREENHOUSE/2009/06/13/Reverse+Proxy+with+Apache+mod_proxy
https://confluence.sakaiproject.org/display/DOC/Sakai+Admin+Guide+-+Advanced+Tomcat++%28and+Apache%29+Configuration