Thursday, January 28, 2010

No binding factory for namespace http://schemas.xmlsoap.org/wsdl/soap/ registered

The error is misleading:

The spring configuration file for CXF is missing some imports:

    <import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />

Wednesday, January 27, 2010

Gah! Ontology Lookup Service fails against it's own Schema!!

There is a Ontology lookup service available here:

http://www.ebi.ac.uk/ontology-lookup/

Having a central repository of Ontologies is great idea and I give them kudos for all the hard work.
They advertise a web service  for looking up various Ontologies using the SOAP protocol, which can be found here:

http://www.ebi.ac.uk/ontology-lookup/WSDLDocumentation.do#Link0332BDE0

However, as of today, they have issues with their web service.
I used the wsdl2java utility found with Apache CXF and that generated the stub code successfully.
Using the stub code I threw together some client code to invoke a service. An example is shown below:

package au.edu.apf.phenomebank.ontology;



import java.util.List;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.xml.xml_soap.Map;
import org.apache.xml.xml_soap.MapItem;

import uk.ac.ebi.ontology_lookup.ontologyquery.Query;
import uk.ac.ebi.ontology_lookup.ontologyquery.QueryService;

public class OLSTest {

    public static void main (String[] args) {
        
        
        QueryService ss = new QueryService();
        

        Query ontQuery = ss.getOntologyQuery();
        
        Client client = ClientProxy.getClient(ontQuery);
        client.getInInterceptors().add(new LoggingInInterceptor());
        //client.getInInterceptors().add(new FixInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor());
        
        
        
        System.out.println("Getting ontology names");
        Map ontologyNames =  ontQuery.getOntologyNames();
        
        
        List<MapItem> mapItems = ontologyNames.getItem();
        for (MapItem mapItem : mapItems) {
            Object mapValue = mapItem.getValue();
            System.out.println("mapValue="+mapValue);
        }
    }
    
}

The errors started to happen when I invoked a service call on the stub API:
ontQuery.getOntologyNames();

