Sunday, January 24, 2010

Restricting Access to Web application through Tomcat configuration

I have an external client that needed access to an internal web server for testing purposes. In the past, we solved this problem by restricting access on based on World IPs. That is, most of our clients had static IPs that remained unchanged regardless of which network they belonged to. With this in mind, we were able to allow access through the firewall based on IP.

In this case, our client had dynamic IPs. That is, their IP was always changing and the above solution wouldn't work. In other workplaces, this problem was typically solved using VPN, however the network admins didn't support this at the time.

I did not want to build a custom authentication mechanism at the application level just for testing purposes. That would mean changing the behaviour of my application just for testing! GAH!

Instead I applied a login-based security mechanism at the Tomcat level as follows.

In my web.xml file of the web application I added the following:
  <!-- Define a Security Constraint on this Application -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Block access to entire application</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <!-- NOTE:  This role is not present in the default users file -->
       <role-name>zebrafish</role-name>
    </auth-constraint>
  </security-constraint>

  <!-- Define the Login Configuration for this Application -->
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Zebrafish</realm-name>
  </login-config>

  <!-- Security roles referenced by this web application -->
  <security-role>
    <description>
      The role that is required to log in to the Zebrafish Application
    </description>
    <role-name>zebrafish</role-name>
  </security-role>

And in the /conf/tomcat-users.xml I added a new user and role as follows:

<user username="philip" password="philip" roles="zebrafish"/>  

Upon application redeployment and server restart, any access to the web application requires authentication via a popup dialog and once we go to production, it is very easy to disable.

Wednesday, January 20, 2010

webAppRootKey and multiple spring web applications on a single Tomcat instance

When deploying multiple spring applications onto a single tomcat instance we need to provide a unique webAppRootKey in the web.xml file.
    A good explanation can be found here:
    http://groups.google.com/group/riotfamily/browse_thread/thread/9a0edf69575d3ab6?pli=1

Tuesday, January 19, 2010

NullPointerException org.apache.commons.digester.Digester.getXMLReader(Digester.java:1058)

Maven is great build tool making it easy to fetch all the library dependencies for a particular build. But what happens when you've got an application that uses wide variety of libraries of which can be dependent on the same library but different versions. Indeed we can have conflicts and the title of this blog is what I got as a result of some transitive dependency of Apache CXF.

The root cause of the above error is because an older version of the SAXParserFactory was being used. The class loaders for commons digester was using the SAXParserFactory from another JAR file in the classpath rather than the one provided in the JDK 1.6.
Others have had similar problems as in this forum


It turns out I had ther xercesImpl-2.6.2 in my classpath. This I needed to remove and boilied down to adding exclusions in my POM file as follows:

    <!-- 
    ========================
    Apache CXF Web services
    ========================
    -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-bundle-minimal</artifactId>
        <version>2.2.4</version>
        
        <exclusions>
            <exclusion>
                <groupId>xalan</groupId>                
                <artifactId>xalan</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xalan</groupId>                
                <artifactId>serializer</artifactId>
            </exclusion>

            <exclusion>
                <groupId>xom</groupId>
                <artifactId>xom</artifactId>
            </exclusion>        

            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xerces</artifactId>
            </exclusion>

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

            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xmlParserAPIs</artifactId>
            </exclusion>
            
            <exclusion>
                <groupId>org.apache.santuario</groupId>
                <artifactId>xmlsec</artifactId>
            </exclusion>            
            
        </exclusions>        
        
    </dependency>  

Sunday, January 17, 2010

Spring bind "java.lang.IllegalArgumentException: No enum const class"

With the migration to Tomcat 6 you must becareful with the "status.value" when comparing values.

Expressions like the following will not work:

<c:if test="${status.value == session }">selected="true"</c:if>

Instead it should be the following:

<c:if test="${criteria.session.value == session.value }">selected="true"</c:if>

Here's a more complete example:

    <b>Session: </b>
    <spring:bind path="criteria.session">
        <select name="${status.expression }" >
        <c:forEach items="${sessions}" var="session" >
            <option value='${session.value }' 
                <c:if test="${criteria.session.value == session.value }">selected="true"</c:if>            
            >${session.name}</option>
        </c:forEach>
        </select>
    </spring:bind>

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