By default JAXWS generates the corresponding datamodel for the generated stubs and skeletons. This has some disadvantages. You cannot reuse the model with diefferent WebServices. In addition if you change the WebService you have to regenerate the model. This is bad particulalry if you manually changed the model.

But there is a solution. There is a concept of so-called binding-files.

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:ext="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:e="http://www.mydomain.com/Entity">
    <jaxb:bindings schemaLocation="./Entity.xsd" namespace="http://www.mydomain.com/Entity" node="/*">
    	<jaxb:bindings scd="~e:Entity">
        	<jaxb:class ref="com.mydomain.model.Entity" />
    	</jaxb:bindings>
</jaxb:bindings>

The wsimport-utility will use the declared class Entity (e.g. generated with JAXB) if you use this switches:

wsimport -Xnocompile -b xml/bindings-file.xml -s src/main/ xml/your.wsdl

 

Some days ago I produced a deadlock on Tomcat-startup. I deployed a class implementing ServletContextListener that instantiates a WebService clientstub object. The problem was that the endpoint was an WebService deployed on the same Tomcat instance.

Everything works fine till restart of Tomcat. On startup Tomcat locks the connector since all web-applications are deployed. Tomcat accepts incoming connections but waits until deployment of all web-applicationsĀ  is completed. What happens is that the ServletContextListener implementation wants to download the WSDL of the WebService but Tomcat is waiting until all applications are deployed but the deployment-process cannot be completed until the WSDL can be reached.

The consequence is that you shouldn’t access any of the web-applications, in any methods executed on the deployment-phase, deployed on the same tomcat.

 

For my diploma-thesis I need to unmarshall a xml-string. In principle this is no problem, but the xml-string represents a JAXB-Entity that is not annotated with @XmlRootElement. This causes an exception during unmarshalling. Nevertheless you can unmarshall xml using JAXBElement-class.

private YourClass unmarshallFromString(String s) throws JAXBException {
{
    JAXBElement<YourClass> ret = null;
    JAXBContext jaxbCtx = JAXBContext.newInstance(YourClass.class.getPackage().getName());
    Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
    //Throw exception if problems occur during parsing
    unmarshaller.setEventHandler(new ValidationEventHandler() {
       public boolean handleEvent(ValidationEvent event) {
         throw new RuntimeException(event.getMessage(), event.getLinkedException());
       }
    });
    Source src = new StreamSource(new StringReader(s));
    ret = unmarshaller.unmarshal(src, EventSources.class);
    return (YourClass) ret.getValue();
}
 

Activiti is a Workflow Mangement System (WfMS) that is completely written in Java. Activiti is a opensource-project initiated by alfresco. Activiti is based on a Process Virtual Machine (PVM). Simplified the PVM can execute graphs consisting of nodes and transitions. Based on this abstraction several graph-based languages can be implemented. Activiti implements BPMN 2.0 and is therefore one of the first Worflow-Engines that is able to execute BPMN 2.0.

Activiti is very flexible and can be easily extended to fit custom needs. One important customization can be done by creating an ActivityBehavior. ActivityBehaviors reflect the behavior of nodes executed by the PVM. The so called ServiceTask-activity has an attribute in its xml-representation that specifies the behavior of this Activity. It looks like this:

<serviceTask activiti:class="MyImplementation" ... >

The class MyImplementation.class or a jar containing the class have to be in {TOMCAT_HOME}/webapps/activiti-rest/WEB-INF/lib/. During runtime Activiti instantiates this class by reflection. But lets continue on how to implement the MyImplementation class.

The implementation should extend org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior. The activiti-engine executes public void execute(ActivityExecution execution) during runtime so if you want to realize custom behavior you have to override this method. At the end you should call leave(ActivityExecution execution) that tells the Engine that the activity is completed.

Some details on the concept “PVM” can be found here

You will be surprised to read about jBPM while I talked about Activiti above. jBPM 4 is also based on a PVM. The lead-architect of the Activiti-Engine is Tom Baeyens. He was a developer of jBPM before he started the work on Activiti. I think he is the/one father of the PVM-abstraction.

http://docs.jboss.com/jbpm/pvm/article/

 

JAXB stands for Java Architecture for XML-Binding. JAXB maps xml-types to java-classes and vice-versa.
The reference implementation of this java specification causes some problems when used with current Java 6. Java 6 ships with its own JAXB 2.0 implementation that is not compatible to the most current versions JAXB 2.1 and 2.2.
If you use this versions in your applications you have to put the jaxb-api.jar into the JAVA_HOME/lib/endorsed folder of your Java Runtime Environment (JRE). An alternative is to launch your java-application with the runtime-property “java.endorsed.dirs” set to the location of the jaxb-api.jar. For both alternatives you need to ship the implementation jars (e.g. jaxb-impl.jar, …) with your application.

I encountered an additional problem when switching from JAXB 2.1 to 2.2. There was a fix in JAXB 2.1 that improved parsing of abstract xml-types. This enables JAXB to parse xsi:type attribute which allows to use abstract XML-Types that are mapped on an abstract Java-Classes. The concrete type will be declared using xsi:type attribute. This fix was disabled in JAXB 2.2 for some reason. And it have to be enabled using the JAXBContext property com.sun.xml.bind.improvedXsiTypeHandling . The corresponding Bug can be found here: http://java.net/jira/browse/JAXB-620.

You have to set JAXBContext property com.sun.xml.bind.improvedXsiTypeHandling to true.

How to set properties
If you want to set properties on startup of JVM you need to use the switch -D (e.g. java -Djava.endorsed.dirs={path_to_lib} …)

Example of how to use abstract xml-types mapped on abstract classes in java using JAXB

<xsi:complexType name="Animal" abstract="true">
  <xsi:sequence>
    <xsi:element name="name" type="xsi:string"/>
  </xsi:sequence>
</xsi:complexType>
<xsi:complexType name="Fish">
  <complexContent>
     <xsi:extension base="a:animal">
       <sequence>
         <element name="amountOfFins" type="xsi:integer" />
       </sequence>
     </xsi:extension>
  </xsi:complexContent>
</xsi:complexType>
<xsi:complexType name="Mammal">
  <complexContent>
     <xsi:extension base="a:animal">
       <sequence>
         <element name="amountOfLegs" type="xsi:integer" />
       </sequence>
     </xsi:extension>
  </xsi:complexContent>
</xsi:complexType>
<xsi:element name="animalInstance" type="a:animal"/>

An instance of an animal could look like this:

<?xml version="1.0"?>
<animalInstance xsi:type="a:Mammal" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:a="http://....../Animal">
  <a:name>Dog</a:name>
  <a:amountOfLegs>4</a:amountOfLegs>
</anInstance>

JAXB is able to unmarshal this instance correctly and create a mammal Java-object. Marshalling is also no problem. So you are able to write generic methods for animals. This is useful especially for WebServices (e.g. using JAXWS). So you don’t have to implement a WebService-operation for every subtype. One operation handling the abstract animal-type is sufficient.

More information on JAXB 2.0

http://jaxb.java.net/guide/Migrating_JAXB_2_0_applications_to_JavaSE_6.html

© 2011 Softwareengineering in practise Suffusion theme by Sayontan Sinha