Wednesday, December 9, 2009

Object instantiation with JSTL and JSP

Have you ever wanted to instantiate an object and use them in your JSTL expressions? In my case, I wanted to surround an object with a wrapper class that provided extra functionality to the objected being wrapped, and be able to access the wrapped object from within JSTL expressions.

To do this I used a combination of JSP and JSTL. I used JSP tags to instantiate the wrapper class and JSTL to assign the object being wrapped as follows:


                <jsp:useBean id="strainWrapper" class="au.edu.apf.phenomebank.strain.StrainHelperWrapper" />                    
                <c:set target="${strainWrapper}" property="strain" value="${mouse.strain}" />
                
                ${strainWrapper.genotypingAssays}




public class StrainHelperWrapper {

    private Strain strain; 
    
    public StrainHelperWrapper() {}
    
    public StrainHelperWrapper(Strain strain) {
        this.strain = strain;
    }
    
    public Strain getStrain() {
        return strain;
    }
    public void setStrain(Strain strain) {
        this.strain = strain;
    }

    
    
    /**
     * Returns a list of Amplifluor requirements for the Genotyping Assays
     * @return
     */
    public String getAmplifluors() {
        StringBuilder sb = new StringBuilder();
        
        if (strain != null) {
            List<Genotype> genotyping = strain.getGenotypes();
            if (genotyping != null) {
                int counter = 0;
                for (Genotype genotype: genotyping) {
                    if (counter > 0)
                        sb.append(", ");
                    String yesNo = genotype.getAmplifluor() ? "Yes" : "No";
                    sb.append(yesNo);
                    counter++;
                }                
            }
        }
        return sb.toString();
        
        
    }

Sunday, December 6, 2009

Hibernate: Deleting element from a Collection doesn't get deleted in database

In Hibernate we are able to remove an element from a java.util.Collection by invoking Iterator.remove() on the Iterator object. When the collection is saved, Hibernate will automatically delete the element that was removed from the database. Below is an example of removing the element from the Collection:

            for (Iterator<StoragePosition> it = mouse.getPositions().iterator(); it.hasNext() ;) {
                StoragePosition sp = it.next();
                
                if (! Util.isValid(sp.getPosition())) {        
                    it.remove();
                }
            }

The "cascade" attribute configured in the Hibernate configuration file (hbm.xml) plays an important role in how it will behave when handling elements that have been removed from a Collection. In order for this to work the cascade attribute should have the following value: all-delete-orphan. A cascade value of save-update will not work. Below is a segment of the configuration file:


    <set name="positions" inverse="true" table="mouse_storage_positions" cascade="all-delete-orphan" lazy="true" batch-size="8">
             <key column="mouse_id" />                      
             <one-to-many class="au.edu.apf.phenomebank.inventory.StoragePosition" />     
         </set>    

Thursday, November 26, 2009

Tomcat PermGenSpace on several redeployments

The PermGenSpace bug has been an issue for a long time. Several people have diagnosed this bug in ClassLoader of the JVM and there are several posts which can easily be searched on google.

This issue typically occurs after several reployments to Tomcat. However there are ways to relieve or extend the number of redeployments you can do without having to do full Tomcat restart everytime. You can add the following options to your JAVA_OPTS environment variable in the catalina.bat or catalina.sh file in the bin folder of tomcat:

-Xmx768m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m

Windows 7 as a Java, Tomcat, Postgres developer

I've been given a new computer at work on the (ANU campus) just yesterday and it came preinstalled with the new Windows 7. I've been told I am probably the first person at the college to be using Windows 7 so I almost felt like a guinea pig and seeing if it has any compatibility issues especially for my development environment. But after spending some time on it, I can tell you it really wasn't that painful to make the transition.

Java 6

Since I was running a 64 bit machine I needed to download the Windows x64 option when loading from the sun webite:

Download Java 6

Eclipse

Since I was running the 64bit version of Java, I needed to download the 64bit version of eclipse for Windows. I had downloaded version 3.5.1

Eclipse Download page

The direct download for the 64 bit version on windows is here
Direct eclipse download 64bit Windows

The eclipse that was downloaded was not the Java EE bundle. So it was missing a lot of the functionality that I was used to such as HTML editors, JSP editors etc.... To download the plugins for that kind of support,
In Eclipse goto: Help - Install new software
and supply the following URL: http://download.eclipse.org/releases/galileo
Then select the "Web, XML and Java EE Development" package.
Now eclipse is ready to go.

Postgres

Initially I attempted to install the latest Postgres binary Version 8.4 for windows and it immediately came back with an installation error. I followed up on some forums and many others had encountered similar issues. I was told that people had better luck with version 8.3 which I downloaded from here:

Download postgres 8.3

In the default installation I still encountered some errors. In this case, it complained something about a 'Secondary Logon service'. To enable this service I did the following:

I went to the 'Services' windows doing the following: Start - Control Panel - System and Security - Administrative tools - Services


In the services window, search for the 'Secondary Logon service' and enable it.





