users@jax-rpc.java.net

Re: ServiceLifeCycle interface, threading and request handling

From: Roberto Chinnici <Roberto.Chinnici_at_Sun.COM>
Date: Wed, 10 Apr 2002 10:37:01 -0700

Here's an example:

    public class MyImplementation implements
                         MyRemoteInterface,ServiceLifecycle {

    private ServletEndpointContext ctx;

    public void init(java.lang.Object context){
        ctx=(ServletEndpointContext)context;
    }

    public int doSomething(String arg) throws RemoteException {
        SOAPMessageContext msgctx= (SOAPMessageContext) (ctx.getMessageContext());
        // use the message context here...

        HttpSession session = ctx.getHttpSession();
        // now use the HTTP session...

        return ...; // code to compute the return value for this method
    }
}

So the idea is that you should save the context in the init() method, then
in your business methods (like doSomething() above) you can call the
getters and they'll return the correct values for the SOAPMessageContext,
HttpSession and UserPrincipal. Those values are meaningful only for that
one invocation only. You should NOT get those values in the init() method
because they're meaningless there, and you should NOT save the value of,
say, HttpSession across invocations because its scope is exactly one
method invocation and nothing more.

This is entirely analogous to the SessionContext and EntityContext
interfaces in EJB, by the way.

Roberto


Sam wrote:

