|
|
||
Rama Pulavarthi's BlogJanuary 2007 ArchivesUsing Addressing With JAX-WS Clients without WSDLPosted by ramapulavarthi on January 21, 2007 at 01:54 AM | Permalink | Comments (3)Addressing can be enabled on client by having a wsdl with <wsaw:UsingAddressing/> in the wsdl definitions or enabling AddressingFeature while creating the client proxy. In EA3, Although Addressing is enabled, for it to work the clients (esp. Dispatch) have to be created with wsdl, otherwise Addressing headers are not sent automatically by the JAX-WS Runtime. The reason was wsa:Action header which is mandatory comes from wsdl either it be explicitly specified or implicitly computed using wsdl:operation's definition. All other addressing headers can be computed without WSDL or assume default values. The same wsa:Action header is used as SOAPAction http header. JAX-WS API provides way to set SOAPAction header in the message context. Using this mechanism, Recently I made a fix to use Addressing runtime. Now for Addressing to work, WSDL is no more needed. All you need to do is set BindingProvider.SOAPACTION_URI_PROPERTY property. An example below shows its usage. Service service = Service.create(SERVICE_QNAME); service.addPort(PORT_QNAME, SOAPBinding.SOAP11HTTP_BINDING, "http://localhost:8080/service/example"); Dispatch<Source> dispatch = service.createDispatch(PORT_QNAME, Source.class, Service.Mode.PAYLOAD, new AddressingFeature()); dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true); dispatch.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY,"http://example.com/action/dothis"); dispatch.invoke(requestSrc); If you set these properties, JAXWS Runtime takes care of sending all the addressing headers in the SOAP Message. These are the messages with Addressing disabled(default)/enabled with the dispatch client. Addressing not enabled: <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <addNumbers xmlns="http://example.com/"> <number1>10</number1> <number2>10</number2> </addNumbers> </S:Body> </S:Envelope> </S:Body> </S:Envelope> Addressing enabled: <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing">http://localhost:8080/service/example</To> <Action xmlns="http://www.w3.org/2005/08/addressing">http://example.com/action/dothis</Action> <ReplyTo xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://www.w3.org/2005/08/addressing/anonymous</Address> </ReplyTo> <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:45c2f4eb-48ea-4 be4-8376-05535313ef9f</MessageID> </S:Header> <S:Body> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <addNumbers xmlns="http://example.com/"> <number1>10</number1> <number2>10</number2> </addNumbers> </S:Body> </S:Envelope> </S:Body> </S:Envelope> Hope this makes it easy to use Addressing with Dispatch. Extending JAX-WS With AnnotationsPosted by ramapulavarthi on January 16, 2007 at 09:31 AM | Permalink | Comments (1)As you know JAX-WS 2.1 is the re-architected version of JAX-WS 2.0 with high performance and additional features supporting JAX-WS 2.1 Spec. It provides a lot of extension points for developers to utilize the plug-in mechansim to modify/extend the default JAX-WS behavior. These extension points can be used at Tool time as well as Runtime. See JAX-WS 2.1 Architecture document for more details. Extension Points: I will briefly go over some of the extension points and concentrate more on extending using Java annotations and leave others for you to explore. Tube: Tube is a
filter that
lets you work on the Packet ( an abstraction of Message with context)
and pass it on to the next tube in the chain. You can think of it like
a Handler but has efficient access to the Message through different
API. Tubes can run asynchronusly, which means request packet and
response packet can be processed by different threads.See Tube
documentation for more details.
WSDLGeneratorExtension: WSDLGenerator uses Service finder mechanism to discover WSDLGeneratorExtensions and calls them to contribute in the generation of WSDL. See WSDLGeneratorExtension documentation for more details. WSDLParserExtension: These extensions are called by WSDL Parser at runtime to process the WSDL extensibility elements in the wsdl definitions. For example, W3CAddressingWSDLParserExtension in RI uses this to process <wsaw:UsingAddressing> extensibility element in wsdl:binding and wsdl:portType definitions. See WSDLParserExtension documentation for more details documentation for more details. Web Service Features: For these various extensions to be picked up and used at runtime, corresponding features have to enabled either through WSDL or Java Annotations on Endpoint implementation or Programatic configuration of features on the Client. JAX-WS 2.1 Specification introduces WebServiceFeature and WebServiceFeatureAnnotation to specify features on a client and endpoint implementation. In 2.1 RI, It uses this Web Service feature mechanism to support W3C Addressing using @Addressing and AddressingFeature Writing Custom Web Service Feature: One can use similar mechanism to extend JAX-WS by defining custom annotations and its bean representation to be used by client runtime. Annotations are used on the endpoint implementation class where as features in bean form are used on client-side. For this to work, the custom annotations should follow these rules.
Examples: In the following example, I will show you how one can utilize this extension mechanism. Although W3C Addressing Specification is a recommendation, Some still use Member Submision version of addressing. To support this, there is a RI specific feature @MemberSubmissionAddressing. Look closely at @MemberSubmissionAddressing class. It uses to MemberSubmissionAddressingFeature as bean, which can be used on client-side to enable the feature. @WebServiceFeatureAnnotation(id= MemberSubmissionAddressingFeature.ID,bean=MemberSubmissionAddressingFeature.class) public @interface MemberSubmissionAddressing { /** * Specifies if this feature is enabled or disabled. */ boolean enabled() default true; /** * Property to determine the value of the * <code>wsdl:required</code> attribute on * <code>wsaw:UsingAddressing</code> element in the WSDL. */ boolean required() default false; } public class MemberSubmissionAddressingFeature extends WebServiceFeature { /** * Create an MemberSubmissionAddressingFeature * @param enabled specifies whether this feature should * be enabled or not. */ public MemberSubmissionAddressingFeature(boolean enabled) { this.enabled = enabled; } /** * Create an <code>MemberSubmissionAddressingFeature</code> * @param enabled specifies whether this feature should * be enabled or not. * @param required specifies the value that will be used * for the <code>required</code> attribute on the * <code>wsaw:UsingAddressing</code> element. */ @FeatureConstructor({"enabled","required"}) public MemberSubmissionAddressingFeature(boolean enabled, boolean required) { this.enabled = enabled; this.required = required; } ............. ............. } Notice that only one constructor has been marked with @FeatureConstructor which captures the names of the parameters in the corresponding annotation. When a endpoint implementation is marked with @MemberSubmissionAddressing(required=false,enabled=true), JAX-WS Runtime makes this available to StandaloneTubelineAssembler, which plugs in the WsaTube which validates addressing headers on incoming messages. Similarly, W3CAddressingWSDLGeneratorExtension checks if AddressingFeature is enabled on WSBinding and based on its value, adds it as wsdl extensibility element like<wsaw:UsingAddressing wsdl:required="true"> in the binding definitions. That's all !!! Infact, you can write your own Tube and plug it in your TubelineAssembler if a custom feature is enabled and process the messages that transferred through the Tube. See RI specific features like @Stateful, @HttpSessionScope, @MemberSubmissionAddressing to see how one can utilize this mechanism. We hope developers will find these extension points useful to extend default JAX-WS behavior. Please send in your useful comments to dev@jax-ws.dev.java.net Problems using JAX-WS 2.1 and JAXB 2.1 with JDK 6?Posted by ramapulavarthi on January 12, 2007 at 12:12 AM | Permalink | Comments (10)When using JAX-WS 2.1 and JAXB 2.1 with JDK 6, you may see errors like this when running Web Services Tools (wsimport and wsgen) in JAX-WS 2.1 installation. While invoking wsimport:
D:\work\jax-ws\test\>%JAXWS_HOME%\bin\wsimport -d temp hello_literal.wsdl
parsing WSDL...
Exception in thread "main" java.lang.LinkageError: JAXB 2.0 API is being loaded
from the bootstrap classloader, but this RI (from jar:file:/D:/work/axws-ri/lib/jaxb-impl.jar!
/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API.
Use the endorsed directory mechanism to place jaxb-api.jar i
n the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.
While invoking wsgen:
Exception in thread "main" java.lang.LinkageError: JAXB 2.0 API is being loaded
from the bootstrap classloader, but this RI (from jar:file:/D:/work/jaxws-ri/lib/jaxb-impl.jar!
/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API.
Use the endorsed directory mechanism to place jaxb-api.jar i
n the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.
Sometimes its pretty clear what the error is, but not in all cases. JAXB 2.0 and JAX-WS 2.0 are part of JDK 6. To use JAX-WS 2.1 with JDK 6, newer versions of API jars (JAX-WS 2.1 and JAXB 2.1 API jars) need to be in bootclasspath before rt.jar. To do this you can use Java endorsed mechanism to override whats in Java platform. See http://java.sun.com/j2se/1.5.0/docs/guide/standards/ for more details on Endorsed Standards Override Mechanism. To get around this issue, You can simply copy jaxb-api.jar, jaxws-api.jar to <java-home>/lib/endorsed Here <java-home> refers to the directory where the runtime software is installed (which is the top-level directory of the J2SE Runtime Environment or the jre directory in the JDK). If you prefer to not change JDK, For invoking wsimport and wsgen tools in JAX-WS 2.1, you can set WSIMPORT_OPTS=-Djava.endorsed.dirs=%JAXWS_HOME%/lib & WSGEN_OPTS=-Djava.endorsed.dirs=%JAXWS_HOME%/lib, where JAXWS_HOME points to JAX-WS 2.1 installation. If you use ant tasks, you can pass -Djava.endorsed.dirs=%JAXWS_HOME%/lib as jvmarg while calling wsimport and wsgen ant tasks. For this to work, you need to set fork="true" attribute of wsimport and wsgen ant tasks. | ||
|
|