 I also disabled User Access control (UAC) which seemed to cause problems for other people by following the steps outlined here

Once the above steps were completed I was able to continue with the normal installation procedure for Postgres 8.3.

Wednesday, November 18, 2009

JSTL test condition and trailing spaces

Took me a few minutes to track this one down, but it did catch me by surprise. The trailing spaces in the test conditions for JSTL tags do make a difference. For those that are interested I was using Tomcat 6.

I was getting the following errors in my stacktrace:


An error occurred at line: 40 in the jsp file: /WEB-INF/jsp/genotypingInventory.jsp
The method setTest(boolean) in the type IfTag is not applicable for the arguments (String)
37:                     <td class="right-col">${sp.box.box }</td>
38:                     <td class="right-col">${sp.position }</td>
39:                     <td class="right-col">
40:                             <c:if test="${not empty sp.mouse.strain} ">
41:
42:                             </c:if>
43:                     </td>      


The error was in the line:


<c:if test="${not empty sp.mouse.strain} ">


The problem is the extra space after the end curly bracket. After changing it to the following it worked fine:



<c:if test="${not empty sp.mouse.strain}">

Monday, November 16, 2009

Migration from Tomcat 5.5 to Tomcat 6.0.20

The migration from Tomcat 5.5 to Tomcat 6.0.20 was relatively painless except for the 3 following issues I encountered.


Issue #1: Unable to read TLD issue

Turns out that I was including a copy of jsp-api-2.0.jar in the build of my WEB-INF/lib directory, and Tomcat already had it in its lib folder. Deleting the jar from my WEB-INF/lib directory fixed the problem.

Reference:
http://forums.sun.com/thread.jspa?threadID=580206&am

Issue #2: Missing mail.jar
Add the mail.jar to lib folder of Tomcat 6





Issue #3: Different Enum behaviour with JSTL


Don't use enum values directly in JSTL. Instead provide a getter method to retrieve the value such as getValue() and invoke ${enum.value} rather than just ${enum}. In Tomcat 5.5 the behaviour was if you had ${enum} internally it would return enum.toString(). Now with Tomcat 6 and as per section 1.18.2 of the 2.1 JSP-EL spec, the behaviour now returns enum.name(). So if you want the return the toString() value create and invoke getValue().

Reference:
https://issues.apache.org/bugzilla/show_bug.cgi?id=46920

Wednesday, November 11, 2009

Sharing your Vodafone Mobile Connect internet with Linux

This article will describe the details on how to setup your linux machine to share its internet connection with users connected to a router through your Vodafone Mobile Connection internet connection.

Vodafone Mobile Connect Card driver for Linux is a tool that allows you to establish a connection to the Internet using 3G cards. Details on installing the driver for your Vodafone Mobile connect onto your linux machine click here.

To find your driver click here.

I did have issues with the default DNS server configuration provided by the drivers. If you experience something similar try the following IP addresses for your DNS configuration:

  • 208.67.220.220 
  • 208.67.222.222
Once you have got your internet connection working on the linux machine, set the default gateway to point to your internet connection that will probably have an alias of ppp0. In Fedora linux I would type the following:

route add default gw 0.0.0.0 ppp0
If you type 'route' at the command-line you should see something similar to this:

[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.64.64.64     *               255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
link-local      *               255.255.0.0     U     0      0        0 eth0
default         *               0.0.0.0         U     0      0        0 ppp0

You also want to give your linux machine a static IP so that users on the router can point to your machine as their gateway. This is the following configuration I used:

IP: 192.168.1.105
subnet mask: 255.255.255.0
gateway: 0.0.0.0
 Now on the client computer that's connected to the router, configure their network settings to have the following:

Gateway: 192.168.1.105
subnet mask: 255.255.255.0
Now you can have multiple computers all sharing the same internet connection going through the Vodafone Mobile Connect card.

Cheers,
Phil