> Roberto,
>
> I beg to differ again on this. I think the example I posted is quite
> correct. This code I posted was based on the extracts I quoted from the
> specs earlier plus... Section 10.1.3 of the JAX-RPC specs
>
> <quote>
> For service endpoints deployed on a servlet container based JAX-RPC
> runtime system, the context parameter in the ServiceLifecycle.init
> method is required to be of the Java type
> javax.xml.rpc.server.ServletEndpointContext. The ServletEndpoint Context
> provides an endpoint context maintained by the underlying servlet
> container based JAX-RPC runtime system."
> </quote>
>
> Hence the cast done below should work in this implementation class :-
>
> public class MyImplementation implements
> myremoteInterface,ServiceLifecycle {
>
> private ServletEndpointContext ctx;
>
> public void init(java.lang.Object context){
> ctx=(ServletEndpointContext)context;
> SOAPMessageContext msgctx= (SOAPMessageContext)
> (ctx.getMessageContext());
> // =====> SOAPMessage message=msgctx.getMessage();
> }
> // other code
> }
>
> If this code is not correct then I fail to see how a reference to the
> SOAPMessageContext (and hence access to the attachment in the message)
> can be obtained by the implementation class.
>
> Could you please post a code extract (or pseudo-code) demonstrating how
> the callback you talk about below can be made ?
>
> Further if a reference to the ServletContext is passed (which it is not
> as
> per 10.1.3) the there is definately no way in which the implementation
> class
> can access the SOAPMessageContext. (Unless it is an attribute of the
> context, which
> would make it a context wide attribute...which in turn would imply that
> if there
> were two requests, the second request would over-write the value of the
> context wide attribute...totaly currupting data.
>
> I further have another issue with this whole concept of the
> ServletEndpointContext and the second para you mentioned below
> (of thread locals)
>
> The API for the ServletEndpointContext includes the following methods :-
>
> public java.security.Principal getUserPrincipal();
> public javax.xml.rpc.handler.MessageContext getMessageContext();
> public javax.servlet.http.HttpSession getSession();
> public javax.servlet.ServletContext getServletContext();
>
> What you are saying is that the container needs to change the values
> returned by this context dynamically, depending on the request being
> processed....
> This is bound to lead to currupted data !
>
> Eg, the init is called and variables are initailzed. The context is
> stored in an instance variable.... later on in the business methods
> the HttpSession is retrived,used and stored in an instance variable.
> Now a second request is dispatched to the implementation...values
> of the HttpSession are switched (magically by the container) to
> reflect the second clients session... the business method now uses
> the second HttpSession (totally overwriting the previous one).
>
> If indeed this makes sense, then it should be explictly stated that
> the implementation class should *not* store the HttpSession etc
> as intance variables *but* retreive them from the ServletEndpointContext
> in ever business method invocation ! (since they could change)
>
> Does this make sense ?
>
> /Sam
>
> Roberto Chinnici wrote:
> >
> > The example posted by Sam is incorrect because when init(Object) gets called,
> > the only ServletEndpointContext property that is guaranteed to contain a valid
> > value is ServletContext. The values of the MessageContext, HttpSession and
> > UserPrincipal are unspecified at that time.
> >
> > The idea behind this is that in the init() method you should only look up resources
> > using the ServletContext object. Typically, you'll also store a reference to the
> > ServletEndpointContext object in one of your fields. After you're done initializing,
> > the server will start calling your business methods and in the course of processing
> > those invocations you can use the other getters on ServletEndpointContext.
> >
> > Please notice that an implementation is required to return the appropriate
> > values for all those properties even in the case where several requests are
> > being served by the *same* endpoint instance in parallel. We expect that
> > implementations will use thread local variables to make this possible.
> >
> > Regards,
> > Roberto
> >
> > --
> > Roberto Chinnici
> > Java and XML Software
> > Sun Microsystems, Inc.
> >
> > Sang Shin wrote:
> >
> > > Sam wrote:
> > > >
> > > > Here is a quote from this months Java Live chat.
> > > >
> > > > "Roberto Chinnici: In the 0.8 specification an endpoint implementation
> > > > class is initialized with an object on which it can call back to obtain
> > > > the SOAPMessageContext for the request, so it could use that to access
> > > > the attachments. Another strategy would be to use message handlers to
> > > > deal with attachments and put the data where the endpoint implementation
> > > > class can find it -- this would work in EA2 too, incidentally. "
> > > >
> > > > Well I have a problem with this answer and I have a feeling that
> > > > this interface might be broken...
> > >
> > > Yes, I had a problem with the first part of his answer.
> > >
> > > The init(java.lang.Object context) method of the
> > > ServiceLifeCycle
> > > interface is meant to pass ServletContext not
> > > SOAPMessageContext.
> > > (The SOAPMessageContext gets passed around by SOAP message
> > > handlers in their init() methods.) So the example code you
> > > cited
> > > below should not happen.
> > >
> > > -Sang
> > >
> > > >
> > > > Here is an excerpt from the specs :
> > > >
> > > > "....After the service endpoint object is instantiated, the JAX-RPC
> > > > runtime system is required to initialize the endpoint before any
> > > > requests can be serviced. The JAX-RPC runtime system is required to
> > > > invoke the ServiceLifecycle.init method ......."
> > > >
> > > > "Once a service endpoint has been initialized, the JAX-RPC runtime
> > > > system may dispatch multiple remote method invocations to the service
> > > > endpoint object. These method invocations must correspond to the remote
> > > > methods in the service endpoint interface implemented by the service
> > > > endpoint class."
> > > >
> > > > This leads me to believe that the init() is *not* called for every
> > > > request
> > > > but only once, when the class is initialized....much like how servlets
> > > > are initialized in the servlet specs.
> > > >
> > > > Which is fine... But heres where the problem comes in. Consider the
> > > > following code.
> > > >
> > > > public class MyImplementation implements
> > > > myremoteInterface,ServiceLifecycle {
> > > >
> > > > private ServletEndpointContext ctx;
> > > >
> > > > public void init(java.lang.Object context){
> > > > ctx=(ServletEndpointContext)context;
> > > > SOAPMessageContext msgctx= (SOAPMessageContext)
> > > > (ctx.getMessageContext());
> > > > // =====> SOAPMessage message=msgctx.getMessage();
> > > > }
> > > > // other code
> > > > }
> > > >
> > > > Well if the actual soap message is retrevied via the context ....how can
> > > > this work , unless....the init() method is (= MUST be) called for every
> > > > incoming request that the implementation is servicing....otherwise
> > > > the class will have access to only one message...the first one . And
> > > > what happens in the case when the instance is processing multiple
> > > > requests, from different clients, with different messages,
> > > > simulatneously (as per the requirements)??
> > > >
> > > > And in a related question to the above para, how should developers
> > > > assume the threading model of these implementations ?? Like RMI ?
> > > > (where the object could be serviceing multiple requests from different
> > > > clients simultaenously...and hence isnt thread safe ?)...
> > > >
> > > > I.E like RMI no client specific (in the case of JAX-RPC message
> > > > specific) state
> > > > should be stored in the instance variables....?? If so then again,
> > > > the above code will not work...since the only way to access
> > > > the SOAPMessage object in other methods of this class is to put
> > > > it in an instance variable.
> > > >
> > > > Please clarify and advice.
> > > >
> > > > /Sam
> > > >
> > > > _________________________________________________________
> > > > Do You Yahoo!?
> > > > Get your free @yahoo.com address at http://mail.yahoo.com
> > >
> > > --
> > >
> > > ---------------------------------------------
> > > Sang Shin sang.shin_at_sun.com
> > > Strategic Market Development (781) 442-0531(Work)
> > > Sun Microsystems, Inc. (781) 993-1136(Fax)
> > >
> > > http://www.plurb.com/misc/xml/brandeis-xml-2001.html#bio
> > > http://www.plurb.com/misc/te/SangSchedule.html
> > > ---------------------------------------------
>
> _________________________________________________________
> Do You Yahoo!?
> Get your free @yahoo.com address at http://mail.yahoo.com