On Thursday 17 March 2011 7:43:24 AM Jerome Revillard wrote:
> Dear all,
> 
> I'm currently deploying different CXF services inside Tomcat. Each service
> is inside his own webapps so the class loaders are different. I want to
> communicate between the different services using the coloc feature but it
> seems that the classloader is a problem.

There are a bunch of problems, the classloaders likely being the biggest one 
though.

> Indeed, let's take an example. Let's assume that I have a service A in
> webappsA and a service B in webAppsB. As far as I understood looking at the
> source code, the webappsA class loader will contain it's own list of CXF
> servers with one instance of ServerImpl for the services A and the webappsB
> will contain also it's own list of CXF servers and this list will contain
> only the server of the service B.
> 
> The Coloc interceptor check the coloc feature by looking inside the Server
> list a corresponding server but it my case, for instance, if the coloc
> feature is requested for the service A to contact B, the webappsA class
> loader will never find the Server B as it's in the webapssB classloader
> only.
> 
> Do you know how I can manage it? I will try to move some jars inside the
> common webapps but I wonder if I will no break something....

You would need to have all the CXF jars into the share/lib dir as well as the 
jars that contain all the classes and interfaces that would be shared.   If 
the types are not shared, they would also end up in different classloaders and 
thus not shareable.

One that is all set, you would likely need to write another java object (also 
placed in the share/lib area) that would implement the ServerRegistry 
interface and replace the default ServerRegistry of the bus with that.  

Likely, the best approach is to subclass our ServerRegistryImpl and just 
override the getServers() call to return a full collection.   Thus, something 
like:  (pseudo code, haven't compiled it or anything)

public class MyServerRegistry extends ServerRegistryImpl {
      static List<WeakReference<MyServerRegistry>> allRegistries 
             = new LinkedList<WeakReference<MyServerRegistry>>();

     public MyServerRegister(Bus b) {
              super(b);
              synchronized(allRegistries) {
                 allRegistries.add(new WeakReference<MyServerRegistry>(this)); 
              }
     }
    //return the list of servers local to this bus/app
    public List<Server> getLocalServers() {
        return super.getServers();
    }

    public List<Server> getServers() {
        List<Server> ret = new ArrayList<Server>();
        synchronized (allRegistries) {
            ListIterator<WeakReference<MyServerRegistry>> iterator 
                   = allRegistries.listIterator();
            while (iterator.hasNext()) {
                 WeakReference<MyServerRegistry> b = iterator.next();
                 MyServerRegistry r = b.get();
                 if (r == null) {
                        //it's been garbage collected, remove the reference
                        iterator.remove();
                  } else {
                        ret.addAll(r.getLocalServers());
                 }
            }
        }
        return ret;
    }


You can then register that in your spring config via:

<bean id="org.apache.cxf.endpoint.ServerRegistry" 
        class=".....MyServerRegistry"
        lazy-init="false">
        <constructor-arg ref="cxf"/>
    </bean>



> I want to use the coloc feature in order to give really quick access to
> sensitive methods (that I cannot provide as jar because of a lot of
> configuration/security issues) to the services. Do you see another way to
> do it?

The above should do it.

Dan


> 
> All the best,
> Jerome
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Coloc-Tomcat-webapps-tp3873140p3873140.htm
> l Sent from the cxf-user mailing list archive at Nabble.com.

-- 
Daniel Kulp
[email protected]
http://dankulp.com/blog
Talend - http://www.talend.com

Reply via email to