The Source for Java Technology Collaboration
User: Password:



Jitendra Kotamraju

Jitendra Kotamraju's Blog

Web Service endpoints in Mustang

Posted by jitu on January 18, 2006 at 05:17 PM | Comments (25)

Mustang has a very good support for Web Services. One can create, publish a Web Service very easily. First write the Web Service endpoint implementation, and then use javax.xml.ws.Endpoint API to create and publish the Web Service.
package myws;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class Implementor {
    public int add(int a, int b) {
        return a+b;
    }
}

package myws;

import javax.xml.ws.Endpoint;

public class WSWrapper {
    public static void main(String[] args) {
        Implementor impl = new Implementor();
        // Create and publish the endpoint at the given address
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/add", impl);
    }
}
Compile both the java files and run the java class myws.WSWrapper (Typically one needs to run wsgen before running the program but in this case it is not required). JAXWS runtime created and published a Web Service in publish() method. The WSDL of the Web Service is published at http://localhost:8080/add?wsdl and can be accessed from the browser. Now write a client to access this Web Service !!

Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first)

  • I don't get it. Is there a web server running at that address (http://localhost:8080) already? IIS?

    Posted by: fuerte on January 20, 2006 at 10:08 AM

  • Yes, publish() creates a web server and is bound at localhost:8080. The web server is not IIS.

    Posted by: jitu on January 20, 2006 at 10:48 AM

  • Okay, so it creates a lightweight web server? Does the web server run all the time, or do you start it somehow? Web server is part of JSE6?

    Posted by: fuerte on January 20, 2006 at 11:47 AM

  • Thank you, this is a very enlightening article! Amazing how easy it is to deploy web services in mustang.

    Posted by: gruenewa on January 23, 2006 at 02:33 AM

  • I tried it with the latest Mustang and NetBeans 5 rc2. It works, but I still don't understand exactly how. Looking at the code Endpoint.publish it would seem that the class is done, the program exists, but it does not. The new web server keeps on serving until the process is killed.

    If I add endpoint.stop(); then the process exists immediately.

    It would be nice to know how the process can be stopped, besides killing it.

    Posted by: fuerte on January 23, 2006 at 11:20 AM

  • Only way to end this process is to do endpoint.stop() somewhere in the application. One would typically publish the endpoint, endpoint would be servicing requests, and when the application decides to stop the web service, it calls endpoint.stop(). The stop() method stops the underlying light weight http server.


    For e.g.:

    endpoint.publish(...)
    // can use the current thread do some other processing
    ...
    if (stopService()) {
    endpoint.stop();
    }


    in stopService(), the application could put logic when to stop the service(for e.g. some logic using wait(), notify() etc.) This works fine when you want to embed the webservice hosting as part of your application.

    There are other ways to publish endpoint with application having more control and I will go over those scenarios in future blogs.

    Posted by: jitu on January 23, 2006 at 12:22 PM

  • OK, but maybe it would have been safer if the web server had just stopped automatically when the program exits. Now it is possible that the process "hangs" forever. I understand that it is just doing what it is supposed to do.

    In ASP.NET web services have a nice default page, which opens if you GET the page in browser. There you can enter the parameters and test the service without a real web service client. This I would like to have in Java as well. ?wsdl works the same as ASP.NET.

    Posted by: fuerte on January 23, 2006 at 02:44 PM

  • Wow. Very nice WS support for server side - it even has a built in web server!.

    What about the client side RPC proxies?

    > In ASP.NET web services have a nice default page, which opens if you GET the page in browser.

    I agree with this suggestion! It helps for immediate testing without a client application.

    Posted by: simonmcmahon on January 23, 2006 at 09:42 PM

  • In my opinnion immediate testing is very simple. See for instance this perl script:

    #!/usr/bin/perl -w

    use SOAP::Lite;

    my $calculator = SOAP::Lite
    -> service('http://localhost:8080/add?wsdl');
    print $calculator
    -> add(34,66), "\n";

    So why bloat the JDK? The business of an endpoint is to publish a web service. In my opinnion testing is a different concern/aspect.

    Posted by: gruenewa on January 24, 2006 at 12:44 AM

  • Hello.
    I have a question for you.
    I wrote some java-code:

    @WebService()
    @SOAPBinding(style = Style.RPC)
    public class AddStringsImpl implements AddStringsIF {
    public String addStrings(String str1, String str2) {
    return str1 + ":" + str2;
    }
    }

    Atfer this I'm publish my service:
    Endpoint.publish("http://localhost:9090/AddStrings", new/n AddStringsImpl());

    After this I startup my application. In Internet Explorer I'm type address: "http://localhost:9090/AddStrings?wsdl" and store result into wsdl file on disk.

    In Delphi I'm import this wsdl-file and try to invoke my addStrings method, but failed.
    There are error's:
    Error in decoding SOAP Message/n
    at com.sun.xml.ws.encoding.soap.server.SOAPXMLDecoder.toInternalMessage(SOAPXMLDecoder.java:78)
    at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.toMessageInfo(SOAPMessageDispatcher.java:147)
    at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher$SoapInvoker.invoke(SOAPMessageDispatcher.java:465)
    at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDispatcher.java:117)
    at com.sun.xml.ws.server.Tie.handle(Tie.java:89)
    at com.sun.xml.ws.transport.http.server.WSHttpHandler.post(WSHttpHandler.java:103)
    at com.sun.xml.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:459)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:669)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:694)
    at java.lang.Thread.run(Thread.java:620)
    Caused by: java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
    at com.sun.xml.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:321)
    at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.parseXsiType(XsiTypeLoader.java:52)
    at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:30)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:362)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:340)
    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:33)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:189)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:123)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:332)
    at com.sun.xml.bind.v2.runtime.BridgeImpl.unmarshal(BridgeImpl.java:61)
    at com.sun.xml.ws.encoding.jaxb.JAXBTypeSerializer.deserialize(JAXBTypeSerializer.java:212)
    at com.sun.xml.ws.encoding.jaxb.RpcLitPayloadSerializer.deserialize(RpcLitPayloadSerializer.java:127)
    at com.sun.xml.ws.encoding.soap.SOAPDecoder.decodeBodyContent(SOAPDecoder.java:290)
    at com.sun.xml.ws.encoding.soap.SOAPDecoder.decodeBody(SOAPDecoder.java:262)
    at com.sun.xml.ws.encoding.soap.SOAPDecoder.decodeEnvelope(SOAPDecoder.java:195)
    at com.sun.xml.ws.encoding.soap.server.SOAPXMLDecoder.toInternalMessage(SOAPXMLDecoder.java:75)
    ... 11 more

    Posted by: dima_yakovlev_russia on January 26, 2006 at 04:29 AM

  • Hi, again!
    I'm sorry! My previos error is not exist in Mustang build 68!!!

    But I have question.
    When I use my oun types in web service methods, my types don't include into wsdl which generated!
    Why?

    There are method declaration code:
    @WebMethod(operationName = "getUser", action="getUser")
    @WebResult(name = "return")
    public UserInfo getUser();

    Posted by: dima_yakovlev_russia on January 26, 2006 at 10:13 PM

  • How to use it if an AS is already running?

    Posted by: pascalfares on January 27, 2006 at 11:39 PM

  • The WSDL should contain schema types for custom types. The posted example doesn't require to run wsgen tool as it doesn't generate any artifacts. Typically follow these steps

    Starting from Java
    - Write Web Service implementation, a wrapper to publish it
    - Use wsgen tool to generate portable artifacts
    - Run the wrapper class to start the web service

    Starting from WSDL
    - Use wsimport tool to generate portable artifacts
    - Write Web Service implementation, a wrapper to publish it
    - Run the wrapper class to start the web service

    Posted by: jitu on January 28, 2006 at 11:34 PM

  • Is application server usefull anymore ?
    What role for glassfish now ?

    Posted by: andleg2000 on March 18, 2006 at 04:25 PM

  • I've noticed that if you write a client that makes requests in a tight loop as fast as possible that the server can hang temporarily and mangle requests at time. I don't think the server side of this equation is very robust and may have some threading issues.

    Posted by: seifertd on May 03, 2006 at 10:40 PM

  • Can anyone respond to the pevious comment, which infers that the built-in HTTP server has potential bugs and performance problems? How easy is it (i.e. what API could I call) to plug in another embedded HTTP server, like Jetty?

    Posted by: zmonster on July 20, 2006 at 09:17 PM

  • We used already a lot this feature already in JWSDP 2.0. When we publish a a webservice, JWSDP started well our webservice.
    But we are facing on the folowing problem:
    If you stop the Endpoint and restart it. we recieved :
    Caused by: java.net.BindException: Address already in use: bind

    How do you stop correctly an Endpoint object ?

    Posted by: pgodot on January 23, 2007 at 07:19 AM

  • Hi! Any idea why the JavaDocs don't state that Endpoint.publish() can throw a BindException? It can throw one if you use it statically and another JVM has it running. But I can't catch the BindException because it's a checked exception. If I try to catch it, the compiler tells me the code can't throw a BindException and won't compile and run. Without it, I get a BindException at run time. I can catch Exception, and getMessage() tells me I have a BindException. I know to go out and stop the other JVM to prevent the BindException, but I'd like to catch it properly in the program, too. Any suggestions? Thanks!-- --SMSS

    Posted by: smss on February 23, 2007 at 01:57 PM

  • how can you unlashed the following cached page?:

    PGh0bWw+PGhlY9odG1sPg0K..

    thanks
    Dev articles

    Posted by: mydomainoffer on May 18, 2007 at 02:38 PM

  • I want this functionality very bad. However, I don't understand Endpoint.publish(java.lang.Object).
    How can I integrate JAX-WS with a servlet container, so that I can create services that will be received by the container and forwarded to the WS engine?
    I have heard there is a HttpServer provider api that can be implemented by servlet containers, but that is not standard and only works for the JAX-WS RI, not for JAX-WS in general.

    I would like to be able to:
    1. Write a Java interface with all annotations needed to create a WS;
    2. Write an implementation class that has only the @WebService(serviceEndpointInterface=...) annotation and nothing else;
    3. Deploy the service by instantiating the implementation, creating an Endpoint bound to the implementation, publish it to a path *relative* to my web server's root URL, and have it be serviced by my servlet container. How far is JAX-WS RI from that?
    -- Douglas

    Posted by: datique on March 31, 2008 at 07:20 AM

  • Currently JAX-WS API doesn't provide a portable way do (3) i.e to create a glue API between servlet container and WS engine. Let me ask you what are the advantages of your suggested approach over deploying as a servlet web application ?

    Posted by: jitu on April 01, 2008 at 04:19 PM

  • My view is that WS is just one more remoting possibility for server-side POJOs.

    So I have already created similar infrastructure that takes a POJO and a Remote interface (note that the POJO need not implement the interface) and exports the given POJO through the given interface. Aside from being thread-safe, the POJO need not know it is being used by a remote process. This is easily accomplished with dynamic proxies and their invocation handlers.

    With web services, Xfire would allow me to do a similar thing, but JAX-WS is a much more appealing technology and I want to leverage its functionality by annotating an interface and publishing a POJO that is not aware it is being used as a WS endpoint.

    What are the advantages? Simply decoupling your business logic from your middleware architecture. I believe that frameworks come and go, but my business logic is created to last, so it better stay in simple POJOs and not in an annotated WS implementation class.

    -- Doug

    Posted by: datique on April 02, 2008 at 03:56 AM

  • Hmm, I think I answered with respect to 1 and 2. Sorry.

    For 3, I think the best reason to be able to create glue code between JAX-WS and a servlet container is to be able to leverage that container's performance features instead of creating a standalone server.

    In corporate environments, the sysadmin will gladly let you deploy your web application (even if it is a bridge to some other server) after all it is what the server is there to do. But just try to bind to a privileged port with your own standalone server and the security officer comes ask you what you are trying to do with that open hole through their firewall. So I think integration with a container is paramount to successfully deploying web services in any production environment.

    If you are thinking "why not just create the sun-jaxws.xml and webxml descriptors and drop a WAR in the container?" then I think my previous post is the answer.

    -- Doug

    BTW, I forgot in the previous post, first paragraph, to mention that I was talking about RMI, but I guess the Remote keyword might have delivered the message.

    Posted by: datique on April 02, 2008 at 04:05 AM

  • I've been thinking. Is it possible to programmatically assign a Web Service instance to the WSServlet in a web application deployment (maybe through the context listener) instead of having to deploy sun-jaxws.xml?

    If I could deploy a web application and have the container call me back to ask which web service instance to use for a given url-pattern that would already be good enough for me.

    -- Doug

    Posted by: datique on April 02, 2008 at 04:20 AM

  • I've done some homework and found out that by creating an annotation which is itself annotated with the InstanceResolverAnnotation meta-annotation (that sure looks complicated, doesn't it? :-)) I can plug my own InstanceResolver into JAX-WS RI, my own "WS implementation factory" so to speak.
    Is this InstanceResolver extension point going to remain stable in JAX-WS RI?

    Posted by: datique on April 09, 2008 at 08:06 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds