Hi Gary

It's done now - I'm happy you've brought this issue up as the code looks much 
betetr to me now.
If you could try the trunk (mvn install -Pfastinstall, cd api, mvn install, cd ../distribution, mvn install) during the next day or two and confirm if things work for you as expected then it would be good.

Now, I haven't done the patch you were referring to in a seperate email, to do with the CXFServlet update. Would you be interested in providing a complete patch ? If you do then you just might want to modify

https://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/resources/jaxrs_spring_providers

by updating web.xml with another CXFServlet definition and add another beans.xml there and then add some simple test to this quite old test (just because it uses the above resources)
https://svn.apache.org/repos/asf/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java

Cheers, Sergey

----- Original Message ----- From: "Sergey Beryozkin" <sbery...@progress.com>
To: <dev@cxf.apache.org>; "'Daniel Kulp'" <dk...@apache.org>
Sent: Tuesday, March 10, 2009 12:35 PM
Subject: Re: ProviderFactory singleton?


Hi Gary

Thanks for posting the code. I thought of going with a slightly different route, after a brief chat with Dan yesterday. The idea is to associate a ProviderFactory instance with a given endpoint (info). Such instance could be then retrieved from a given message whenever needed and it should work on a client side quite nicely too, with both proxies and http-centric clients, or so I hope at the moment. It should also avoid the need to synchronize in getInstance(). It should be done by the end of tomorrow sharp. I will get back to you if the route I'm thinking of at the moment will lead me to nowhere :-) and plead for a patch :-)

All your contribuition is being really appreciated - I'm not sure I'll apply your patch to a cxf servlet this week but I do consider your help in making sure the ProviderFactory working nicely with endpoins with identical addresses being equivalent of submitting a patch on its own.

Cheers, Sergey

----- Original Message ----- From: "Tong, Gary (IDEAS)" <gary.t...@morganstanley.com>
To: "'Daniel Kulp'" <dk...@apache.org>; <dev@cxf.apache.org>
Sent: Tuesday, March 10, 2009 11:50 AM
Subject: RE: ProviderFactory singleton?


Proof of Concept Implementation:

ProviderFactory:

   public static ProviderFactory getInstance() {
       return getInstance("/");
   }

   public static ProviderFactory getInstance(String baseAddress) {
       Bus bus = BusFactory.getThreadDefaultBus();
       ProviderFactoryMap providerFactoryMap = 
bus.getExtension(ProviderFactoryMap.class);
       if (providerFactoryMap == null) {
           providerFactoryMap = new ProviderFactoryMap();
           bus.setExtension(providerFactoryMap, ProviderFactoryMap.class);
       }
       ProviderFactory pf = null;
       synchronized (ProviderFactoryMap.class) {
           pf = providerFactoryMap.get(baseAddress);
           if (pf == null) {
               pf = new ProviderFactory();
               providerFactoryMap.put(baseAddress, pf);
           }
       }
       return pf;
   }

ProviderFactoryMap:

public class ProviderFactoryMap extends HashMap<String, ProviderFactory> {
  private static final long serialVersionUID = 1L;
}

Quick & dirty way of doing it. Passes my tests. Almost definitely not the best way of implementing it though. It's not thread safe, and at the very least, seems like we should explicitly pass the bus around instead of using the thread local. It looks like creating something like ProviderManagerImpl would fit conventions better.

Have the code checked out now.  Can work on a patch if there is interest.

Regards,
Gary


-----Original Message-----
From: Daniel Kulp [mailto:dk...@apache.org]
Sent: 09 March 2009 18:53
To: dev@cxf.apache.org
Cc: Tong, Gary (IDEAS)
Subject: Re: ProviderFactory singleton?


It's not just OSGi as well.   One way of setting up CXF with tomcat is to put
the CXF jars into the tomcat shared/lib directory and then deploy 100
wars/applications each using CXF with their own CXF servlet.   In that case,
anything "static" gets shared between all 100 services, although each
application would have it's own bus and stuff.     Every single one of those
100 apps may have a service names "/foo" based off of it's base.   They
obviously need to be resolved correctly to the correct factories.

This is actually how I setup the JAX-WS tck to run.

One more note:  by sticking the factory onto the endpoint, it gets properly
garbage collected on undeploy.   The current setup stores all the factories in
a map.   They NEVER get removed.   Thus, undeploying the app would result in
memory leaks and such.    That's one of the major advantages to popping the
data onto the endpoint object.   It pretty much gets cleaned up automatically.
For a while, ws-rm/ws-a did the same thing (store in static maps).   We had
problems getting everything cleaned up all the time.   Moved it all to storing
it on the endpoint, problem solved.

Dan

On Mon March 9 2009 6:54:38 am Tong, Gary (IDEAS) wrote:
Hi Sergey,

I've done a bit of work to allow two overlapping addresses to be
deployed side-by-side.  It mostly involes doing all the configuration
within a child context.  Small change really, which works fine except
for the bit about the providers.

I think Dan is talking about the same deployment issues as I am.  In
OSGi you could have two bundles that both use CXF JAX-RS that end up
stomping all over each other's singletons.  This really shouldn't
happen, but some OSGi (most?) containers allow for shared classloading
in one fashion or another, which could cause issues.

Gary

-----Original Message-----
From: Sergey Beryozkin [mailto:sbery...@progress.com]
Sent: 09 March 2009 10:38
To: Daniel Kulp; dev@cxf.apache.org
Subject: Re: ProviderFactory singleton?

Hi,

I wish someone explained me why things will get worse in OSGI, with
ProviderFactory.getInstance(). There's a direct relationship between
any given endpoint and a ProviderFactory instance and ProviderFactory
does not rely itself on some FactoryFinders, etc...It's all quite
straightforward really there and  at the moment I don't see why things
will fail in OSGI, given that in fact I've seen CXF JAXRS working in
OSGI, though withougt multiple endpoints being involved. Is it because
ProviderFactory has static fields ? Are we talking here about multiple
CXF JAXRS bundles being loaded ? I guess we will have multiple
versions in this case so I don't see why classloading issues will arise in such 
cases. What is it that I'm missing ?
It simply encapsulates the requirement "try user providers first,
delegate to the defulat ones as the last resort".

> Each module has no knowledge of any other module its deployed next
> to, which is why multiple modules may easily have overlapping addresses.

this is more intertesting to me really, as it's about the concrete
problem which might occur at the deployment time. I honestly did not
know that it were possible to have multiple jaxrs:endpoints with
identical address values working even only with default providers
involved (note, overlapping addresses, as in say '/bar' and '/' should
work fine with per-endpoint providers), with CXF servlets providing
the needed uniqueness to the actual adresses. I'll need to think how
it can be accomodated - I'm just not sure yet how :-). Perhaps the
validation rules invoked at the deployment time would ensure the
uniqueness of jaxrs:endpoint addresses - but that depends on the
availability of such rules - and again - if things are expected to
work with multiple endpoints having identical @adress values then CXF JAXRS has to ensure per-endpoint providers don't clash with eath other.

thanks, Sergey

> On Fri March 6 2009 7:12:51 am Sergey Beryozkin wrote:
>> One issue is that ProviderFactory is also used at the moment in the
>> client api,
>
> Doesn't the Client API also use the Bus?   Could/Should it?   (example:
> does it currently use the HTTPConduit/transport?)   If so, hanging this
> off the bus is probably the best idea.    I definitely agree that
> Singletons are a really bad idea.   It actually will get worse with OSGi
> as classloaders and stuff are different so that singleton could end
> up holding onto things and exposing things from other applications.
>
> Dan
>
>> though an endpoint info representation is also created there. So we
>> might in principle have a thread local endpoint info storage, such
>> that ProviderFactory.getInstance() would use thread-local endpoint
>> info as a key to get the actual ProviderFactory instance.
>> Perhaps a simpler option is to just keep a ProviderFactory instance
>> with a given Endpoint. I need to think about it - it's getting a
>> bit tight now, as 2.2 is likely to go out quite soon so such a
>> change may not make it into the trunk say next week...
>>
>> But do you think the possible update as suggested above would not
>> be quite acceptable in your case, even as a workaround? I'd like to
>> understand better when it may be unrealistic to ensure that
>> different endpoints have their own addresses : perhaps there're
>> policies on which uri patterns go to web.xml or to resource classes, etc ?
>>
>> Cheers, Sergey
>>
>>
>>
>> -----Original Message-----
>> From: Tong, Gary (IDEAS) [mailto:gary.t...@morganstanley.com]
>> Sent: 06 March 2009 11:44
>> To: dev@cxf.apache.org
>> Subject: RE: ProviderFactory singleton?
>>
>> > Is it when you have multiple CXF servlets, each of them
>> > referencing
>>
>> different spring configuration files ?
>>
>> Yes exactly.
>>
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sbery...@progress.com]
>> Sent: 06 March 2009 10:18
>> To: dev@cxf.apache.org
>> Subject: RE: ProviderFactory singleton?
>>
>> Hi Gary
>>
>> I've updated a bit ProviderFactory on the trunk, there's a default
>> ProviderFactory which hosts the default providers and a
>> ProviderFactory instance per every endpoint address, for ex,
>> ProviderFactory.getInstance() and ProviderFactory.getInstance("/")
>> would return an instance keyed by '/', etc.
>> So I thought that an endpoint address, as specified by
>> jaxrs:endpoint, would be a unique enough key for ProviderFactory
>> instances.
>>
>> Do you have the case where multiple endpoints share the same
>> jaxrs:endpoint/@address ?
>>
>> Is it when you have multiple CXF servlets, each of them referencing
>> different spring configuration files ?
>>
>> Cheers, Sergey
>>
>> -----Original Message-----
>> From: Tong, Gary (IDEAS) [mailto:gary.t...@morganstanley.com]
>> Sent: 06 March 2009 09:14
>> To: dev@cxf.apache.org
>> Subject: ProviderFactory singleton?
>>
>> Been looking through the code, and why is ProviderFactory a singleton?
>> I would think it would be tied to a bus or a server.  It
>> differentiates by address, but currently I'm working on something
>> with two side-by-side CXF servlets that load completely different
>> CXF configurations.  In this case, providers declared in one server
>> are bleeding into the other because the ProviderFactory uses a singleton.
>>
>> Worth fixing?  Also, are there any other uses of singletons in the
>> system that maybe should be looked at?
>>
>> Cheers,
>> Gary
>>
>> -------------------------------------------------------------------
>> --
>> ---
>> --
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use
>> of this email is prohibited when received in error.
>>
>> -------------------------------------------------------------------
>> --
>> ---
>> --
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use
>> of this email is prohibited when received in error.
>
> --
> Daniel Kulp
> dk...@apache.org
> http://www.dankulp.com/blog

----------------------------------------------------------------------
----
NOTICE: If received in error, please destroy and notify sender. Sender
does not intend to waive confidentiality or privilege. Use of this
email is prohibited when received in error.

--
Daniel Kulp
dk...@apache.org
http://www.dankulp.com/blog

--------------------------------------------------------------------------
NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.

Reply via email to