The following errors were dumped in Eclipse:
DefaultValidationEventHandler: [ERROR]: unexpected element (uri:"", local:"item"). Expected elements are <{http://xml.apache.org/xml-soap}item> 
     Location: line 1
28/01/2010 5:09:52 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
WARNING: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"", local:"item"). Expected elements are <{http://xml.apache.org/xml-soap}item> 

Bascially, it's complaning that the <item>> element is missing the namespace of
http://xml.apache.org/xml-soap 

To verify was wrong I needed to look at the actual SOAP message being sent to me:

  <?xml version="1.0" encoding="UTF-8" ?> 
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <getOntologyNamesResponse xmlns="http://www.ebi.ac.uk/ontology-lookup/OntologyQuery">
- <getOntologyNamesReturn>
- <item xmlns:ns1="http://xml.apache.org/xml-soap" xmlns="">
  <key xsi:type="xsd:string">LSM</key> 
  <value xsi:type="xsd:string">Leukocyte Surface Markers</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TADS</key> 
  <value xsi:type="xsd:string">Tick Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FBsp</key> 
  <value xsi:type="xsd:string">Fly taxonomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FIX</key> 
  <value xsi:type="xsd:string">Physico-Chemical Methods and Properties</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">HOM</key> 
  <value xsi:type="xsd:string">Homology Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">SPD</key> 
  <value xsi:type="xsd:string">Spider Comparative Biology Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">RO</key> 
  <value xsi:type="xsd:string">Multiple Alignment</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">HP</key> 
  <value xsi:type="xsd:string">Human phenotype ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MOD</key> 
  <value xsi:type="xsd:string">Protein Modifications (PSI-MOD)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">BTO</key> 
  <value xsi:type="xsd:string">BRENDA tissue / enzyme source</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MFO</key> 
  <value xsi:type="xsd:string">Medaka Fish Anatomy and Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TTO</key> 
  <value xsi:type="xsd:string">Teleost taxonomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">WBls</key> 
  <value xsi:type="xsd:string">C. elegans Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">APO</key> 
  <value xsi:type="xsd:string">Yeast phenotypes</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MAT</key> 
  <value xsi:type="xsd:string">Minimal Information About Anatomy ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">NEWT</key> 
  <value xsi:type="xsd:string">NEWT UniProt Taxonomy Database</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MI</key> 
  <value xsi:type="xsd:string">Molecular Interaction (PSI MI 2.5)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FAO</key> 
  <value xsi:type="xsd:string">Fungal Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TAIR</key> 
  <value xsi:type="xsd:string">Arabidopsis Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">IDO</key> 
  <value xsi:type="xsd:string">Infectious Disease Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">EMAP</key> 
  <value xsi:type="xsd:string">Mouse Gross Anatomy and Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">AAO</key> 
  <value xsi:type="xsd:string">Amphibian Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PRO</key> 
  <value xsi:type="xsd:string">Protein Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">OBO_REL</key> 
  <value xsi:type="xsd:string">OBO Relationship Types</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ZFA</key> 
  <value xsi:type="xsd:string">Zebrafish Anatomy and Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MA</key> 
  <value xsi:type="xsd:string">Mouse Adult Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">XAO</key> 
  <value xsi:type="xsd:string">Xenopus anatomy and development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TRANS</key> 
  <value xsi:type="xsd:string">Pathogen transmission</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PATO</key> 
  <value xsi:type="xsd:string">Phenotypic qualities (properties)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TGMA</key> 
  <value xsi:type="xsd:string">Mosquito Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PRIDE</key> 
  <value xsi:type="xsd:string">PRIDE Controlled Vocabulary</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">REX</key> 
  <value xsi:type="xsd:string">Physico-Chemical Process</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">UO</key> 
  <value xsi:type="xsd:string">Unit Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">CARO</key> 
  <value xsi:type="xsd:string">Common Anatomy Reference Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">SEP</key> 
  <value xsi:type="xsd:string">Separation Methods</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TAO</key> 
  <value xsi:type="xsd:string">Teleost Anatomy and Development Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MP</key> 
  <value xsi:type="xsd:string">Mammalian Phenotype</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">EV</key> 
  <value xsi:type="xsd:string">eVOC (Expressed Sequence Annotation for Humans)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FBdv</key> 
  <value xsi:type="xsd:string">Drosophila Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">HAO</key> 
  <value xsi:type="xsd:string">Hymenoptera Anatomy Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MS</key> 
  <value xsi:type="xsd:string">PSI Mass Spectrometry Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">GRO</key> 
  <value xsi:type="xsd:string">Cereal Plant Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">EO</key> 
  <value xsi:type="xsd:string">Plant Environmental Conditions</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PAR</key> 
  <value xsi:type="xsd:string">Protein Affinity Reagents</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">IMR</key> 
  <value xsi:type="xsd:string">Molecule Role (INOH)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PSI</key> 
  <value xsi:type="xsd:string">Mass Spectroscopy CV (PSI-MS)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PW</key> 
  <value xsi:type="xsd:string">Pathway Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">IEV</key> 
  <value xsi:type="xsd:string">Event (INOH)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ECO</key> 
  <value xsi:type="xsd:string">Evidence Codes</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MIAA</key> 
  <value xsi:type="xsd:string">Minimal Information About Anatomy ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ENVO</key> 
  <value xsi:type="xsd:string">Environmental Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">BS</key> 
  <value xsi:type="xsd:string">Biosapiens Annotations</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">CCO</key> 
  <value xsi:type="xsd:string">Cell Cycle Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">TO</key> 
  <value xsi:type="xsd:string">Cereal Plant Trait</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FBcv</key> 
  <value xsi:type="xsd:string">Flybase Controlled Vocabulary</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MIRO</key> 
  <value xsi:type="xsd:string">Mosquito Insecticide Resistance</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">WBPhenotype</key> 
  <value xsi:type="xsd:string">C. elegans phenotype</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">CHEBI</key> 
  <value xsi:type="xsd:string">Chemical Entities of Biological Interest</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">DOID</key> 
  <value xsi:type="xsd:string">Human Disease</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">BSPO</key> 
  <value xsi:type="xsd:string">Spatial Reference Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ZDB</key> 
  <value xsi:type="xsd:string">Zebrafish Anatomy and Development</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">WBbt</key> 
  <value xsi:type="xsd:string">C. elegans gross anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FBbi</key> 
  <value xsi:type="xsd:string">Biological Imaging Methods</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ATO</key> 
  <value xsi:type="xsd:string">Amphibian Taxonomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FBbt</key> 
  <value xsi:type="xsd:string">Drosophila Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">SO</key> 
  <value xsi:type="xsd:string">Sequence Types and Features</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">FMA</key> 
  <value xsi:type="xsd:string">Foundational Model of Anatomy Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">EHDA</key> 
  <value xsi:type="xsd:string">Human Developmental Anatomy, timed version</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ZEA</key> 
  <value xsi:type="xsd:string">Maize Gross Anatomy</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PM</key> 
  <value xsi:type="xsd:string">Phenotypic manifestation (genetic context)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">PO</key> 
  <value xsi:type="xsd:string">Plant Ontology (Structure, Growth and Developmental Stage)</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">EFO</key> 
  <value xsi:type="xsd:string">ArrayExpress Experimental Factor Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">GO</key> 
  <value xsi:type="xsd:string">Gene Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">ENA</key> 
  <value xsi:type="xsd:string">European Nucleotide Archive Submission Ontology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">MPATH</key> 
  <value xsi:type="xsd:string">Mouse Pathology</value> 
  </item>
- <item xmlns="">
  <key xsi:type="xsd:string">CL</key> 
  <value xsi:type="xsd:string">Cell Type</value> 
  </item>
  </getOntologyNamesReturn>
  </getOntologyNamesResponse>
  </soapenv:Body>
  </soapenv:Envelope>


The main problem is that nearly all the<item> elements don't have a declared namespace. Here's an example:


<item xmlns="">
  <key xsi:type="xsd:string">HOM</key> 
  <value xsi:type="xsd:string">Homology Ontology</value> 
  </item>

And yet in the WSDL file the schema requires that the namespaces be fully qualified:

  <schema elementFormDefault="qualified" targetNamespace="http://xml.apache.org/xml-soap" xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://model.web.ook.ebi.ac.uk"/>
   <complexType name="mapItem">
    <sequence>
     <element name="key" nillable="true" type="xsd:anyType"/>
     <element name="value" nillable="true" type="xsd:anyType"/>
    </sequence>
   </complexType>
   <complexType name="Map">
    <sequence>
     <element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
    </sequence>
   </complexType>
   <complexType name="Vector">
    <sequence>
     <element maxOccurs="unbounded" minOccurs="0" name="item" type="xsd:anyType"/>
    </sequence>
   </complexType>
  </schema>

The workaround for this problem was to download the WSDL file and manually change it from qualified to unqualified as follows:



  <schema elementFormDefault="unqualified" targetNamespace="http://xml.apache.org/xml-soap" xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://model.web.ook.ebi.ac.uk"/>
   <complexType name="mapItem">
    <sequence>
     <element name="key" nillable="true" type="xsd:anyType"/>
     <element name="value" nillable="true" type="xsd:anyType"/>
    </sequence>
   </complexType>
   <complexType name="Map">
    <sequence>
     <element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
    </sequence>
   </complexType>
   <complexType name="Vector">
    <sequence>
     <element maxOccurs="unbounded" minOccurs="0" name="item" type="xsd:anyType"/>
    </sequence>
   </complexType>
  </schema>


More details about this issue can be followed up here:

http://code.google.com/p/ols-ebi/issues/detail?id=6

Hope this helps somebody from the headaches i had to go through to get this working!!

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>